def test_CZgate(self, setup_eng, pure, hbar, tol):
     """Test the action of the CZ gate in phase space"""
     if not pure:
         pytest.skip("Test only runs on pure states")
     N = 2
     eng, prog = setup_eng(N)
     r = 3
     x1 = 2
     x2 = 1
     p1 = 1.37
     p2 = 2.71
     s = 0.5
     with prog.context as q:
         ops.Sgate(r) | q[0]
         ops.Xgate(x1) | q[0]
         ops.Zgate(p1) | q[0]
         ops.Sgate(r) | q[1]
         ops.Xgate(x2) | q[1]
         ops.Zgate(p2) | q[1]
         ops.CZgate(s) | q
     state = eng.run(prog).state
     CZmat = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, s, 1, 0],
                       [s, 0, 0, 1]])
     Vexpected = 0.5 * hbar * CZmat @ np.diag(
         np.exp([-2 * r, -2 * r, 2 * r, 2 * r])) @ CZmat.T
     # Checks the covariance matrix is transformed correctly
     assert np.allclose(state.cov(), Vexpected, atol=tol, rtol=0)
     rexpected = CZmat @ np.array([x1, x2, p1, p2])
     # Checks the means are transformed correctly
     assert np.allclose(state.means(), rexpected, atol=tol, rtol=0)
    def test_Pgate(self, setup_eng, pure, hbar, tol):
        """Test the action of the P gate in phase space"""
        if not pure:
            pytest.skip("Test only runs on pure states")
        N = 1
        eng, prog = setup_eng(N)
        r = 3
        x1 = 2
        p1 = 1.3
        s = 0.5
        with prog.context as q:
            ops.Sgate(r) | q
            ops.Xgate(x1) | q
            ops.Zgate(p1) | q
            ops.Pgate(s) | q
        state = eng.run(prog).state

        Pmat = np.array([[1, 0], [s, 1]])
        
        Vexpected = 0.5 * hbar * Pmat @ np.diag(np.exp([-2 * r, 2 * r])) @ Pmat.T
        rexpected = Pmat @ np.array([x1, p1])
        
        # Check the covariance and mean transformed correctly
        if eng.backend_name == "gaussian":
            assert np.allclose(state.cov(), Vexpected, atol=tol, rtol=0)
            assert np.allclose(state.means(), rexpected, atol=tol, rtol=0)
            
        elif eng.backend_name == "bosonic":
            assert np.allclose(state.covs(), np.expand_dims(Vexpected,axis=0), atol=tol, rtol=0)
            assert np.allclose(state.means(), np.expand_dims(rexpected,axis=0), atol=tol, rtol=0)
def test_non_primitive_gates():
    """Tests that the compiler is able to compile a number of non-primitive Gaussian gates"""

    width = 6
    eng = sf.LocalEngine(backend="gaussian")
    eng1 = sf.LocalEngine(backend="gaussian")
    circuit = sf.Program(width)
    A = np.random.rand(width, width) + 1j * np.random.rand(width, width)
    A = A + A.T
    valsA = np.linalg.svd(A, compute_uv=False)
    A = A / 2 * np.max(valsA)
    B = np.random.rand(
        width // 2, width // 2) + 1j * np.random.rand(width // 2, width // 2)
    valsB = np.linalg.svd(B, compute_uv=False)
    B = B / 2 * valsB
    B = np.block([[0 * B, B], [B.T, 0 * B]])
    with circuit.context as q:
        ops.GraphEmbed(A) | q
        ops.BipartiteGraphEmbed(B) | q
        ops.Pgate(0.1) | q[1]
        ops.CXgate(0.2) | (q[0], q[1])
        ops.MZgate(0.4, 0.5) | (q[2], q[3])
        ops.Fourier | q[0]
        ops.Xgate(0.4) | q[1]
        ops.Zgate(0.5) | q[3]
    compiled_circuit = circuit.compile(compiler="gaussian_unitary")
    cv = eng.run(circuit).state.cov()
    mean = eng.run(circuit).state.means()

    cv1 = eng1.run(compiled_circuit).state.cov()
    mean1 = eng1.run(compiled_circuit).state.means()
    assert np.allclose(cv, cv1)
    assert np.allclose(mean, mean1)
Exemplo n.º 4
0
    def test_CXgate(self, setup_eng, pure, hbar, tol):
        """Test the action of the CX gate in phase space"""
        if not pure:
            pytest.skip("Test only runs on pure states")
        N = 2
        eng, prog = setup_eng(N)
        r = 3
        x1 = 2
        x2 = 1
        p1 = 1.37
        p2 = 2.71
        s = 0.5
        with prog.context as q:
            ops.Sgate(r) | q[0]
            ops.Xgate(x1) | q[0]
            ops.Zgate(p1) | q[0]
            ops.Sgate(r) | q[1]
            ops.Xgate(x2) | q[1]
            ops.Zgate(p2) | q[1]
            ops.CXgate(s) | q
        state = eng.run(prog).state

        CXmat = np.array([[1, 0, 0, 0], [s, 1, 0, 0], [0, 0, 1, -s],
                          [0, 0, 0, 1]])

        Vexpected = 0.5 * hbar * CXmat @ np.diag(
            np.exp([-2 * r, -2 * r, 2 * r, 2 * r])) @ CXmat.T
        rexpected = CXmat @ np.array([x1, x2, p1, p2])

        # Check the covariance and mean transformed correctly
        if eng.backend_name == "gaussian":
            assert np.allclose(state.cov(), Vexpected, atol=tol, rtol=0)
            assert np.allclose(state.means(), rexpected, atol=tol, rtol=0)

        elif eng.backend_name == "bosonic":
            indices = from_xp(2)
            Vexpected = Vexpected[:, indices][indices, :]
            rexpected = rexpected[indices]
            assert np.allclose(state.covs(),
                               np.expand_dims(Vexpected, axis=0),
                               atol=tol,
                               rtol=0)
            assert np.allclose(state.means(),
                               np.expand_dims(rexpected, axis=0),
                               atol=tol,
                               rtol=0)
def test_merge_incompatible():
    """Test merging of incompatible gates does nothing"""
    eng, _ = sf.Engine(3)

    with eng:
        ops.Xgate(0.6) | 0
        ops.Zgate(0.2) | 0

    eng.optimize()
    assert len(eng.cmd_queue) == 2
Exemplo n.º 6
0
    def test_merge_incompatible(self):
        """Test merging of incompatible gates does nothing"""
        prog = sf.Program(3)

        with prog.context:
            ops.Xgate(0.6) | 0
            ops.Zgate(0.2) | 0

        prog = prog.optimize()
        assert len(prog) == 2
    def test_xx_1(self, tmpdir):
        prog = sf.Program(3)

        with prog.context as q:
            ops.Xgate(1) | (q[1])
            ops.Xgate(1) | (q[1])

        xx_test_1_output = dedent(r"""            \documentclass{article}
            \usepackage{qcircuit}
            \begin{document}
            \Qcircuit {
             & \qw  & \qw  & \qw \\
             & \gate{X}  & \gate{X}  & \qw \\
             & \qw  & \qw  & \qw \\
            }
            \end{document}""")

        result = prog.draw_circuit(tex_dir=tmpdir)[1]
        assert result == xx_test_1_output, failure_message(
            result, xx_test_1_output)
    def test_xx_1(self, tmpdir):
        eng, q = sf.Engine(3)

        with eng:
            ops.Xgate(1) | (q[1])
            ops.Xgate(1) | (q[1])

        xx_test_1_output = dedent(r"""            \documentclass{article}
            \usepackage{qcircuit}
            \begin{document}
            \Qcircuit {
             & \qw  & \qw  & \qw \\
             & \gate{X}  & \gate{X}  & \qw \\
             & \qw  & \qw  & \qw \\
            }
            \end{document}""")

        result = eng.draw_circuit(print_queued_ops=True, tex_dir=tmpdir)[1]
        assert result == xx_test_1_output, failure_message(
            result, xx_test_1_output)
Exemplo n.º 9
0
 def test_Xgate_decomposition(self, hbar, tol):
     """Test that the X gate is correctly decomposed into a displacement gate"""
     n = 1
     prog = sf.Program(n)
     x = 0.7
     alpha = x / np.sqrt(2 * hbar)
     X = ops.Xgate(x)
     cmds = X.decompose(prog.register)
     assert isinstance(cmds[0].op, ops.Dgate)
     assert np.allclose(cmds[0].op.p[0], alpha, atol=tol, rtol=0)
     assert np.allclose(cmds[0].op.p[1], 0, atol=tol, rtol=0)
    def test_x_displacement(self, setup_eng, hbar, tol):
        """test x displacement on the Gaussian backend gives correct displacement"""
        eng, prog = setup_eng(1)

        with prog.context as q:
            ops.Xgate(X) | q

        state = eng.run(prog)
        mu_x = state.means()[0]

        assert state.hbar == hbar
        assert np.allclose(mu_x, X, atol=tol, rtol=0)
    def test_x_displacement(self, setup_eng, hbar, tol):
        """test x displacement on the Gaussian and Bosonic backends gives correct displacement"""
        eng, prog = setup_eng(1)

        with prog.context as q:
            ops.Xgate(X) | q

        state = eng.run(prog).state
        if eng.backend_name == "gaussian":
            mu_x = state.means()[0]
        elif eng.backend_name == "bosonic":
            mu_x = state.means()[0, 0]

        assert state.hbar == hbar
        assert np.allclose(mu_x, X, atol=tol, rtol=0)
Exemplo n.º 12
0
    def test_shots_with_timebins_non_multiple_of_concurrent_modes(self):
        """Test that multiple shots work when having the number of timebins be
        a non-multiple of the number of concurrent modes"""
        theta = [0] * 3
        shots = 2

        prog = sf.TDMProgram(N=2)
        with prog.context(theta) as (p, q):
            ops.Xgate(50) | q[1]
            ops.MeasureHomodyne(p[0]) | q[0]
        eng = sf.Engine("gaussian")
        res = eng.run(prog, shots=shots)
        samples = res.samples

        expected = np.array([[[0, 50, 50]], [[50, 50, 50]]])

        assert np.allclose(samples, expected, atol=4)
Exemplo n.º 13
0
    def test_one_mode_gates_from_operators(self, drawer):
        prog = sf.Program(3)

        with prog.context as q:
            ops.Xgate(1) | (q[0])
            ops.Zgate(1) | (q[0])
            ops.Kgate(1) | (q[0])
            ops.Vgate(1) | (q[0])
            ops.Pgate(1) | (q[0])
            ops.Rgate(1) | (q[0])
            ops.Sgate(1) | (q[0])
            ops.Dgate(1) | (q[0])

        for op in prog.circuit:
            method, mode = drawer._gate_from_operator(op)
            assert callable(method) and hasattr(drawer, method.__name__)
            assert mode == 1
    def test_one_mode_gates_from_operators(self, drawer):
        eng, q = sf.Engine(3)

        with eng:
            ops.Xgate(1) | (q[0])
            ops.Zgate(1) | (q[0])
            ops.Kgate(1) | (q[0])
            ops.Vgate(1) | (q[0])
            ops.Pgate(1) | (q[0])
            ops.Rgate(1) | (q[0])
            ops.Sgate(1) | (q[0])
            ops.Dgate(1) | (q[0])

        for op in eng.cmd_queue:
            method, mode = drawer._gate_from_operator(op)
            assert callable(method) and hasattr(drawer, method.__name__)
            assert mode == 1
Exemplo n.º 15
0
    def test_parse_op(self, drawer):
        prog = sf.Program(3)

        with prog.context as q:
            ops.Xgate(1) | (q[0])
            ops.Zgate(1) | (q[0])
            ops.CXgate(1) | (q[0], q[1])
            ops.CZgate(1) | (q[0], q[1])
            ops.BSgate(0, 1) | (q[0], q[1])
            ops.S2gate(0, 1) | (q[0], q[1])
            ops.CKgate(1) | (q[0], q[1])
            ops.Kgate(1) | (q[0])
            ops.Vgate(1) | (q[0])
            ops.Pgate(1) | (q[0])
            ops.Rgate(1) | (q[0])
            ops.Sgate(1) | (q[0])
            ops.Dgate(1) | (q[0])

        for op in prog.circuit:
            drawer.parse_op(op)

        expected_circuit_matrix = [
            [
                "\\gate{X}",
                "\\gate{Z}",
                "\\ctrl{1}",
                "\\ctrl{1}",
                "\\multigate{1}{BS}",
                "\\multigate{1}{S}",
                "\\ctrl{1}",
                "\\gate{K}",
                "\\gate{V}",
                "\\gate{P}",
                "\\gate{R}",
                "\\gate{S}",
                "\\gate{D}",
            ],
            ["\\qw"] * 2 +
            ["\\targ", "\\gate{Z}", "\\ghost{BS}", "\\ghost{S}", "\\gate{K}"] +
            ["\\qw"] * 6,
            ["\\qw"] * 13,
        ]

        assert drawer._circuit_matrix == expected_circuit_matrix
    def test_parse_op(self, drawer):
        eng, q = sf.Engine(3)

        with eng:
            ops.Xgate(1) | (q[0])
            ops.Zgate(1) | (q[0])
            ops.CXgate(1) | (q[0], q[1])
            ops.CZgate(1) | (q[0], q[1])
            ops.BSgate(0, 1) | (q[0], q[1])
            ops.S2gate(0, 1) | (q[0], q[1])
            ops.CKgate(1) | (q[0], q[1])
            ops.Kgate(1) | (q[0])
            ops.Vgate(1) | (q[0])
            ops.Pgate(1) | (q[0])
            ops.Rgate(1) | (q[0])
            ops.Sgate(1) | (q[0])
            ops.Dgate(1) | (q[0])

        for op in eng.cmd_queue:
            drawer.parse_op(op)

        expected_circuit_matrix = [
            [
                "\\gate{X}",
                "\\gate{Z}",
                "\\ctrl{1}",
                "\\ctrl{1}",
                "\\multigate{1}{BS}",
                "\\multigate{1}{S}",
                "\\ctrl{1}",
                "\\gate{K}",
                "\\gate{V}",
                "\\gate{P}",
                "\\gate{R}",
                "\\gate{S}",
                "\\gate{D}",
            ],
            ["\\qw"] * 2 +
            ["\\targ", "\\gate{Z}", "\\ghost{BS}", "\\ghost{S}", "\\gate{K}"] +
            ["\\qw"] * 6,
            ["\\qw"] * 13,
        ]

        assert drawer._circuit_matrix == expected_circuit_matrix
    def test_Pgate(self, setup_eng, pure, hbar, tol):
        """Test the action of the P gate in phase space"""
        if not pure:
            pytest.skip("Test only runs on pure states")
        N = 1
        eng, prog = setup_eng(N)
        r = 3
        x1 = 2
        p1 = 1.3
        s = 0.5
        with prog.context as q:
            ops.Sgate(r) | q
            ops.Xgate(x1) | q
            ops.Zgate(p1) | q
            ops.Pgate(s) | q
        state = eng.run(prog).state

        Pmat = np.array([[1, 0], [s, 1]])
        Vexpected = 0.5 * hbar * Pmat @ np.diag(np.exp([-2 * r, 2 * r
                                                        ])) @ Pmat.T
        assert np.allclose(Vexpected, state.cov(), atol=tol, rtol=0)
        rexpected = Pmat @ np.array([x1, p1])
        assert np.allclose(rexpected, state.means(), atol=tol, rtol=0)
Exemplo n.º 18
0
 def Q(self):
     """The common test gate"""
     return ops.Xgate(0.5)
Exemplo n.º 19
0
    def test_create_delete_reset(self, backend):
        """Test various use cases creating and deleting modes,
        together with engine resets."""
        eng, reg = sf.Engine(2)

        # define some gates
        X = ops.Xgate(0.5)

        alice, bob = reg
        # states of the subsystems: active, not_measured
        state = np.full((len(reg), 2), True)

        def prog1(q):
            """program 1"""
            X | q
            ops.MeasureX | q

        def prog2(q):
            """program 2"""
            X | q
            ops.MeasureX | q
            ops.Del | q
            state[q.ind, 0] = False  # no longer active

        def reset():
            """reset the engine"""
            eng.reset()
            state[:] = True

        def check():
            """Check the activity and measurement state of subsystems.

            Activity state is changed right away when a Del command is applied to Engine,
            but a measurement result only becomes available during Engine.run().
            """
            for r, (a, nm) in zip(reg, state):
                assert r.active == a
                assert (r.val is None) == nm

        def input(p, reg):
            """input a program to the engine"""
            with eng:
                p(reg)

            check()

        def input_and_run(p, reg):
            """input a program to the engine and run it"""
            with eng:
                p(reg)

            check()
            eng.run(backend)

            # now measured (assumes p will always measure reg!)
            state[reg.ind, 1] = False
            check()

        reset()
        ## (1) run several independent programs, resetting everything in between
        input_and_run(prog1, alice)
        reset()
        input_and_run(prog2, bob)
        reset()

        ## (2) interactive state evolution in multiple runs
        input_and_run(prog2, alice)
        input_and_run(prog1, bob)
        reset()

        ## (3) repeat a (possibly extended) program fragment (the fragment must not create/delete subsystems!)
        input_and_run(prog1, alice)
        eng.cmd_queue.extend(eng.cmd_applied[-1])
        check()
        input_and_run(prog1, bob)
        reset()

        ## (4) interactive use, "changed my mind"
        input_and_run(prog1, alice)
        input(prog2, bob)
        eng.reset_queue()  # scratch that, back to last checkpoint
        state[bob.ind, 0] = True  # bob should be active again
        check()
        input_and_run(prog1, bob)
        reset()

        ## (5) reset the state, run the same program again to get new measurement samples
        input_and_run(prog1, alice)
        input(prog2, bob)
        eng.reset(keep_history=True)

        state[
            alice.ind,
            1] = True  # measurement result was erased, activity did not change
        state[bob.ind, 1] = True
        check()
        eng.run(backend)
        state[alice.ind, 1] = False
        state[bob.ind, 1] = False
        check()