예제 #1
0
 def prog(sample):
     p = pq.Program(n_qubits)
     n_features = len(sample)
     for j in range(n_qubits):
         p.inst(RY(np.arcsin(sample[j % n_features])), j)
         p.inst(RZ(np.arccos(sample[j % n_features]**2)), j)
     return p
def output_prog(theta):
    p = pq.Program(n_qubits)
    theta = theta.reshape(3, n_qubits, depth)
    for i in range(depth):
        p += ising_prog
        for j in range(n_qubits):
            rj = n_qubits - j - 1
            p.inst(RX(theta[0, rj, i]), j)
            p.inst(RZ(theta[1, rj, i]), j)
            p.inst(RX(theta[2, rj, i]), j)
    return p
예제 #3
0
def ising_prog_gen(trotter_steps, T, n_qubits):
    """
    Generates Quil program evolving system according to fully connected
    transverse Ising hamiltionian. The exponential of a sum of non-commuting 
    Pauli operators is generated by Trotter Suzuki approximation of first order 
    (Lie product formula). 
    Important: The generation of matrix exponential could be done only on  
    quantum computer simulator. 
    
    :param trotter_steps: (int) trotter steps. 
    :param T: (int) evolution time. 
    :param n_qubits: (int) number of qubits in a circuit.  
    
    :return (Program) Quil program evolving system according to fully connected
        transverse Ising hamiltionian.
    """
    # Initilize coefficients
    h_coeff = np.random.uniform(-1.0, 1.0, size=n_qubits)
    J_coeff = dict()
    for val in itertools.combinations(range(n_qubits), 2):
        J_coeff[val] = np.random.uniform(-1.0, 1.0)

    # Unitary
    for steps in range(trotter_steps):

        non_inter = [
            linalg.expm(
                -(1j) * T / trotter_steps *
                multi_kron(*[h * X if i == j else I for i in range(n_qubits)]))
            for j, h in enumerate(h_coeff)
        ]
        inter = [
            linalg.expm(-(1j) * T / trotter_steps * multi_kron(*[
                J * Z if i == k[0] else Z if i == k[1] else I
                for i in range(n_qubits)
            ])) for k, J in J_coeff.items()
        ]
        ising_step = multi_dot(*non_inter + inter)

        if steps == 0:
            ising_gate = ising_step
        else:
            ising_gate = multi_dot(ising_step, ising_gate)

    ising_prog = pq.Program(n_qubits)
    ising_prog.inst(ising_gate)

    return ising_prog
def grad_prog(theta, idx, sign):
    theta = theta.reshape(3, n_qubits, depth)
    idx = np.unravel_index(idx, theta.shape)
    p = pq.Program(n_qubits)
    for i in range(depth):
        p += ising_prog
        for j in range(n_qubits):
            rj = n_qubits - j - 1
            if idx == (0, rj, i):
                p.inst(RX(sign * np.pi / 2.0), j)
            p.inst(RX(theta[0, rj, i]), j)
            if idx == (1, rj, i):
                p.inst(RZ(sign * np.pi / 2.0), j)
            p.inst(RZ(theta[1, rj, i]), j)
            if idx == (2, rj, i):
                p.inst(RX(sign * np.pi / 2.0), j)
            p.inst(RX(theta[2, rj, i]), j)
    return p
def input_prog(sample):
    p = pq.Program(n_qubits)
    for j in range(n_qubits):
        p.inst(RY(np.arcsin(sample[0])), j)
        p.inst(RZ(np.arccos(sample[0]**2)), j)
    return p

#==============================================================================
# Quantum Circuit Learning - Regression
#==============================================================================
from qsimulator import Z
from qcl import QCL

state_generators = dict()
state_generators['input'] = input_prog
state_generators['output'] = output_prog
state_generators['grad'] = grad_prog

initial_theta = np.random.uniform(0.0, 2 * np.pi, size=3 * n_qubits * depth)

operator = pq.Program(n_qubits)
operator.inst(Z, 0)
operator_programs = [operator]
est = QCL(state_generators,
          initial_theta,
          loss="mean_squared_error",
          operator_programs=operator_programs,
          epochs=20,
          batch_size=m,
          verbose=True)

est.fit(X, y)
results = est.get_results()

X_test = np.linspace(-1.0, 1.0, 50)
y_pred = est.predict(X_test)