Example #1
0
    def test_eq_symmetric_bsgate(self, compare_params):
        """Mode order doesn't matter in programs with symmetric beamsplitter."""
        prog_1 = sf.Program(2)
        prog_2 = sf.Program(2)

        with prog_1.context as q:
            ops.Fock(2) | q[0]
            ops.BSgate(np.pi / 4, np.pi / 2) | (q[0], q[1]
                                                )  # symmetric beamsplitter
            ops.MeasureFock() | q[1]

        with prog_2.context as q:
            ops.Fock(2) | q[0]
            ops.BSgate(np.pi / 4, np.pi / 2) | (q[1], q[0]
                                                )  # symmetric beamsplitter
            ops.MeasureFock() | q[1]

        # should be equivalent
        assert prog_1.equivalence(prog_2, compare_params=compare_params)
        assert prog_2.equivalence(prog_1, compare_params=compare_params)
Example #2
0
    def test_equivalence_same_prog(self, prog, compare_params):
        """Same program equivalence."""
        assert prog.equivalence(prog)

        with prog.context as q:
            ops.Fock(2) | q[0]
            ops.BSgate() | (q[0], q[1])
            ops.MeasureFock() | q[1]

        # should be equivalent
        assert prog.equivalence(prog, compare_params=compare_params)
    def test_measure_fock(self, setup_eng, cutoff, batch_size):
        """Test that Fock post-selection on Fock states
        exiting one arm of a beamsplitter results in conservation
        of photon number in the other. """
        total_photons = cutoff - 1
        for n in range(cutoff):
            eng, prog = setup_eng(2)
            with prog.context as q:
                ops.Fock(n) | q[0]
                ops.Fock(total_photons - n) | q[1]
                ops.BSgate() | q
                ops.MeasureFock(select=n // 2) | q[0]
                ops.MeasureFock() | q[1]

            eng.run(prog)  # FIXME measurements above commute, but they should not since the postselection may fail if the other one is performed first!
            photons_out = sum([i.val for i in q])

            if batch_size is not None:
                assert np.all(photons_out == np.tile(total_photons, batch_size))
            else:
                assert np.all(photons_out == total_photons)
    def test_has_post_selection(self):
        """Check that the ``has_post_selection`` property behaves as expected when it uses
        post-selection or not.
        """
        # instantiate two programs for testing
        prog_1, prog_2 = sf.Program(2), sf.Program(2)

        # program with post-selection
        with prog_1.context as q:
            ops.Fock(2) | q[0]
            ops.BSgate() | (q[0], q[1])
            ops.MeasureHomodyne(select=0, phi=np.pi) | q[0]
            ops.MeasureFock() | q[1]

        # program without post-selection
        with prog_2.context as q:
            ops.Fock(2) | q[0]
            ops.BSgate() | (q[0], q[1])
            ops.MeasureFock() | q[1]
        assert prog_1.has_post_selection
        assert prog_2.has_post_selection is False
Example #5
0
    def test_eq_operator(self):
        """Equality operator check."""
        prog_1 = sf.Program(2)
        prog_2 = sf.Program(2)

        # should be equivalent
        assert prog_1 == prog_2
        assert prog_2 == prog_1

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

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

        # should be equal
        assert prog_1 == prog_2
        assert prog_2 == prog_1
Example #6
0
    def test_equivalence(self, compare_params):
        """Identical, but different, programs are equal."""
        prog_1 = sf.Program(2)
        prog_2 = sf.Program(2)

        # should be equivalent
        assert prog_1.equivalence(prog_2)
        assert prog_2.equivalence(prog_1)

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

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

        # should be equivalent
        assert prog_1.equivalence(prog_2, compare_params=compare_params)
        assert prog_2.equivalence(prog_1, compare_params=compare_params)
    def test_fock_darkcounts_single_mode(self, dark_counts, setup_eng,
                                         monkeypatch):
        """Test Fock measurements return expected results with dark counts on one detector"""
        with monkeypatch.context() as m:
            m.setattr(np.random, "poisson",
                      lambda dc, shape: dc * np.ones(shape, dtype=int))

            eng, prog = setup_eng(2)
            n = [2, 1]

            with prog.context as q:
                ops.Fock(n[0]) | q[0]
                ops.Fock(n[1]) | q[1]
                ops.MeasureFock(dark_counts=dark_counts) | q[0]
                ops.MeasureFock() | q[1]

            eng.run(prog)

            if isinstance(dark_counts, int):
                dark_counts = [dark_counts]

            assert q[0].val == n[0] + dark_counts[0]
            assert q[1].val == n[1]
    def test_measure_fock(self, setup_eng, cutoff, batch_size):
        """Test that Fock post-selection on Fock states
        exiting one arm of a beamsplitter results in conservation
        of photon number in the other. """
        eng, q = setup_eng(2)

        for n in range(cutoff - 1):
            total_photons = cutoff - 1

            with eng:
                ops.Fock(n) | q[0]
                ops.Fock(total_photons - n) | q[1]
                ops.BSgate() | q
                ops.MeasureFock(select=cutoff // 2) | q[0]
                ops.MeasureFock() | q[1]

            eng.run()
            photons_out = sum([i.val for i in q])

            if batch_size is not None:
                total_photons = np.tile(total_photons, batch_size)

            assert np.all(photons_out == total_photons)
    def test_fock_state(self, setup_eng, cutoff, bsize, pure, tol):
        """Test fock state function matches Fock backends"""
        eng, prog = setup_eng(1)
        n = 2

        with prog.context as q:
            ops.Fock(n) | q[0]

        state = eng.run(prog).state
        ket = utils.fock_state(n, fock_dim=cutoff)
        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)
Example #10
0
    def test_linked_copy(self, prog):
        """Check that the ``_linked_copy`` method copies a program correctly."""

        with prog.context as q:
            ops.Fock(2) | q[0]
            ops.BSgate() | (q[0], q[1])
            ops.MeasureFock() | q[1]

        prog_copy = prog._linked_copy()

        # registers should be the same
        for i, regref in prog_copy.reg_refs.items():
            assert regref is prog.reg_refs[i]

        for i, cmd in enumerate(prog_copy.circuit):
            assert cmd is prog.circuit[i]

        assert prog_copy.source is prog