Skip to content

Commit

Permalink
Entanglement fidelity of a quantum channel (#4158)
Browse files Browse the repository at this point in the history
  • Loading branch information
viathor committed Jun 3, 2021
1 parent 7065c6d commit 074c4e4
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
1 change: 1 addition & 0 deletions cirq-core/cirq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
density_matrix,
density_matrix_from_state_vector,
dirac_notation,
entanglement_fidelity,
eye_tensor,
fidelity,
kraus_to_channel_matrix,
Expand Down
1 change: 1 addition & 0 deletions cirq-core/cirq/qis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from cirq.qis.clifford_tableau import CliffordTableau

from cirq.qis.measures import (
entanglement_fidelity,
fidelity,
von_neumann_entropy,
)
Expand Down
27 changes: 26 additions & 1 deletion cirq-core/cirq/qis/measures.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import numpy as np
import scipy

from cirq import value
from cirq import protocols, value
from cirq.qis.states import (
QuantumState,
infer_qid_shape,
Expand Down Expand Up @@ -273,3 +273,28 @@ def von_neumann_entropy(
if validate:
_ = quantum_state(state, qid_shape=qid_shape, copy=False, validate=True, atol=atol)
return 0.0


def entanglement_fidelity(operation: 'cirq.SupportsChannel') -> float:
r"""Returns entanglement fidelity of a given quantum channel.
Entanglement fidelity $F_e$ of a quantum channel $E: L(H) \to L(H)$ is the overlap between
the maximally entangled state $|\phi\rangle = \frac{1}{\sqrt{dim H}} \sum_i|i\rangle|i\rangle$
and the state obtained by sending one half of $|\phi\rangle$ through the channel $E$, i.e.
$$
F_e = \langle\phi|(E \otimes I)(|\phi\rangle\langle\phi|)|\phi\rangle
$$
where $I: L(H) \to L(H)$ is the identity map.
Args:
operation: Quantum channel whose entanglement fidelity is to be computed.
Returns:
Entanglement fidelity of the channel represented by operation.
"""
f = 0.0
for k in protocols.channel(operation):
f += np.abs(np.trace(k)) ** 2
n_qubits = protocols.num_qubits(operation)
return float(f / 4 ** n_qubits)
37 changes: 37 additions & 0 deletions cirq-core/cirq/qis/measures_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,40 @@ def test_von_neumann_entropy():
)
== 0
)


@pytest.mark.parametrize(
'gate, expected_entanglement_fidelity',
(
(cirq.I, 1),
(cirq.X, 0),
(cirq.Y, 0),
(cirq.Z, 0),
(cirq.S, 1 / 2),
(cirq.CNOT, 1 / 4),
(cirq.TOFFOLI, 9 / 16),
),
)
def test_entanglement_fidelity_of_unitary_channels(gate, expected_entanglement_fidelity):
assert np.isclose(cirq.entanglement_fidelity(gate), expected_entanglement_fidelity)


@pytest.mark.parametrize('p', (0, 0.1, 0.2, 0.5, 0.8, 0.9, 1))
@pytest.mark.parametrize(
'channel_factory, entanglement_fidelity_formula',
(
# Each Pauli error turns the maximally entangled state into an orthogonal state, so only
# the error-free term, whose pre-factor is 1 - p, contributes to entanglement fidelity.
(cirq.depolarize, lambda p: 1 - p),
(lambda p: cirq.depolarize(p, n_qubits=2), lambda p: 1 - p),
(lambda p: cirq.depolarize(p, n_qubits=3), lambda p: 1 - p),
# See e.g. https://quantumcomputing.stackexchange.com/questions/16074 for average fidelity,
# then use Horodecki formula F_avg = (N F_e + 1) / (N + 1) to find entanglement fidelity.
(cirq.amplitude_damp, lambda gamma: 1 / 2 - gamma / 4 + np.sqrt(1 - gamma) / 2),
),
)
def test_entanglement_fidelity_of_noisy_channels(p, channel_factory, entanglement_fidelity_formula):
channel = channel_factory(p)
actual_entanglement_fidelity = cirq.entanglement_fidelity(channel)
expected_entanglement_fidelity = entanglement_fidelity_formula(p)
assert np.isclose(actual_entanglement_fidelity, expected_entanglement_fidelity)

0 comments on commit 074c4e4

Please sign in to comment.