Пример #1
0
def qnn_layer(layer_number):
    with tf.name_scope('layer_{}'.format(layer_number)):
        BSgate(bs_variables[layer_number, 0, 0, 0], bs_variables[layer_number, 0, 0, 1]) \
        | (q[0], q[1])

        for i in range(mode_number):
            Rgate(phase_variables[layer_number, i, 0]) | q[i]

        for i in range(mode_number):
            Sgate(
                tf.clip_by_value(sq_magnitude_variables[layer_number, i],
                                 -sq_clip, sq_clip),
                sq_phase_variables[layer_number, i]) | q[i]

        BSgate(bs_variables[layer_number, 0, 1, 0], bs_variables[layer_number, 0, 1, 1]) \
        | (q[0], q[1])

        for i in range(mode_number):
            Rgate(phase_variables[layer_number, i, 1]) | q[i]

        for i in range(mode_number):
            Dgate(
                tf.clip_by_value(disp_magnitude_variables[layer_number, i],
                                 -disp_clip, disp_clip),
                disp_phase_variables[layer_number, i]) | q[i]

        for i in range(mode_number):
            Kgate(
                tf.clip_by_value(kerr_variables[layer_number, i], -kerr_clip,
                                 kerr_clip)) | q[i]
def layer(l):
    with tf.name_scope('layer_{}'.format(l)):
        BSgate(theta1[l], phi1[l]) | (q[0], q[1])
        Rgate(r1[l]) | q[0]
        Sgate(tf.clip_by_value(sqr1[l], -sq_clip, sq_clip), sqphi1[l]) | q[0]
        Sgate(tf.clip_by_value(sqr2[l], -sq_clip, sq_clip), sqphi2[l]) | q[1]
        BSgate(theta2[l], phi2[l]) | (q[0], q[1])
        Rgate(r2[l]) | q[0]
        Dgate(tf.clip_by_value(dr1[l], -disp_clip, disp_clip), dphi1[l]) | q[0]
        Dgate(tf.clip_by_value(dr2[l], -disp_clip, disp_clip), dphi2[l]) | q[1]
        Kgate(tf.clip_by_value(kappa1[l], -kerr_clip, kerr_clip)) | q[0]
        Kgate(tf.clip_by_value(kappa2[l], -kerr_clip, kerr_clip)) | q[1]
def test_cov_is_pure():
    """Tests space unrolling when going into the Gaussian backend"""
    delays = [1, 6, 36]
    modes = 216
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])
    net = modes + sum(delays)
    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])
    vac_modes = sum(delays)

    with prog.context(*angles) as (p, q):
        Sgate(0.8) | q[n[0]]
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    prog.space_unroll()

    eng = sf.Engine(backend="gaussian")
    results = eng.run(prog)
    cov = results.state.cov()
    mu = np.zeros(len(cov))
    mu_vac, cov_vac = reduced_state(mu, cov, list(range(vac_modes)))
    mu_comp, cov_comp = reduced_state(mu, cov, list(range(vac_modes, net)))
    assert np.allclose(cov_vac, 0.5 * (sf.hbar) * np.identity(2 * vac_modes))
    assert is_pure_cov(cov_comp, hbar=sf.hbar)
def test_is_permutation_when_angle_pi_on_two(delays, modes):
    """Checks that if all the beamsplitters are cross then the absolute value output matrix is a permutation matrix"""
    delays = list(delays)
    net = modes + sum(delays)
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])
    angles[0] = np.pi / 2 * np.random.randint(2, size=net)
    angles[1] = np.pi / 2 * np.random.randint(2, size=net)
    angles[2] = np.pi / 2 * np.random.randint(2, size=net)
    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])
    vac_modes = sum(delays)

    with prog.context(*angles) as (p, q):
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    prog.space_unroll()

    compiled = prog.compile(compiler="passive")
    passive_elem = compiled.circuit[0]
    U = passive_elem.op.p[0]
    assert np.allclose(U @ U.T.conj(), np.identity(len(U)))
    assert np.allclose(list(map(max, np.abs(U))), 1.0)
def test_no_entanglement_between_padding_and_computational_modes(
        delays, modes):
    """Test that the U matrix is the identity if there is no beamsplitter mixing and no rotations"""
    delays = list(delays)
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])
    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])
    vac_modes = sum(delays)

    with prog.context(*angles) as (p, q):
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    prog.space_unroll()

    compiled = prog.compile(compiler="passive")
    passive_elem = compiled.circuit[0]
    U = passive_elem.op.p[0]
    # Check that it is indeed the identity
    U_AA = U[:vac_modes, :vac_modes]
    U_AB = U[vac_modes:, :vac_modes]
    U_BA = U[:vac_modes, vac_modes:]
    U_BB = U[vac_modes:, vac_modes:]

    assert np.allclose(U_AA, np.identity(vac_modes))
    assert np.allclose(U_AB, 0)
    assert np.allclose(U_BA, 0)
    assert np.allclose(U_BB @ U_BB.T.conj(), np.identity(len(U_BB)))
Пример #6
0
    def decompose(self, reg):
        # make BS gate
        theta = self.layer['BS'][0]
        phi = self.layer['BS'][1]
        BS = BSgate(theta, phi)

        # make Kerr gate
        K = Kgate(self.layer['K'][0])

        # make rotation gate
        R = Rgate(self.layer['R'][0])

        cmds = []

        for i in range(self.num_layers):  #pylint: disable=unused-variable
            for q0, q1 in self.layer['BS'][2]:
                cmds.append(Command(BS, (reg[q0], reg[q1])))

            for mode in self.layer['K'][1]:
                cmds.append(Command(K, reg[mode]))

            for mode in self.layer['R'][1]:
                cmds.append(Command(R, reg[mode]))

        return cmds
Пример #7
0
def input_qnn_layer():
    with tf.name_scope('inputlayer'):
        Sgate(tf.clip_by_value(output_layer[:, 0], -sq_clip, sq_clip), output_layer[:, 1]) | q[0]
        Sgate(tf.clip_by_value(output_layer[:, 2], -sq_clip, sq_clip), output_layer[:, 3]) | q[1]

        BSgate(output_layer[:, 4], output_layer[:, 5]) | (q[0], q[1])

        Rgate(output_layer[:, 6]) | q[0]
        Rgate(output_layer[:, 7]) | q[1]

        Dgate(tf.clip_by_value(output_layer[:, 8], -disp_clip, disp_clip), output_layer[:, 9]) \
        | q[0]
        Dgate(tf.clip_by_value(output_layer[:, 10], -disp_clip, disp_clip), output_layer[:, 11]) \
        | q[0]

        Kgate(tf.clip_by_value(output_layer[:, 12], -kerr_clip, kerr_clip)) | q[0]
        Kgate(tf.clip_by_value(output_layer[:, 13], -kerr_clip, kerr_clip)) | q[0]
Пример #8
0
    def test_outside_context(self):
        """test setting hbar outside of engine context"""
        H, t = rotation(self.phi)
        Ugate = GaussianPropagation(H, t, hbar=self.hbar)
        resD, resV = self.ref_circuit(Ugate)
        expD, expV = self.ref_circuit(Rgate(self.phi))

        # test the covariance matrix
        self.assertTrue(np.allclose(resV, expV))
        # test the vector of means
        self.assertTrue(np.allclose(resD, expD))
Пример #9
0
    def test_single_mode_gate(self, hbar):
        """Test Rgate gives correct means and cov in global mode"""
        H, t = rotation(self.phi, mode=1, hbar=hbar)
        resD, resV = self.H_circuit(H, t)

        gate = Rgate(self.phi)
        expD, expV = self.ref_circuit(gate, 1)

        # test the covariance matrix
        assert np.allclose(resV, expV)
        # test the vector of means
        assert np.allclose(resD, expD)
Пример #10
0
    def test_single_mode_gate(self):
        """Test Rgate gives correct means and cov in global mode"""
        self.eng.reset()
        q = self.eng.register

        H, t = rotation(self.phi, mode=1, hbar=self.hbar)
        resD, resV = self.H_circuit(H, t)

        gate = Rgate(self.phi)
        expD, expV = self.ref_circuit(gate, q[1])

        # test the covariance matrix
        self.assertTrue(np.allclose(resV, expV))
        # test the vector of means
        self.assertTrue(np.allclose(resD, expD))
Пример #11
0
    def decompose(self, reg):
        # make BS gate
        theta = self.layer['BS'][0]
        phi = self.layer['BS'][1]
        BS = BSgate(theta, phi)

        # make cross-Kerr gate
        CK = None
        param = self.layer.get('CK', [0])[0]
        if param != 0:
            CK = CKgate(param)

        # make Kerr gate
        K = None
        param = self.layer.get('K', [0])[0]
        if param != 0:
            K = Kgate(param)

        # make rotation gate
        R = None
        param = self.layer.get('R', [0])[0]
        if param != 0:
            R = Rgate(param)

        cmds = []

        for i in range(self.num_layers):  #pylint: disable=unused-variable
            for q0, q1 in self.layer['BS'][2]:
                cmds.append(Command(BS, (reg[q0], reg[q1])))

            if CK is not None:
                for q0, q1 in self.layer['CK'][1]:
                    cmds.append(Command(CK, (reg[q0], reg[q1])))

            if K is not None:
                for mode in self.layer['K'][1]:
                    cmds.append(Command(K, reg[mode]))

            if R is not None:
                for mode in self.layer['R'][1]:
                    cmds.append(Command(R, reg[mode]))

        return cmds
Пример #12
0
def test_lossless_no_mixing_no_rotation_U(delays, modes):
    """Test that the U matrix is the identity if there is no beamsplitter mixing and no rotations"""
    delays = list(delays)
    angles = np.zeros([2 * len(delays), modes + sum(delays)])
    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])

    with prog.context(*angles) as (p, q):
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    prog.space_unroll()

    compiled = prog.compile(compiler="passive")
    passive_elem = compiled.circuit[0]
    U = passive_elem.op.p[0]
    # Check that it is indeed the identity
    assert np.allclose(U, np.identity(len(U)))
Пример #13
0
def test_space_unrolling():
    """Tests that space-unrolling works and that it can be done twice"""
    delays = [1, 6, 36]
    modes = 216
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])

    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])

    with prog.context(*angles) as (p, q):
        Sgate(0.8) | q[n[0]]
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    assert prog.is_unrolled == False

    prog.space_unroll()

    assert prog.timebins == 259
    vac_modes = prog.concurr_modes - 1
    assert prog.num_subsystems == prog.timebins + vac_modes

    # check that the number of gates are correct.
    assert [isinstance(cmd.op, Sgate)
            for cmd in prog.circuit].count(True) == prog.timebins
    assert [isinstance(cmd.op, Rgate)
            for cmd in prog.circuit].count(True) == 259 * len(delays)
    assert [isinstance(cmd.op, BSgate)
            for cmd in prog.circuit].count(True) == 259 * len(delays)

    prog.space_unroll()

    # space-unroll the program twice to check that it works
    assert prog.is_unrolled == True
Пример #14
0
def test_rolling_space_unrolled():
    """Tests that rolling a space-unrolled circuit works"""
    delays = [1, 6, 36]
    modes = 216
    angles = np.concatenate([
        generate_valid_bs_sequence(delays, modes),
        generate_valid_r_sequence(delays, modes)
    ])

    d = len(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram([N])

    with prog.context(*angles) as (p, q):
        Sgate(0.8) | q[n[0]]
        for i in range(d):
            Rgate(p[i + d]) | q[n[i]]
            BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]])

    rolled_circuit = prog.circuit.copy()
    num_subsystems_pre_roll = prog.num_subsystems
    init_num_subsystems_pre_roll = prog.init_num_subsystems

    assert prog.is_unrolled == False

    # space-unroll the program
    prog.space_unroll()

    assert prog.is_unrolled == True

    # roll the program back up
    prog.roll()

    assert prog.is_unrolled == False
    assert prog.num_subsystems == num_subsystems_pre_roll
    assert prog.init_num_subsystems == init_num_subsystems_pre_roll

    assert len(prog.circuit) == len(rolled_circuit)
    assert prog.circuit == rolled_circuit
Пример #15
0
# Copyright 2018 Xanadu Quantum Technologies Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
r"""
Operations
==========

This file contains the Strawberry Fields quantum operations
that decompose the BosonOperator and QuadOperator from OpenFermion.

These operations are used directly in BlackBird code, complementing
existing operations.

For example:

.. code-block:: python

    prog = sf.Program(3)
    eng = sf.Engine("gaussian")

    H1 = BosonOperator('0^ 0')
    # connect to the remote engine and obtain a ``device`` object
    eng = sf.RemoteEngine("borealis")
    device = eng.device

    # create a list of list of gate arguments for a GBS instance
    gate_args_list = borealis_gbs(device, modes=288, squeezing="high")

    # create a Strawberry Fields program
    delays = [1, 6, 36]
    vac_modes = sum(delays)
    n, N = get_mode_indices(delays)
    prog = sf.TDMProgram(N)
    with prog.context(*gate_args_list) as (p, q):
        Sgate(p[0]) | q[n[0]]
        for i in range(len(delays)):
            Rgate(p[2 * i + 1]) | q[n[i]]
            BSgate(p[2 * i + 2], np.pi / 2) | (q[n[i + 1]], q[n[i]])
        MeasureFock() | q[0]

    # define number of shots and submit job to hardware
    shots = 250_000
    results = eng.run(prog, shots=shots, crop=True)

    # the GBS samples
    samples = results.samples

    # plot the estimated simulation times of the experimental samples
    plot_simulation_time(samples)

    # obtain first and second moment of the photon-number distribution: mean photon
    # number and photon-number covariance
Пример #17
0
    def layer(i, size):
        Rgate(rtheta_1[i, 0]) | (q[0])
        BSgate(phi_1[i, 0], 0) | (q[0], q[1])
        Rgate(rtheta_1[i, 2]) | (q[1])

        for j in range(size):
            Sgate(r[i, j]) | q[j]

        Rgate(rtheta_2[i, 0]) | (q[0])
        BSgate(phi_2[i, 0], 0) | (q[0], q[1])
        Rgate(rtheta_2[i, 2]) | (q[2])
        BSgate(phi_2[i, 2], theta_2[i, 3]) | (q[2], q[3])
        Rgate(rtheta_2[i, 1]) | (q[1])
        BSgate(phi_2[i, 1], 0) | (q[1], q[2])
        Rgate(rtheta_2[i, 0]) | (q[0])
        BSgate(phi_2[i, 0], 0) | (q[0], q[1])
        Rgate(rtheta_2[i, 0]) | (q[0])
        Rgate(rtheta_2[i, 1]) | (q[1])
        Rgate(rtheta_2[i, 2]) | (q[2])
        Rgate(rtheta_2[i, 3]) | (q[3])
        BSgate(phi_2[i, 2], 0) | (q[2], q[3])
        Rgate(rtheta_2[i, 2]) | (q[2])
        BSgate(phi_2[i, 1], 0) | (q[1], q[2])
        Rgate(rtheta_2[i, 1]) | (q[1])

        for j in range(size):
            Kgate(kappa[i, j]) | q[j]