def test_embed_graph(self, setup_eng, hbar):
        """Test that an embedded graph has the right total mean photon number. """

        eng, prog = setup_eng(2)
        A = np.array([[0.0, 1.0], [1.0, 0.0]])
        n_mean_per_mode = 1
        with prog.context as q:
            ops.GraphEmbed(A, n_mean_per_mode) | (q[0], q[1])

        state = eng.run(prog).state
        cov = state.cov()
        n_mean_tot = np.trace(cov / (hbar / 2) - np.identity(4)) / 4
        expected = 2 * n_mean_per_mode
        assert np.allclose(n_mean_tot, expected)
예제 #2
0
    def test_graph_embed(self, setup_eng, tol):
        """Test that embedding a traceless adjacency matrix A
        results in the property Amat/A = c J, where c is a real constant,
        and J is the all ones matrix"""
        N = 3
        eng, prog = setup_eng(3)

        with prog.context as q:
            ops.GraphEmbed(A) | q

        state = eng.run(prog).state
        Amat = eng.backend.circuit.Amat()

        # check that the matrix Amat is constructed to be of the form
        # Amat = [[B^\dagger, 0], [0, B]]
        assert np.allclose(Amat[:N, :N], Amat[N:, N:].conj().T, atol=tol)
        assert np.allclose(Amat[:N, N:], np.zeros([N, N]), atol=tol)
        assert np.allclose(Amat[N:, :N], np.zeros([N, N]), atol=tol)

        ratio = np.real_if_close(Amat[N:, N:] / A)
        ratio /= ratio[0, 0]
        assert np.allclose(ratio, np.ones([N, N]), atol=tol)
예제 #3
0
    def test_decomposition(self, hbar, tol):
        """Test that an graph is correctly decomposed"""
        n = 3
        prog = sf.Program(n)

        A = np.random.random([n, n]) + 1j * np.random.random([n, n])
        A += A.T
        A -= np.trace(A) * np.identity(n) / 3

        sq, U = dec.graph_embed(A)

        G = ops.GraphEmbed(A)
        cmds = G.decompose(prog.register)

        assert np.all(sq == G.sq)
        assert np.all(U == G.U)

        S = np.identity(2 * n)

        # calculating the resulting decomposed symplectic
        for cmd in cmds:
            # all operations should be BSgates, Rgates, or Sgates
            assert isinstance(
                cmd.op, (ops.Interferometer, ops.BSgate, ops.Rgate, 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.Rgate):
                S = _rotation(cmd.op.p[0].x, modes, n) @ S

            if isinstance(cmd.op, ops.BSgate):
                S = _beamsplitter(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

        # calculate Hamilton's A matrix: A = X.(I-Q^{-1})*
        I = np.identity(n)
        O = np.zeros_like(I)
        X = np.block([[O, I], [I, O]])

        x = cov[:n, :n]
        xp = cov[:n, n:]
        p = cov[n:, n:]

        aidaj = (x + p + 1j * (xp - xp.T) - 2 * I) / 4
        aiaj = (x - p + 1j * (xp + xp.T)) / 4

        Q = np.block([[aidaj, aiaj.conj()], [aiaj, aidaj.conj()]
                      ]) + np.identity(2 * n)

        A_res = X @ (np.identity(2 * n) - np.linalg.inv(Q)).conj()

        # The bottom right corner of A_res should be identical to A,
        # up to some constant scaling factor. Check if the ratio
        # of all elements is one
        ratio = np.real_if_close(A_res[n:, n:] / A)
        ratio /= ratio[0, 0]

        assert np.allclose(ratio, np.ones([n, n]), atol=tol, rtol=0)
예제 #4
0
 def test_identity(self, tol):
     """Test that nothing is done if the adjacency matrix is the identity"""
     G = ops.GraphEmbed(np.identity(6))
     assert G.identity