def test_reduced_gaussian_exceptions(): """raises an exception""" mu = np.array([0, 0, 0, 0]) cov = np.identity(4) with pytest.raises(ValueError, match="Provided mode is larger than the number of subsystems."): reduced_gaussian(mu, cov, [0, 5])
def test_disp_torontonian_two_mode(scale): """Calculates the probability of clicking for a two mode state""" cv = random_covariance(2) mu = scale * (2 * np.random.rand(4) - 1) prob_click = threshold_detection_prob(mu, cv, [1, 1]) mu0, cv0 = reduced_gaussian(mu, cv, [0]) mu1, cv1 = reduced_gaussian(mu, cv, [1]) expected = ( 1 - density_matrix_element(mu0, cv0, [0], [0]) - density_matrix_element(mu1, cv1, [0], [0]) + density_matrix_element(mu, cv, [0, 0], [0, 0]) ) assert np.allclose(expected, prob_click)
def test_reduced_gaussian_full_state(): """returns the arguments""" mu = np.array([0, 0, 0, 0]) cov = np.identity(4) res = reduced_gaussian(mu, cov, list(range(2))) assert np.all(mu == res[0]) assert np.all(cov == res[1])
def test_reduced_gaussian_two_mode(): """test that reduced gaussian returns the correct result""" m = 5 N = 2 * m mu = np.arange(N) cov = np.arange(N**2).reshape(N, N) res = reduced_gaussian(mu, cov, [0, 2]) assert np.all(res[0] == np.array([0, 2, m, m + 2]))
def test_reduced_gaussian(n): """test that reduced gaussian returns the correct result""" m = 5 N = 2 * m mu = np.arange(N) cov = np.arange(N ** 2).reshape(N, N) res = reduced_gaussian(mu, cov, n) assert np.all(res[0] == np.array([n, n + m])) assert np.all(res[1] == np.array([[(N + 1) * n, (N + 1) * n + m], [(N + 1) * n + N * m, (N + 1) * n + N * m + m]]))
def marginals(mu: np.ndarray, V: np.ndarray, n_max: int, hbar: float = 2.0) -> np.ndarray: r"""Generate single-mode marginal distributions from the displacement vector and covariance matrix of a Gaussian state. **Example usage:** >>> mu = np.array([0.00000000, 2.82842712, 0.00000000, ... 0.00000000, 0.00000000, 0.00000000]) >>> V = np.array([[1.0, 0.0, 0.0, 0.0, 0.0, 0.0], ... [0.0, 1.0, 0.0, 0.0, 0.0, 0.0], ... [0.0, 0.0, 1.0, 0.0, 0.0, 0.0], ... [0.0, 0.0, 0.0, 1.0, 0.0, 0.0], ... [0.0, 0.0, 0.0, 0.0, 1.0, 0.0], ... [0.0, 0.0, 0.0, 0.0, 0.0, 1.0]]) >>> n_max = 10 >>> marginals(mu, V, n_max) array([[1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], [1.35335284e-01, 2.70670567e-01, 2.70670566e-01, 1.80447044e-01, 9.02235216e-02, 3.60894085e-02, 1.20298028e-02, 3.43708650e-03, 8.59271622e-04, 1.90949249e-04], [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]]) Args: mu (array): displacement vector V (array): covariance matrix n_max (int): maximum number of vibrational quanta in the distribution hbar (float): the value of :math:`\hbar` in the commutation relation :math:`[\x,\p]=i\hbar`. Returns: array[list[float]]: marginal distributions """ if not V.shape[0] == V.shape[1]: raise ValueError("The covariance matrix must be a square matrix") if not len(mu) == len(V): raise ValueError( "The dimension of the displacement vector and the covariance matrix must be equal" ) if n_max <= 0: raise ValueError( "The number of vibrational states must be larger than zero") n_modes = len(mu) // 2 p = np.zeros((n_modes, n_max)) for mode in range(n_modes): mui, vi = quantum.reduced_gaussian(mu, V, mode) for i in range(n_max): p[mode, i] = np.real( quantum.density_matrix_element(mui, vi, [i], [i], hbar=hbar)) return p