Source code for mrmustard.physics.gaussian
# Copyright 2021 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.
"""This module contains functions for performing calculations on objects in the Gaussian representations."""
from __future__ import annotations
from mrmustard import math, settings
from mrmustard.utils.typing import Matrix, Scalar, Vector
__all__ = [
"fidelity",
"number_means",
"purity",
"symplectic_eigenvals",
"von_neumann_entropy",
]
[docs]
def number_means(cov: Matrix, means: Vector) -> Vector:
r"""Returns the photon number means vector given a Wigner covariance matrix and a means vector.
Args:
cov: the Wigner covariance matrix
means: the Wigner means vector
Returns:
Vector: the photon number means vector
"""
N = means.shape[-1] // 2
return (
means[:N] ** 2
+ means[N:] ** 2
+ math.diag_part(cov[:N, :N])
+ math.diag_part(cov[N:, N:])
- settings.HBAR
) / (2 * settings.HBAR)
[docs]
def purity(cov: Matrix) -> Scalar:
r"""Returns the purity of the state with the given covariance matrix.
Args:
cov (Matrix): the covariance matrix
Returns:
float: the purity
"""
return 1 / math.sqrt(math.det((2 / settings.HBAR) * cov))
[docs]
def symplectic_eigenvals(cov: Matrix) -> Vector:
r"""Returns the sympletic eigenspectrum of a covariance matrix.
For a pure state, we expect the sympletic eigenvalues to be 1.
Args:
cov (Matrix): the covariance matrix
Returns:
List[float]: the sympletic eigenvalues
"""
J = math.J(cov.shape[-1] // 2) # create a sympletic form
M = math.matmul(1j * J, cov * (2 / settings.HBAR))
vals = math.abs(math.eigvals(M)) # compute the eigenspectrum
vals = math.sort(vals)
return vals[::2] # return the even eigenvalues
[docs]
def von_neumann_entropy(cov: Matrix) -> float:
r"""Returns the Von Neumann entropy.
For a pure state, we expect the Von Neumann entropy to be 0.
Reference: (https://arxiv.org/pdf/1110.3234.pdf), Equations 46-47.
Args:
cov (Matrix): the covariance matrix
Returns:
float: the Von Neumann entropy
"""
def g(x):
return math.xlogy((x + 1) / 2, (x + 1) / 2) - math.xlogy((x - 1) / 2, (x - 1) / 2 + 1e-9)
symp_vals = symplectic_eigenvals(cov)
return math.sum(g(symp_vals))
[docs]
def fidelity(mu1: Vector, cov1: Matrix, mu2: Vector, cov2: Matrix) -> float:
r"""Returns the fidelity of two gaussian states.
Reference: `arXiv:2102.05748 <https://arxiv.org/pdf/2102.05748.pdf>`_, equations 95-99.
Note that we compute the square of equation 98.
Args:
mu1: The means vector of state 1.
cov1: The covariance matrix of state 1.
mu2: The means vector of state 2.
cov2: The covariance matrix of state 2.
Returns:
The fidelity of the two states.
"""
cov1 = math.cast(cov1 / settings.HBAR, "complex128") # convert to units where hbar = 1
cov2 = math.cast(cov2 / settings.HBAR, "complex128") # convert to units where hbar = 1
mu1 = math.cast(mu1, "complex128")
mu2 = math.cast(mu2, "complex128")
deltar = (mu2 - mu1) / math.sqrt(
settings.HBAR,
dtype=mu1.dtype,
) # convert to units where hbar = 1
J = math.J(cov1.shape[0] // 2)
I = math.eye(cov1.shape[0])
J = math.cast(J, "complex128")
I = math.cast(I, "complex128")
cov12_inv = math.inv(cov1 + cov2)
V = math.transpose(J) @ cov12_inv @ ((1 / 4) * J + cov2 @ J @ cov1)
W = -2 * (V @ (1j * J))
W_inv = math.inv(W)
matsqrtm = math.sqrtm(
I - W_inv @ W_inv,
) # this also handles the case where the input matrix is close to zero
f0_top = math.det((matsqrtm + I) @ (W @ (1j * J)))
f0_bot = math.det(cov1 + cov2)
f0 = math.sqrt(f0_top / f0_bot) # square of equation 98
dot = math.sum(
math.transpose(deltar) * math.matvec(cov12_inv, deltar),
) # computing (mu2-mu1)/sqrt(hbar).T @ cov12_inv @ (mu2-mu1)/sqrt(hbar)
_fidelity = f0 * math.exp((-1 / 2) * dot) # square of equation 95
return math.real(_fidelity)
_modules/mrmustard/physics/gaussian
Download Python script
Download Notebook
View on GitHub