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 hilbert_schmidt_inner_product to quantum_info.metrics #1476

Merged
merged 13 commits into from
Oct 14, 2024
6 changes: 6 additions & 0 deletions doc/source/api-reference/qibo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,12 @@ Trace distance
raised when using `cupy` backend.


Hilbert-Schmidt inner product
"""""""""""""""""""""""""""""

.. autofunction:: qibo.quantum_info.hilbert_schmidt_inner_product


Hilbert-Schmidt distance
""""""""""""""""""""""""

Expand Down
2 changes: 1 addition & 1 deletion src/qibo/quantum_info/entropies.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ def mutual_information(
of state :math:`\\rho` is given by

.. math::
I(\\rho}) \\equiv S(\\rho_{A}) + S(\\rho_{B}) - S(\\rho) \\, ,
I(\\rho) \\equiv S(\\rho_{A}) + S(\\rho_{B}) - S(\\rho) \\, ,

where :math:`B` is the remaining qubits that are not in partition :math:`A`,
and :math:`S(\\cdot)` is the :func:`qibo.quantum_info.von_neumann_entropy`.
Expand Down
45 changes: 39 additions & 6 deletions src/qibo/quantum_info/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,41 @@ def trace_distance(state, target, check_hermitian: bool = False, backend=None):
return distance


def hilbert_schmidt_inner_product(operator_A, operator_B, backend=None):
"""Calculate the Hilbert-Schmidt inner product between two operators.

Given two operators :math:`A, \\, B \\in \\mathcal{H}`, the Hilbert-Schmidt
inner product between the two is given by

.. math::
\\braket{A, \\, B}_{\\text{HS}} = \\text{tr}\\left(A^{\\dagger} \\, B\\right) \\, .

Args:
operator_A (ndarray): operator :math:`A`.
operator_B (ndarray): operator :math:`B`.
backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used
in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`.
Defaults to ``None``.

Returns:
float: Hilbert-Schmidt inner product :math:`\\braket{A, \\, B}_{\\text{HS}}`.
"""
backend = _check_backend(backend)

inner_product = backend.np.trace(backend.np.conj(operator_A.T) @ operator_B)

return backend.np.real(inner_product)


def hilbert_schmidt_distance(state, target, backend=None):
"""Hilbert-Schmidt distance between two quantum states:
"""Calculate the Hilbert-Schmidt distance between two quantum states:

.. math::
\\langle \\rho \\, , \\, \\sigma \\rangle_{\\text{HS}} =
\\text{tr}\\left((\\rho - \\sigma)^{2}\\right)
\\braket{\\rho - \\sigma, \\, \\rho - \\sigma}_{\\text{HS}} =
\\text{tr}\\left((\\rho - \\sigma)^{2}\\right) \\, ,

where :math:`\\braket{\\cdot, \\, \\cdot}_{\\text{HS}}` is the
:func:`qibo.quantum_info.hilbert_schmidt_inner_product`.

Args:
state (ndarray): statevector or density matrix.
Expand All @@ -151,6 +180,11 @@ def hilbert_schmidt_distance(state, target, backend=None):
Returns:
float: Hilbert-Schmidt distance between ``state`` :math:`\\rho`
and ``target`` :math:`\\sigma`.

References:
1. P. J. Coles, M. Cerezo, and L. Cincio, *Strong bound between trace distance
and Hilbert-Schmidt distance for low-rank states*, `Phys. Rev. A 100, 022103
<https://doi.org/10.1103/PhysRevA.100.022103>`_ (2019).
"""
backend = _check_backend(backend)

Expand All @@ -171,10 +205,9 @@ def hilbert_schmidt_distance(state, target, backend=None):
state = backend.np.outer(backend.np.conj(state), state)
target = backend.np.outer(backend.np.conj(target), target)

distance = backend.np.real(backend.np.trace((state - target) ** 2))
distance = float(distance)
difference = state - target

return distance
return hilbert_schmidt_inner_product(difference, difference, backend=backend)


def fidelity(state, target, check_hermitian: bool = False, backend=None):
Expand Down
10 changes: 6 additions & 4 deletions src/qibo/quantum_info/superoperator_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ def vectorization(state, order: str = "row", backend=None):
If ``order="row"``, then:

.. math::
|\\rho) = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{k} \\otimes \\ket{l}
|\\rho) = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{k} \\otimes \\ket{l} \\, .

If ``order="column"``, then:

.. math::
|\\rho) = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{l} \\otimes \\ket{k}
|\\rho) = \\sum_{k, l} \\, \\rho_{kl} \\, \\ket{l} \\otimes \\ket{k} \\, .

If ``state`` is a 3-dimensional tensor, it is interpreted as a batch of states.

If ``state`` is a 3-dimensional tensor it is interpreted as a batch of states.
Args:
state: statevector, density matrix, an array of statevectors, or an array of density matrices.
state (ndarray): statevector, density matrix, an array of statevectors,
or an array of density matrices.
order (str, optional): If ``"row"``, vectorization is performed
row-wise. If ``"column"``, vectorization is performed
column-wise. If ``"system"``, a block-vectorization is
Expand Down