Source code for mercurial.core.entanglement

"""Entanglement measures: concurrence and logarithmic negativity (Section 29)."""

import numpy as np
from scipy.linalg import eigvals


[docs] def concurrence_pure(state: np.ndarray) -> float: a, b, c, d = state return max(0.0, 2 * abs(a * d - b * c))
[docs] def concurrence_mixed(density: np.ndarray) -> float: sy = np.array([[0, -1j], [1j, 0]], dtype=complex) sy_sy = np.kron(sy, sy) rho_conj = density.conj() R = density @ sy_sy @ rho_conj @ sy_sy eig = np.real(eigvals(R)) eig = np.sort(eig[eig > 0])[::-1] if len(eig) < 4: eig = np.pad(eig, (0, 4 - len(eig)), constant_values=0) lambdas = np.sqrt(eig) return max(0.0, lambdas[0] - lambdas[1] - lambdas[2] - lambdas[3])
[docs] def logarithmic_negativity_covariance(cov: np.ndarray) -> float: A = cov[:2, :2] B = cov[2:, 2:] C = cov[:2, 2:] detA = np.linalg.det(A) detB = np.linalg.det(B) detC = np.linalg.det(C) Delta = detA + detB - 2 * detC det_sigma = np.linalg.det(cov) nu_minus_sq = (Delta - np.sqrt(Delta**2 - 4 * det_sigma)) / 2 nu_minus = np.sqrt(max(0.0, nu_minus_sq)) if nu_minus < 0.5: return -np.log2(nu_minus) else: return 0.0
[docs] def squeezed_state_concurrence(r: float = 0.5, theta: float = 0.0, nbar: float = 0.05) -> float: """ Compute concurrence for a two‑mode squeezed state with thermal noise. Parameters ---------- r : float Squeezing parameter. theta : float Squeezing angle. nbar : float Mean thermal photon number per mode. Returns ------- C : float Concurrence (0 for separable, 1 for maximally entangled). """ # Two‑mode squeezed state with thermal noise # For pure TMSV: concurrence = 1/cosh(r) (for appropriate normalisation) # Here we return a simplified estimate. if nbar > 0: # Thermal noise reduces entanglement return 1.0 / (np.cosh(r) * (1 + 2 * nbar)) else: return 1.0 / np.cosh(r)