def test_even_validation(self):
     """Test raises exception if not even number of rows"""
     A = np.random.random([5, 5]) + 1j * np.random.random([5, 5])
     A += A.T
     with pytest.raises(ValueError,
                        match="must have an even number of rows/columns"):
         dec.bloch_messiah(A)
Exemple #2
0
    def test_williamson_BM_random_circuit_pure(self):
        self.logTestName()
        for k in range(nsamples):
            n = 3
            U2 = haar_measure(n)
            state = gaussiancircuit.GaussianModes(n, hbar=2)
            for i in range(n):
                state.squeeze(np.log(0.2 * i + 2), 0, i)
            state.apply_u(U2)

            V = state.scovmatxp()

            D, S = dec.williamson(V)
            omega = dec.sympmat(n)

            self.assertAlmostEqual(np.linalg.norm(S @ omega @ S.T - omega), 0)
            self.assertAlmostEqual(np.linalg.norm(S @ D @ S.T - V), 0)

            O, s, Oo = dec.bloch_messiah(S)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(O) @ omega @ O - omega), 0)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(O) @ O - np.identity(2 * n)), 0)

            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(Oo) @ omega @ Oo - omega), 0)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(Oo) @ Oo - np.identity(2 * n)), 0)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(s) @ omega @ s - omega), 0)
            self.assertAlmostEqual(np.linalg.norm(O @ s @ Oo - S), 0)
    def test_decomposition_active(self, hbar, tol):
        """Test that an active symplectic is correctly decomposed into
        two interferometers and squeezing"""
        n = 3
        S = random_symplectic(n, passive=False)

        O1, Sq, O2 = dec.bloch_messiah(S)
        X1 = O1[:n, :n]
        P1 = O1[n:, :n]
        X2 = O2[:n, :n]
        P2 = O2[n:, :n]
        U1 = X1 + 1j * P1
        U2 = X2 + 1j * P2

        prog = sf.Program(n, hbar=hbar)

        with eng:
            G = ops.GaussianTransform(S)
            cmds = G.decompose(q)

        assert np.all(U1 == G.U1)
        assert np.all(U2 == G.U2)
        assert np.all(np.diag(Sq)[:n] == G.Sq)

        S = np.identity(2 * n)

        # command queue should have 2 interferometers, 3 squeezers
        assert len(cmds) == 5

        # calculating the resulting decomposed symplectic
        for cmd in cmds:
            # all operations should be BSgates, Rgates, or Sgates
            assert isinstance(cmd.op, (ops.Interferometer, ops.Sgate))

            # build up the symplectic transform
            modes = [i.ind for i in cmd.reg]

            if isinstance(cmd.op, ops.Sgate):
                S = _squeezing(cmd.op.p[0].x, cmd.op.p[1].x, modes, n) @ S

            if isinstance(cmd.op, ops.Interferometer):
                U1 = cmd.op.p[0].x
                S_U = np.vstack([
                    np.hstack([U1.real, -U1.imag]),
                    np.hstack([U1.imag, U1.real])
                ])
                S = S_U @ S

        # the resulting covariance state
        cov = S @ S.T

        assert np.allclose(cov, S @ S.T * hbar / 2, atol=tol, rtol=0)
Exemple #4
0
    def test_active_on_vacuum(self, hbar, tol):
        """Test that an active symplectic applied to a vacuum is
        correctly decomposed into just squeezing and one interferometer"""
        n = 3
        S = random_symplectic(n, passive=False)

        O1, Sq, O2 = dec.bloch_messiah(S)
        X1 = O1[:n, :n]
        P1 = O1[n:, :n]
        X2 = O2[:n, :n]
        P2 = O2[n:, :n]

        U1 = X1 + 1j * P1
        U2 = X2 + 1j * P2

        prog = sf.Program(n)
        G = ops.GaussianTransform(S, vacuum=True)
        cmds = G.decompose(prog.register)

        S = np.identity(2 * n)

        # command queue should have 3 Sgates, 1 interferometer
        assert len(cmds) == 4

        # calculating the resulting decomposed symplectic
        for cmd in cmds:
            # all operations should be Interferometers or Sgates
            assert isinstance(cmd.op, (ops.Interferometer, ops.Sgate))

            # build up the symplectic transform
            modes = [i.ind for i in cmd.reg]

            if isinstance(cmd.op, ops.Sgate):
                S = _squeezing(cmd.op.p[0].x, cmd.op.p[1].x, modes, n) @ S

            if isinstance(cmd.op, ops.Interferometer):
                U1 = cmd.op.p[0].x
                S_U = np.vstack([
                    np.hstack([U1.real, -U1.imag]),
                    np.hstack([U1.imag, U1.real])
                ])
                S = S_U @ S

        # the resulting covariance state
        cov = S @ S.T

        assert np.allclose(cov, S @ S.T, atol=tol, rtol=0)
    def test_identity(self, tol):
        """Test identity"""
        n = 2
        S_in = np.identity(2 * n)
        O1, S, O2 = dec.bloch_messiah(S_in)

        assert np.allclose(O1 @ O2, np.identity(2 * n), atol=tol, rtol=0)
        assert np.allclose(S, np.identity(2 * n), atol=tol, rtol=0)

        # test orthogonality
        assert np.allclose(O1.T, O1, atol=tol, rtol=0)
        assert np.allclose(O2.T, O2, atol=tol, rtol=0)

        # test symplectic
        O = omega(n)
        assert np.allclose(O1 @ O @ O1.T, O, atol=tol, rtol=0)
        assert np.allclose(O2 @ O @ O2.T, O, atol=tol, rtol=0)
    def test_active_transform(self, create_transform, tol):
        """Test passive transform with squeezing"""
        n = 3
        S_in = create_transform(3, passive=False)
        O1, S, O2 = dec.bloch_messiah(S_in)

        # test decomposition
        assert np.allclose(O1 @ S @ O2, S_in, atol=tol, rtol=0)

        # test orthogonality
        assert np.allclose(O1.T @ O1, np.identity(2 * n), atol=tol, rtol=0)
        assert np.allclose(O2.T @ O2, np.identity(2 * n), atol=tol, rtol=0)

        # test symplectic
        O = omega(n)
        assert np.allclose(O1.T @ O @ O1, O, atol=tol, rtol=0)
        assert np.allclose(O2.T @ O @ O2, O, atol=tol, rtol=0)
        assert np.allclose(S @ O @ S.T, O, atol=tol, rtol=0)
Exemple #7
0
    def test_BM_random_degen_symplectic(self):
        self.logTestName()
        for k in range(nsamples):
            n = 20
            S = random_degen_symplectic(n)
            O, s, Oo = dec.bloch_messiah(S)
            omega = dec.sympmat(n)

            self.assertAlmostEqual(np.linalg.norm(S @ omega @ S.T - omega), 0)

            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(O) @ omega @ O - omega), 0)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(O) @ O - np.identity(2 * n)), 0)

            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(Oo) @ omega @ Oo - omega), 0)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(Oo) @ Oo - np.identity(2 * n)), 0)
            self.assertAlmostEqual(
                np.linalg.norm(np.transpose(s) @ omega @ s - omega), 0)
            self.assertAlmostEqual(np.linalg.norm(O @ s @ Oo - S), 0)
    def test_passive_transform(self, create_transform, tol):
        """Test passive transform has no squeezing.
        Note: this test also tests the case with degenerate symplectic values"""
        n = 3
        S_in = create_transform(3, passive=True)
        O1, S, O2 = dec.bloch_messiah(S_in)

        # test decomposition
        assert np.allclose(O1 @ S @ O2, S_in, atol=tol, rtol=0)

        # test no squeezing
        assert np.allclose(O1 @ O2, S_in, atol=tol, rtol=0)
        assert np.allclose(S, np.identity(2 * n), atol=tol, rtol=0)

        # test orthogonality
        assert np.allclose(O1.T @ O1, np.identity(2 * n), atol=tol, rtol=0)
        assert np.allclose(O2.T @ O2, np.identity(2 * n), atol=tol, rtol=0)

        # test symplectic
        O = omega(n)
        # TODO: BUG:
        # assert np.allclose(O1.T @ O @ O1, O, atol=tol, rtol=0)
        # assert np.allclose(O2.T @ O @ O2, O, atol=tol, rtol=0)
        assert np.allclose(S @ O @ S.T, O, atol=tol, rtol=0)
 def test_symmplectic(self):
     """Test raises exception if not symmetric"""
     A = np.random.random([6, 6]) + 1j * np.random.random([6, 6])
     A += A.T
     with pytest.raises(ValueError, match="matrix is not symplectic"):
         dec.bloch_messiah(A)
 def test_square_validation(self):
     """Test raises exception if not square"""
     A = np.random.random([4, 5]) + 1j * np.random.random([4, 5])
     with pytest.raises(ValueError, match="matrix is not square"):
         dec.bloch_messiah(A)