def test_coherent_squeezed(): """Test density matrix for a squeezed displaced state""" r = 0.43 mu = np.array([0.24, -0.2]) V = np.diag(np.array(np.exp([-2 * r, 2 * r]))) res = density_matrix(mu, V) # fmt: off expected = np.array( [[ 0.89054874, 0.15018085 + 0.05295904j, -0.23955467 + 0.01263025j, -0.0734589 - 0.02452154j, 0.07862323 - 0.00868528j ], [ 0.15018085 - 0.05295904j, 0.02847564, -0.03964706 + 0.01637575j, -0.01384625 + 0.00023317j, 0.01274241 - 0.00614023j ], [ -0.23955467 - 0.01263025j, -0.03964706 - 0.01637575j, 0.06461854, 0.01941242 + 0.00763805j, -0.02127257 + 0.00122123j ], [ -0.0734589 + 0.02452154j, -0.01384625 - 0.00023317j, 0.01941242 - 0.00763805j, 0.00673463, -0.00624626 + 0.00288134j ], [ 0.07862323 + 0.00868528j, 0.01274241 + 0.00614023j, -0.02127257 - 0.00122123j, -0.00624626 - 0.00288134j, 0.00702606 ]]) # fmt:on assert np.allclose(res, expected)
def test_density_matrix_displaced_squeezed_postselect(): """Test density matrix for a squeezed state with postselection""" r = 0.43 mu = np.array([0, 0.24, 0, -0.2]) V = np.diag(np.array(np.exp([1, -2 * r, 1, 2 * r]))) res = density_matrix(mu, V, post_select={0: 0}, cutoff=20, normalize=True)[:5, :5] # fmt:off expected = np.array( [[ 0.89054874, 0.15018085 + 0.05295904j, -0.23955467 + 0.01263025j, -0.0734589 - 0.02452154j, 0.07862323 - 0.00868528j ], [ 0.15018085 - 0.05295904j, 0.02847564, -0.03964706 + 0.01637575j, -0.01384625 + 0.00023317j, 0.01274241 - 0.00614023j ], [ -0.23955467 - 0.01263025j, -0.03964706 - 0.01637575j, 0.06461854, 0.01941242 + 0.00763805j, -0.02127257 + 0.00122123j ], [ -0.0734589 + 0.02452154j, -0.01384625 - 0.00023317j, 0.01941242 - 0.00763805j, 0.00673463, -0.00624626 + 0.00288134j ], [ 0.07862323 + 0.00868528j, 0.01274241 + 0.00614023j, -0.02127257 - 0.00122123j, -0.00624626 - 0.00288134j, 0.00702606 ]]) # fmt:on assert np.allclose(res, expected)
def fock_amplitudes_one_mode(alpha, cov, cutoff): """ Returns the Fock space density matrix of gaussian state characterized by a complex displacement alpha and a (symmetric) covariance matrix The Fock ladder ladder goes from 0 to cutoff-1""" r = 2 * np.array([alpha.real, alpha.imag]) if is_pure_cov(cov): psi = state_vector(r, cov, normalize=True, cutoff=cutoff) rho = np.outer(psi, psi.conj()) return rho return density_matrix(r, cov, normalize=True, cutoff=cutoff)
def test_density_matrix_vacuum(): """Test density matrix for a vacuum state""" mu = np.zeros([2]) V = np.identity(2) res = density_matrix(mu, V) expected = np.zeros([5, 5]) expected[0, 0] = 1 assert np.allclose(res, expected)
def test_density_matrix_squeezed_postselect(): """Test density matrix for a squeezed state with postselection""" r = 0.43 mu = np.zeros([4]) V = np.diag(np.array(np.exp([1, -2 * r, 1, 2 * r]))) res = density_matrix(mu, V, post_select={0: 0}, cutoff=15, normalize=True)[:5, :5] expected = np.array([[0.91417429, 0, -0.26200733, 0, 0.09196943], [0, 0, 0, 0, 0], [-0.26200733, 0, 0.07509273, 0, -0.02635894], [0, 0, 0, 0, 0], [0.09196943, 0, -0.02635894, 0, 0.00925248],]) assert np.allclose(res, expected)
def test_density_matrix_squeezed(): """Test density matrix for a squeezed state""" r = 0.43 mu = np.zeros([2]) V = np.diag(np.array(np.exp([-2 * r, 2 * r]))) res = density_matrix(mu, V) expected = np.array([[0.91417429, 0, -0.26200733, 0, 0.09196943], [0, 0, 0, 0, 0], [-0.26200733, 0, 0.07509273, 0, -0.02635894], [0, 0, 0, 0, 0], [0.09196943, 0, -0.02635894, 0, 0.00925248],]) assert np.allclose(res, expected)
def test_cubic_phase(): """Test that all the possible ways of obtaining a cubic phase state using the different methods agree""" mu = np.array([ -0.50047867, 0.37373598, 0.01421683, 0.26999427, 0.04450994, 0.01903583 ]) cov = np.array([ [ 1.57884241, 0.81035494, 1.03468307, 1.14908791, 0.09179507, -0.11893174 ], [ 0.81035494, 1.06942863, 0.89359234, 0.20145142, 0.16202296, 0.4578259 ], [ 1.03468307, 0.89359234, 1.87560498, 0.16915661, 1.0836528, -0.09405278 ], [ 1.14908791, 0.20145142, 0.16915661, 2.37765137, -0.93543385, -0.6544286 ], [ 0.09179507, 0.16202296, 1.0836528, -0.93543385, 2.78903152, -0.76519088 ], [ -0.11893174, 0.4578259, -0.09405278, -0.6544286, -0.76519088, 1.51724222 ], ]) cutoff = 7 # the Fock state measurement of mode 0 to be post-selected m1 = 1 # the Fock state measurement of mode 1 to be post-selected m2 = 2 psi = state_vector(mu, cov, post_select={ 0: m1, 1: m2 }, cutoff=cutoff, hbar=2) psi_c = state_vector(mu, cov, cutoff=cutoff, hbar=2)[m1, m2, :] rho = density_matrix(mu, cov, post_select={ 0: m1, 1: m2 }, cutoff=cutoff, hbar=2) rho_c = density_matrix(mu, cov, cutoff=cutoff, hbar=2)[m1, m2, :, m1, m2, :] assert np.allclose(np.outer(psi, psi.conj()), rho) assert np.allclose(np.outer(psi_c, psi_c.conj()), rho) assert np.allclose(rho_c, rho)
def circuit(cutoff, l1=0.85, l2=1): """Runs the heralded circuit with specified parameters, returning the output fidelity to the requested weak cubic phase state, the post-selection probability, and the Wigner log negativity. Args: cutoff (int): the Fock basis truncation l1 (float): squeeze cavity loss l2 (float): PNR loss Returns: tuple: a tuple containing the output fidelity to the target ON state, the probability of post-selection, the state norm before entering the beamsplitter, the state norm after exiting the beamsplitter, and the density matrix of the output state. """ # weak cubic phase state parameter a = 0.53 # the Fock state measurement of mode 0 to be post-selected m1 = 1 # the Fock state measurement of mode 1 to be post-selected m2 = 2 # define target state target_state = cubic_phase_state(a, cutoff) # gate parameters for the heralded quantum circuit. # squeezing magnitudes sq_r = [0.71, 0.67, -0.42] # squeezing phase sq_phi = [-2.07, 0.06, -3.79] # displacement magnitudes d_r = [-0.02, 0.34, 0.02] # beamsplitter theta bs_theta1, bs_theta2, bs_theta3 = [-1.57, 0.68, 2.5] # beamsplitter phi bs_phi1, bs_phi2, bs_phi3 = [0.53, -4.51, 0.72] # quantum circuit prior to entering the beamsplitter prog = sf.Program(3) with prog.context as q: for k in range(3): ops.Sgate(sq_r[k], sq_phi[k]) | q[k] ops.Dgate(d_r[k]) | q[k] ops.LossChannel(l1) | q[k] ops.BSgate(bs_theta1, bs_phi1) | (q[0], q[1]) ops.BSgate(bs_theta2, bs_phi2) | (q[1], q[2]) ops.BSgate(bs_theta3, bs_phi3) | (q[0], q[1]) ops.LossChannel(l2) | q[0] ops.LossChannel(l2) | q[1] eng = sf.Engine("gaussian") state = eng.run(prog).state mu = state.means() cov = state.cov() rho = density_matrix(mu, cov, post_select={ 0: m1, 1: m2 }, cutoff=cutoff, hbar=2) # probability of measuring m1 and m2 prob = np.abs(np.trace(rho)) # output state if prob != 0: rho = rho / prob # fidelity with the target state fidelity = np.abs(np.trace(np.einsum("ij,jk->ik", rho, target_state))) return fidelity, prob, rho
def get_density_matrix(self, cutoff = 5): return quantum.density_matrix(self.mu, self.cov, cutoff=cutoff)