|
4 | 4 |
|
5 | 5 | from qibo.backends import _check_backend
|
6 | 6 | from qibo.config import PRECISION_TOL, raise_error
|
7 |
| -from qibo.quantum_info.linalg_operations import partial_trace |
| 7 | +from qibo.quantum_info.linalg_operations import ( |
| 8 | + matrix_power, |
| 9 | + partial_trace, |
| 10 | + partial_transpose, |
| 11 | +) |
8 | 12 | from qibo.quantum_info.metrics import fidelity, purity
|
9 | 13 |
|
10 | 14 |
|
@@ -116,6 +120,39 @@ def entanglement_of_formation(
|
116 | 120 | return ent_of_form
|
117 | 121 |
|
118 | 122 |
|
| 123 | +def negativity(state, bipartition, backend=None): |
| 124 | + """Calculates the negativity of a bipartite quantum state. |
| 125 | +
|
| 126 | + Given a bipartite state :math:`\\rho \\in \\mathcal{H}_{A} \\otimes \\mathcal{H}_{B}`, |
| 127 | + the negativity :math:`\\operatorname{Neg}(\\rho)` is given by |
| 128 | +
|
| 129 | + .. math:: |
| 130 | + \\operatorname{Neg}(\\rho) = \\frac{1}{2} \\, |
| 131 | + \\left( \\norm{\\rho_{B}}_{1} - 1 \\right) \\, , |
| 132 | +
|
| 133 | + where :math:`\\rho_{B}` is the reduced density matrix after tracing out qubits in |
| 134 | + partition :math:`A`, and :math:`\\norm{\\cdot}_{1}` is the Schatten :math:`1`-norm |
| 135 | + (also known as nuclear norm or trace norm). |
| 136 | +
|
| 137 | + Args: |
| 138 | + state (ndarray): statevector or density matrix. |
| 139 | + bipartition (list or tuple or ndarray): qubits in the subsystem to be traced out. |
| 140 | + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used |
| 141 | + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. |
| 142 | + Defaults to ``None``. |
| 143 | +
|
| 144 | + Returns: |
| 145 | + float: Negativity :math:`\\operatorname{Neg}(\\rho)` of state :math:`\\rho`. |
| 146 | + """ |
| 147 | + backend = _check_backend(backend) |
| 148 | + |
| 149 | + reduced = partial_transpose(state, bipartition, backend) |
| 150 | + reduced = backend.np.conj(reduced.T) @ reduced |
| 151 | + norm = backend.np.trace(matrix_power(reduced, 1 / 2, backend)) |
| 152 | + |
| 153 | + return float(backend.np.real((norm - 1) / 2)) |
| 154 | + |
| 155 | + |
119 | 156 | def entanglement_fidelity(
|
120 | 157 | channel, nqubits: int, state=None, check_hermitian: bool = False, backend=None
|
121 | 158 | ):
|
|
0 commit comments