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)
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
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
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)
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