Exemplo n.º 1
0
    def test_merge(self, tol):
        """Test that two interferometers merge: U = U1 @ U2"""
        n = 3
        U1 = random_interferometer(n)
        U2 = random_interferometer(n)

        int1 = ops.Interferometer(U1)
        int1inv = ops.Interferometer(U1.conj().T)
        int2 = ops.Interferometer(U2)

        # an interferometer merged with its inverse is identity
        assert int1.merge(int1inv) is None

        # two merged unitaries are the same as their product
        assert np.allclose(int1.merge(int2).p[0].x, U2 @ U1, atol=tol, rtol=0)
Exemplo n.º 2
0
    def test_no_s2gates(self, tol):
        """Test identity S2gates are inserted when no S2gates
        are provided."""
        prog = sf.Program(8)
        U = random_interferometer(4)

        with prog.context as q:
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        expected = sf.Program(8)

        with expected.context as q:
            ops.S2gate(0) | (q[0], q[4])
            ops.S2gate(0) | (q[1], q[5])
            ops.S2gate(0) | (q[2], q[6])
            ops.S2gate(0) | (q[3], q[7])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        res = prog.compile("X8_01")
        expected = expected.compile("X8_01")
        assert program_equivalence(res, expected, atol=tol)
Exemplo n.º 3
0
    def runJob(self, eng):
        num_subsystem = 8
        prog = sf.Program(num_subsystem, name="remote_job")
        U = random_interferometer(4)
        with prog.context as q:
            # Initial squeezed states
            # Allowed values are r=1.0 or r=0.0
            ops.S2gate(1.0) | (q[0], q[4])
            ops.S2gate(1.0) | (q[1], q[5])
            ops.S2gate(1.0) | (q[3], q[7])

            # Interferometer on the signal modes (0-3)
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.BSgate(0.543, 0.123) | (q[2], q[0])
            ops.Rgate(0.453) | q[1]
            ops.MZgate(0.65, -0.54) | (q[2], q[3])

            # *Same* interferometer on the idler modes (4-7)
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.BSgate(0.543, 0.123) | (q[6], q[4])
            ops.Rgate(0.453) | q[5]
            ops.MZgate(0.65, -0.54) | (q[6], q[7])

            ops.MeasureFock() | q


        eng = eng
        results =eng.run(prog, shots=10)
        # state = results.state
        # measurements = results.samples
        return results.samples
Exemplo n.º 4
0
    def test_missing_s2gates(self, chip, tol):
        """Test identity S2gates are inserted when some (but not all)
        S2gates are included."""
        prog = sf.Program(12)
        U = random_interferometer(6)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[1], q[7])
            ops.S2gate(SQ_AMPLITUDE) | (q[3], q[9])
            ops.S2gate(SQ_AMPLITUDE) | (q[5], q[11])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3], q[4], q[5])
            ops.Interferometer(U) | (q[6], q[7], q[8], q[9], q[10], q[11])
            ops.MeasureFock() | q

        expected = sf.Program(12)

        with expected.context as q:
            ops.S2gate(0) | (q[0], q[6])
            ops.S2gate(SQ_AMPLITUDE) | (q[1], q[7])
            ops.S2gate(0) | (q[2], q[8])
            ops.S2gate(SQ_AMPLITUDE) | (q[3], q[9])
            ops.S2gate(0) | (q[4], q[10])
            ops.S2gate(SQ_AMPLITUDE) | (q[5], q[11])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3], q[4], q[5])
            ops.Interferometer(U) | (q[6], q[7], q[8], q[9], q[10], q[11])
            ops.MeasureFock() | q

        res = prog.compile(chip.short_name)
        expected = expected.compile(chip.short_name)
        assert program_equivalence(res, expected, atol=tol)
Exemplo n.º 5
0
 def test_random_inteferometer_is_unitary(self, modes, tol, real):
     """Test that a random interferometer is unitary"""
     U = utils.random_interferometer(modes, real=real)
     assert np.allclose(U @ U.conj().T,
                        np.identity(modes),
                        atol=tol,
                        rtol=0)
Exemplo n.º 6
0
    def test_no_s2gates(self, num_pairs, tol):
        """Test identity S2gates are inserted when no S2gates
        are provided."""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)

        with prog.context as q:
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(
                q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        expected = sf.Program(2 * num_pairs)

        with expected.context as q:
            for i in range(num_pairs):
                ops.S2gate(0) | (q[i], q[i + num_pairs])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(
                q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        res = prog.compile(compiler="Xcov")
        expected = expected.compile(compiler="Xcov")
        assert program_equivalence(res, expected, atol=tol)
Exemplo n.º 7
0
    def test_interferometers(self, tol):
        """Test that the compilation correctly decomposes the interferometer using
        the rectangular_symmetric mesh"""
        prog = sf.Program(8)
        U = random_interferometer(4)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[0], q[4])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[1], q[5])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[2], q[6])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[3], q[7])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        res = prog.compile("X8_01")

        expected = sf.Program(8)

        with expected.context as q:
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[0], q[4])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[1], q[5])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[2], q[6])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[3], q[7])
            ops.Interferometer(U,
                               mesh="rectangular_symmetric",
                               drop_identity=False) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U,
                               mesh="rectangular_symmetric",
                               drop_identity=False) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        expected = expected.compile(DummyCircuit())

        assert program_equivalence(res, expected, atol=tol)
    def test_missing_s2gates(self, num_pairs, tol):
        """Test identity S2gates are inserted when some (but not all)
        S2gates are included."""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)
        assert num_pairs > 3
        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[1], q[num_pairs + 1])
            ops.S2gate(SQ_AMPLITUDE) | (q[3], q[num_pairs + 3])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        expected = sf.Program(2 * num_pairs)

        with expected.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[1], q[num_pairs + 1])
            ops.S2gate(0) | (q[0], q[num_pairs + 0])
            ops.S2gate(SQ_AMPLITUDE) | (q[3], q[num_pairs + 3])
            ops.S2gate(0) | (q[2], q[num_pairs + 2])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        res = prog.compile("Xunitary")
        expected = expected.compile("Xunitary")
        assert program_equivalence(res, expected, atol=tol)
    def test_interferometers(self, tol):
        """Test interferometers correctly decompose to MZ gates"""
        prog = sf.Program(4)
        U = random_interferometer(2)

        with prog.context as q:
            ops.S2gate(0.5) | (q[0], q[2])
            ops.S2gate(0.5) | (q[1], q[3])
            ops.Interferometer(U) | (q[0], q[1])
            ops.Interferometer(U) | (q[2], q[3])
            ops.MeasureFock() | q

        res = prog.compile("chip0")

        expected = sf.Program(4)

        with expected.context as q:
            ops.S2gate(0.5, 0) | (q[0], q[2])
            ops.S2gate(0.5, 0) | (q[1], q[3])
            ops.Interferometer(U,
                               mesh="rectangular_symmetric",
                               drop_identity=False) | (q[0], q[1])
            ops.Interferometer(U,
                               mesh="rectangular_symmetric",
                               drop_identity=False) | (q[2], q[3])
            ops.MeasureFock() | q

        expected = expected.compile(DummyCircuit())

        assert program_equivalence(res, expected, atol=tol)
    def test_interferometers(self, num_pairs, tol):
        """Test that the compilation correctly decomposes the interferometer using
        the rectangular_symmetric mesh"""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)

        with prog.context as q:
            for i in range(0, num_pairs):
                ops.S2gate(SQ_AMPLITUDE) | (q[i], q[i + num_pairs])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        res = prog.compile("Xunitary")

        expected = sf.Program(2 * num_pairs)

        with expected.context as q:
            for i in range(0, num_pairs):
                ops.S2gate(SQ_AMPLITUDE) | (q[i], q[i + num_pairs])
            ops.Interferometer(U, mesh="rectangular_symmetric", drop_identity=False) | tuple(
                q[i] for i in range(num_pairs)
            )
            ops.Interferometer(U, mesh="rectangular_symmetric", drop_identity=False) | tuple(
                q[i] for i in range(num_pairs, 2 * num_pairs)
            )
            ops.MeasureFock() | q

        expected = expected.compile(DummyCircuit())
        # Note that since DummyCircuit() has a hard coded limit of 8 modes we only check for this number
        assert program_equivalence(res, expected, atol=tol, compare_params=False)
Exemplo n.º 11
0
    def test_decomposition(self, tol):
        """Test that an interferometer is correctly decomposed"""
        n = 3
        prog = sf.Program(n)
        U = random_interferometer(n)
        BS1, BS2, R = dec.clements(U)

        G = ops.Interferometer(U)
        cmds = G.decompose(prog.register)

        S = np.identity(2 * n)

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

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

            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

        # the resulting applied unitary
        X1 = S[:n, :n]
        P1 = S[n:, :n]
        U_applied = X1 + 1j * P1

        assert np.allclose(U, U_applied, atol=tol, rtol=0)
    def test_no_s2gates(self, num_pairs, tol):
        """Test identity S2gates are inserted when no S2gates
        are provided."""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)

        with prog.context as q:
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        expected = sf.Program(2 * num_pairs)

        with expected.context as q:
            for i in range(num_pairs):
                ops.S2gate(0) | (q[i], q[i + num_pairs])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        # with pytest.raises(CircuitError, match="There can be no operations before the S2gates."):
        res = prog.compile("Xunitary")
        # with pytest.raises(CircuitError, match="There can be no operations before the S2gates."):
        expected = expected.compile("Xunitary")
        assert program_equivalence(res, expected, atol=tol)
Exemplo n.º 13
0
    def test_interferometers(self, chip, tol):
        """Test that the compilation correctly decomposes the interferometer using
        the rectangular_symmetric mesh"""
        prog = sf.Program(12)
        U = random_interferometer(6)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[0], q[6])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[1], q[7])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[2], q[8])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[3], q[9])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[4], q[10])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[5], q[11])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3], q[4], q[5])
            ops.Interferometer(U) | (q[6], q[7], q[8], q[9], q[10], q[11])
            ops.MeasureFock() | q

        res = prog.compile(chip.short_name)

        expected = sf.Program(12)

        with expected.context as q:
            for i, j in np.arange(12).reshape(2, -1).T:
                ops.S2gate(SQ_AMPLITUDE, 0) | (q[i], q[j])

            ops.Interferometer(U, mesh="rectangular_symmetric", drop_identity=False) | (q[0], q[1], q[2], q[3], q[4], q[5])
            ops.Interferometer(U, mesh="rectangular_symmetric", drop_identity=False) | (q[6], q[7], q[8], q[9], q[10], q[11])
            ops.MeasureFock() | q

        expected = expected.compile(DummyCircuit())

        assert program_equivalence(res, expected, atol=tol)
Exemplo n.º 14
0
def sample_average_fidelity(V, U, cutoff, samples=10000):
    r"""The average fidelity between the two unitaries, calculated via
    Monte-Carlo integration.

    This function returns the following average fidelity:

    .. math::
        \bar{F}  = \frac{1}{N} \sum_{i=0}^{N} |\langle 0 \mid W_i^\dagger V^\dagger U(\vec{\theta}) W_i \mid 0\rangle|^2

    where :math:`W_i` is a Haar-distributed random unitary,
    :math:`V` the target unitary, and
    :math:`U` the learnt unitary.

    The target unitary should be of shape [c**m, c**m], where m is
    the number of modes, and c is the simulation cutoff.

    The learnt unitary should be of shape [c**m, d**m], where m is
    the number of modes, c is the simulation cutoff, and d is unitary truncation.

    Args:
        V (array): the target unitary.
        U (array): the learnt unitary.
        cutoff (int): the simulation Fock basis truncation.
        samples (int): the number of samples to perform in the
            Monte-Carlo integration.

    Returns:
        float: Returns the sampled averaged fidelity :math:`\bar{F}`.
    """
    # simulation cutoff
    c = cutoff
    # number of modes
    m = get_modes(V, c)
    # gate cutoff
    d = np.int(U.shape[1]**(1/m))

    if m == 1:
        # single mode unitary
        # reshape the target unitary to be shape [c, d]
        Ut = V[:, :d]
    elif m == 2:
        # two mode unitary
        # reshape the target unitary to be shape [c^2, d^2]
        Ut = V.reshape(c, c, c, c)[:, :, :d, :d].reshape(c**2, d**2)

    fid = []
    Wlist = []
    for i in range(samples):
        W = random_interferometer(d**m)
        Wlist.append(W)
        f = np.abs(W[:, 0].conj().T @ Ut.conj().T @ U @ W[:, 0])**2
        fid.append(f)

    return np.mean(fid)
 def test_not_all_modes_measured(self, num_pairs):
     """Test exceptions raised if not all modes are measured"""
     prog = sf.Program(2 * num_pairs)
     U = random_interferometer(num_pairs)
     with prog.context as q:
         for i in range(num_pairs):
             ops.S2gate(SQ_AMPLITUDE) | (q[i], q[i + num_pairs])
         ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
         ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
         ops.MeasureFock() | (q[0], q[num_pairs])
     with pytest.raises(CircuitError, match="All modes must be measured"):
         prog.compile("Xunitary")
    def test_no_s2gates(self):
        """Test exceptions raised if no S2gates are present"""
        prog = sf.Program(4)
        U = random_interferometer(2)

        with prog.context as q:
            ops.Interferometer(U) | (q[0], q[1])
            ops.Interferometer(U) | (q[2], q[3])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="must start with two S2gates"):
            res = prog.compile("chip0")
Exemplo n.º 17
0
    def test_unitary_too_large(self, chip):
        """Test exception raised if the unitary is applied to more
        than just modes [0, 1, 2, 3] and [4, 5, 6, 7]."""
        prog = sf.Program(12)
        U = random_interferometer(12)

        with prog.context as q:
            for i, j in np.arange(12).reshape(2, -1).T:
                ops.S2gate(SQ_AMPLITUDE, 0) | (q[i], q[j])
            ops.Interferometer(U) | q
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="must be applied separately"):
            res = prog.compile(chip.short_name)
Exemplo n.º 18
0
    def test_s2gate_repeated_modes(self, chip):
        """Test exceptions raised if S2gates are repeated"""
        prog = sf.Program(12)
        U = random_interferometer(6)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[6])
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[6])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3], q[4], q[5])
            ops.Interferometer(U) | (q[6], q[7], q[8], q[9], q[10], q[11])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="incompatible topology."):
            res = prog.compile(chip.short_name)
    def test_incorrect_s2gates(self):
        """Test exceptions raised if S2gates do not appear on correct modes"""
        prog = sf.Program(4)
        U = random_interferometer(2)

        with prog.context as q:
            ops.S2gate(0.5) | (q[0], q[2])
            ops.Interferometer(U) | (q[0], q[1])
            ops.Interferometer(U) | (q[2], q[3])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError,
                           match="S2gates do not appear on the correct modes"):
            res = prog.compile("chip0")
    def test_not_all_modes_measured(self):
        """Test exceptions raised if not all modes are measured"""
        prog = sf.Program(4)
        U = random_interferometer(2)

        with prog.context as q:
            ops.S2gate(0.5) | (q[0], q[2])
            ops.S2gate(0.5) | (q[1], q[3])
            ops.Interferometer(U) | (q[0], q[1])
            ops.Interferometer(U) | (q[2], q[3])
            ops.MeasureFock() | (q[0], q[1])

        with pytest.raises(CircuitError, match="All modes must be measured"):
            res = prog.compile("chip0")
Exemplo n.º 21
0
    def test_s2gate_repeated_modes(self):
        """Test exceptions raised if S2gates are repeated"""
        prog = sf.Program(8)
        U = random_interferometer(4)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[4])
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[4])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="incompatible topology."):
            res = prog.compile("X8_01")
    def test_unitary_too_large(self, num_pairs):
        """Test exception raised if the unitary is applied to more
        than just modes [0, 1, 2, 3, ..., num_pairs-1] and [num_pairs, num_pairs+1, ..., 2*num_pairs-1]."""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(2 * num_pairs)

        with prog.context as q:
            for i in range(0, num_pairs):
                ops.S2gate(SQ_AMPLITUDE) | (q[i], q[i + num_pairs])
            ops.Interferometer(U) | q
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="The applied unitary cannot mix between the modes"):
            res = prog.compile("Xunitary")
    def test_unitary_too_large(self):
        """Test exception raised if the unitary is applied to more
        than just modes [0, 1] and [2, 3]."""
        prog = sf.Program(4)
        U = random_interferometer(4)

        with prog.context as q:
            ops.S2gate(0.5) | (q[0], q[2])
            ops.S2gate(0.5) | (q[1], q[3])
            ops.Interferometer(U) | q
            ops.BSgate() | (q[2], q[3])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="must be applied separately"):
            res = prog.compile("chip0")
    def test_s2gate_repeated_modes(self, num_pairs):
        """Test exceptions raised if S2gates are repeated"""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)
        with prog.context as q:
            for i in range(num_pairs):
                ops.S2gate(SQ_AMPLITUDE) | (q[i], q[i + num_pairs])

            ops.S2gate(SQ_AMPLITUDE + 0.1) | (q[0], q[num_pairs])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match=r"Incorrect squeezing val"):
            prog.compile("Xunitary")
    def test_incorrect_s2gate_modes(self, num_pairs):
        """Test exceptions raised if S2gates do not appear on correct modes"""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)
        n_modes = 2 * num_pairs
        half_n_modes = n_modes // 2
        with prog.context as q:
            for i in range(num_pairs):
                ops.S2gate(SQ_AMPLITUDE) | (q[2 * i], q[2 * i + 1])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="S2gates do not appear on the correct modes."):
            res = prog.compile("Xunitary")
Exemplo n.º 26
0
    def test_incorrect_s2gate_modes(self):
        """Test exceptions raised if S2gates do not appear on correct modes"""
        prog = sf.Program(8)
        U = random_interferometer(4)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[1])
            ops.S2gate(SQ_AMPLITUDE) | (q[2], q[3])
            ops.S2gate(SQ_AMPLITUDE) | (q[4], q[5])
            ops.S2gate(SQ_AMPLITUDE) | (q[7], q[6])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="S2gates do not appear on the correct modes"):
            res = prog.compile("X8_01")
Exemplo n.º 27
0
    def test_unitary_too_large(self):
        """Test exception raised if the unitary is applied to more
        than just modes [0, 1, 2, 3] and [4, 5, 6, 7]."""
        prog = sf.Program(8)
        U = random_interferometer(8)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[0], q[4])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[1], q[5])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[2], q[6])
            ops.S2gate(SQ_AMPLITUDE, 0) | (q[3], q[7])
            ops.Interferometer(U) | q
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="must be applied separately"):
            res = prog.compile("X8_01")
Exemplo n.º 28
0
    def test_not_all_modes_measured(self):
        """Test exceptions raised if not all modes are measured"""
        prog = sf.Program(8)
        U = random_interferometer(4)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[4])
            ops.S2gate(SQ_AMPLITUDE) | (q[1], q[5])
            ops.S2gate(SQ_AMPLITUDE) | (q[2], q[6])
            ops.S2gate(SQ_AMPLITUDE) | (q[3], q[7])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | (q[0], q[1])

        with pytest.raises(CircuitError, match="All modes must be measured"):
            res = prog.compile("X8_01")
    def test_unitaries_do_not_match(self, num_pairs):
        """Test exception raised if the unitary applied to modes [0, 1, 2, 3] is
        different to the unitary applied to modes [4, 5, 6, 7]"""
        prog = sf.Program(2 * num_pairs)
        U = random_interferometer(num_pairs)

        with prog.context as q:
            for i in range(0, num_pairs):
                ops.S2gate(SQ_AMPLITUDE) | (q[i], q[i + num_pairs])
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs))
            ops.Interferometer(U) | tuple(q[i] for i in range(num_pairs, 2 * num_pairs))
            ops.BSgate() | (q[2], q[3])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match="The applied unitary on modes"):
            prog.compile("Xunitary")
Exemplo n.º 30
0
    def test_incorrect_s2gate_params(self):
        """Test exceptions raised if S2gates have illegal parameters"""
        prog = sf.Program(8)
        U = random_interferometer(4)

        with prog.context as q:
            ops.S2gate(SQ_AMPLITUDE) | (q[0], q[4])
            ops.S2gate(0) | (q[1], q[5])
            ops.S2gate(SQ_AMPLITUDE) | (q[2], q[6])
            ops.S2gate(SQ_AMPLITUDE+0.1) | (q[3], q[7])
            ops.Interferometer(U) | (q[0], q[1], q[2], q[3])
            ops.Interferometer(U) | (q[4], q[5], q[6], q[7])
            ops.MeasureFock() | q

        with pytest.raises(CircuitError, match=r"Incorrect squeezing value\(s\) \(r, phi\)={\(1.1, 0.0\)}"):
            res = prog.compile("X8_01")