Exemple #1
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)
Exemple #2
0
    def test_loss_channel(self, setup_eng, tol):
        """Test loss channel with no transmission produces vacuum"""
        eng, prog = setup_eng(1)

        with prog.context as q:
            ops.Dgate(A) | q[0]
            ops.LossChannel(0) | q[0]

        eng.run(prog)
        assert np.all(eng.backend.is_vacuum(tol))
Exemple #3
0
def test_passive_program(tol, depth, width):
    """Tests that a circuit and its compiled version produce the same Gaussian state"""
    circuit = sf.Program(width)

    T_circuit = np.eye(width, dtype=np.complex128)
    with circuit.context as q:
        for _ in range(depth):
            U = unitary_group.rvs(width)
            T_circuit = U @ T_circuit
            ops.Interferometer(U) | q
            for i in range(width):
                ops.LossChannel(0.5) | q[i]
            T_circuit *= np.sqrt(0.5)

    compiled_circuit = circuit.compile(compiler="passive")
    T = compiled_circuit.circuit[0].op.p[0]
    assert np.allclose(T, T_circuit, atol=tol, rtol=0)
    def setup_one_mode_circuit(self, setup_eng, cutoff):
        """Create the circuit for following tests"""
        eng_ref, p0 = setup_eng(1)

        S = ops.Sgate(1.1, -1.4)
        L = ops.LossChannel(0.45)

        initial_state = np.random.rand(cutoff, cutoff)

        with p0.context as q:
            ops.DensityMatrix(initial_state) | q

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

        rho = eng_ref.run([p0, prog]).state.dm()
        return prog, rho, initial_state
    def setup_one_mode_circuit(self, setup_eng, cutoff):
        """Create the circuit for following tests"""
        eng_ref, q = setup_eng(1)

        S = ops.Sgate(1.1, -1.4)
        L = ops.LossChannel(0.45)

        initial_state = np.random.rand(cutoff, cutoff)

        with eng_ref:
            ops.DensityMatrix(initial_state) | q
            S | q
            L | q

        eng, q = sf.Engine(1)

        with eng:
            S | q
            L | q

        rho = eng_ref.run().dm()
        return eng, rho, initial_state
Exemple #6
0
    def test_passive_channel(self, M, setup_eng, tol):
        """check that passive channel is consistent with unitary methods"""
        U = unitary_group.rvs(M)

        loss_in = np.random.random(M)
        loss_out = np.random.random(M)

        T = (np.sqrt(loss_in) * U) * np.sqrt(loss_out[np.newaxis].T)

        eng, prog = setup_eng(M)
        with prog.context as q:
            for i in range(M):
                ops.Sgate(1) | q[i]
                ops.Dgate(A) | q[i]
            ops.PassiveChannel(T) | q

        state = eng.run(prog).state
        cov1 = state.cov()
        mu1 = state.means()

        eng, prog = setup_eng(M)
        with prog.context as q:
            for i in range(M):
                ops.Sgate(1) | q[i]
                ops.Dgate(A) | q[i]
                ops.LossChannel(loss_in[i]) | q[i]
            ops.Interferometer(U) | q
            for i in range(M):
                ops.LossChannel(loss_out[i]) | q[i]

        state = eng.run(prog).state
        cov2 = state.cov()
        mu2 = state.means()

        assert np.allclose(cov1, cov2, atol=tol, rtol=0)
        assert np.allclose(mu1, mu2, atol=tol, rtol=0)

        u, s, v = np.linalg.svd(T)

        eng, prog = setup_eng(M)
        with prog.context as q:
            for i in range(M):
                ops.Sgate(1) | q[i]
                ops.Dgate(A) | q[i]
            ops.Interferometer(v) | q
            for i in range(M):
                ops.LossChannel(s[i]**2) | q[i]
            ops.Interferometer(u) | q

        state = eng.run(prog).state
        cov3 = state.cov()
        mu3 = state.means()

        assert np.allclose(cov1, cov3, atol=tol, rtol=0)
        assert np.allclose(mu1, mu3, atol=tol, rtol=0)

        T1 = u * s
        eng, prog = setup_eng(M)
        with prog.context as q:
            for i in range(M):
                ops.Sgate(1) | q[i]
                ops.Dgate(A) | q[i]
            ops.PassiveChannel(v) | q
            ops.PassiveChannel(T1) | q

        state = eng.run(prog).state
        cov4 = state.cov()
        mu4 = state.means()

        assert np.allclose(cov1, cov4, atol=tol, rtol=0)
        assert np.allclose(mu1, mu4, atol=tol, rtol=0)
 def test_thermalloss_merging_different_nbar(self, tol):
     """test the merging of Loss and ThermalLoss raises exception"""
     G = ops.ThermalLossChannel(a, 2 * c)
     with pytest.raises(MergeFailure):
         merged = G.merge(ops.LossChannel(b))
 def test_loss_merging_identity(self, tol):
     """test the merging of two Loss channels such that
     the resulting loss channel is simply the identity"""
     G = ops.LossChannel(a)
     merged = G.merge(ops.LossChannel(1.0 / a))
     assert merged is None
 def test_loss_merging(self, tol):
     """test the merging of two Loss channels (with default values
     for optional parameters)"""
     G = ops.LossChannel(a)
     merged = G.merge(ops.LossChannel(b))
     assert np.allclose(merged.p[0], a * b, atol=tol, rtol=0)
def circuit(cutoff, l1=0.85, l2=1):
    """Runs the heralded circuit with specified parameters,
    returning the output fidelity to the requested weak cubic phase state,
    the post-selection probability, and the Wigner log negativity.

    Args:
        cutoff (int): the Fock basis truncation
        l1 (float): squeeze cavity loss
        l2 (float): PNR loss

    Returns:
        tuple: a tuple containing the output fidelity to the target ON state,
            the probability of post-selection, the state norm before entering the beamsplitter,
            the state norm after exiting the beamsplitter, and the density matrix of the output state.
    """
    # weak cubic phase state parameter
    a = 0.53
    # the Fock state measurement of mode 0 to be post-selected
    m1 = 1
    # the Fock state measurement of mode 1 to be post-selected
    m2 = 2

    # define target state
    target_state = cubic_phase_state(a, cutoff)

    # gate parameters for the heralded quantum circuit.
    # squeezing magnitudes
    sq_r = [0.71, 0.67, -0.42]
    # squeezing phase
    sq_phi = [-2.07, 0.06, -3.79]
    # displacement magnitudes
    d_r = [-0.02, 0.34, 0.02]
    # beamsplitter theta
    bs_theta1, bs_theta2, bs_theta3 = [-1.57, 0.68, 2.5]
    # beamsplitter phi
    bs_phi1, bs_phi2, bs_phi3 = [0.53, -4.51, 0.72]

    # quantum circuit prior to entering the beamsplitter
    eng, q = sf.Engine(3)
    with eng:
        for k in range(3):
            ops.Sgate(sq_r[k], sq_phi[k]) | q[k]
            ops.Dgate(d_r[k]) | q[k]
            ops.LossChannel(l1) | q[k]

        ops.BSgate(bs_theta1, bs_phi1) | (q[0], q[1])
        ops.BSgate(bs_theta2, bs_phi2) | (q[1], q[2])
        ops.BSgate(bs_theta3, bs_phi3) | (q[0], q[1])
        ops.LossChannel(l2) | q[0]
        ops.LossChannel(l2) | q[1]

    state = eng.run("gaussian", cutoff_dim=cutoff)
    mu = state.means()
    cov = state.cov()

    rho = density_matrix(mu,
                         cov,
                         post_select={
                             0: m1,
                             1: m2
                         },
                         cutoff=cutoff,
                         hbar=2)

    # probability of measuring m1 and m2
    prob = np.abs(np.trace(rho))

    # output state
    if prob != 0:
        rho = rho / prob

    # fidelity with the target state
    fidelity = np.abs(np.trace(np.einsum("ij,jk->ik", rho, target_state)))
    return fidelity, prob, rho