Skip to content

Commit

Permalink
Fix doc quantum information and ising (#2732)
Browse files Browse the repository at this point in the history
* Ising doc

* Move entropy test

* Math doc

* Measurement doc

* qinfo doc

* Update pennylane/qinfo/transforms.py

Co-authored-by: Edward Jiang <[email protected]>

* Apply suggestions from code review

Co-authored-by: Edward Jiang <[email protected]>

* Update pennylane/math/quantum.py

* Update

* Fix kwargs for fidelity (#2740)

* update

* Typo

* Update pennylane/qinfo/transforms.py

Co-authored-by: Christina Lee <[email protected]>

Co-authored-by: Christina Lee <[email protected]>

* Reduced dm

* Apply suggestions from code review

Co-authored-by: Edward Jiang <[email protected]>

* remove reduce dm

Co-authored-by: Edward Jiang <[email protected]>
Co-authored-by: Christina Lee <[email protected]>
  • Loading branch information
3 people authored Jun 17, 2022
1 parent 0778b2e commit 9a07e07
Show file tree
Hide file tree
Showing 8 changed files with 446 additions and 377 deletions.
1 change: 0 additions & 1 deletion pennylane/math/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ def __getattr__(name):
"is_independent",
"marginal_prob",
"mutual_info",
"reduced_dm",
"ones_like",
"reduced_dm",
"requires_grad",
Expand Down
65 changes: 44 additions & 21 deletions pennylane/math/quantum.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def marginal_prob(prob, axis):
def _density_matrix_from_matrix(density_matrix, indices, check_state=False):
"""Compute the density matrix from a state represented with a density matrix.
Args:
density_matrix (tensor_like): 2D density matrix tensor. This tensor should be of size ``(2**N, 2**N)`` for some
integer number of wires``N``.
Expand Down Expand Up @@ -249,7 +250,7 @@ def _partial_trace(density_matrix, indices):
[[1.+0.j 0.+0.j]
[0.+0.j 0.+0.j]], shape=(2, 2), dtype=complex128)
"""
# Does not support same indices sum in backprop
# Autograd does not support same indices sum in backprop
if get_interface(density_matrix) == "autograd":
density_matrix = _partial_trace_autograd(density_matrix, indices)
return density_matrix
Expand Down Expand Up @@ -395,7 +396,8 @@ def _density_matrix_from_state_vector(state, indices, check_state=False):


def reduced_dm(state, indices, check_state=False, c_dtype="complex128"):
"""Compute the reduced density matrix from a state vector or a density matrix.
"""Compute the reduced density matrix from a state vector or a density matrix. It supports all interfaces (Numpy,
Autograd, Torch, Tensorflow and Jax).
Args:
state (tensor_like): ``(2**N)`` state vector or ``(2**N, 2**N)`` density matrix.
Expand All @@ -406,8 +408,6 @@ def reduced_dm(state, indices, check_state=False, c_dtype="complex128"):
Returns:
tensor_like: Reduced density matrix of size ``(2**len(indices), 2**len(indices))``
**Example**
>>> x = [1, 0, 1, 0] / np.sqrt(2)
Expand All @@ -420,7 +420,7 @@ def reduced_dm(state, indices, check_state=False, c_dtype="complex128"):
[0.+0.j 0.+0.j]]
>>> y = tf.Variable([1, 0, 0, 0], dtype=tf.complex128)
>>> reduced_dm(z, indices=[1])
>>> reduced_dm(y, indices=[1])
tf.Tensor(
[[1.+0.j 0.+0.j]
[0.+0.j 0.+0.j]], shape=(2, 2), dtype=complex128)
Expand Down Expand Up @@ -454,7 +454,8 @@ def reduced_dm(state, indices, check_state=False, c_dtype="complex128"):


def vn_entropy(state, indices, base=None, check_state=False, c_dtype="complex128"):
r"""Compute the Von Neumann entropy from a state vector or density matrix on a given subsystem.
r"""Compute the Von Neumann entropy from a state vector or density matrix on a given subsystem. It supports all
interfaces (Numpy, Autograd, Torch, Tensorflow and Jax).
.. math::
S( \rho ) = -\text{Tr}( \rho \log ( \rho ))
Expand All @@ -471,13 +472,21 @@ def vn_entropy(state, indices, base=None, check_state=False, c_dtype="complex128
**Example**
The entropy of a subsystem for any state vectors can be obtained. Here is an example for the
maximally entangled state, where the subsystem entropy is maximal (default base for log is exponential).
>>> x = [1, 0, 0, 1] / np.sqrt(2)
>>> vn_entropy(x, indices=[0])
0.6931472
The logarithm base can be switched to 2 for example.
>>> vn_entropy(x, indices=[0], base=2)
1.0
The entropy can be obtained by providing a quantum state as a density matrix, for example:
>>> y = [[1/2, 0, 0, 1/2], [0, 0, 0, 0], [0, 0, 0, 0], [1/2, 0, 0, 1/2]]
>>> vn_entropy(x, indices=[0])
0.6931472
Expand Down Expand Up @@ -534,7 +543,8 @@ def mutual_info(state, indices0, indices1, base=None, check_state=False, c_dtype
The mutual information is a measure of correlation between two subsystems.
More specifically, it quantifies the amount of information obtained about
one system by measuring the other system.
one system by measuring the other system. It supports all interfaces
(Numpy, Autograd, Torch, Tensorflow and Jax).
Each state can be given as a state vector in the computational basis, or
as a density matrix.
Expand All @@ -552,13 +562,19 @@ def mutual_info(state, indices0, indices1, base=None, check_state=False, c_dtype
**Examples**
The mutual information between subsystems for a state vector can be returned as follows:
>>> x = np.array([1, 0, 0, 1]) / np.sqrt(2)
>>> qml.math.mutual_info(x, indices0=[0], indices1=[1])
1.3862943611198906
It is also possible to change the log basis.
>>> qml.math.mutual_info(x, indices0=[0], indices1=[1], base=2)
2.0
Similarly the quantum state can be provided as a density matrix:
>>> y = np.array([[1/2, 1/2, 0, 1/2], [1/2, 0, 0, 0], [0, 0, 0, 0], [1/2, 0, 0, 1/2]])
>>> qml.math.mutual_info(y, indices0=[0], indices1=[1])
0.4682351577408206
Expand Down Expand Up @@ -628,8 +644,9 @@ def fidelity(state0, state1, check_state=False, c_dtype="complex128"):
F( \ket{\psi} , \ket{\phi}) = \left|\braket{\psi, \phi}\right|^2
.. note::
The second state is coerced to the type and dtype of the first state. The fidelity is returned in the type
of the interface of the first state.
It supports all interfaces (Numpy, Autograd, Torch, Tensorflow and Jax). The second state is coerced
to the type and dtype of the first state. The fidelity is returned in the type of the interface of the
first state.
Args:
state0 (tensor_like): 1D state vector or 2D density matrix
Expand All @@ -643,20 +660,26 @@ def fidelity(state0, state1, check_state=False, c_dtype="complex128"):
**Example**
>>> state0 = [0.98753537-0.14925137j, 0.00746879-0.04941796j]
>>> state1 = [0.99500417+0.j, 0.09983342+0.j]
>>> qml.math.fidelity(state0, state1)
0.9905158135644924
Two state vectors can be used as arguments and the fidelity (overlap) is returned, e.g.:
>>> state0 = [0.98753537-0.14925137j, 0.00746879-0.04941796j]
>>> state1 = [0.99500417+0.j, 0.09983342+0.j]
>>> qml.math.fidelity(state0, state1)
0.9905158135644924
Alternatively one can give a state vector and a density matrix as arguments, e.g.:
>>> state0 = [0, 1]
>>> state1 = [[0, 0], [0, 1]]
>>> qml.math.fidelity(state0, state1)
1.0
>>> state0 = [0, 1]
>>> state1 = [[0, 0], [0, 1]]
>>> qml.math.fidelity(state0, state1)
1.0
It also works with two density matrices, e.g.:
>>> state0 = [[1, 0], [0, 0]]
>>> state1 = [[0, 0], [0, 1]]
>>> qml.math.fidelity(state0, state1)
0.0
>>> state0 = [[1, 0], [0, 0]]
>>> state1 = [[0, 0], [0, 1]]
>>> qml.math.fidelity(state0, state1)
0.0
"""
# Cast as a c_dtype array
Expand Down
24 changes: 18 additions & 6 deletions pennylane/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,11 +879,17 @@ def circuit_entropy(x):
>>> circuit_entropy(np.pi/2)
0.6931472
It is also possible to get the gradient of the previous QNode:
>>> param = np.array(np.pi/4, requires_grad=True)
>>> qml.grad(circuit_entropy)(param)
0.6232252401402305
.. note::
Calculating the derivative of :func:`~.vn_entropy` is currently only supported when
Calculating the derivative of :func:`~.vn_entropy` is currently supported when
using the classical backpropagation differentiation method (``diff_method="backprop"``)
with a compatible device.
with a compatible device and finite differences (``diff_method="finite-diff"``).
"""
wires = qml.wires.Wires(wires)
return MeasurementProcess(VnEntropy, wires=wires, log_base=log_base)
Expand Down Expand Up @@ -914,20 +920,26 @@ def mutual_info(wires0, wires1, log_base=None):
dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def circuit(x):
def circuit_mutual(x):
qml.IsingXX(x, wires=[0, 1])
return qml.mutual_info(wires0=[0], wires1=[1])
Executing this QNode:
>>> circuit(np.pi / 2)
>>> circuit_mutual(np.pi/2)
1.3862943611198906
It is also possible to get the gradient of the previous QNode:
>>> param = np.array(np.pi/4, requires_grad=True)
>>> qml.grad(circuit_mutual)(param)
1.2464504802804612
.. note::
Calculating the derivative of :func:`~.mutual_info` is currently only supported when
Calculating the derivative of :func:`~.mutual_info` is currently supported when
using the classical backpropagation differentiation method (``diff_method="backprop"``)
with a compatible device.
with a compatible device and finite differences (``diff_method="finite-diff"``).
.. seealso::
Expand Down
8 changes: 4 additions & 4 deletions pennylane/ops/qubit/parametric_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -2306,7 +2306,7 @@ class IsingXX(Operation):
r"""
Ising XX coupling gate
.. math:: XX(\phi) = \exp(-i \frac{\theta}{2} (X \otimes X)) =
.. math:: XX(\phi) = \exp(-i \frac{\phi}{2} (X \otimes X)) =
\begin{bmatrix} =
\cos(\phi / 2) & 0 & 0 & -i \sin(\phi / 2) \\
0 & \cos(\phi / 2) & -i \sin(\phi / 2) & 0 \\
Expand Down Expand Up @@ -2437,7 +2437,7 @@ class IsingYY(Operation):
r"""
Ising YY coupling gate
.. math:: \mathtt{YY}(\phi) = \exp(-i \frac{\theta}{2} (Y \otimes Y)) =
.. math:: \mathtt{YY}(\phi) = \exp(-i \frac{\phi}{2} (Y \otimes Y)) =
\begin{bmatrix}
\cos(\phi / 2) & 0 & 0 & i \sin(\phi / 2) \\
0 & \cos(\phi / 2) & -i \sin(\phi / 2) & 0 \\
Expand Down Expand Up @@ -2567,7 +2567,7 @@ class IsingZZ(Operation):
r"""
Ising ZZ coupling gate
.. math:: ZZ(\phi) = \exp(-i \frac{\theta}{2} (Z \otimes Z) =
.. math:: ZZ(\phi) = \exp(-i \frac{\phi}{2} (Z \otimes Z)) =
\begin{bmatrix}
e^{-i \phi / 2} & 0 & 0 & 0 \\
0 & e^{i \phi / 2} & 0 & 0 \\
Expand Down Expand Up @@ -2729,7 +2729,7 @@ class IsingXY(Operation):
r"""
Ising (XX + YY) coupling gate
.. math:: \mathtt{XY}(\phi) = \exp(-i \frac{\theta}{4} (X \otimes X + Y \otimes Y) =
.. math:: \mathtt{XY}(\phi) = \exp(-i \frac{\theta}{4} (X \otimes X + Y \otimes Y)) =
\begin{bmatrix}
1 & 0 & 0 & 0 \\
0 & \cos(\phi / 2) & i \sin(\phi / 2) & 0 \\
Expand Down
Loading

0 comments on commit 9a07e07

Please sign in to comment.