Esempio n. 1
0
    def test_measured_parameter(self, setup_eng):
        """Test that a circuit with measured parameters executes successfully."""
        eng, prog = setup_eng(2)

        with prog.context as q:
            ops.MeasureX | q[0]
            ops.Sgate(q[0].par) | q[1]
            # symbolic hermitian conjugate together with register reference
            ops.Dgate(q[0].par, 0).H | q[1]
            # algebraic transformation
            ops.Sgate(q[0].par**2) | q[1]
            # algebraic transformation and h.c.
            ops.Dgate(q[0].par, np.pi).H | q[1]

        eng.run(prog)
Esempio n. 2
0
    def test_extract_arbitrary_unitary_one_mode(self, setup_eng, cutoff, tol):
        """Test that arbitrary unitary extraction works for 1 mode"""
        S = ops.Sgate(0.4, -1.2)
        D = ops.Dgate(2, 0.9)
        K = ops.Kgate(-1.5)

        # not a state but it doesn't matter
        initial_state = np.random.rand(cutoff) + 1j * np.random.rand(cutoff)

        eng_ref, p0 = setup_eng(1)
        with p0.context as q:
            ops.Ket(initial_state) | q

        prog = sf.Program(p0)
        with prog.context as q:
            S | q
            D | q
            K | q

        U = utils.extract_unitary(prog,
                                  cutoff_dim=cutoff,
                                  backend=eng_ref.backend_name)

        if isinstance(U, tf.Tensor):
            with tf.Session() as sess:
                sess.run(tf.global_variables_initializer())
                in_state = tf.constant(initial_state.reshape([-1]),
                                       dtype=tf.complex64)
                final_state = sess.run(tf.einsum("ab,b", U, in_state))
        else:
            final_state = U @ initial_state

        expected_state = eng_ref.run([p0, prog]).ket()
        assert np.allclose(final_state, expected_state, atol=tol, rtol=0)
    def test_displaced_squeezed(self, setup_eng, hbar, cutoff, bsize, pure,
                                tol):
        """Test displaced squeezed function matches Fock backends"""
        eng, prog = setup_eng(1)
        a = 0.32 + 0.1j
        r = 0.112
        phi = 0.123

        with prog.context as q:
            ops.Sgate(r, phi) | q[0]
            ops.Dgate(np.abs(a), np.angle(a)) | q[0]

        state = eng.run(prog).state
        ket = utils.displaced_squeezed_state(np.abs(a),
                                             np.angle(a),
                                             r,
                                             phi,
                                             basis="fock",
                                             fock_dim=cutoff,
                                             hbar=hbar)

        if not pure:
            expected = state.dm()
            ket = np.tile(np.outer(ket, ket.conj()), (bsize, 1, 1))
        else:
            expected = state.ket()
            ket = np.tile(ket, (bsize, 1))

        assert np.allclose(expected, ket, atol=tol, rtol=0)
    def test_cropping_tdmprogram_with_several_spatial_modes(self):
        """Test that error is raised when cropping samples from a TDM program with more than
        one spatial mode"""

        prog = TDMProgram(N=[1, 2])
        with prog.context([0, np.pi / 2], [0, np.pi / 2]) as (p, q):
            ops.Sgate(4) | q[0]
            ops.Sgate(4) | q[2]
            ops.MeasureHomodyne(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[1]

        with pytest.raises(
            NotImplementedError,
            match="Cropping vacuum modes for programs with more than one spatial mode is not implemented.",
        ):
            prog.get_crop_value()
    def test_S2gate_decomp_equal(self, setup_eng, r, tol):
        """Tests that the S2gate gives the same transformation as its decomposition."""
        eng, prog = setup_eng(2)

        phi = 0.273
        BS = ops.BSgate(np.pi / 4, 0)
        with prog.context as q:
            ops.S2gate(r, phi) | q
            # run decomposition with reversed arguments
            BS | q
            ops.Sgate(-r, phi) | q[0]
            ops.Sgate(r, phi) | q[1]
            BS.H | q

        eng.run(prog)
        assert np.all(eng.backend.is_vacuum(tol))
Esempio n. 6
0
    def test_apply_history(self, setup_eng, pure):
        """Tests the reapply history argument works correctly with a backend"""
        eng, q = setup_eng(2)

        a = 0.23
        r = 0.1

        def inspect():
            res = []
            print_fn = lambda x: res.append(x.__str__())
            eng.print_applied(print_fn)
            return res

        with eng:
            ops.Dgate(a) | q[0]
            ops.Sgate(r) | q[1]

        state1 = eng.run()
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[0])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
        ]

        assert inspect() == expected

        # reset backend, but reapply history
        eng.backend.reset(pure=pure)
        state2 = eng.run(apply_history=True)
        assert inspect() == expected
        assert state1 == state2

        # append more commands to the same backend
        with eng:
            ops.Rgate(r) | q[0]

        state3 = eng.run()
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[0])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
            "Run 1:",
            "Rgate({}) | (q[0])".format(r),
        ]

        assert inspect() == expected
        assert not state2 == state3

        # reset backend, but reapply history
        eng.backend.reset(pure=pure)
        state4 = eng.run(apply_history=True)
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[0])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
            "Rgate({}) | (q[0])".format(r),
        ]

        assert inspect() == expected
        assert state3 == state4
    def test_displaced_squeezed(self, a, r, phi, setup_eng, hbar, tol):
        """Test displaced squeezed function matches Gaussian backends"""
        eng, prog = setup_eng(1)

        with prog.context as q:
            ops.Sgate(r, phi) | q[0]
            ops.Dgate(np.abs(a), np.angle(a)) | q[0]

        state = eng.run(prog).state

        mu, cov = utils.displaced_squeezed_state(np.abs(a),
                                                 np.angle(a),
                                                 r,
                                                 phi,
                                                 basis="gaussian",
                                                 hbar=hbar)

        if eng.backend_name == "gassian":
            mu_exp, cov_exp = state.reduced_gaussian(0)
            assert np.allclose(mu, mu_exp, atol=tol, rtol=0)
            assert np.allclose(cov, cov_exp, atol=tol, rtol=0)

        elif eng.backend_name == "bosonic":
            _, mu_exp, cov_exp = state.reduced_bosonic(0)
            assert np.allclose(np.expand_dims(mu, axis=0),
                               mu_exp,
                               atol=tol,
                               rtol=0)
            assert np.allclose(np.expand_dims(cov, axis=0),
                               cov_exp,
                               atol=tol,
                               rtol=0)
    def test_unroll_shots(self):
        """Test unrolling program several times using different number of shots."""
        n = 2
        shots = 2

        prog = sf.TDMProgram(N=2)
        with prog.context([0] * n, [0] * n, [0] * n) as (p, q):
            ops.Sgate(0.5643, 0) | q[1]
            ops.BSgate(p[0]) | (q[1], q[0])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        prog_length = len(prog.circuit)
        assert prog_length == 4

        prog.unroll(shots=shots)
        assert len(prog.circuit) == n * shots * prog_length

        # unroll once more with the same number of shots to cover caching
        prog.unroll(shots=shots)
        assert len(prog.circuit) == n * shots * prog_length

        # unroll once more with a different number of shots
        shots = 3
        prog.unroll(shots=shots)
        assert len(prog.circuit) == n * shots * prog_length

        prog.roll()
        assert len(prog.circuit) == prog_length
    def test_extract_arbitrary_unitary_one_mode(self, setup_eng, cutoff, tol):
        """Test that arbitrary unitary extraction works for 1 mode"""
        S = ops.Sgate(0.4, -1.2)
        D = ops.Dgate(2, 0.9)
        K = ops.Kgate(-1.5)

        # not a state but it doesn't matter
        initial_state = np.random.rand(cutoff) + 1j * np.random.rand(cutoff)

        eng_ref, p0 = setup_eng(1)
        with p0.context as q:
            ops.Ket(initial_state) | q

        prog = sf.Program(p0)
        with prog.context as q:
            S | q
            D | q
            K | q

        U = utils.extract_unitary(prog,
                                  cutoff_dim=cutoff,
                                  backend=eng_ref.backend_name)

        if isinstance(U, tf.Tensor):
            U = U.numpy()

        final_state = U @ initial_state

        expected_state = eng_ref.run([p0, prog]).state.ket()

        assert np.allclose(final_state, expected_state, atol=tol, rtol=0)
Esempio n. 10
0
def test_free_parameters(setup_eng, tol):
    """Programs with free parameters."""

    eng, prog = setup_eng(1)
    x = prog.params("x")  # free parameter
    with prog.context as q:
        ops.Dgate(x) | q
        ops.Sgate(-1.2 * x * pf.sin(x**2 - 0.1)) | q

    with pytest.raises(ParameterError, match="Unknown free parameter"):
        eng.run(prog, args={"foo": 1.0})
    with pytest.raises(ParameterError,
                       match="unbound parameter with no default value"):
        eng.run(prog)

    # successful run
    eng.run(prog, args={x: 0.0})
    assert np.all(eng.backend.is_vacuum(tol))
    eng.reset()

    # now set a default value for the free parameter
    x.default = 0.0
    eng.run(prog)
    assert np.all(eng.backend.is_vacuum(tol))
    eng.reset()

    # override the default
    x.default = 1.0
    eng.run(prog, args={x: 0.0})
    assert np.all(eng.backend.is_vacuum(tol))
    def setup_two_mode_circuit(self, setup_eng, cutoff):
        """Create the circuit for following tests"""
        eng_ref, q = setup_eng(2)

        S = ops.Sgate(2)
        B = ops.BSgate(2.234, -1.165)

        initial_state = np.complex64(
            np.random.rand(*[cutoff] * 4) + 1j * np.random.rand(*[cutoff] * 4))

        with eng_ref:
            ops.DensityMatrix(initial_state) | q
            S | q[0]
            B | q
            S | q[1]
            B | q

        eng, q = sf.Engine(2)

        with eng:
            S | q[0]
            B | q
            S | q[1]
            B | q

        rho = eng_ref.run().dm()
        return eng, rho, initial_state
def layer(params, q):
    """CV quantum neural network layer acting on ``N`` modes.

    Args:
        params (list[float]): list of length ``2*(max(1, N-1) + N**2 + n)`` containing
            the number of parameters for the layer
        q (list[RegRef]): list of Strawberry Fields quantum registers the layer
            is to be applied to
    """
    N = len(q)
    M = int(N * (N - 1)) + max(1, N - 1)

    int1 = params[:M]
    s = params[M:M + N]
    int2 = params[M + N:2 * M + N]
    dr = params[2 * M + N:2 * M + 2 * N]
    dp = params[2 * M + 2 * N:2 * M + 3 * N]
    k = params[2 * M + 3 * N:2 * M + 4 * N]

    # begin layer
    interferometer(int1, q)

    for i in range(N):
        ops.Sgate(s[i]) | q[i]

    interferometer(int2, q)

    for i in range(N):
        ops.Dgate(dr[i], dp[i]) | q[i]
        ops.Kgate(k[i]) | q[i]
def test_modes_subset(depth):
    """Tests that the compiler recognizes which modes are not being modified and acts accordingly"""

    width = 10
    eng = sf.LocalEngine(backend="gaussian")
    eng1 = sf.LocalEngine(backend="gaussian")
    circuit = sf.Program(width)
    indices = (1, 4, 2, 6, 7)
    active_modes = len(indices)
    with circuit.context as q:
        for _ in range(depth):
            U, s, V, _ = random_params(active_modes, 2.0 / depth, 1.0)
            ops.Interferometer(U) | tuple(q[i] for i in indices)
            for i, index in enumerate(indices):
                ops.Sgate(s[i]) | q[index]
            ops.Interferometer(V) | tuple(q[i] for i in indices)
    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)
    assert len(compiled_circuit.circuit[0].reg) == 5
    indices = [compiled_circuit.circuit[0].reg[i].ind for i in range(5)]
    assert indices == sorted(list(indices))
Esempio n. 14
0
    def test_delays_tdmprogram_with_several_spatial_modes(self):
        """Test that error is raised when calculating the delays of a TDM program with more than
        one spatial mode"""

        prog = TDMProgram(N=[1, 2])
        with prog.context([0, np.pi / 2], [0, np.pi / 2]) as (p, q):
            ops.Sgate(4) | q[0]
            ops.Sgate(4) | q[2]
            ops.MeasureHomodyne(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[1]

        with pytest.raises(
            NotImplementedError,
            match="Calculating delays for programs with more than one spatial mode is not implemented.",
        ):
            prog.get_delays()
    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)
Esempio n. 16
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)
Esempio n. 17
0
    def test_GBS_compile_no_fock_meas(self):
        """Tests that GBS compilation fails when no fock measurements are made."""
        prog = sf.Program(2)
        with prog.context as q:
            ops.Dgate(1.0) | q[0]
            ops.Sgate(-0.5) | q[1]

        with pytest.raises(program.CircuitError, match="GBS circuits must contain Fock measurements."):
            prog.compile('gbs')
Esempio n. 18
0
    def test_generate_code_no_engine(self):
        """Test generating code for a regular program with no engine"""
        prog = sf.Program(3)

        with prog.context as q:
            ops.Sgate(0.54, 0) | q[0]
            ops.BSgate(0.45, np.pi / 2) | (q[0], q[2])
            ops.Sgate(3 * np.pi / 2, 0) | q[1]
            ops.BSgate(2 * np.pi, 0.62) | (q[0], q[1])
            ops.MeasureFock() | q[0]

        code = io.generate_code(prog)

        code_list = code.split("\n")
        expected = prog_txt_no_engine.split("\n")

        for i, row in enumerate(code_list):
            assert row == expected[i]
Esempio n. 19
0
    def test_neq_operator(self):
        """Not-equal operator check."""
        prog_1 = sf.Program(2)
        prog_2 = sf.Program(2)

        with prog_1.context as q:
            ops.Sgate(0.2) | q[0]
            ops.BSgate() | (q[0], q[1])
            ops.MeasureFock() | q[1]

        with prog_2.context as q:
            ops.Sgate(4.2) | q[0]
            ops.BSgate() | (q[0], q[1])
            ops.MeasureFock() | q[1]

        # should NOT be equal
        assert prog_1 != prog_2
        assert prog_2 != prog_1
Esempio n. 20
0
def test_one_dimensional_cluster_tokyo():
    """
    One-dimensional temporal-mode cluster state as demonstrated in
    https://aip.scitation.org/doi/pdf/10.1063/1.4962732
    """
    sq_r = 5

    n = 10  # for an n-mode cluster state
    shots = 3

    # first half of cluster state measured in X, second half in P
    theta1 = [0] * int(n / 2) + [np.pi / 2] * int(n / 2)  # measurement angles for detector A
    theta2 = theta1  # measurement angles for detector B

    prog = TDMProgram(N=[1, 2])
    with prog.context(theta1, theta2, shift="default") as (p, q):
        ops.Sgate(sq_r, 0) | q[0]
        ops.Sgate(sq_r, 0) | q[2]
        ops.Rgate(np.pi / 2) | q[0]
        ops.BSgate(np.pi / 4) | (q[0], q[2])
        ops.BSgate(np.pi / 4) | (q[0], q[1])
        ops.MeasureHomodyne(p[0]) | q[0]
        ops.MeasureHomodyne(p[1]) | q[1]
    eng = sf.Engine("gaussian")

    result = eng.run(prog, shots=shots)
    reshaped_samples = result.samples

    for sh in range(shots):
        X_A = reshaped_samples[sh][0][: n // 2]  # X samples from detector A
        P_A = reshaped_samples[sh][0][n // 2 :]  # P samples from detector A
        X_B = reshaped_samples[sh][1][: n // 2]  # X samples from detector B
        P_B = reshaped_samples[sh][1][n // 2 :]  # P samples from detector B

        # nullifiers defined in https://aip.scitation.org/doi/pdf/10.1063/1.4962732, Eqs. (1a) and (1b)
        ntot = len(X_A) - 1
        nX = np.array([X_A[i] + X_B[i] + X_A[i + 1] - X_B[i + 1] for i in range(ntot)])
        nP = np.array([P_A[i] + P_B[i] - P_A[i + 1] + P_B[i + 1] for i in range(ntot)])

        nXvar = np.var(nX)
        nPvar = np.var(nP)

        assert np.allclose(nXvar, 2 * sf.hbar * np.exp(-2 * sq_r), rtol=5 / np.sqrt(n))
        assert np.allclose(nPvar, 2 * sf.hbar * np.exp(-2 * sq_r), rtol=5 / np.sqrt(n))
Esempio n. 21
0
    def test_apply_history(self, eng):
        """Tests the reapply history argument"""
        a = 0.23
        r = 0.1

        def inspect():
            res = []
            print_fn = lambda x: res.append(x.__str__())
            eng.print_applied(print_fn)
            return res

        p1 = sf.Program(2)
        with p1.context as q:
            ops.Dgate(a) | q[1]
            ops.Sgate(r) | q[1]

        eng.run(p1)
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[1])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
        ]
        assert inspect() == expected

        # run the program again
        eng.reset()
        eng.run(p1)
        assert inspect() == expected

        # apply more commands to the same backend
        p2 = sf.Program(2)
        with p2.context as q:
            ops.Rgate(r) | q[1]

        eng.run(p2)
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[1])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
            "Run 1:",
            "Rgate({}) | (q[1])".format(r),
        ]

        assert inspect() == expected

        # reapply history
        eng.reset()
        eng.run([p1, p2])
        #expected = [
        #    "Run 0:",
        #    "Dgate({}, 0) | (q[1])".format(a),
        #    "Sgate({}, 0) | (q[1])".format(r),
        #    "Rgate({}) | (q[1])".format(r),
        #]

        assert inspect() == expected
    def test_CXgate_decomp_equal(self, setup_eng, s, tol):
        """Tests that the CXgate gives the same transformation as its decomposition."""
        eng, prog = setup_eng(2)

        r = np.arcsinh(-s / 2)
        y = -1 / np.cosh(r)
        x = -np.tanh(r)
        theta = np.arctan2(y, x) / 2

        with prog.context as q:
            ops.CXgate(s) | q
            # run decomposition with reversed arguments
            ops.BSgate(-(np.pi / 2 + theta), 0) | q
            ops.Sgate(r, np.pi) | q[0]
            ops.Sgate(r, 0) | q[1]
            ops.BSgate(-theta, 0) | q

        eng.run(prog)
        assert np.all(eng.backend.is_vacuum(tol))
Esempio n. 23
0
def test_all_passive_gates(hbar, tol):
    """test that all gates run and do not cause anything to crash"""

    eng = sf.LocalEngine(backend="gaussian")
    circuit = sf.Program(4)

    with circuit.context as q:
        for i in range(4):
            ops.Sgate(1, 0.3) | q[i]
        ops.Rgate(np.pi) | q[0]
        ops.PassiveChannel(np.ones((2, 2))) | (q[1], q[2])
        ops.LossChannel(0.9) | q[1]
        ops.MZgate(0.25 * np.pi, 0) | (q[2], q[3])
        ops.PassiveChannel(np.array([[0.83]])) | q[0]
        ops.sMZgate(0.11, -2.1) | (q[0], q[3])
        ops.Interferometer(np.array([[np.exp(1j * 2)]])) | q[1]
        ops.BSgate(0.8, 0.4) | (q[1], q[3])
        ops.Interferometer(0.5**0.5 * np.fft.fft(np.eye(2))) | (q[0], q[2])
        ops.PassiveChannel(0.1 * np.ones((3, 3))) | (q[3], q[1], q[0])

    cov = eng.run(circuit).state.cov()

    circuit = sf.Program(4)
    with circuit.context as q:
        ops.Rgate(np.pi) | q[0]
        ops.PassiveChannel(np.ones((2, 2))) | (q[1], q[2])
        ops.LossChannel(0.9) | q[1]
        ops.MZgate(0.25 * np.pi, 0) | (q[2], q[3])
        ops.PassiveChannel(np.array([[0.83]])) | q[0]
        ops.sMZgate(0.11, -2.1) | (q[0], q[3])
        ops.Interferometer(np.array([[np.exp(1j * 2)]])) | q[1]
        ops.BSgate(0.8, 0.4) | (q[1], q[3])
        ops.Interferometer(0.5**0.5 * np.fft.fft(np.eye(2))) | (q[0], q[2])
        ops.PassiveChannel(0.1 * np.ones((3, 3))) | (q[3], q[1], q[0])

    compiled_circuit = circuit.compile(compiler="passive")
    T = compiled_circuit.circuit[0].op.p[0]

    S_sq = np.eye(8, dtype=np.complex128)
    r = 1
    phi = 0.3
    for i in range(4):
        S_sq[i, i] = np.cosh(r) - np.sinh(r) * np.cos(phi)
        S_sq[i, i + 4] = -np.sinh(r) * np.sin(phi)
        S_sq[i + 4, i] = -np.sinh(r) * np.sin(phi)
        S_sq[i + 4, i + 4] = np.cosh(r) + np.sinh(r) * np.cos(phi)

    cov_sq = (hbar / 2) * S_sq @ S_sq.T
    mu = np.zeros(8)

    P = interferometer(T)
    L = (hbar / 2) * (np.eye(P.shape[0]) - P @ P.T)
    cov2 = P @ cov_sq @ P.T + L

    assert np.allclose(cov, cov2, atol=tol, rtol=0)
Esempio n. 24
0
    def test_apply_history(self, backend):
        """Tests the reapply history argument"""
        eng, q = sf.Engine(2)

        a = 0.23
        r = 0.1

        def inspect():
            res = []
            print_fn = lambda x: res.append(x.__str__())
            eng.print_applied(print_fn)
            return res

        with eng:
            ops.Dgate(a) | q[0]
            ops.Sgate(r) | q[1]

        eng.run(backend)
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[0])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
        ]

        assert inspect() == expected

        # reapply history
        state2 = eng.run(apply_history=True)
        assert inspect() == expected

        # append more commands to the same backend
        with eng:
            ops.Rgate(r) | q[0]

        eng.run()
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[0])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
            "Run 1:",
            "Rgate({}) | (q[0])".format(r),
        ]

        assert inspect() == expected

        # reapply history
        eng.run(apply_history=True)
        expected = [
            "Run 0:",
            "Dgate({}, 0) | (q[0])".format(a),
            "Sgate({}, 0) | (q[1])".format(r),
            "Rgate({}) | (q[0])".format(r),
        ]

        assert inspect() == expected
    def test_shots_default(self):
        """Test that default shots (1) is used"""
        prog = sf.TDMProgram(2)
        eng = sf.Engine("gaussian")

        with prog.context([1, 2], [3, 4]) as (p, q):
            ops.Sgate(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[0]

        results = eng.run(prog)
        assert results.samples.shape[0] == 1
Esempio n. 26
0
    def test_shots_default(self):
        """Test that default shots (1) is used"""
        prog = sf.Program(1)
        eng = sf.Engine("gaussian")

        with prog.context as q:
            ops.Sgate(0.5) | q[0]
            ops.MeasureFock() | q

        results = eng.run(prog)
        assert results.samples.shape[0] == 1
Esempio n. 27
0
    def test_regref_no_func_str(self):
        """Test a regreftransform with no function string raises exception"""
        prog = Program(2)

        with prog.context as q:
            ops.Sgate(0.43) | q[0]
            ops.MeasureX | q[0]
            ops.Zgate(ops.RR(q[0], lambda x: 2 * x)) | q[1]

        with pytest.raises(ValueError, match="not supported by Blackbird"):
            io.to_blackbird(prog)
Esempio n. 28
0
    def test_measured_par_str(self):
        """Test a MeasuredParameter with some transformations converts properly"""
        prog = Program(2)
        with prog.context as q:
            ops.Sgate(0.43) | q[0]
            ops.MeasureX | q[0]
            ops.Zgate(2 * pf.sin(q[0].par)) | q[1]

        bb = io.to_blackbird(prog)
        expected = {"op": "Zgate", "modes": [1], "args": ["2*sin(q0)"], "kwargs": {}}
        assert bb.operations[-1] == expected
Esempio n. 29
0
    def test_free_par_str(self):
        """Test a FreeParameter with some transformations converts properly"""
        prog = Program(2)
        r, alpha = prog.params('r', 'alpha')
        with prog.context as q:
            ops.Sgate(r) | q[0]
            ops.Zgate(3 * pf.log(-alpha)) | q[1]

        bb = io.to_blackbird(prog)
        assert bb.operations[0] == {"op": "Sgate", "modes": [0], "args": ['{r}', 0.0], "kwargs": {}}
        assert bb.operations[1] == {"op": "Zgate", "modes": [1], "args": ['3*log(-{alpha})'], "kwargs": {}}
    def test_extract_arbitrary_unitary_two_modes_vectorized(
            self, setup_eng, cutoff, batch_size, tol):
        """Test that arbitrary unitary extraction works for 2 mode when vectorized"""
        bsize = 1
        if batch_size is not None:
            bsize = batch_size

        S = ops.Sgate(0.4, -1.2)
        B = ops.BSgate(2.234, -1.165)

        # not a state but it doesn't matter
        initial_state = np.complex64(
            np.random.rand(cutoff, cutoff) +
            1j * np.random.rand(cutoff, cutoff))

        eng_ref, p0 = setup_eng(2)
        with p0.context as q:
            ops.Ket(initial_state) | q

        prog = sf.Program(p0)
        with prog.context as q:
            S | q[0]
            B | q
            S | q[1]
            B | q

        U = utils.extract_unitary(
            prog,
            cutoff_dim=cutoff,
            vectorize_modes=True,
            backend=eng_ref.backend_name,
        )

        if isinstance(U, tf.Tensor):
            U = U.numpy()

        final_state = U @ initial_state.reshape([-1])
        expected_state = eng_ref.run([p0, prog]).state.ket()

        if isinstance(expected_state, tf.Tensor):
            expected_state = expected_state.numpy()

        if expected_state.shape[
                0] == bsize:  # the Fock backend does not support batching!
            for exp_state in expected_state:
                assert np.allclose(final_state,
                                   exp_state.reshape([-1]),
                                   atol=tol,
                                   rtol=0)
        else:
            assert np.allclose(final_state,
                               expected_state.reshape([-1]),
                               atol=tol,
                               rtol=0)