예제 #1
0
    def test_all(self, hbar, tol):
        """Test requesting all wires returns the full state"""
        mu, cov = symplectic.vacuum_state(4, hbar=hbar)
        res = symplectic.reduced_state(mu, cov, [0, 1, 2, 3])
        expected = np.zeros([8]), np.identity(8) * hbar / 2

        assert np.allclose(res[0], expected[0], atol=tol, rtol=0)
        assert np.allclose(res[1], expected[1], atol=tol, rtol=0)
예제 #2
0
    def test_integer(self, hbar, tol):
        """Test requesting via an integer"""
        mu, cov = symplectic.vacuum_state(4, hbar=hbar)
        res = symplectic.reduced_state(mu, cov, 0)
        expected = np.zeros([2]), np.identity(2) * hbar / 2

        assert np.allclose(res[0], expected[0], atol=tol, rtol=0)
        assert np.allclose(res[1], expected[1], atol=tol, rtol=0)
예제 #3
0
 def test_vacuum_state(self, hbar, tol):
     """Test the vacuum state is correct."""
     modes = 3
     means, cov = symplectic.vacuum_state(modes, hbar=hbar)
     assert np.allclose(means, np.zeros([2 * modes]), atol=tol, rtol=0)
     assert np.allclose(cov,
                        np.identity(2 * modes) * hbar / 2,
                        atol=tol,
                        rtol=0)
예제 #4
0
    def test_inverse_ops_cancel(self, hbar, tol):
        """Test that applying squeezing and interferometers to a four mode circuit,
        followed by applying the inverse operations, return the state to the vacuum"""

        # the symplectic matrix
        O = np.block([[np.zeros([4, 4]), np.identity(4)],
                      [-np.identity(4), np.zeros([4, 4])]])

        # begin in the vacuum state
        mu_init, cov_init = symplectic.vacuum_state(4, hbar=hbar)

        # add displacement
        alpha = np.random.random(size=[4]) + np.random.random(size=[4]) * 1j
        D = np.concatenate([alpha.real, alpha.imag])
        mu = mu_init + D
        cov = cov_init.copy()

        # random squeezing
        r = np.random.random()
        phi = np.random.random()
        S = symplectic.expand(symplectic.two_mode_squeezing(r, phi),
                              modes=[0, 1],
                              N=4)

        # check symplectic
        assert np.allclose(S @ O @ S.T, O, atol=tol, rtol=0)

        # random interferometer
        # fmt:off
        u = np.array([[
            -0.06658906 - 0.36413058j, 0.07229868 + 0.65935896j,
            0.59094625 - 0.17369183j, -0.18254686 - 0.10140904j
        ],
                      [
                          0.53854866 + 0.36529723j, 0.61152793 + 0.15022026j,
                          0.05073631 + 0.32624882j, -0.17482023 - 0.20103772j
                      ],
                      [
                          0.34818923 + 0.51864844j, -0.24334624 + 0.0233729j,
                          0.3625974 - 0.4034224j, 0.10989667 + 0.49366039j
                      ],
                      [
                          0.16548085 + 0.14792642j, -0.3012549 - 0.11387682j,
                          -0.12731847 - 0.44851389j, -0.55816075 - 0.5639976j
                      ]])
        # fmt on
        U = symplectic.interferometer(u)

        # check unitary
        assert np.allclose(u @ u.conj().T, np.identity(4), atol=tol, rtol=0)
        # check symplectic
        assert np.allclose(U @ O @ U.T, O, atol=tol, rtol=0)

        # apply squeezing and interferometer
        cov = U @ S @ cov @ S.T @ U.T
        mu = U @ S @ mu

        # check we are no longer in the vacuum state
        assert not np.allclose(mu, mu_init, atol=tol, rtol=0)
        assert not np.allclose(cov, cov_init, atol=tol, rtol=0)

        # return the inverse operations
        Sinv = symplectic.expand(symplectic.two_mode_squeezing(-r, phi),
                                 modes=[0, 1],
                                 N=4)
        Uinv = symplectic.interferometer(u.conj().T)

        # check inverses
        assert np.allclose(Uinv, np.linalg.inv(U), atol=tol, rtol=0)
        assert np.allclose(Sinv, np.linalg.inv(S), atol=tol, rtol=0)

        # apply the inverse operations
        cov = Sinv @ Uinv @ cov @ Uinv.T @ Sinv.T
        mu = Sinv @ Uinv @ mu

        # inverse displacement
        mu -= D

        # check that we return to the vacuum state
        assert np.allclose(mu, mu_init, atol=tol, rtol=0)
        assert np.allclose(cov, cov_init, atol=tol, rtol=0)