예제 #1
0
    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
예제 #2
0
    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)
예제 #3
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)