Beispiel #1
0
    def test2_abstract_variables(self):
        """
        Tests the translation of abstract variables and
        ArithExpression into Qiskit via qlm_to_qiskit()
        """
        prog = Program()
        qubits = prog.qalloc(1)
        var2 = prog.new_var(float, "param2")
        var3 = prog.new_var(float, "param3")
        var4 = 1.0 + 3.14 + var2 - var3
        var5 = 1.0 * 3.14 * (var2 + 4.54) * var3
        var6 = -var5 * var4
        var7 = var4 / (var2 - 7)
        prog.apply(RX(1.0), qubits[0])
        prog.apply(RX(3.14), qubits[0])
        prog.apply(RX(var2), qubits[0])
        prog.apply(RX(var3), qubits[0])
        prog.apply(RX(var4), qubits[0])
        prog.apply(RX(var5), qubits[0])
        prog.apply(RX(var6), qubits[0])
        prog.apply(RX(var7), qubits[0])
        qlm_circ = prog.to_circ()
        qiskit_circ = qlm_to_qiskit(qlm_circ)
        LOGGER.debug("Parameters gotten:")
        for gate_op in qiskit_circ.data:
            for param in gate_op[0]._params:
                LOGGER.debug(param)

        qreg = QuantumRegister(1)
        circ = QuantumCircuit(qreg)
        param2 = Parameter("param2")
        param3 = Parameter("param3")
        param4 = 1.0 + 3.14 + param2 - param3
        param5 = 1.0 * 3.14 * (param2 + 4.54) * param3
        param6 = -param5 * param4
        param7 = param4 / (param2 - 7.0)
        circ.rx(1.0, 0)
        circ.rx(3.14, 0)
        circ.rx(param2, 0)
        circ.rx(param3, 0)
        circ.rx(param4, 0)
        circ.rx(param5, 0)
        circ.rx(param6, 0)
        circ.rx(param7, 0)
        LOGGER.debug("Parameters expected:")
        for gate_op in circ.data:
            for param in gate_op[0]._params:
                LOGGER.debug(param)

        for gotten, expected in zip(qiskit_circ.data, circ.data):
            self.assertEqual(str(gotten[0]._params[0]),
                             str(expected[0]._params[0]))
Beispiel #2
0
def bipartition(s, p):
    
    ###Define a variational circuit
    #As a Program
    prog = Program()
    
    #With n qubits
    nqbits = len(s)
    qbits = prog.qalloc(nqbits)
    
    #Define the variational states (einsatz)
    #|psi(theta)> = Rx1(theta1x)...Rxn(theta1n)|0,...,0>
    
    for i in range(0, nqbits):
        
        for j in range(1):
            #H(qbits[i])
            thetaij = prog.new_var(float, "theta"+str(i)+str(j))    
            if j == 0 :
                RX(np.pi*thetaij)(qbits[i])
                #RZ(thetaij)(qbits[i]) #H Rz H method
            #elif j ==1 :
            #    RY(thetaij)(qbits[i])
            #elif j == 2:
            #    RZ(thetaij)(qbits[i])
            # elif j == 3 :
            #     RY(thetaij)(qbits[i])
            # elif j == 4 :
            #     RX(thetaij)(qbits[i])
            #H(qbits[i])
    
    #export program into a quntum circuit
    circuit = prog.to_circ()
    
    #print created variables"
    print("Variables:", circuit.get_variables())
    
    ###Define an observable
    #Initialization
    obs = Observable(nqbits)
    
    #Observable = Hamiltonian we want to minimize
    # => Reformulate bi-partition problem in Hamiltonian minimalization problem :
    #Bi-partition problem : Find A1,A2 such that A1 u A2 = s and minimizes |sum_{n1 in A1}n1 - sum_{n2 in A2}n2|
    #Optimization Problem : Find e = {ei} in {-1,1}^n minimizing |sum_{1<=i<=n}ei.si|
    #Non-Linear Integer Programming Optimization Problem Find e = {ei} in {-1,1}^n minimizing (sum_{1<=i<=n}ei.si)^2
    #Ising problem : Find e = {ei} in {-1,1}^n minimizing sum_{1<=i<=n}(si)^2 + sum_{1<=i<=n, 1<=i<j<=n} (si.sj).ei.ej)^2 (si^2 = 1)
    
    J = [[si*sj for si in s] for sj in s] 
    b = [si**2 for si in s]
    
    obs += sum(b)*Observable(nqbits, constant_coeff = sum(b))
    
    for i in range(nqbits):
        for j in range(i-1):
        
            obs += Observable(nqbits, pauli_terms = [Term(J[i][j], "ZZ", [i, j])]) #Term(coefficient, tensorprod, [qubits]) 
        
    ###Create a quantum job
    #Made of a circuit and and an observable
    job = circuit.to_job(observable = obs) #nbshots=inf
    
    ###Define classical optimizer : scipy.optimia.minimize
    method_name = "COBYLA" #"Nelder-Mead", "Powell", "CG",...
    optimize = ScipyMinimizePlugin(method = method_name, tol = 1e-3, options = {"maxiter" : p})
    
    ###Define qpu on which to run quantum job
    stack = optimize | get_default_qpu()
    
    optimizer_args = {"method": method_name, "tol":1e-3, "options":{"maxiter":p}}
    
    result = stack.submit(job, meta_data ={"ScipyMinimizePlugin": json.dumps(optimizer_args)})
    
    ###Get characteristics of best parametrized circuit found
    final_energy = result.value
    parameters = json.loads(result.meta_data['parameters'])
    
    print("final energy:", final_energy)
    print('best parameters:', parameters)
    #print('trace:', result.meta_data['optimization_trace'])
    
    ###Deduce the most probable state => solution of the problem
    #Probability to measure qubit i in state |0> : cos(theta_i)^2
    #Probability to measure qubit i in state |1> : sin(theta_i)^2
    states = {}
    
    best_state = ''
    max_proba = 0
    
    for i in range(2**nqbits):
        
        state = bin(i)[2:].zfill(nqbits)
        proba = 1

        for i in range(nqbits):
            proba = proba/2*((1+(-1)**int(state[nqbits-i-1]))*np.cos(parameters[i]*np.pi/2)+(1+(-1)**(int(state[nqbits-i-1])+1))*np.sin(parameters[i]*np.pi/2))
        
        if max_proba < proba:
            max_proba = proba
            best_state = state
        
        states[state] = proba
    
    print(states)
    
    A1 = []
    A2 = []
    
    for i in range(nqbits):
    
        if best_state[i] == '0':
            A1.append(s[i])
    
        elif best_state[i] == '1':
            A2.append(s[i])
    
    return A1, A2
    def test1_abstract_variables(self):
        """
        Tests the conversion of Parameter objects from Qiskit into
        abstract Variable objects in QLM via qiskit_to_qlm.
        """
        qreg = QuantumRegister(1)
        circ = QuantumCircuit(qreg)
        param0 = Parameter("param0")
        param1 = Parameter("param1")
        param2 = Parameter("param2")
        param3 = Parameter("param3")
        param0.expr = 1
        param1.expr = 3.14
        param4 = param0 + param1 + param2 - param3
        param5 = param0 * param1 * (param2 + 4.54) * param3
        param6 = param5 * param4
        param7 = param4 / (param2 - 7)
        circ.rx(param0, 0)
        circ.rx(param1, 0)
        circ.rx(param2, 0)
        circ.rx(param3, 0)
        circ.rx(param4, 0)
        circ.rx(param5, 0)
        circ.rx(param6, 0)
        circ.rx(param7, 0)
        qlm_circ = qiskit_to_qlm(circ)
        i = 0
        for _, params, _ in qlm_circ.iterate_simple():
            for param in params:
                LOGGER.debug(param.to_thrift())
                if i == 0:
                    self.assertEqual(param.to_thrift(), "param0")
                if i == 1:
                    self.assertEqual(param.to_thrift(), "param1")
                if i == 2:
                    self.assertEqual(param.to_thrift(), "param2")
                if i == 3:
                    self.assertEqual(param.to_thrift(), "param3")
                if i == 4:
                    self.assertEqual(
                        param.to_thrift(),
                        "+ + + * -1.0 param3 param2 param0 param1")
                if i == 5:
                    self.assertEqual(
                        param.to_thrift(),
                        "* * * + 4.54 param2 param0 param1 param3")
                if i == 6:
                    self.assertEqual(
                        param.to_thrift(),
                        "* * * * + + + * -1.0 param3 param2 param0 param1 " +
                        "+ 4.54 param2 param0 param1 param3")
                if i == 7:
                    self.assertEqual(
                        param.to_thrift(),
                        "* + + + * -1.0 param3 param2 param0 param1" +
                        " ** + -7.0 param2 -1.0")
            i += 1

        prog = Program()
        qubits = prog.qalloc(1)
        var0 = prog.new_var(float, "param0")
        var1 = prog.new_var(float, "param1")
        var2 = prog.new_var(float, "param2")
        var3 = prog.new_var(float, "param3")
        var4 = var0 + var1 + var2 - var3
        var5 = var0 * var1 * (var2 + 4.54) * var3
        var6 = var5 * var4
        var7 = var4 / (var2 - 7)
        prog.apply(RX(var0), qubits[0])
        prog.apply(RX(var1), qubits[0])
        prog.apply(RX(var2), qubits[0])
        prog.apply(RX(var3), qubits[0])
        prog.apply(RX(var4), qubits[0])
        prog.apply(RX(var5), qubits[0])
        prog.apply(RX(var6), qubits[0])
        prog.apply(RX(var7), qubits[0])
        qlm_circ_expected = prog.to_circ()
        qlm_circ_expected(var0=1)
        qlm_circ_expected(var1=3.14)
        for _, params, _ in qlm_circ_expected.iterate_simple():
            for param in params:
                LOGGER.debug(param.to_thrift())