# How do I get the expectation value of multiple wires?

Hello, let’s say that I have a circuit with N wires. I want the output of my function of my QNode to be the expected value of the PauliY operator across all N qubits. How do I go about this? What I have now is

``````expectation_values = [qml.expval(qml.PauliY(wires=i)) for i in range(nqubits)]
return expectation_values
``````

but this just returns a list of the expected value of each wire. I know that after I execute this circuit I can just do `np.mean()` on the list, but I want the function to return the overall expected value to use it in an optimization procedue. Thank you for the help!

Hey @NickGut0711!

You’re nearly there! You can do something like this:

``````import pennylane as qml
import pennylane.numpy as np

dev = qml.device("default.qubit")

@qml.qnode(dev)
def circuit(params):
for i in range(3):
qml.RX(params[i], i)

return [qml.expval(qml.PauliY(i)) for i in range(3)]

def cost(params):
return np.mean(circuit(params))

params = np.random.uniform(0, np.pi, size=(3,))
cost(params)
``````
``````0.6752343639895312
``````

Let me know if this helps

For more information on returning things from circuits in PennyLane, you can check out this awesome documentation page: QNode returns — PennyLane 0.33.0 documentation

Thank you for all the help and the thoughtful response!

When I naively put the similar cost function you described above into my opt.step I get an error. Here’s my code:

``````def cost(params, phi):
return np.mean(circuit(params, phi))

L = 1
init_params = create_params(L)
phi = phi = np.array([0.001], requires_grad=False)
nqubits = 10

eta = 0.01
steps = 200

opt = qml.QNGOptimizer(eta)

qng_cost = []

for _ in range(steps):
print(f'Step: {_}')
new_params = opt.step(cost, init_params, phi)
qng_cost.append(circuit(new_params))
``````

Here’s the error:

``````{
"name": "ValueError",
"message": "The objective function must either be encoded as a single QNode or an ExpvalCost object for the natural gradient to be automatically computed. Otherwise, metric_tensor_fn must be explicitly provided to the optimizer.",
"stack": "---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
for _ in range(steps):
print(f'Step: {_}')
--->  new_params = opt.step(cost, init_params, phi)
qng_cost.append(circuit(new_params))

File ~/..., in QNGOptimizer.step(self, qnode, grad_fn, recompute_tensor, metric_tensor_fn, *args, **kwargs)
229 def step(
230     self, qnode, *args, grad_fn=None, recompute_tensor=True, metric_tensor_fn=None, **kwargs
231 ):
232     \"\"\"Update the parameter array :math:`x` with one step of the optimizer.
233
234     Args:
(...)
251         array: the new variable values :math:`x^{(t+1)}`
252     \"\"\"
--> 253     new_args, _ = self.step_and_cost(
254         qnode,
255         *args,
257         recompute_tensor=recompute_tensor,
258         metric_tensor_fn=metric_tensor_fn,
259         **kwargs,
260     )
261     return new_args

File ~..., in QNGOptimizer.step_and_cost(self, qnode, grad_fn, recompute_tensor, metric_tensor_fn, *args, **kwargs)
180 # pylint: disable=arguments-differ
181 if not isinstance(qnode, (qml.QNode, qml.ExpvalCost)) and metric_tensor_fn is None:
--> 182     raise ValueError(
183         \"The objective function must either be encoded as a single QNode or \"
184         \"an ExpvalCost object for the natural gradient to be automatically computed. \"
185         \"Otherwise, metric_tensor_fn must be explicitly provided to the optimizer.\"
186     )
188 if recompute_tensor or self.metric_tensor is None:
189     if metric_tensor_fn is None:

ValueError: The objective function must either be encoded as a single QNode or an ExpvalCost object for the natural gradient to be automatically computed. Otherwise, metric_tensor_fn must be explicitly provided to the optimizer."
}
``````

Now, when I read the documentation here for the `QNGOptimizer`, I updated my `opt.step()` to include the `metric_tensor_fn` argument with the `cost` function:

``````for _ in range(steps):
print(f'Step: {_}')
new_params = opt.step(circuit, init_params, phi, metric_tensor_fn=cost)
qng_cost.append(circuit(new_params))
``````

but now I get this error:

``````{
"name": "TypeError",
"message": "'numpy.float64' object cannot be interpreted as an integer",
"stack": "---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~..., in _wrapfunc(obj, method, *args, **kwds)
58 try:
---> 59     return bound(*args, **kwds)
60 except TypeError:
61     # A TypeError occurs if the object does have such a method in its
62     # class, but its signature is not identical to that of NumPy's. This
(...)
66     # Call _wrapit from within the except clause to ensure a potential
67     # exception has a traceback chain.

TypeError: 'numpy.float64' object cannot be interpreted as an integer

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
/... Cell 13 line 1
for _ in range(steps):
print(f'Step: {_}')
--->       new_params = opt.step(circuit, init_params, phi, metric_tensor_fn=cost)
qng_cost.append(circuit(new_params))

File ~/..., in QNGOptimizer.step(self, qnode, grad_fn, recompute_tensor, metric_tensor_fn, *args, **kwargs)
229 def step(
230     self, qnode, *args, grad_fn=None, recompute_tensor=True, metric_tensor_fn=None, **kwargs
231 ):
232     \"\"\"Update the parameter array :math:`x` with one step of the optimizer.
233
234     Args:
(...)
251         array: the new variable values :math:`x^{(t+1)}`
252     \"\"\"
--> 253     new_args, _ = self.step_and_cost(
254         qnode,
255         *args,
257         recompute_tensor=recompute_tensor,
258         metric_tensor_fn=metric_tensor_fn,
259         **kwargs,
260     )
261     return new_args

File ~/..., in QNGOptimizer.step_and_cost(self, qnode, grad_fn, recompute_tensor, metric_tensor_fn, *args, **kwargs)
194 shape = qml.math.shape(_metric_tensor)
195 size = qml.math.prod(shape[: len(shape) // 2])
--> 196 self.metric_tensor = qml.math.reshape(_metric_tensor, (size, size))
198 self.metric_tensor = self.metric_tensor + self.lam * qml.math.eye(
199     size, like=_metric_tensor
200 )

File ~/..., in do(fn, like, *args, **kwargs)
31 \"\"\"Do function named ``fn`` on ``(*args, **kwargs)``, peforming single
32 dispatch to retrieve ``fn`` based on whichever library defines the class of
33 the ``args[0]``, or the ``like`` keyword argument if specified.
(...)
77     <tf.Tensor: id=91, shape=(3, 3), dtype=float32>
78 \"\"\"
79 backend = choose_backend(fn, *args, like=like, **kwargs)
---> 80 return get_lib_fn(backend, fn)(*args, **kwargs)

File ~/..., in reshape(a, newshape, order)
200 @array_function_dispatch(_reshape_dispatcher)
201 def reshape(a, newshape, order='C'):
202     \"\"\"
203     Gives a new shape to an array without changing its data.
204
(...)
283            [5, 6]])
284     \"\"\"
--> 285     return _wrapfunc(a, 'reshape', newshape, order=order)

File ~/..., in _wrapfunc(obj, method, *args, **kwds)
59     return bound(*args, **kwds)
60 except TypeError:
61     # A TypeError occurs if the object does have such a method in its
62     # class, but its signature is not identical to that of NumPy's. This
(...)
66     # Call _wrapit from within the except clause to ensure a potential
67     # exception has a traceback chain.
---> 68     return _wrapit(obj, method, *args, **kwds)

File ~/..., in _wrapit(obj, method, *args, **kwds)
43 except AttributeError:
44     wrap = None
---> 45 result = getattr(asarray(obj), method)(*args, **kwds)
46 if wrap:
47     if not isinstance(result, mu.ndarray):

TypeError: 'numpy.float64' object cannot be interpreted as an integer"
}
``````

I’m unsure what’s going on here. Also, I want to point out that the `phi` parameter of my circuit is just a parameter with `requires_grad=False`. Thank you!

Hey @NickGut0711, can you attach your full code? That way I can run it and try to replicate the error you’re getting and propose a solution