コード例 #1
0
    def test_merge(self, hbar, tol):
        """Test that two symplectics merge: S = S2 @ S1"""
        n = 3
        S1 = random_symplectic(n)
        S2 = random_symplectic(n)

        G1 = ops.GaussianTransform(S1)
        G1inv = ops.GaussianTransform(np.linalg.inv(S1))
        G2 = ops.GaussianTransform(S2)

        # a symplectic merged with its inverse is identity
        assert G1.merge(G1inv) is None

        # two merged symplectics are the same as their product
        assert np.allclose(G1.merge(G2).p[0].x, S2 @ S1, atol=tol, rtol=0)
コード例 #2
0
    def test_decomposition_passive(self, tol):
        """Test that a passive symplectic is correctly decomposed into an interferometer"""
        n = 3
        S = random_symplectic(n, passive=True)
        X1 = S[:n, :n]
        P1 = S[n:, :n]
        U1 = X1 + 1j * P1

        prog = sf.Program(n)
        G = ops.GaussianTransform(S)
        cmds = G.decompose(prog.register)

        S = np.identity(2 * n)

        # command queue should have 1 interferometer
        assert len(cmds) == 1

        # calculating the resulting decomposed symplectic
        for cmd in cmds:
            # all operations should be Interferometers
            assert isinstance(cmd.op, ops.Interferometer)

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

            if isinstance(cmd.op, ops.Interferometer):
                U1 = cmd.op.p[0]
                S_U = np.vstack(
                    [np.hstack([U1.real, -U1.imag]), np.hstack([U1.imag, U1.real])]
                )
                S = S_U @ S

        # the resulting covariance state
        cov = S @ S.T
        assert np.allclose(cov, S @ S.T, atol=tol, rtol=0)
コード例 #3
0
 def test_random_symplectic_active_not_orthogonal(self, modes, hbar, tol,
                                                  block_diag):
     """Test that an active random symplectic matrix is not orthogonal"""
     S = utils.random_symplectic(modes,
                                 passive=False,
                                 block_diag=block_diag)
     assert not np.allclose(
         S @ S.T, np.identity(2 * modes), atol=tol, rtol=0)
コード例 #4
0
    def test_active(self, tol):
        """Test that an active decomposition is correctly flagged as requiring
        two interferometers and squeezing"""
        S1 = random_symplectic(3, passive=False)
        G = ops.GaussianTransform(S1)

        assert G.active
        assert hasattr(G, "U1")
        assert hasattr(G, "Sq")
        assert hasattr(G, "U2")
コード例 #5
0
    def test_random_symplectic_symplectic(self, modes, hbar, passive, tol, block_diag):
        """Test that a random symplectic matrix is symplectic"""
        S = utils.random_symplectic(modes, passive=passive, block_diag=block_diag)

        idm = np.identity(modes)
        omega = np.concatenate(
            (np.concatenate((0 * idm, idm), axis=1), np.concatenate((-idm, 0 * idm), axis=1)),
            axis=0,
        )

        assert np.allclose(S @ omega @ S.T, omega, atol=tol, rtol=0)
コード例 #6
0
    def test_decomposition_active(self, hbar, tol):
        """Test that an active symplectic is correctly decomposed into
        two interferometers and squeezing"""
        n = 3
        S = random_symplectic(n, passive=False)

        O1, Sq, O2 = dec.bloch_messiah(S)
        X1 = O1[:n, :n]
        P1 = O1[n:, :n]
        X2 = O2[:n, :n]
        P2 = O2[n:, :n]
        U1 = X1 + 1j * P1
        U2 = X2 + 1j * P2

        prog = sf.Program(n, hbar=hbar)

        with eng:
            G = ops.GaussianTransform(S)
            cmds = G.decompose(q)

        assert np.all(U1 == G.U1)
        assert np.all(U2 == G.U2)
        assert np.all(np.diag(Sq)[:n] == G.Sq)

        S = np.identity(2 * n)

        # command queue should have 2 interferometers, 3 squeezers
        assert len(cmds) == 5

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

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

            if isinstance(cmd.op, ops.Sgate):
                S = _squeezing(cmd.op.p[0].x, cmd.op.p[1].x, modes, n) @ S

            if isinstance(cmd.op, ops.Interferometer):
                U1 = cmd.op.p[0].x
                S_U = np.vstack([
                    np.hstack([U1.real, -U1.imag]),
                    np.hstack([U1.imag, U1.real])
                ])
                S = S_U @ S

        # the resulting covariance state
        cov = S @ S.T

        assert np.allclose(cov, S @ S.T * hbar / 2, atol=tol, rtol=0)
コード例 #7
0
def test_symplectic_composition(depth, width):
    """Tests that symplectic operations are composed correctly"""
    eng = sf.LocalEngine(backend="gaussian")
    eng1 = sf.LocalEngine(backend="gaussian")
    circuit = sf.Program(width)
    Snet = np.identity(2 * width)
    with circuit.context as q:
        for _ in range(depth):
            S = random_symplectic(width, scale=0.2)
            Snet = S @ Snet
            ops.GaussianTransform(S) | q
    compiled_circuit = circuit.compile(compiler="gaussian_unitary")
    assert np.allclose(compiled_circuit.circuit[0].op.p[0], Snet)
コード例 #8
0
    def test_active_on_vacuum(self, hbar, tol):
        """Test that an active symplectic applied to a vacuum is
        correctly decomposed into just squeezing and one interferometer"""
        n = 3
        S = random_symplectic(n, passive=False)

        O1, Sq, O2 = dec.bloch_messiah(S)
        X1 = O1[:n, :n]
        P1 = O1[n:, :n]
        X2 = O2[:n, :n]
        P2 = O2[n:, :n]

        U1 = X1 + 1j * P1
        U2 = X2 + 1j * P2

        prog = sf.Program(n)
        G = ops.GaussianTransform(S, vacuum=True)
        cmds = G.decompose(prog.register)

        S = np.identity(2 * n)

        # command queue should have 3 Sgates, 1 interferometer
        assert len(cmds) == 4

        # calculating the resulting decomposed symplectic
        for cmd in cmds:
            # all operations should be Interferometers or Sgates
            assert isinstance(cmd.op, (ops.Interferometer, ops.Sgate))

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

            if isinstance(cmd.op, ops.Sgate):
                S = _squeezing(cmd.op.p[0].x, cmd.op.p[1].x, modes, n) @ S

            if isinstance(cmd.op, ops.Interferometer):
                U1 = cmd.op.p[0].x
                S_U = np.vstack([
                    np.hstack([U1.real, -U1.imag]),
                    np.hstack([U1.imag, U1.real])
                ])
                S = S_U @ S

        # the resulting covariance state
        cov = S @ S.T

        assert np.allclose(cov, S @ S.T, atol=tol, rtol=0)
コード例 #9
0
    def test_setting_hbar(self, hbar):
        """Test that an exception is raised if hbar not provided"""
        prog = sf.Program(3, hbar=hbar)
        S1 = random_symplectic(3, passive=False)

        with pytest.raises(ValueError, match="specify the hbar keyword argument"):
            ops.GaussianTransform(S1)

        # hbar can be passed as a keyword arg
        G = ops.GaussianTransform(S1, hbar=hbar)
        assert G.hbar == hbar

        # or determined via the engine context
        with eng:
            G = ops.GaussianTransform(S1)

        assert G.hbar == hbar
コード例 #10
0
 def test_random_symplectic_square(self, modes, hbar, passive, block_diag):
     """Test that a random symplectic matrix on is the right shape"""
     S = utils.random_symplectic(modes,
                                 passive=passive,
                                 block_diag=block_diag)
     assert np.all(S.shape == np.array([2 * modes, 2 * modes]))
コード例 #11
0
    random_covariance,
    squeezed_state,
)
from strawberryfields import ops
from strawberryfields.backends.shared_ops import (
    haar_measure,
    changebasis,
    rotation_matrix as rot,
)

# make the test file deterministic
np.random.seed(42)

u1 = random_interferometer(3)
u2 = random_interferometer(3)
S = random_symplectic(3)


@pytest.fixture
def V_mixed(hbar):
    return random_covariance(3, hbar=hbar, pure=False)


@pytest.fixture
def V_pure(hbar):
    return random_covariance(3, hbar=hbar, pure=True)


@pytest.fixture
def r_means(hbar):
    return np.random.randn(6) * np.sqrt(hbar / 2)
コード例 #12
0
 def test_random_symplectic_passive_orthogonal(self, modes, hbar, tol):
     """Test that a passive random symplectic matrix is orthogonal"""
     S = utils.random_symplectic(modes, passive=True)
     assert np.allclose(S @ S.T, np.identity(2 * modes), atol=tol, rtol=0)