def build_circuit(self):
        # params_counter = 0
        sgates = []
        dgates = []
        kgates = []
        for gate_structure in self.gates_structure:
            if gate_structure[0] is Sgate:
                sgates.append(
                    ParametrizedGate(gate_structure[0], gate_structure[1], [
                        make_param(**gate_structure[2]),
                        make_param(**gate_structure[3])
                    ]))
            if gate_structure[0] is Dgate:
                dgates.append(
                    ParametrizedGate(gate_structure[0], gate_structure[1], [
                        make_param(**gate_structure[2]),
                        make_param(**gate_structure[3])
                    ]))
            if gate_structure[0] is Kgate:
                kgates.append(
                    ParametrizedGate(gate_structure[0], gate_structure[1],
                                     [make_param(**gate_structure[2])]))

        eng, q = sf.Engine(self.n_qumodes)

        rl, U = takagi(self.adj_matrix)
        initial_squeezings = np.arctanh(rl)

        with eng:
            for i, squeeze_value in enumerate(initial_squeezings):
                Sgate(squeeze_value) | i

            Interferometer(U) | q

            for gate in sgates:
                gate.gate(gate.params[0], gate.params[1]) | gate.qumodes

            Interferometer(self.interferometer_matrix) | q

            for gate in dgates:
                gate.gate(gate.params[0], gate.params[1]) | gate.qumodes

            Interferometer(self.interferometer_matrix) | q

            for gate in kgates:
                gate.gate(gate.params[0]) | gate.qumodes

        circuit = {}
        circuit['eng'] = eng
        circuit['q'] = q

        return circuit
Esempio n. 2
0
def circuit(X):
    params = [
        make_param(name='phi', constant=2.),
        make_param(name="theta", constant=1.),
        make_param(name="theta2", constant=.1),
        make_param(name="theta3", constant=.1),
        make_param(name="theta4", constant=.1),
        make_param(name="theta5", constant=.1),
        make_param(name="theta6", constant=.1),
        make_param(name="theta7", constant=.1),
        make_param(name="theta8", constant=.1),
        make_param(name="theta9", constant=.1),
    ]

    eng, q = sf.Engine(2)

    with eng:
        Dgate(X[:, 0], 0.) | q[0]
        Dgate(X[:, 1], 0.) | q[1]
        BSgate(phi=params[0]) | (q[0], q[1])
        BSgate() | (q[0], q[1])
        Vgate(params[1]) | q[0]
        Vgate(params[2]) | q[1]

    num_inputs = X.get_shape().as_list()[0]
    state = eng.run('tf', cutoff_dim=10, eval=False, batch_size=num_inputs)

    p0 = state.fock_prob([0, 2])
    p1 = state.fock_prob([2, 0])
    normalization = p0 + p1 + 1e-10
    output1 = p1 / normalization

    with eng:
        X1 = output1
        Dgate(X1, 0.) | q[0]
        Dgate(0., X1) | q[1]
        BSgate(phi=params[1]) | (q[0], q[1])
        BSgate() | (q[0], q[1])
        Vgate(params[5]) | q[0]
        Vgate(params[6]) | q[1]

    num_inputs1 = X1.get_shape().as_list()[0]
    state2 = eng.run('tf', cutoff_dim=10, eval=False, batch_size=num_inputs1)

    p00 = state2.fock_prob([0, 2])
    p01 = state2.fock_prob([2, 0])
    normalization1 = p00 + p01 + 1e-10
    circuit_output = p01 / normalization1
    return circuit_output
Esempio n. 3
0
def circuit(X):
    # Create a parameter with an initial value of 2.
    params = [make_param(name='phi', constant=2.)]

    eng, q = sf.Engine(2)

    with eng:
        # Note that we are feeding 1-d tensors into gates, not scalars!
        Dgate(X[:, 0], 0.) | q[0]
        Dgate(X[:, 1], 0.) | q[1]
        BSgate(phi=params[0]) | (q[0], q[1])
        BSgate() | (q[0], q[1])

    # We have to tell the engine how big the batches (first dim of X) are
    # which we feed into gates
    num_inputs = X.get_shape().as_list()[0]
    state = eng.run('tf', cutoff_dim=10, eval=False, batch_size=num_inputs)

    # Define the output as the probability of measuring |0,2> as opposed to |2,0>
    p0 = state.fock_prob([0, 2])
    p1 = state.fock_prob([2, 0])
    normalization = p0 + p1 + 1e-10
    circuit_output = p1 / normalization

    return circuit_output
Esempio n. 4
0
def circuit():

    phi = make_param(name='phi', stdev=0.2, regularize=False)
    theta = make_param(name='theta', stdev=0.2, regularize=False)
    a = make_param(name='a', stdev=0.2, regularize=True, monitor=True)
    rtheta = make_param(name='rtheta',
                        stdev=0.2,
                        regularize=False,
                        monitor=True)
    r = make_param(name='r', stdev=0.2, regularize=True, monitor=True)
    kappa = make_param(name='kappa', stdev=0.2, regularize=True, monitor=True)

    eng, q = sf.Engine(2)

    with eng:
        BSgate(phi, theta) | (q[0], q[1])
        Dgate(a) | q[0]
        Rgate(rtheta) | q[0]
        Sgate(r) | q[0]
        Kgate(kappa) | q[0]

    state = eng.run('tf', cutoff_dim=7, eval=False)
    circuit_output = state.all_fock_probs()

    return circuit_output
Esempio n. 5
0
def circuit(X):
    # Create a parameter with an initial value of 2.
    params = [make_param(name='phi', constant=2.), make_param(name="theta", constant=1.), make_param(name="theta2", constant=.1), make_param(name="theta3", constant=.1), 
              make_param(name="theta4", constant=.1), make_param(name="theta5", constant=.1),
              make_param(name="theta6", constant=.1), make_param(name="theta7", constant=.1),
              make_param(name="theta8", constant=.1), make_param(name="theta9", constant=.1),]

    eng, q = sf.Engine(2)

    with eng:
        # Note that we are feeding 1-d tensors into gates, not scalars!
        Dgate(X[:, 0], 0.) | q[0]
        Dgate(X[:, 1], 0.) | q[1]
        BSgate(phi=params[0]) | (q[0], q[1])
        BSgate() | (q[0], q[1])
        Vgate(params[1]) | q[0]
        Vgate(params[2]) | q[1]
Esempio n. 6
0
def circuit():

    # Create a parameter with an initial value of 0.1
    params = [make_param(name='alpha', constant=0.1)]

    eng, q = sf.Engine(1)

    with eng:
        Dgate(params[0]) | q[0]

    state = eng.run('tf', cutoff_dim=7, eval=False)

    # As the output we take the probability of measuring one photon in the mode
    prob = state.fock_prob([1])
    circuit_output = tf.identity(prob, name="prob")
    return circuit_output
Esempio n. 7
0
def circuit(X):
    phi = make_param('phi', constant=2.)

    eng, q = sf.Engine(2)

    with eng:
        Dgate(X[:, 0], 0.) | q[0]
        Dgate(X[:, 1], 0.) | q[1]
        BSgate(phi=phi) | (q[0], q[1])
        BSgate() | (q[0], q[1])

    num_inputs = X.get_shape().as_list()[0]
    state = eng.run('tf', cutoff_dim=10, eval=False, batch_size=num_inputs)

    p0 = state.fock_prob([0, 2])
    p1 = state.fock_prob([2, 0])
    normalisation = p0 + p1 + 1e-10
    circuit_output = p1 / normalisation

    return circuit_output
Esempio n. 8
0
def circuit():

    # Create parameters for 'depth' number of layers.
    # Mark some of them to be regularized and some to be monitored.
    phi = make_param(name='phi', stdev=0.2, shape=[depth], regularize=False)
    theta = make_param(name='theta',
                       stdev=0.2,
                       shape=[depth],
                       regularize=False)
    a = make_param(name='a',
                   stdev=0.2,
                   shape=[depth],
                   regularize=True,
                   monitor=True)
    rtheta = make_param(name='rtheta',
                        stdev=0.2,
                        shape=[depth],
                        regularize=False,
                        monitor=True)
    r = make_param(name='r',
                   stdev=0.2,
                   shape=[depth],
                   regularize=True,
                   monitor=True)
    kappa = make_param(name='kappa',
                       stdev=0.2,
                       shape=[depth],
                       regularize=True,
                       monitor=True)

    # Define a single layer of gates
    def layer(l):
        BSgate(phi[l], theta[l]) | (q[0], q[1])
        Dgate(a[l]) | q[0]
        Rgate(rtheta[l]) | q[0]
        Sgate(r[l]) | q[0]
        Kgate(kappa[l]) | q[0]

    eng, q = sf.Engine(2)

    with eng:
        # Make depth layers
        for d in range(depth):
            layer(d)

    state = eng.run('tf', cutoff_dim=7, eval=False)
    circuit_output = state.all_fock_probs()

    return circuit_output
Esempio n. 9
0
def circuit():

    # This time we want to keep the parameter small via regularization and visualize its evolution in tensorboard
    params = [
        make_param(name='alpha', constant=0.1, regularize=True, monitor=True)
    ]
    eng, q = sf.Engine(1)

    with eng:
        Dgate(params[0]) | q[0]

    state = eng.run('tf', cutoff_dim=7, eval=False)

    circuit_output = state.fock_prob([1])

    # The identity() function allows us to give this tensor a name
    # which we can refer to below
    circuit_output = tf.identity(circuit_output, name="prob")
    trace = tf.identity(state.trace(), name='trace')

    return circuit_output
Esempio n. 10
0
def circuit(X):
    num_qubits = X.get_shape().as_list()[1]

    phi_1 = make_param(name='phi_1',
                       stdev=np.sqrt(2) / num_qubits,
                       shape=[depth, num_qubits],
                       regularize=False)
    theta_1 = make_param(name='theta_1',
                         stdev=np.sqrt(2) / num_qubits,
                         shape=[depth, num_qubits],
                         regularize=False)
    a = make_param(name='a',
                   stdev=np.sqrt(2) / num_qubits,
                   shape=[depth, num_qubits],
                   regularize=False,
                   monitor=True)
    rtheta_1 = make_param(name='rtheta_1',
                          stdev=np.sqrt(2) / num_qubits,
                          shape=[depth, num_qubits],
                          regularize=False,
                          monitor=True)
    r = make_param(name='r',
                   stdev=np.sqrt(2) / num_qubits,
                   shape=[depth, num_qubits],
                   regularize=False,
                   monitor=True)
    kappa = make_param(name='kappa',
                       stdev=np.sqrt(2) / num_qubits,
                       shape=[depth, num_qubits],
                       regularize=False,
                       monitor=True)
    phi_2 = make_param(name='phi_2',
                       stdev=np.sqrt(2) / num_qubits,
                       shape=[depth, num_qubits],
                       regularize=False)
    theta_2 = make_param(name='theta_2',
                         stdev=np.sqrt(2) / num_qubits,
                         shape=[depth, num_qubits],
                         regularize=False)
    rtheta_2 = make_param(name='rtheta_2',
                          stdev=np.sqrt(2) / num_qubits,
                          shape=[depth, num_qubits],
                          regularize=False,
                          monitor=True)

    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]

    eng, q = sf.Engine(num_qubits)

    with eng:
        for i in range(num_qubits):
            Dgate(X[:, i], 0.) | q[i]
        for d in range(depth):
            layer(d, num_qubits)

    num_inputs = X.get_shape().as_list()[0]
    state = eng.run('tf', cutoff_dim=10, eval=False, batch_size=num_inputs)
    circuit_output, var0 = state.quad_expectation(0)

    return circuit_output
    def build_circuit(self, adj_matrix):
        params_counter = 0
        number_of_layers = 2
        all_sgates = [[]] * number_of_layers
        all_dgates = [[]] * number_of_layers
        all_kgates = [[]] * number_of_layers
        all_vgates = [[]] * number_of_layers

        for gate_structure in self.gates_structure:
            current_layer = int(gate_structure[2]['name'].split('_')[-1][0])
            if gate_structure[0] is Sgate:
                current_gate = ParametrizedGate(
                    gate_structure[0], gate_structure[1], [
                        make_param(**gate_structure[2]),
                        make_param(**gate_structure[3])
                    ])
                all_sgates[current_layer].append(current_gate)
            if gate_structure[0] is Dgate:
                current_gate = ParametrizedGate(
                    gate_structure[0], gate_structure[1], [
                        make_param(**gate_structure[2]),
                        make_param(**gate_structure[3])
                    ])
                all_dgates[current_layer].append(current_gate)
            if gate_structure[0] is Kgate:
                current_gate = ParametrizedGate(
                    gate_structure[0], gate_structure[1],
                    [make_param(**gate_structure[2])])
                all_kgates[current_layer].append(current_gate)
            if gate_structure[0] is Vgate:
                current_gate = ParametrizedGate(
                    gate_structure[0], gate_structure[1],
                    [make_param(**gate_structure[2])])
                all_vgates[current_layer].append(current_gate)

        eng, q = sf.Engine(self.n_qumodes)
        rl, U = takagi(adj_matrix)
        initial_squeezings = np.arctanh(rl)

        with eng:
            for i, squeeze_value in enumerate(initial_squeezings):
                Sgate(squeeze_value) | i

            Interferometer(U) | q
            for layer in range(number_of_layers):
                sgates = all_sgates[layer]
                dgates = all_dgates[layer]
                kgates = all_kgates[layer]
                vgates = all_vgates[layer]

                if len(sgates) != 0:
                    Interferometer(self.interferometer_matrix) | q
                    for gate in sgates:
                        gate.gate(gate.params[0],
                                  gate.params[1]) | gate.qumodes

                if len(dgates) != 0:
                    Interferometer(self.interferometer_matrix) | q
                    for gate in dgates:
                        gate.gate(gate.params[0],
                                  gate.params[1]) | gate.qumodes

                for gate in kgates:
                    gate.gate(gate.params[0]) | gate.qumodes

                for gate in vgates:
                    gate.gate(gate.params[0]) | gate.qumodes

        circuit = {}
        circuit['eng'] = eng
        circuit['q'] = q

        return circuit