I want to give a quantum NN a set of point locations and optimize an ansantz such that du/dx = 1 with u(x=0) = 0, 0 <= x <= 1. The solution here is a simple, u(x) = x. My question is (1) is the code i wrote doing what I think I it is, and (2) if so, I’ve noticed that it gives back pretty close to linear solutions but with a slope /= 1, even though I am asking it to enforce this. Could this because the quantum solution is only proportional to the answer?

Thanks everyone!

```
import pennylane as qml
from pennylane import numpy as np
import autograd as ag
dev = qml.device("default.qubit", wires=3)
nlayers = 3
nqbits = 2
max_iterations = 2000 # Maximum number of calls to the optimizer
#shape = qml.StronglyEntanglingLayers.shape(n_layers=nlayers, n_wires=nqbits)
#params = np.random.random(size=shape)
nparams = 3 * nlayers
params = np.random.random([nparams], requires_grad=True)
print("initial params: ",params)
#x = np.array([[0.1, 0.2], [0.3, 0.4], [1.1, 1.2], [1.3, 1.4]], requires_grad=True)
x = np.array([[0.0], [0.3], [0.5], [0.8]], requires_grad=True)
opt = qml.GradientDescentOptimizer(0.01)
@qml.qnode(dev)
def circuit(params, x):
#qml.RX(x[:, 0], wires=0)
#qml.RY(x[:, 1], wires=1)
#qml.RZ(x[:, 0], wires=2)
qml.templates.AngleEmbedding(x, wires=range(nqbits))
#qml.templates.StronglyEntanglingLayers(params, wires=range(nqbits))
for i in range(0,nlayers):
qml.RX(params[i*(nlayers-1) + 0], wires=[0])
qml.RY(params[i*(nlayers-1) + 1], wires=[1])
qml.CNOT(wires=[0,1])
qml.RY(params[i*(nlayers-1) + 2], wires=[0])
#qml.RX(params[0], wires=0)
#qml.RY(params[1], wires=1)
#qml.RZ(params[2], wires=2)
return qml.expval(qml.PauliZ(0))
def loss(params, x):
grad_circ = ag.elementwise_grad(circuit)
#print(grad_circ(params, x)[0]) # I think* [0] = x, [1] = 1, [2] = params
#print(grad_circ(params, x)[1])
#print(grad_circ(params, x)[2])
u_x = grad_circ(params, x)[0]
#grad2_circ = ag.elementwise_grad(grad_circ)
#u_xx = grad2_circ(params, x)[0]
#print("u_x: ",u_x)
#print("u_xx: ",u_xx)
print("circuit at x=0: ",circuit(params,x[0]))
print("u_x: ",u_x);
cost = np.abs(u_x - 1) + np.abs(circuit(params,x[0]))
return cost
cost = [loss(params,x)] # Store the values of the cost function
for n in range(max_iterations):
(params, _), prev_cost = opt.step_and_cost(loss,params,x)
cost.append(loss(params,x))
print(f"Step = {n}, Cost function = {cost[-1]:.8f} ")
print("\n" f"Final value of the cost function = {cost[-1]:.8f} ")
plt.semilogy(range(len(cost)), cost)
plt.ylabel("loss")
plt.xlabel("iteration")
```

Here is an example of the list few lines of output:

Step = 1997, Cost function = 0.04233369

circuit at x=0: Autograd ArrayBox with value 0.0027276330820018013

u_x: Autograd ArrayBox with value 1.039606057608671

circuit at x=0: -0.013977220553959335

u_x: 0.9783536868220091

Step = 1998, Cost function = 0.03562353

circuit at x=0: Autograd ArrayBox with value -0.013977220553959335

u_x: Autograd ArrayBox with value 0.9783536868220091

circuit at x=0: 0.003179064896253525

u_x: 1.0395193985245172

Step = 1999, Cost function = 0.04269846

Final value of the cost function = 0.04269846

I have also attached a plot of the analytic and qml solutions.