# Optimize circuits returning counts

Hello there,

I want to optimize the parameters of a variational circuit that returns qml.counts() to minimize a post-processed classical cost function. From what I understand, this requieres a parameter-shift differentiation method, as the gradient is not analytically defined, however I keep getting the following error:

``````Can't differentiate w.r.t. type <class 'numpy.int64'>
``````

Here is an example of my code:

``````import pennylane as qml
from pennylane import numpy as np

dev = qml.device('default.qubit', wires=2, shots = 100)

@qml.qnode(dev, diff_method="parameter-shift")
def circuit(params):
qml.Rot(*params, wires=0)
qml.Rot(*params, wires=1)
qml.CNOT(wires=[0, 1])
return qml.counts(wires=[0, 1])

def cost(params):
res = circuit(params)
p0 = res['00']/(res['00'] + res['01'])
p1 = res['10']/(res['10'] + res['11'])
return np.abs(p0 - p1)

params = np.random.uniform(size=(2, 3))

for i in range(100):
params = opt.step(cost, params)
if (i+1) % 10 == 0:
print(f"Step {i+1}, Cost {cost(params)}")
``````

I’m not sure if what I want to do makes sense, but I would appreciate any help!

The issue with differentiating circuits which return `qml.counts` is that they return stochastic results. So regardless of the device that you use or the differentiation method, you cannot calculate gradients. This is the source for the error that you’re getting.

Notice that the parameter-shift method calculates analytic gradients, which is great! The magic with this method is that it can calculate these gradients over actual quantum hardware, but it cannot calculate gradients over samples or counts (or classical shadows), since they are stochastic. Instead I recommend that you use any of the other measurements listed in the Measurements page of the PennyLane docs. Measuring `probs` or `expval` for example should work.

Since you’re using a simulator, ‘default.qubit’, you can also change the differentiation method to other methods which are faster.

Please let me know if you have any further questions.

Hello,

Thank for your response! I understand `qml.counts` return stochastic result, but working with real quantum hardware, don’t `probs` and `expval` also return stochastic results? How are `probs` measured if is not by sampling? And how is `expval` measured?

Yes that’s right. But `probs` and `expval` return values that are continuous and differentiable so PennyLane allows you to differentiate over them. Instead if you return samples or counts the values will jump around too much so PennyLane doesn’t allow you to differentiate over them. There’s a hack, in case you really want to measure samples, and it’s to calculate `probs` or `expval` while specifying `shots=1`. This is basically tricking PennyLane because it does allow you to calculate gradients over these measurement types.

From your code however I feel that what you want is closer to the following

``````import pennylane as qml
from pennylane import numpy as np

dev = qml.device('default.qubit', wires=2, shots = 100)

@qml.qnode(dev)#, diff_method="parameter-shift")
def circuit(params):
qml.Rot(*params, wires=0)
qml.Rot(*params, wires=1)
qml.CNOT(wires=[0, 1])
return qml.probs(wires=[0, 1])

def cost(params):
probs = circuit(params)
p0 = probs/(probs + probs)
p1 = probs/(probs + probs)
return np.abs(p0 - p1)

params = np.random.uniform(size=(2, 3))
circuit(params)