Hello,
The code below is based on this paper : https://arxiv.org/pdf/2011.10395.pdf
and it is used to solve non linear DEs.
When I ran the code on the default.qubit , everything works fine (although a bit slow). I then moved it to qiskit.aer, and it get stucks when calculating the gradient. I’m not sure why, but everything else works, i.e. it gets the expectation values and calculate the loss, but then gets stuck, no error message.
I need this to work with qiskit, because I eventually have to run this code on a Hardware.
import qiskit
from qiskit import *
import pennylane as qml
from pennylane import numpy as np
from numpy import pi
from pennylane.optimize import AdamOptimizer
from pennylane.optimize import AdagradOptimizer
import matplotlib.pyplot as plt
import time
dev = qml.device('qiskit.aer', wires=6)
num_layers = 5
bound = 1
div=1
var_init = np.random.uniform(0, np.pi * 2, (3*num_layers, 6))
#this is the ansatz
def layers(var,n_wires,d):
for i in range(n_wires):
qml.RZ(var[0+d*3][i],wires=i)
qml.RX(var[1+d*3][i],wires=i)
qml.RZ(var[2+d*3][i],wires=i)
for i in range(n_wires):
if i !=n_wires-1:
qml.CNOT(wires=[i, i+1])
#this is the first quantum circuit
@qml.qnode(dev)
def qfc(var, x,n_wires,depth):
for i in range(n_wires):
qml.RY(x, wires=i)
# "layer" subcircuits
for d in range(depth):
layers(var,n_wires,d)
return [qml.expval(qml.PauliZ(i)) for i in range(n_wires)]
#second quantum circuit
@qml.qnode(dev)
def dqcplus(var,x,n_wires,depth,num):
#print(var)
for i in range(n_wires):
if i != num:
qml.RY(x,wires=i)
else:
qml.RY(x+pi/2,wires=i)
for d in range(depth):
layers(var,n_wires,d)
return [qml.expval(qml.PauliZ(i)) for i in range(n_wires)]
@qml.qnode(dev)
def dqcmin(var,x,n_wires,depth,num):
for i in range(n_wires):
if i != num:
qml.RY(x,wires=i)
else:
qml.RY(x-pi/2,wires=i)
for d in range(depth):
layers(var,n_wires,d)
return [qml.expval(qml.PauliZ(i)) for i in range(n_wires)]
Don’t worry too much about the second circuits, they are essentially like the first one, but with shifted angles for the gates.
we then have our loss and cost function.
def loss(preds):
loss = 0
for p in preds:
loss += p**2
loss = loss/len(preds)
print("loss calculated")
return loss
def cost(var,points,fb):
preds=[]
for x in points:
cplus = [sum(dqcplus(var = var,x=2*np.arccos(x),n_wires=6,depth=num_layers,num=i))/div for i in range(6)]
cmin = [sum(dqcmin(var = var,x=2*np.arccos(x),n_wires=6,depth=num_layers,num=i))/div for i in range(6)]
du = (1/2)*(-2/np.sqrt(1-x**2))*(sum(cplus)-sum(cmin))
u=fb+sum(qfc(var = var,x=2*np.arccos(x),n_wires=6,depth=num_layers))/div
pred = du+(8*u*(0.1+np.tan(8*x)))
preds.append(pred)
return loss(preds)
and finally, the part where it all goes wrong, the optimization step
opt = AdamOptimizer(0.01, beta1=0.9, beta2=0.99)
var = var_init
coste = []
start = time.time()
print("starting")
for it in range(10):
fb = bound-sum(qfc(var = var,x=2*np.arccos(0),n_wires=6,depth=num_layers))/div
var, _cost = opt.step_and_cost(lambda v:cost(v, np.linspace(0, 0.9, 10),float(fb)),var)
print("success")
coste.append(_cost)
print("Iter: {:5d} | Cost: {:0.7f} ".format(it, _cost))
#if _cost <0.1:
# break
end = time.time()
print("the optimisation is finished, it took")
print(end - start)
Sorry about all the indenting, I’m new to posting on help blog.
So to resume, this code works fine if I use the default.qubit backend. But when I move to qiskit.aer, it fails to calculate the gradient, but it can still evaluate the quantul circuit.
I hope I am just missing something small ? I do know that I have a lot of parameter to optimize, I think its something like 156+ 15662 =1170. But actually its more like 90 since the parameter in the second circuit are the same as the first. But again, it works fine with the default.qubit so I’m quite loss.
Thanks for any help guys