Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VnEntanglementEntropyMP measurement process #6270

Merged
merged 153 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 143 commits
Commits
Show all changes
153 commits
Select commit Hold shift + click to select a range
42dbec2
qinfo deprecation landing
isaacdevlugt Jun 28, 2024
381f066
warning msg
isaacdevlugt Jun 28, 2024
197e61e
Deprecate `qinfo.mutual_info` (#5917)
isaacdevlugt Jul 3, 2024
851c995
Merge branch 'master' into deprecate-qinfo
isaacdevlugt Jul 3, 2024
35cd95a
Deprecate `qinfo.vn_entropy` (#5912)
isaacdevlugt Jul 3, 2024
e6040a1
Merge branch 'master' into deprecate-qinfo
isaacdevlugt Jul 3, 2024
3a217ae
Merge branch 'master' into deprecate-qinfo
isaacdevlugt Aug 16, 2024
12203ca
Deprecate `qinfo.purity` (#5916)
isaacdevlugt Aug 19, 2024
3348fc0
Deprecate `qinfo.vn_entanglement_entropy` (#5914)
isaacdevlugt Aug 19, 2024
c5e4da2
Merge branch 'master' into deprecate-qinfo
isaacdevlugt Aug 19, 2024
4d47991
format
isaacdevlugt Aug 19, 2024
921efd1
Merge branch 'master' into deprecate-qinfo
isaacdevlugt Aug 19, 2024
9c8e3ba
Deprecate `qinfo.reduced_dm`, `qinfo.fidelity`, `qinfo.relative_entro…
isaacdevlugt Aug 19, 2024
2554ea4
trigger CI
isaacdevlugt Aug 19, 2024
1c1dc37
Merge branch 'master' into deprecate-qinfo
isaacdevlugt Aug 20, 2024
e7f5751
fix test
isaacdevlugt Aug 20, 2024
0e3424d
Merge branch 'deprecate-qinfo' of https://github.com/PennyLaneAI/penn…
isaacdevlugt Aug 20, 2024
5be25d2
fix test
isaacdevlugt Aug 20, 2024
283f4a7
Remove fisher functions; better deprecation messages
mudit2812 Sep 10, 2024
9ff9c4f
[skip ci] Skip CI
mudit2812 Sep 10, 2024
4873b95
Fix tests for legacy opmath (#6110)
astralcai Aug 20, 2024
c7cbf26
Migrate Legacy Devices to `devices` module (#6103)
Shiro-Raven Aug 20, 2024
e969dae
Improve implementation of `group_observables` (#6043)
EmilianoG-byte Aug 20, 2024
96dceb1
Wrapping of legacy device automatically in various device creation/qn…
Shiro-Raven Aug 21, 2024
e4a8b03
[no ci] bump nightly version
ringo-but-quantum Aug 21, 2024
09b3d6d
Add is_leaf argument to pytrees\pytrees.py with test at tests\pytrees…
tonmoy-b Aug 21, 2024
62cdc64
Update stable dependency files (#6072)
github-actions[bot] Aug 21, 2024
6b02ed0
Tree-traversal iterative design & analytic-mode (#5868)
vincentmr Aug 21, 2024
44c0e31
use node and edge hints only on newest version (#6122)
EmilianoG-byte Aug 21, 2024
7fcea32
Add support for multi-controlled zyz (#6042)
maliasadi Aug 21, 2024
1a82d78
Upgrade and generalise general state preparation (#6034)
KetpuntoG Aug 21, 2024
e2675d4
Rename argnum with argnums in Catalyst grad related functions (#6117)
rmoyard Aug 21, 2024
2e70e0f
Upgrade and generalise basis state preparation (#6021)
KetpuntoG Aug 21, 2024
b97cfb1
[no ci] bump nightly version
ringo-but-quantum Aug 22, 2024
42a0561
Add Lattice class and transverse-field Ising Hamiltonian (#6106)
ddhawan11 Aug 22, 2024
2437288
Add InfoBox to `QuantumTape` and Update typehints (#6114)
Shiro-Raven Aug 22, 2024
7ee4ae9
[no ci] bump nightly version
ringo-but-quantum Aug 23, 2024
b7ac8d8
Inplace Adder Operators Quantum Arithmetic (#6109)
gmlejarza Aug 23, 2024
050248a
Add spin Hamiltonians: Heisenberg and Fermi-Hubbard (#6128)
ddhawan11 Aug 23, 2024
177b046
add progress bar when downloading datasets (#5560)
timmysilv Aug 23, 2024
7030e95
Multiplier Operators Quantum Arithmetic (#6112)
gmlejarza Aug 23, 2024
4e1b1f6
Update stable dependency files (#6125)
github-actions[bot] Aug 23, 2024
49118bc
Disable CI for draft PRs (#6093)
anthayes92 Aug 23, 2024
37246e6
Improvements to Jitting: broadcasted measurements and counts on all w…
albi3ro Aug 23, 2024
473b80d
OutAdder and ModExp Operators Quantum Arithmetic (#6121)
gmlejarza Aug 23, 2024
1f4cc29
[no ci] bump nightly version
ringo-but-quantum Aug 26, 2024
10f013c
Preparation for 0.38 release candidate (#6139)
mudit2812 Aug 26, 2024
0a9d049
Bump dev version to 0.39 (#6142)
mudit2812 Aug 26, 2024
60f0ce8
[no ci] bump nightly version
ringo-but-quantum Aug 27, 2024
5410cca
Update reviewer for RC sync workflow (#6152)
mudit2812 Aug 27, 2024
7e83a9a
Daily rc sync to master (#6150)
github-actions[bot] Aug 27, 2024
d8c1403
[BUGFIX] Pytrees: Handle empty shot vector (#6155)
brownj85 Aug 27, 2024
1c847c1
[no ci] bump nightly version
ringo-but-quantum Aug 28, 2024
28c2572
Change strategy for determining RC branch version (#6168)
mudit2812 Aug 28, 2024
bd6eb23
Daily rc sync to master (#6169)
github-actions[bot] Aug 28, 2024
1670732
Fix split_non_commuting bug for Hamiltonians with identity term (#6022)
austingmhuang Aug 28, 2024
f36bbc3
Update stable dependencies on schedule (#6164)
mudit2812 Aug 28, 2024
ae5ea3d
[no ci] bump nightly version
ringo-but-quantum Aug 29, 2024
f997f34
[Capture Project] Easier access to custom primitives (#6129)
albi3ro Aug 29, 2024
de791f9
Daily rc sync to master (#6178)
github-actions[bot] Aug 29, 2024
7b0de96
Mark spin tests for only new opmath (#6177)
mudit2812 Aug 29, 2024
5d5c625
[no ci] bump nightly version
ringo-but-quantum Aug 30, 2024
b0e4128
Daily rc sync to master (#6193)
github-actions[bot] Aug 30, 2024
dec6adc
Test support for capturing nested control flows (#6111)
obliviateandsurrender Aug 31, 2024
e52b994
[no ci] bump nightly version
ringo-but-quantum Sep 2, 2024
cd3d167
[no ci] bump nightly version
ringo-but-quantum Sep 3, 2024
88491ed
`PrepSelPrep` template works with `torch` (#6191)
willjmax Sep 3, 2024
b037ad2
Daily rc sync to master (#6200)
github-actions[bot] Sep 3, 2024
5a146ee
[no ci] bump nightly version
ringo-but-quantum Sep 4, 2024
0c97cb3
Final RC sync for v0.38 (#6205)
mudit2812 Sep 4, 2024
5c4aa3a
FermiWord and FermiSentence __repr__ now return a unique representati…
willjmax Sep 4, 2024
2bdb0b9
Remove `hamiltonian_expand` and `sum_expand` (#6204)
albi3ro Sep 4, 2024
9e4a1fb
[no ci] bump nightly version
ringo-but-quantum Sep 5, 2024
c474451
qsvt wire order (#6212)
KetpuntoG Sep 5, 2024
f0346bb
Miscellaneous updates to CI workflows (#6214)
mudit2812 Sep 5, 2024
283b32c
Update CI to install `mitiq` for `Mitigate` tests (#6216)
mudit2812 Sep 5, 2024
110f3bd
Remove Pytrees bugfix changelog entry (#6189)
mudit2812 Sep 5, 2024
0c26255
Qubitization reformat (#6182)
KetpuntoG Sep 5, 2024
68376be
Bump upload/download-artifact version to v4 (#6224)
mudit2812 Sep 5, 2024
fdd6a63
[no ci] bump nightly version
ringo-but-quantum Sep 6, 2024
825bad1
Various removals for v0.39 (#6203)
albi3ro Sep 6, 2024
9beba48
Remove `default.qubit.tf` (#6207)
albi3ro Sep 6, 2024
390a53a
Remove Python 3.9 in favour of 3.10 as minimum (#6223)
mlxd Sep 6, 2024
58b36eb
Make process_samples on SampleMP jit-compatible with Tracer indices (…
lillian542 Sep 6, 2024
1904af5
Add tests for `MidMeasureMP` and `Conditional` dispatches (#6118)
obliviateandsurrender Sep 6, 2024
0ecc115
[Program Capture] Capture & execute `qml.grad` in plxpr (#6120)
dwierichs Sep 9, 2024
2884078
Rremove labeled PR types from workflows (#6235)
anthayes92 Sep 9, 2024
cf04b6c
Add pauli_rep diagonalization (#6113)
lillian542 Sep 9, 2024
1013d1e
Rename datasets coverage artifact (#6233)
mudit2812 Sep 9, 2024
5696270
[no ci] bump nightly version
ringo-but-quantum Sep 9, 2024
9dff98c
Qml.Qubitization wire order (#6229)
KetpuntoG Sep 9, 2024
8bb1d80
Remove `default.qubit.torch` (#6208)
albi3ro Sep 9, 2024
55e3a31
qml.qchem.excitations optionaly returns fermionic operators (#6171)
willjmax Sep 9, 2024
7746abf
FermiWord and FermiSentence to_mat() method optionally return sparse …
willjmax Sep 9, 2024
2e15022
[Program Capture] Capture & execute `qml.jacobian` in plxpr (#6127)
dwierichs Sep 9, 2024
065d240
Fix zero-jvps with shot vectors (#6219)
dwierichs Sep 10, 2024
31a0aee
[no ci] bump nightly version
ringo-but-quantum Sep 10, 2024
5661278
Adding adjoint methods to FermiWord and FermiSentence classes (#6166)
willjmax Sep 10, 2024
ebbbba2
Remove `Operator.expand` (#6227)
albi3ro Sep 10, 2024
1d9de8e
Merge branch 'master' into deprecate-qinfo
mudit2812 Sep 10, 2024
e189b69
fisher tests removal
mudit2812 Sep 10, 2024
40dfcba
Fix unclosed parenthesis
mudit2812 Sep 10, 2024
453ab58
[skip ci] Removing pytest.warns
mudit2812 Sep 10, 2024
19ed4b1
Fix tests
mudit2812 Sep 11, 2024
d3b217c
Fix CI failures
mudit2812 Sep 11, 2024
91f06b1
Fix vn_entanglement_entropy shape
mudit2812 Sep 11, 2024
43afa76
Add tests for vn_entanglement_entropy
mudit2812 Sep 11, 2024
5a6b593
Merge branch 'master' into deprecate-qinfo
mudit2812 Sep 11, 2024
2ff15b5
Fix copyright date
mudit2812 Sep 11, 2024
1cafca7
Update changelog with MP entry
mudit2812 Sep 11, 2024
e5e4751
Rename qinfo test file
mudit2812 Sep 11, 2024
9ab8d37
Fix failing tests
mudit2812 Sep 12, 2024
b81c667
[skip ci] Fix dm tests
mudit2812 Sep 12, 2024
06c4bc7
Remove vn_entanglement_entropy MP
mudit2812 Sep 13, 2024
d1d5c88
Remove tests
mudit2812 Sep 13, 2024
b9e30a8
Merge branch 'master' into deprecate-qinfo
mudit2812 Sep 13, 2024
cf337dd
Remove init entry
mudit2812 Sep 13, 2024
79789d4
Add `VnEntanglementEntropyMP` measurement process
mudit2812 Sep 13, 2024
1cba1de
Add to __init__
mudit2812 Sep 13, 2024
0c7b2d7
[skip ci] Fix doc formatting
mudit2812 Sep 16, 2024
cde7b81
Fix failing test in legacy opmath (#6272)
astralcai Sep 13, 2024
da09fd1
remove default.qubit.autograd (#6210)
albi3ro Sep 13, 2024
4a62336
Deprecate top level access to legacy device base classes (#6238)
albi3ro Sep 13, 2024
12c50e3
[Program Capture] Add pytree support to captured `qml.grad` and `qml.…
dwierichs Sep 15, 2024
738b2c0
[no ci] bump nightly version
ringo-but-quantum Sep 16, 2024
a049ffb
Pennylane is compatible with numpy 2.0 (#6061)
EmilianoG-byte Sep 16, 2024
df1788c
Clean up how `interface` is handled in `QNode` and `qml.execute` (#6225)
astralcai Sep 16, 2024
c3b9c07
Updating torch to 2.3.0 (#6258)
PietropaoloFrisoni Sep 16, 2024
6e75f86
[no ci] bump nightly version
ringo-but-quantum Sep 17, 2024
adb9ab6
Add `reference.qubit` for testing and reference (#6181)
astralcai Sep 17, 2024
f5d1807
Deprecation QubitStateVector (#6172)
KetpuntoG Sep 17, 2024
02f7efa
PennyLane is compatible with JAX 0.4.28 (#6255)
PietropaoloFrisoni Sep 17, 2024
1d28c69
`qinfo` module deprecations and removals (#5911)
isaacdevlugt Sep 17, 2024
a9b54b6
Miscellaneous deprecations (#6277)
mudit2812 Sep 17, 2024
fcae2b4
Remove `decomp_depth` from `qml.device` constructor (#6234)
albi3ro Sep 17, 2024
bbc47b0
[no ci] bump nightly version
ringo-but-quantum Sep 18, 2024
fc80d56
Remove `simplify` argument from `Hamiltonian` and `LinearCombination`…
mudit2812 Sep 18, 2024
2835656
Merge branch 'master' into vn-entanglement-mp
mudit2812 Sep 18, 2024
b79558c
Add process_density_matrix
mudit2812 Sep 18, 2024
6b97e30
Add note to test
mudit2812 Sep 18, 2024
0edab5c
Merge branch 'master' into vn-entanglement-mp
mudit2812 Sep 18, 2024
8d85979
Apply suggestions from code review
mudit2812 Sep 18, 2024
32b8e04
Update tests/devices/test_qutrit_device.py
mudit2812 Sep 18, 2024
831dae0
Update pennylane/devices/_qubit_device.py
mudit2812 Sep 18, 2024
0f5395c
Update pennylane/devices/_qutrit_device.py
mudit2812 Sep 18, 2024
0d34b3e
Merge branch 'master' into vn-entanglement-mp
mudit2812 Sep 18, 2024
e01396b
black-pylint
mudit2812 Sep 18, 2024
719efa6
Merge branch 'master' into vn-entanglement-mp
mudit2812 Sep 18, 2024
d920143
Add tests for coverage
mudit2812 Sep 19, 2024
4a93aa0
Update which errors to catch
mudit2812 Sep 19, 2024
f1adefc
Merge branch 'master' into vn-entanglement-mp
mudit2812 Sep 19, 2024
03a7afb
Fix failing test
mudit2812 Sep 19, 2024
5ed5f7c
Minor whitespace fix
mudit2812 Sep 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
# Release 0.39.0-dev (development release)

<h3>New features since last release</h3>

* A new `qml.vn_entanglement_entropy` measurement process has been added which measures the
Von Neumann entanglement entropy of a quantum state.
[(#5911)](https://github.com/PennyLaneAI/pennylane/pull/5911)

<h3>Improvements 🛠</h3>

Expand Down
1 change: 1 addition & 0 deletions pennylane/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
state,
var,
vn_entropy,
vn_entanglement_entropy,
purity,
mutual_info,
classical_shadow,
Expand Down
51 changes: 51 additions & 0 deletions pennylane/devices/_qubit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
StateMeasurement,
StateMP,
VarianceMP,
VnEntanglementEntropyMP,
VnEntropyMP,
)
from pennylane.operation import Operation, operation_derivative
Expand Down Expand Up @@ -740,6 +741,29 @@
)
result = self.vn_entropy(wires=obs.wires, log_base=obs.log_base)

elif isinstance(m, VnEntanglementEntropyMP):
if self.wires.labels != tuple(range(self.num_wires)):
raise qml.QuantumFunctionError(

Check warning on line 746 in pennylane/devices/_qubit_device.py

View check run for this annotation

Codecov / codecov/patch

pennylane/devices/_qubit_device.py#L746

Added line #L746 was not covered by tests
"Returning the Von Neumann entanglement entropy is not supported when using custom wire labels"
)

if self._shot_vector is not None:
raise NotImplementedError(
"Returning the Von Neumann entanglement entropy is not supported with shot vectors."
)

if self.shots is not None:
warnings.warn(

Check warning on line 756 in pennylane/devices/_qubit_device.py

View check run for this annotation

Codecov / codecov/patch

pennylane/devices/_qubit_device.py#L756

Added line #L756 was not covered by tests
"Requested Von Neumann entanglement entropy with finite shots; the returned "
"state information is analytic and is unaffected by sampling. To silence "
"this warning, set shots=None on the device.",
UserWarning,
)
wires0, wires1 = obs.raw_wires
result = self.vn_entanglement_entropy(
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved
wires0=wires0, wires1=wires1, log_base=obs.log_base
)

elif isinstance(m, MutualInfoMP):
if self.wires.labels != tuple(range(self.num_wires)):
raise qml.QuantumFunctionError(
Expand Down Expand Up @@ -799,6 +823,7 @@
VarianceMP,
ProbabilityMP,
VnEntropyMP,
VnEntanglementEntropyMP,
MutualInfoMP,
ShadowExpvalMP,
),
Expand Down Expand Up @@ -1038,6 +1063,32 @@
wires = wires.tolist()
return qml.math.vn_entropy(state, indices=wires, c_dtype=self.C_DTYPE, base=log_base)

def vn_entanglement_entropy(self, wires0, wires1, log_base):
r"""Returns the Von Neumann entanglement entropy prior to measurement.
.. math::
S(\rho_A) = -\text{Tr}[\rho_A \log \rho_A] = -\text{Tr}[\rho_B \log \rho_B] = S(\rho_B)
Args:
wires0 (Sequence[int] or int): the wires of the first subsystem
wires1 (Sequence[int] or int): the wires of the second subsystem
log_base (float): Base for the logarithm.
Returns:
float: returns the Von Neumann entropy
"""
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved
try:
state = self.density_matrix(wires=self.wires)
except qml.QuantumFunctionError as e: # pragma: no cover
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved
raise NotImplementedError(
f"Cannot compute the Von Neumman entropy with device {self.name} that is not capable of returning the "
f"state. "
) from e

wires0 = wires0.tolist()
wires1 = wires1.tolist()

return qml.math.vn_entanglement_entropy(
state, indices0=wires0, indices1=wires1, c_dtype=self.C_DTYPE, base=log_base
)

def mutual_info(self, wires0, wires1, log_base):
r"""Returns the mutual information prior to measurement:

Expand Down
18 changes: 18 additions & 0 deletions pennylane/devices/_qutrit_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,24 @@ def vn_entropy(self, wires, log_base):
"Unsupported return type specified for observable Von Neumann entropy"
)

def vn_entanglement_entropy(self, wires0, wires1, log_base):
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved
r"""Returns the Von Neumann entanglement entropy prior to measurement.
.. math::
S(\rho_A) = -\text{Tr}[\rho_A \log \rho_A] = -\text{Tr}[\rho_B \log \rho_B] = S(\rho_B)
Args:
wires0 (Sequence[int] or int): the wires of the first subsystem
wires1 (Sequence[int] or int): the wires of the second subsystem
log_base (float): Base for the logarithm.
Returns:
float: returns the Von Neumann entropy
"""
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved
# TODO: Add support for VnEntanglementEntropy return type. Currently, qml.math is hard coded to calculate this for qubit
# states (see `qml.math.vn_entanglement_entropy()`), so it needs to be updated before VnEntanglementEntropy can be supported for qutrits.
# For now, if a user tries to request this return type, an error will be raised.
raise qml.QuantumFunctionError(
"Unsupported return type specified for observable Von Neumann entanglement entropy"
)

def mutual_info(self, wires0, wires1, log_base):
r"""Returns the mutual information prior to measurement:

Expand Down
10 changes: 7 additions & 3 deletions pennylane/devices/default_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
SampleMP,
StateMP,
VarianceMP,
VnEntanglementEntropyMP,
VnEntropyMP,
)
from pennylane.operation import Channel
Expand Down Expand Up @@ -637,6 +638,9 @@ def _snapshot_measurements(self, density_matrix, measurement):
density_matrix, indices=map_wires, c_dtype=self.C_DTYPE, base=base
)

elif isinstance(measurement, VnEntanglementEntropyMP):
snap_result = measurement.process_density_matrix(density_matrix, wire_order=self.wires)

elif isinstance(measurement, MutualInfoMP):
base = measurement.log_base
wires0, wires1 = list(map(self.map_wires, measurement.raw_wires))
Expand Down Expand Up @@ -762,9 +766,9 @@ def execute(self, circuit, **kwargs):
# not specified or all wires specified.
self.measured_wires = self.wires
return super().execute(circuit, **kwargs)
if isinstance(m, (VnEntropyMP, MutualInfoMP)):
# VnEntropy, MutualInfo: Computed for the state
# prior to measurement. So, readout error need not be applied to the
if isinstance(m, (VnEntropyMP, VnEntanglementEntropyMP, MutualInfoMP)):
# VnEntropy, VnEntanglementEntropyMP, MutualInfo: Computed for the state
# prior to measurement. So, readout error need not be applied on the
# corresponding device wires.
continue
wires_list.append(m.wires)
Expand Down
2 changes: 2 additions & 0 deletions pennylane/measurements/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ def circuit(x):
StateMeasurement,
Variance,
VnEntropy,
VnEntanglementEntropy,
)
from .mid_measure import MeasurementValue, MidMeasureMP, measure, find_post_processed_mcms
from .mutual_info import MutualInfoMP, mutual_info
Expand All @@ -298,3 +299,4 @@ def circuit(x):
from .state import DensityMatrixMP, StateMP, density_matrix, state
from .var import VarianceMP, var
from .vn_entropy import VnEntropyMP, vn_entropy
from .vn_entanglement_entropy import VnEntanglementEntropyMP, vn_entanglement_entropy
4 changes: 4 additions & 0 deletions pennylane/measurements/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ObservableReturnTypes(Enum):
State = "state"
MidMeasure = "measure"
VnEntropy = "vnentropy"
VnEntanglementEntropy = "vnentanglemententropy"
MutualInfo = "mutualinfo"
Shadow = "shadow"
ShadowExpval = "shadowexpval"
Expand Down Expand Up @@ -90,6 +91,9 @@ def __repr__(self):
VnEntropy = ObservableReturnTypes.VnEntropy
"""Enum: An enumeration which represents returning Von Neumann entropy before measurements."""

VnEntanglementEntropy = ObservableReturnTypes.VnEntanglementEntropy
astralcai marked this conversation as resolved.
Show resolved Hide resolved
"""Enum: An enumeration which represents returning Von Neumann entanglement entropy before measurements."""

MutualInfo = ObservableReturnTypes.MutualInfo
"""Enum: An enumeration which represents returning the mutual information before measurements."""

Expand Down
184 changes: 184 additions & 0 deletions pennylane/measurements/vn_entanglement_entropy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Copyright 2018-2024 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=protected-access
"""
This module contains the qml.vn_entanglement_entropy measurement.
"""
from copy import copy
from typing import Optional, Sequence

import pennylane as qml
from pennylane.wires import Wires

from .measurements import StateMeasurement, VnEntanglementEntropy


def vn_entanglement_entropy(wires0, wires1, log_base=None):
r"""Measures the `Von Neumann entanglement entropy <https://en.wikipedia.org/wiki/Entropy_of_entanglement>`_
of a quantum state:

.. math::

S(\rho_A) = -\text{Tr}[\rho_A \log \rho_A] = -\text{Tr}[\rho_B \log \rho_B] = S(\rho_B)

where :math:`S` is the Von Neumann entropy; :math:`\rho_A = \text{Tr}_B [\rho_{AB}]` and
:math:`\rho_B = \text{Tr}_A [\rho_{AB}]` are the reduced density matrices for each partition.
The Von Neumann entanglement entropy is a measure of the degree of quantum entanglement between
two subsystems constituting a pure bipartite quantum state. The entropy of entanglement is the
Von Neumann entropy of the reduced density matrix for any of the subsystems. If it is non-zero,
it indicates the two subsystems are entangled.

Args:
wires0 (Sequence[int] or int): the wires of the first subsystem
wires1 (Sequence[int] or int): the wires of the second subsystem
log_base (float): Base for the logarithm.

Returns:
VnEntanglementEntropyMP: measurement process instance

**Example:**

.. code-block:: python3

dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def circuit(x):
qml.RY(x, 0)
qml.Hadamard(0)
qml.CNOT([0, 1])
return qml.vn_entanglement_entropy([0], [1])

Executing this QNode:

>>> circuit(1.967)
0.16389850379003218

It is also possible to get the gradient of the previous QNode:

>>> param = np.array(np.pi/4, requires_grad=True)
>>> qml.grad(circuit)(param)
tensor(-0.62322524, requires_grad=True)

.. note::

Calculating the derivative of :func:`~pennylane.vn_entanglement_entropy` is currently supported when
using the classical backpropagation differentiation method (``diff_method="backprop"``)
with a compatible device and finite differences (``diff_method="finite-diff"``).

.. seealso:: :func:`~pennylane.vn_entropy` and :func:`pennylane.math.vn_entanglement_entropy`
"""
wires0 = qml.wires.Wires(wires0)
wires1 = qml.wires.Wires(wires1)

# the subsystems cannot overlap
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved
if not any(qml.math.is_abstract(w) for w in wires0 + wires1) and [
wire for wire in wires0 if wire in wires1
]:
raise qml.QuantumFunctionError(

Check warning on line 88 in pennylane/measurements/vn_entanglement_entropy.py

View check run for this annotation

Codecov / codecov/patch

pennylane/measurements/vn_entanglement_entropy.py#L88

Added line #L88 was not covered by tests
"Subsystems for computing entanglement entropy must not overlap."
)
return VnEntanglementEntropyMP(wires=(wires0, wires1), log_base=log_base)


class VnEntanglementEntropyMP(StateMeasurement):
"""Measurement process that computes the Von Neumann entanglement entropy between the provided wires.
Please refer to :func:`~pennylane.vn_entanglement_entropy` for detailed documentation.

Args:
wires (Sequence[.Wires]): The wires the measurement process applies to.
id (str): custom label given to a measurement instance, can be useful for some applications
where the instance has to be identified
log_base (float): base for the logarithm
"""

def _flatten(self):
metadata = (("wires", tuple(self.raw_wires)), ("log_base", self.log_base))
return (None, None), metadata

Check warning on line 107 in pennylane/measurements/vn_entanglement_entropy.py

View check run for this annotation

Codecov / codecov/patch

pennylane/measurements/vn_entanglement_entropy.py#L106-L107

Added lines #L106 - L107 were not covered by tests

# pylint: disable=too-many-arguments
def __init__(
self,
wires: Optional[Sequence[Wires]] = None,
id: Optional[str] = None,
log_base: Optional[float] = None,
):
self.log_base = log_base
super().__init__(wires=wires, id=id)

# pylint: disable=arguments-differ
@classmethod
def _primitive_bind_call(cls, wires: Sequence, **kwargs):
if cls._wires_primitive is None: # pragma: no cover
# just a safety check
return type.__call__(cls, wires=wires, **kwargs) # pragma: no cover
return cls._wires_primitive.bind(*wires[0], *wires[1], n_wires0=len(wires[0]), **kwargs)

Check warning on line 125 in pennylane/measurements/vn_entanglement_entropy.py

View check run for this annotation

Codecov / codecov/patch

pennylane/measurements/vn_entanglement_entropy.py#L125

Added line #L125 was not covered by tests

def __repr__(self):
return f"VnEntanglementEntropy(wires0={self.raw_wires[0].tolist()}, wires1={self.raw_wires[1].tolist()}, log_base={self.log_base})"

@property
def hash(self):
"""int: returns an integer hash uniquely representing the measurement process"""
fingerprint = (

Check warning on line 133 in pennylane/measurements/vn_entanglement_entropy.py

View check run for this annotation

Codecov / codecov/patch

pennylane/measurements/vn_entanglement_entropy.py#L133

Added line #L133 was not covered by tests
self.__class__.__name__,
tuple(self.raw_wires[0].tolist()),
tuple(self.raw_wires[1].tolist()),
self.log_base,
)

return hash(fingerprint)

Check warning on line 140 in pennylane/measurements/vn_entanglement_entropy.py

View check run for this annotation

Codecov / codecov/patch

pennylane/measurements/vn_entanglement_entropy.py#L140

Added line #L140 was not covered by tests

@property
def return_type(self):
return VnEntanglementEntropy

@property
def numeric_type(self):
return float

def map_wires(self, wire_map: dict):
new_measurement = copy(self)
new_measurement._wires = [
Wires([wire_map.get(wire, wire) for wire in wires]) for wires in self.raw_wires
]
return new_measurement

def shape(
self, shots: Optional[int] = None, num_device_wires: int = 0
): # pylint: disable=unused-argument
return ()

def process_state(self, state: Sequence[complex], wire_order: Wires):
density_matrix = qml.math.dm_from_state_vector(state)
return self.process_density_matrix(density_matrix=density_matrix, wire_order=wire_order)

def process_density_matrix(
self, density_matrix: Sequence[complex], wire_order: Wires
): # pylint: disable=unused-argument
return qml.math.vn_entanglement_entropy(
density_matrix,
indices0=list(self._wires[0]),
indices1=list(self._wires[1]),
c_dtype=density_matrix.dtype,
base=self.log_base,
)
mudit2812 marked this conversation as resolved.
Show resolved Hide resolved


if VnEntanglementEntropyMP._wires_primitive is not None:

@VnEntanglementEntropyMP._wires_primitive.def_impl
def _(*all_wires, n_wires0, **kwargs):
wires0 = all_wires[:n_wires0]
wires1 = all_wires[n_wires0:]
return type.__call__(VnEntanglementEntropyMP, wires=(wires0, wires1), **kwargs)

Check warning on line 184 in pennylane/measurements/vn_entanglement_entropy.py

View check run for this annotation

Codecov / codecov/patch

pennylane/measurements/vn_entanglement_entropy.py#L182-L184

Added lines #L182 - L184 were not covered by tests
Loading
Loading