def gaussian_state(self, hbar): """A test Gaussian state to use in testing""" # quadrature rotation # construct the expected vector of means and covariance matrix mu = R(qphi).T @ np.array([a.real, a.imag]) * np.sqrt(2 * hbar) cov = R(qphi).T @ utils.squeezed_cov(r, phi, hbar=hbar) @ R(qphi) return mu, cov
def test_squeezed_cov(self, hbar, r, phi, tol): """test squeezed covariance utility function returns correct covariance""" cov = utils.squeezed_cov(r, phi, hbar=hbar) expected = (hbar / 2) * np.array([ [ np.cosh(2 * r) - np.cos(phi) * np.sinh(2 * r), -2 * np.cosh(r) * np.sin(phi) * np.sinh(r), ], [ -2 * np.cosh(r) * np.sin(phi) * np.sinh(r), np.cosh(2 * r) + np.cos(phi) * np.sinh(2 * r), ], ]) assert np.allclose(cov, expected, atol=tol, rtol=0)
def test_three_mode_arbitrary(self, setup_backend, pure, hbar, tol): """Test that the correct result is returned for an arbitrary quadratic polynomial""" backend = setup_backend(3) # increase the cutoff to 7 for accuracy backend.reset(cutoff_dim=7, pure=pure) # fmt:off A = np.array([[ 0.7086495, -0.39299695, 0.30536448, 0.48822049, 0.64987373, 0.7020327 ], [ -0.39299695, 0.0284145, 0.53202656, 0.20232385, 0.26288656, 0.20772833 ], [ 0.30536448, 0.53202656, 0.28126466, 0.64192545, -0.36583748, 0.51704656 ], [ 0.48822049, 0.20232385, 0.64192545, 0.51033017, 0.29129713, 0.77103581 ], [ 0.64987373, 0.26288656, -0.36583748, 0.29129713, 0.37646972, 0.2383589 ], [ 0.7020327, 0.20772833, 0.51704656, 0.77103581, 0.2383589, -0.96494418 ]]) # fmt:on d = np.array([ 0.71785224, -0.80064627, 0.08799823, 0.76189805, 0.99665321, -0.60777437 ]) k = 0.123 a_list = [0.044 + 0.023j, 0.0432 + 0.123j, -0.12 + 0.04j] r_list = [0.1065, 0.032, -0.123] phi_list = [0.897, 0.31, 0.432] mu = np.zeros([6]) cov = np.zeros([6, 6]) # squeeze and displace each mode for i, (a_, r_, phi_) in enumerate(zip(a_list, r_list, phi_list)): backend.prepare_displaced_squeezed_state(np.abs(a_), np.angle(a_), r_, phi_, i) mu[2 * i:2 * i + 2] = (R(qphi).T @ np.array([a_.real, a_.imag]) * np.sqrt(2 * hbar)) cov[2 * i:2 * i + 2, 2 * i:2 * i + 2] = ( R(qphi).T @ utils.squeezed_cov(r_, phi_, hbar=hbar) @ R(qphi)) # apply a beamsplitter to the modes backend.beamsplitter(np.pi / 4, 0.0, 0, 1) backend.beamsplitter(np.pi / 4, 0.0, 1, 2) state = backend.state() mean, var = state.poly_quad_expectation(A, d, k, phi=qphi) # apply a beamsplitter to vector of means and covariance matrices t = 1 / np.sqrt(2) BS = np.array([[t, 0, -t, 0], [0, t, 0, -t], [t, 0, t, 0], [0, t, 0, t]]) S1 = block_diag(BS, np.identity(2)) S2 = block_diag(np.identity(2), BS) C = changebasis(3) mu = C.T @ S2 @ S1 @ mu cov = C.T @ S2 @ S1 @ cov @ S1.T @ S2.T @ C modes = list(np.arange(6).reshape(2, -1).T) mean_ex = np.trace(A @ cov) + mu @ A @ mu + mu @ d + k var_ex = (2 * np.trace(A @ cov @ A @ cov) + 4 * mu.T @ A.T @ cov @ A @ mu + d.T @ cov @ d + 2 * mu.T @ A.T @ cov @ d + 2 * d.T @ cov @ A @ mu - np.sum([ np.linalg.det(hbar * A[:, m][n]) for m in modes for n in modes ])) assert np.allclose(mean, mean_ex, atol=tol, rtol=0) assert np.allclose(var, var_ex, atol=tol, rtol=0)