# Help to building cost function

In this git repo they wrote the single_cost with expvalcost. But in the new version I need to use expval . How can i change the code?

single_cost = qml.ExpvalCost(ansatz, H, dev)
w = np.arange(num_qubits, 0, -1)

def total_cost(params):
cost = 0
for state_idx in range(num_qubits):
cost += w[state_idx] * single_cost(params, state_idx=state_idx)
return cost
max_iterations = 200
costs =

# Initial parameters for the ansatz

num_layers = 8
params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3))

Hi @Kaushik ,
Below is an example of how `qml.expval` works.

``````@qml.qnode(dev)
def cost_function(params):
some_qfunc(params)
return qml.expval(Hamiltonian)
``````

Comparing to the code you’re looking at, `some_qfunc` would become `ansatz `, `params` would become `params, wires, state_idx=0`, and `Hamiltonian` would become `H`.

Then you can write `single_cost =cost_function(params, wires, state_idx=0)`.

I hope this helps you!

I tried to write it

``````    @qml.qnode(self.dev)
def cost_function( params,wires=self.num_qubits, state_idx=0):
self.ansatz(params,wires=self.num_qubits,state_idx=0)
return qml.expval(H)
self.single_cost = cost_function(params,wires = self.num_qubits,state_idx=0)
``````

and total_cost like this

def total_cost(self,params, kwargs):
single_cost = kwargs.get(‘single_cost’)
w = kwargs.get(‘w’)
cost = 0
for state_idx in range(2
self.num_qubits):
cost +=w[state_idx]*single_cost(params,wires=self.num_qubits, state_idx=state_idx)
return cost

Error: cost +=w[state_idx]*single_cost(params,wires=self.num_qubits, state_idx=state_idx)

TypeError: ‘tensor’ object is not callable

Here
self.w = np.arange(2**self.num_qubits, 0, -1)

Hi @Kaushik,

Can you please write a minimal example which shows this error?
Something that I can use to try to replicate your error.

Below is an example of how to perform an optimization within a class (taken from another Forum thread). It might help you get an idea on how to set up your program.

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

class MyClass:
def __init__(self, n_qubits):
self.n_qubits = n_qubits
device = qml.device("default.qubit", wires=n_qubits)

self.quantum_node = qml.QNode(self.quantum_function, device)

def quantum_function(self, params):
for i in range(len(params)):
qml.RX(params[i], wires=i)
return [qml.expval(qml.PauliZ(i)) for i in range(len(params))]

def cost(self, params):
return -np.sum(self.quantum_node(params))

def do_optimization(self):
params = np.random.uniform(0, np.pi, size=(self.n_qubits,), requires_grad=True)
for n in range(10):
params = opt.step(self.cost, params)
print(self.cost(params))

obj = MyClass(4)
obj.do_optimization()
``````

I hope this helps you solve your question!

Thank you for help. But when I am changing the way of writing of single_cost , should I change the way of writing total_cost also?

`````` def states(self, nq=None)->list:
if not nq:
nq = self.num_qubits
st = []
for i in range(2 ** nq):
formStr = '0' + repr(nq) + 'b'
st.append(format(i, formStr))
return st

def ansatz(self, params, wires, state_idx=0)-> None:
state = self.states(nq =self.num_qubits)

for ind_qb, qb in enumerate(list(state[state_idx])):
if qb =='1':
qml.PauliX(wires=wires[ind_qb])
``````

then cost total cost is defined

Hi @Kaushik,

Actually the original code runs if you leave `total_cost` as it is but change `single_cost` in a different way. So instead of having a `cost_function` qnode, you can have a `single_cost` qnode instead.

``````@qml.qnode(dev)
def single_cost(params, state_idx=0):
ansatz(params,wires=range(num_qubits),state_idx=state_idx)
return qml.expval(H)
``````

I hope this helps you!

1 Like

I changed the single_cost function

``````  @qml.qnode(self.dev)
def single_cost( params, state_idx=0):
self.ansatz(params,wires=range(num_qubits),state_idx=state_idx)
return qml.expval(H)
``````

Still the program is showing error

self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost = self.single_cost, w= self.w)

AttributeError: ‘SSVQE’ object has no attribute ‘single_cost’

Hi @Kaushik,

Here you have a part of the line saying `self.single_cost` but you haven’t defined it as an attribute. If you change it to `single_cost` you shouldn’t see the error anymore.

1 Like
``````import pandas as pd
import scipy as scp

from pennylane import numpy as np
import matplotlib.pyplot as plt
from math import pi
import os
from pennylane import numpy as np
import pennylane as qml
from pennylane.templates import RandomLayers
from pennylane import expval, var, device
from pennylane.transforms import mitigate_with_zne
from ase.build import bulk
from ase.lattice import FCC
from pennylane import numpy as np
from multiprocessing import pool

from functools import wraps
from time import time

class KP:
def __init__(self, ep0=1.5292, delta=0.340, a=5.653, Ep=22.71, verbose=1, npoints_path=15):
self.RY =1
self.ep0= 1.5292
self.delta = 0.341
self.a=a
self.verbose = verbose
self.npoints_path = npoints_path
self.Ep = 22.71
self.gamma1 = 7.03
self.gamma2 = 2.33
self.gamma3 = 3.03
self.mass = 0.0665
self.P = 9.75

def lattice(self,atom = 'Si',structure = 'diamond', path = 'XGL'):
self.atom =atom
self.structure = structure
self.pathPoints = path

struc = bulk(self.atom,self.structure, a= self.a)
self.lat = struc.cell.get_bravais_lattice()

self.path = struc.cell.bandpath(self.pathPoints, npoints=self.npoints_path)
pt = FCC(self.a).bandpath(self.pathPoints, npoints = self.npoints_path)

self.p_axis = pt.get_linear_kpoint_axis(eps = 1e-5)[0]
self.p_labels_vert = pt.get_linear_kpoint_axis(eps = 1e-5)[1]
self.p_labels_stg = pt.get_linear_kpoint_axis(eps = 1e-5)[2]

if self.verbose == 1:
print('Symmetry points =  ',list(self.lat.get_special_points()))
print('k-vector-path = ', self.p_axis)
print('Path vertices = ', self.p_labels_vert)
print('Path labels = ', self.p_labels_stg)

self.data = pd.DataFrame(self.path.kpts,columns=['kx','ky','kz'])
self.data['k'] = np.sqrt((self.data['kx'])**2+(self.data['kx'])**2+(self.data['kx'])**2)

def Hamilton_GaAs(self, index = 0, nqbits=3, custom_lattice = False)->np.array:
if not custom_lattice:
self.lattice()
else:
print("define a custom lattice")

k = self.data.iloc[index].k
kx = self.data.iloc[index].kx
ky = self.data.iloc[index].ky
kz = self.data.iloc[index].kz
kmais = kx + 1j * ky
kmenos = kx - 1j * ky
e = 1 / self.mass - (self.Ep/3) * ((2 / self.ep0) + 1 / (self.ep0 + self.delta))
P = 9.75

Q = - ((self.gamma1 + self.gamma2)*(kx**2 - ky**2) - (self.gamma1 - 2*self.gamma2)*kz**2 )
R = -np.sqrt(3)*(self.gamma2*(kx**2 - ky**2) + 2*1j*self.gamma3*kx*ky)
Ec = self.ep0 + e*(kx**2 + ky**2 + kz**2)
Pz = self.P * kz
T = - ((self.gamma1 - self.gamma2)*(kx**2 + ky**2) + (self.gamma1 + 2*self.gamma2)*kz**2 )
S = 1j * (2*np.sqrt(3) * self.gamma3 * kz * kmenos)
Pmais = self.P * kmais / np.sqrt(2)
Pmenos = self.P * kmenos / np.sqrt(2)
H = np.zeros((4,4), dtype=np.complex64)

H[0,0] = T/2
H[0,1] = - S
H[0,2] = - 1j * (T-Q) / np.sqrt(2)
H[0,3] = - 1j * np.sqrt(2/3) * Pz
H[1,1] = Q/2
H[1,2] = -1j * np.conjugate(S) / np.sqrt(2)
H[1,3] = - Pmais
H[2,2] = ((Q+T)/2 - self.delta) / 2
H[2,3] = -Pz  / np.sqrt(3)
H[3,3] = Ec/2
self.H = H + np.transpose(np.conjugate(H))
return self.H[:2**nqbits,:2**nqbits]

class SSVQE:
def __init__(self, index=0, ep0=1.5292, delta=0.752, a=5.653, num_qubits=2, verbose=1,
npoints_path=15, machine=None, num_layers=2, num_excited=0):
self.time = []
self.num_qubits= num_qubits
self.index=index
self.verbose=verbose
self.npoints_path= npoints_path
self.ep0=ep0
self.delta=delta
self.a=a
self.HKP= KP(ep0=self.ep0, delta=self.delta, a=self.a, verbose=self.verbose, npoints_path= self.npoints_path)
self.HH = self.HKP.Hamilton_GaAs(index=self.index,nqbits =self.num_qubits)
self.data = self.HKP.data
self.machine= machine
self.num_layers= num_layers
self.num_excited= num_excited

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

if self.verbose ==1:
print('Hamiltonian:')
print(self.HH)
print('Number of Qubits:', self.num_qubits)
print('Running on ', machine)
self.epoch2print =50
elif self.verbose == 0:
self.epoch2print = 200

def states(self, nq=None)->list:
if not nq:
nq = self.num_qubits
st = []
for i in range(2 ** nq):
formStr = '0' + repr(nq) + 'b'
st.append(format(i, formStr))
return st

def ansatz(self, params, wires, state_idx=0)-> None:
state = self.states(nq =self.num_qubits)

for ind_qb, qb in enumerate(list(state[state_idx])):
if qb =='1':
qml.PauliX(wires=wires[ind_qb])

qml.templates.StronglyEntanglingLayers(params, wires = range(self.num_qubits))

def total_cost(self,params, **kwargs):
single_cost = kwargs.get('single_cost')
w = kwargs.get('w')
cost = 0
for state_idx in range(2**self.num_qubits):
cost +=w[state_idx]*single_cost(params,wires=self.num_qubits, state_idx=state_idx)
return cost
def run(self, params, max_iterations =1000, conv_tol = 1e-5, n_excited = 1, optimizer = 'Adam',
opt_rate = 0.1,method= 'simple',processes=None):
self.n_excited = n_excited
self.max_iterations = max_iterations
self.conv_tol = conv_tol
self.params = params

coeffs, obs_list = qml.pauli.conversion._generalized_pauli_decompose(self.HH)
obs_groupings = qml.pauli.group_observables(observables=obs_list, grouping_type="qwc", method="rlf")

H = qml.Hamiltonian(coeffs, obs_list)
eigen,_ = np.linalg.eigh(self.HH)
energies = np.zeros(2)

self.dev = qml.device("default.qubit", wires = self.num_qubits)

@qml.qnode(self.dev)
def single_cost( params,wires=self.num_qubits, state_idx=0):
self.ansatz(params,wires=self.num_qubits,state_idx=0)
return qml.expval(H)
self.single_cost = single_cost

self.w = np.arange(2**self.num_qubits, 0, -1)
energy_optimized, ind, energies_during_opt = self.optimize(params, optm=optimizer, opt_rate=opt_rate, conv_tol=self.conv_tol)

results = {
'energy_optimized': energy_optimized,
'param_optimized': params,
'all_energies': energies_during_opt,
'number_of_cycles': ind,
'convergence_tolerance': self.conv_tol
}
return results

def optimize(self,params,optm = 'Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm,opt_rate)
costs = []

conv = 10
KP_callback_energies = np.zeros((self.n_excited+1,self.max_iterations))
low_energy = 1e3
param_low_energy = params

prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w = self.w)
conv = np.abs(prev_energy - energy)

KP_callback_energies[0,i] = prev_energy
if energy < low_energy:
print('Energy lowered, Actual low energy = ', energy)
low_energy = energy
param_low_energy = self.params

if i%1 == 0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', energy)

if(conv<= self.conv_tol):
break

print("optimization converged after ", i , "cycles1")
if energy > low_energy:
self.params = param_low_energy
print('Energy non_converged after maximum iterations... ')

energy_optimized = np.zeros(self.num_excited + 1)
for exc in range(self.num_excited+1):
energy_optimized[exc] = self.single_cost(self.params, state_idx = exc)

return enrgy_optimized, i, KP_callback_energies
def optimizers(self, optm, opt_rate, eps=1e-8):

else:
raise ValueError("Unsupported optimizer: {}".format(optm))
return opt

if __name__=='__main__':
num_layers = 5 # number of entangling layers of the ansatz
num_qubits = 2 # number of qubits
point_path = 1 # number of points in Brillouin Zone path
num_excited = num_qubits**2 - 1

vqe = SSVQE(index=0, num_qubits=num_qubits, num_excited=num_excited, npoints_path=1, machine="PennyLane_statevector")
params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3), requires_grad=True)
print('params', params)

res = vqe.run(params, max_iterations=1)
``````

This is the program but it is showing error again and again.

``````TypeError                                 Traceback (most recent call last)
Cell In[1], line 295
292 params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3), requires_grad=True)
293 print('params', params)
--> 295 res = vqe.run(params, max_iterations=1)

Cell In[1], line 214, in SSVQE.run(self, params, max_iterations, conv_tol, n_excited, optimizer, opt_rate, method, processes)
208 self.single_cost = single_cost
213 self.w = np.arange(2**self.num_qubits, 0, -1)
--> 214 energy_optimized, ind, energies_during_opt = self.optimize(params, optm=optimizer, opt_rate=opt_rate, conv_tol=self.conv_tol)
216 results = {
217     'energy_optimized': energy_optimized,
218     'param_optimized': params,
(...)
221     'convergence_tolerance': self.conv_tol
222 }
223 return results

Cell In[1], line 240, in SSVQE.optimize(self, params, optm, opt_rate, conv_tol)
238 prev = 1e3
239 for i in range(self.max_iterations):
--> 240     self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost = self.single_cost, w= self.w)
241     energy = self.total_cost(self.params, single_cost = self.single_cost, w = self.w)
242     conv = np.abs(prev_energy - energy)

44 def step_and_cost(self, objective_fn, *args, grad_fn=None, **kwargs):
45     """Update trainable arguments with one step of the optimizer and return the corresponding
46     objective function value prior to the step.
47
(...)
61         If single arg is provided, list [array] is replaced by array.
62     """
67     if forward is None:

104 r"""Compute gradient of the objective function at the given point and return it along with
105 the objective function forward pass (if available).
106
(...)
119     will not be evaluted and instead ``None`` will be returned.
120 """
--> 122 grad = g(*args, **kwargs)
123 forward = getattr(g, "forward", None)
125 num_trainable_args = sum(getattr(arg, "requires_grad", False) for arg in args)

162     self._forward = self._fun(*args, **kwargs)
163     return ()
166 self._forward = ans

18 else:
19     x = tuple(args[i] for i in argnum)
---> 20 return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)

183 vjp, ans = _make_vjp(fun, x)  # pylint: disable=redefined-outer-name
185 if vspace(ans).size != 1:
--> 186     raise TypeError(
187         "Grad only applies to real scalar-output functions. "
189     )

``````

Can you help me to debug the code and run it properly?

Hi @Kaushik,

You’re getting this error because you’re trying to find the gradient over a function that returns multiple values instead of just one (you can learn more here in the docs).

I think the best is to check the return for your cost function and reduce it to a single value. Or roll back some of the changes you made since the last working version.

Let me know if this helps!

@qml.qnode(self.dev)
def single_cost( params,wires=self.num_qubits, state_idx=0):
self.ansatz(params,wires=self.num_qubits,state_idx=0)
return qml.expval(H)
self.single_cost = single_cost(params,wires=self.num_qubits, state_idx=0)

If I define the single_cost like this , it is showing error

cost +=w[state_idx]*single_cost(params,wires=self.num_qubits, state_idx=state_idx)

TypeError: ‘tensor’ object is not callable

I tried to use pennylane 0.32 version

import pennylane.utils
from matplotlib import pyplot as plt

import pandas as pd
import scipy as scp

from pennylane import numpy as np
import matplotlib.pyplot as plt
from math import pi

import os
from pennylane import numpy as np
import pennylane as qml
from pennylane.templates import RandomLayers
from pennylane import expval, var, device

from mitiq.zne.scaling import fold_global
from mitiq.zne.inference import RichardsonFactory
from mitiq.zne.scaling import fold_gates_at_random as folding
from pennylane.transforms import mitigate_with_zne
from mitiq.zne import execute_with_zne
from mitiq.zne.scaling import fold_gates_at_random as folding
from qiskit.providers.fake_provider import FakeLima
from qiskit.providers.aer.noise import NoiseModel

from ase.build import bulk
from ase.lattice import FCC
from pennylane import numpy as np
from qiskit.providers.fake_provider import FakeLima
from multiprocessing import pool

from functools import wraps
from time import time

from qiskit import Aer
from optimparallel import minimize_parallel
from qiskit import IBMQ

class KP:
def init(self, ep0=1.5292, delta=0.340, a=5.653, Ep=22.71, verbose=1, npoints_path=15):

``````    self.RY =1
self.ep0= 1.5292
self.delta = 0.341
self.a=a
self.verbose = verbose
self.npoints_path = npoints_path
self.Ep = 22.71
self.gamma1 = 7.03
self.gamma2 = 2.33
self.gamma3 = 3.03
self.mass = 0.0665
self.P = 9.75

def lattice(self,atom = 'Si',structure = 'diamond', path = 'XGL'):
self.atom =atom
self.structure = structure
self.pathPoints = path

struc = bulk(self.atom,self.structure, a= self.a)
self.lat = struc.cell.get_bravais_lattice()

self.path = struc.cell.bandpath(self.pathPoints, npoints=self.npoints_path)
pt = FCC(self.a).bandpath(self.pathPoints, npoints = self.npoints_path)

self.p_axis = pt.get_linear_kpoint_axis(eps = 1e-5)[0]
self.p_labels_vert = pt.get_linear_kpoint_axis(eps = 1e-5)[1]
self.p_labels_stg = pt.get_linear_kpoint_axis(eps = 1e-5)[2]

if self.verbose == 0:
print('Symmetry points =  ',list(self.lat.get_special_points()))
print('k-vector-path = ', self.p_axis)
print('Path vertices = ', self.p_labels_vert)
print('Path labels = ', self.p_labels_stg)

#creating a dataframe to stroe the path
self.data = pd.DataFrame(self.path.kpts,columns=['kx','ky','kz'])
self.data['k'] = np.sqrt((self.data['kx'])**2+(self.data['kx'])**2+(self.data['kx'])**2)

def Hamilton_GaAs(self, index = 0, nqbits=3, custom_lattice = False)->np.array:
if not custom_lattice:
self.lattice()
else:
print("define a custom lattice")

k = self.data.iloc[index].k
kx = self.data.iloc[index].kx
ky = self.data.iloc[index].ky
kz = self.data.iloc[index].kz

kmais = kx + 1j * ky
kmenos = kx - 1j * ky

e = 1 / self.mass - (self.Ep/3) * ((2 / self.ep0) + 1 / (self.ep0 + self.delta))
P = 9.75

Q = - ((self.gamma1 + self.gamma2)*(kx**2 - ky**2) - (self.gamma1 - 2*self.gamma2)*kz**2 )
R = -np.sqrt(3)*(self.gamma2*(kx**2 - ky**2) + 2*1j*self.gamma3*kx*ky)
Ec = self.ep0 + e*(kx**2 + ky**2 + kz**2)
Pz = self.P * kz

T = - ((self.gamma1 - self.gamma2)*(kx**2 + ky**2) + (self.gamma1 + 2*self.gamma2)*kz**2 )
S = 1j * (2*np.sqrt(3) * self.gamma3 * kz * kmenos)
Pmais = self.P * kmais / np.sqrt(2)
Pmenos = self.P * kmenos / np.sqrt(2)

H = np.zeros((4,4), dtype=np.complex64)

H[0,0] = T/2
H[0,1] = - S
H[0,2] = - 1j * (T-Q) / np.sqrt(2)
H[0,3] = - 1j * np.sqrt(2/3) * Pz
H[1,1] = Q/2
H[1,2] = -1j * np.conjugate(S) / np.sqrt(2)
H[1,3] = - Pmais

H[2,2] = ((Q+T)/2 - self.delta) / 2
H[2,3] = -Pz  / np.sqrt(3)

H[3,3] = Ec/2

self.H = H + np.transpose(np.conjugate(H))
return self.H[:2**nqbits,:2**nqbits]
``````

class SSVQE:

``````def __init__(self, index=0, ep0=1.5292, delta=0.752, a=5.653, num_qubits=2, verbose=1, npoints_path=15, machine=None, num_layers=2, num_excited=0):

self.time = []
self.num_qubits= num_qubits
self.index=index
self.verbose=verbose
self.npoints_path= npoints_path
self.ep0=ep0
self.delta=delta
self.a=a
self.HKP= KP(ep0=self.ep0, delta=self.delta, a=self.a, verbose=self.verbose, npoints_path= self.npoints_path)
self.HH = self.HKP.Hamilton_GaAs(index=self.index,nqbits =self.num_qubits)
self.data = self.HKP.data
self.machine= machine
self.num_layers= num_layers
self.num_excited= num_excited

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

if self.verbose ==1:
print('Hamiltonian:')
print(self.HH)
print('Number of Qubits:', self.num_qubits)
print('Running on ', machine)
self.epoch2print =50
elif self.verbose == 0:
self.epoch2print = 200

def states(self, nq=None)->list:
if not nq:
nq = self.num_qubits
st = []
for i in range(2 ** nq):
formStr = '0' + repr(nq) + 'b'
st.append(format(i, formStr))
return st

def ansatz(self, params, wires, state_idx=0)-> None:
state = self.states(nq =self.num_qubits)

for ind_qb, qb in enumerate(list(state[state_idx])):
if qb =='1':
qml.PauliX(wires=wires[ind_qb])

qml.templates.StronglyEntanglingLayers(params, wires = range(self.num_qubits))

def total_cost(self,params, **kwargs):
single_cost = kwargs.get('single_cost')
w = kwargs.get('w')
cost = 0
for state_idx in range(2**self.num_qubits):
cost +=w[state_idx]*single_cost(params, state_idx=state_idx)
return cost

def run(self, params, max_iterations =1000, conv_tol = 1e-5, n_excited = 1, optimizer = 'Adam', opt_rate = 0.1,method= 'simple',processes=None):
self.n_excited = n_excited
self.max_iterations = max_iterations
self.conv_tol = conv_tol
self.params = params

coeffs, obs_list = qml.pauli.conversion._generalized_pauli_decompose(self.HH)

obs_groupings = qml.pauli.group_observables(observables=obs_list, grouping_type="qwc", method="rlf")
print("Number of required measurements after optimization", len(obs_groupings))

H = qml.Hamiltonian(coeffs, obs_list)

eigen,_ = np.linalg.eigh(self.HH)
energies = np.zeros(2)

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

self.nonoiseDev = qml.device("default.qubit", wires = self.num_qubits)
self.nonoisesingle_cost = qml.ExpvalCost(self.ansatz, H , self.nonoiseDev, optimize = True)

single_cost = qml.ExpvalCost(self.ansatz, H, self.dev, optimize = True)
self.single_cost=qml.jacobian(single_cost)

self.w = np.arange(2**self.num_qubits, 0, -1)

if method == "parallel" and optimizer !='COBYLA':
energy_optimized, ind, energies_during_opt = self.optimize_parallel(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)
params,optm=optimizer,opt_rate=opt_rate,conv_tol=self.conv_tol)
elif method == "simple":
energy_optimized, ind, energies_during_opt = self.optimize(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)
energy_optimized, ind, energies_during_opt = self.optimize_parallel(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)

results = {
'energy_optimized': energy_optimized,
'param_optimized':params,
'all_energies':energies_during_opt,
'number_of_cycles':ind,
'convergence_tolerance':self.conv_tol

}

return results

def timing(f):
@wraps(f)
def wrap(self,*args,**kw):
ts=time()
result = f(self,*args,**kw)
te = time()
dt = te-ts
print('function_time'%(f.__name__,args,kw,te-ts))
self.time.append({'seconds': dt})
return result
return wrap

def optimize_conver(self,params,optm='Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm, opt_rate= opt_rate)
costs = []

conv = np.ones(self.n_excited +1)

KP_callback_energies = np.zeros(self.n_excited+1,self.max_iterations)

prev = np.ones(self.n_excited+1)* 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(
self.total_cost,self.params,single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params,single_cost= self.single_cost, w= self.w)

for exc in range(self.n_excited+1):
if conv[exc] == self.conv_tol:
en = self.single_cost(self.params, state_idx = exc)
conv[exc] = np.abs(en-prev[exc])
prev[exc] = en

KP_callback_energies[exc, i] = en

if i%1==0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', prev)

if np.all(conv = self.conv_tol):
break

print("optimization convergence after ",i,"cycles1")
energy_optimized = prev

return energy_optimized, i, KP_callback_energies

@timing
def optimize(self,params,optm = 'Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm,opt_rate)
costs = []

conv = 10
KP_callback_energies = np.zeros((self.n_excited+1,self.max_iterations))
low_energy = 1e3
param_low_energy = params

prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w = self.w)
conv = np.abs(prev_energy - energy)

KP_callback_energies[0,i] = prev_energy

if energy < low_energy:
print('Energy lowered, Actual low energy = ', energy)
low_energy = energy
param_low_energy = self.params

if i%1 == 0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', energy)

if(conv<= self.conv_tol):
break

print("optimization converged after ", i , "cycles1")

if energy > low_energy:
self.params = param_low_energy
print('Energy non_converged after maximum iterations... ')

energy_optimized = np.zeros(self.num_excited + 1)
for exc in range(self.num_excited+1):
energy_optimized[exc] = self.single_cost(self.params, state_idx = exc)

return energy_optimized, i, KP_callback_energies

@timing
self.params = params
opt = self.optimizers(optm, opt_rate = opt_rate)

costs = []

self.conv_tol_local = 1e-2
conv = 10

KP_callback_energies = []
en = np.zeros(self.n_excited+1)
prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost= self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w= self.w)

KP_callback_energies.append(energy)

if conv > self.conv_tol_local:
conv = np.abs(prev_energy = energy)
prev = energy
elif  (self.conv_tol_local > self.conv_tol and conv <= self.conv_tol_local):
opt_rate = opt_rate/2
self.conv_tol_local = self.conv_tol_local/10
opt = self.optimizers(optm,opt_rate = opt_rate)
conv = np.abs(prev_energy - energy)
prev = energy

elif self.conv_tol_local<= self.conv_tol and conv <= self.conv_tol:
for exc in range (self.n_excited +1):
en[exc] = self.single_cost(self.params, state_idx = exc)

if i%1 ==0:
print('iteration', i)
print('conv=', conv)
print('energy', energy)
print('step_size= ', opt_rate)
print('conv_tol_local = ', self.conv_tol_local)

print("optimization converged after ", i, "cycles1")
print("optimized energies ", en)
return en, i, KP_callback_energies

def optimizers(self, optm, opt_rate, eps=1e-8):

else:
raise ValueError("Unsupported optimizer: {}".format(optm))
return opt
``````

if name==‘main’:
num_layers = 5 # number of entangling layers of the ansatz
num_qubits = 2 # number of qubits
point_path = 1 # number of points in Brillouin Zone path
num_excited = num_qubits**2 - 1

``````vqe = SSVQE(index=0, num_qubits=num_qubits, num_excited=num_excited, npoints_path=1, machine="PennyLane_statevector")
params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3), requires_grad=True)
print('params', params)

res = vqe.run(params, max_iterations=2000)
``````

params = res.get(‘param_optimized’)

It is showing error:ValueError: cannot reshape array of size 60 into shape (5,2,3)

import pennylane.utils
from matplotlib import pyplot as plt

import pandas as pd
import scipy as scp

from pennylane import numpy as np
import matplotlib.pyplot as plt
from math import pi

import os
from pennylane import numpy as np
import pennylane as qml
from pennylane.templates import RandomLayers
from pennylane import expval, var, device

from mitiq.zne.scaling import fold_global
from mitiq.zne.inference import RichardsonFactory
from mitiq.zne.scaling import fold_gates_at_random as folding
from pennylane.transforms import mitigate_with_zne
from mitiq.zne import execute_with_zne
from mitiq.zne.scaling import fold_gates_at_random as folding
from qiskit.providers.fake_provider import FakeLima
from qiskit.providers.aer.noise import NoiseModel

from ase.build import bulk
from ase.lattice import FCC
from pennylane import numpy as np
from qiskit.providers.fake_provider import FakeLima
from multiprocessing import pool

from functools import wraps
from time import time

from qiskit import Aer
from optimparallel import minimize_parallel
from qiskit import IBMQ

class KP:
def init(self, ep0=1.5292, delta=0.340, a=5.653, Ep=22.71, verbose=1, npoints_path=15):

``````    self.RY =1
self.ep0= 1.5292
self.delta = 0.341
self.a=a
self.verbose = verbose
self.npoints_path = npoints_path
self.Ep = 22.71
self.gamma1 = 7.03
self.gamma2 = 2.33
self.gamma3 = 3.03
self.mass = 0.0665
self.P = 9.75

def lattice(self,atom = 'Si',structure = 'diamond', path = 'XGL'):
self.atom =atom
self.structure = structure
self.pathPoints = path

struc = bulk(self.atom,self.structure, a= self.a)
self.lat = struc.cell.get_bravais_lattice()

self.path = struc.cell.bandpath(self.pathPoints, npoints=self.npoints_path)
pt = FCC(self.a).bandpath(self.pathPoints, npoints = self.npoints_path)

self.p_axis = pt.get_linear_kpoint_axis(eps = 1e-5)[0]
self.p_labels_vert = pt.get_linear_kpoint_axis(eps = 1e-5)[1]
self.p_labels_stg = pt.get_linear_kpoint_axis(eps = 1e-5)[2]

if self.verbose == 0:
print('Symmetry points =  ',list(self.lat.get_special_points()))
print('k-vector-path = ', self.p_axis)
print('Path vertices = ', self.p_labels_vert)
print('Path labels = ', self.p_labels_stg)

#creating a dataframe to stroe the path
self.data = pd.DataFrame(self.path.kpts,columns=['kx','ky','kz'])
self.data['k'] = np.sqrt((self.data['kx'])**2+(self.data['kx'])**2+(self.data['kx'])**2)

def Hamilton_GaAs(self, index = 0, nqbits=3, custom_lattice = False)->np.array:
if not custom_lattice:
self.lattice()
else:
print("define a custom lattice")

k = self.data.iloc[index].k
kx = self.data.iloc[index].kx
ky = self.data.iloc[index].ky
kz = self.data.iloc[index].kz

kmais = kx + 1j * ky
kmenos = kx - 1j * ky

e = 1 / self.mass - (self.Ep/3) * ((2 / self.ep0) + 1 / (self.ep0 + self.delta))
P = 9.75

Q = - ((self.gamma1 + self.gamma2)*(kx**2 - ky**2) - (self.gamma1 - 2*self.gamma2)*kz**2 )
R = -np.sqrt(3)*(self.gamma2*(kx**2 - ky**2) + 2*1j*self.gamma3*kx*ky)
Ec = self.ep0 + e*(kx**2 + ky**2 + kz**2)
Pz = self.P * kz

T = - ((self.gamma1 - self.gamma2)*(kx**2 + ky**2) + (self.gamma1 + 2*self.gamma2)*kz**2 )
S = 1j * (2*np.sqrt(3) * self.gamma3 * kz * kmenos)
Pmais = self.P * kmais / np.sqrt(2)
Pmenos = self.P * kmenos / np.sqrt(2)

H = np.zeros((4,4), dtype=np.complex64)

H[0,0] = T/2
H[0,1] = - S
H[0,2] = - 1j * (T-Q) / np.sqrt(2)
H[0,3] = - 1j * np.sqrt(2/3) * Pz
H[1,1] = Q/2
H[1,2] = -1j * np.conjugate(S) / np.sqrt(2)
H[1,3] = - Pmais

H[2,2] = ((Q+T)/2 - self.delta) / 2
H[2,3] = -Pz  / np.sqrt(3)

H[3,3] = Ec/2

self.H = H + np.transpose(np.conjugate(H))
return self.H[:2**nqbits,:2**nqbits]
``````

class SSVQE:

``````def __init__(self, index=0, ep0=1.5292, delta=0.752, a=5.653, num_qubits=2, verbose=1, npoints_path=15, machine=None, num_layers=2, num_excited=0):

self.time = []
self.num_qubits= num_qubits
self.index=index
self.verbose=verbose
self.npoints_path= npoints_path
self.ep0=ep0
self.delta=delta
self.a=a
self.HKP= KP(ep0=self.ep0, delta=self.delta, a=self.a, verbose=self.verbose, npoints_path= self.npoints_path)
self.HH = self.HKP.Hamilton_GaAs(index=self.index,nqbits =self.num_qubits)
self.data = self.HKP.data
self.machine= machine
self.num_layers= num_layers
self.num_excited= num_excited

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

if self.verbose ==1:
print('Hamiltonian:')
print(self.HH)
print('Number of Qubits:', self.num_qubits)
print('Running on ', machine)
self.epoch2print =50
elif self.verbose == 0:
self.epoch2print = 200

def states(self, nq=None)->list:
if not nq:
nq = self.num_qubits
st = []
for i in range(2 ** nq):
formStr = '0' + repr(nq) + 'b'
st.append(format(i, formStr))
return st

def ansatz(self, params, wires, state_idx=0)-> None:
state = self.states(nq =self.num_qubits)

for ind_qb, qb in enumerate(list(state[state_idx])):
if qb =='1':
qml.PauliX(wires=wires[ind_qb])

qml.templates.StronglyEntanglingLayers(params, wires = range(self.num_qubits))

def total_cost(self,params, **kwargs):
single_cost = kwargs.get('single_cost')
w = kwargs.get('w')
cost = 0
for state_idx in range(2**self.num_qubits):
cost +=w[state_idx]*single_cost(params, state_idx=state_idx)
return cost

def run(self, params, max_iterations =1000, conv_tol = 1e-5, n_excited = 1, optimizer = 'Adam', opt_rate = 0.1,method= 'simple',processes=None):
self.n_excited = n_excited
self.max_iterations = max_iterations
self.conv_tol = conv_tol
self.params = params

coeffs, obs_list = qml.pauli.conversion._generalized_pauli_decompose(self.HH)

obs_groupings = qml.pauli.group_observables(observables=obs_list, grouping_type="qwc", method="rlf")
print("Number of required measurements after optimization", len(obs_groupings))

H = qml.Hamiltonian(coeffs, obs_list)

eigen,_ = np.linalg.eigh(self.HH)
energies = np.zeros(2)

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

self.nonoiseDev = qml.device("default.qubit", wires = self.num_qubits)
self.nonoisesingle_cost = qml.ExpvalCost(self.ansatz, H , self.nonoiseDev, optimize = True)

self.single_cost = qml.ExpvalCost(self.ansatz, H, self.dev, optimize = True,requires_grad=True)

self.w = np.arange(2**self.num_qubits, 0, -1)

if method == "parallel" and optimizer !='COBYLA':
energy_optimized, ind, energies_during_opt = self.optimize_parallel(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)
params,optm=optimizer,opt_rate=opt_rate,conv_tol=self.conv_tol)
elif method == "simple":
energy_optimized, ind, energies_during_opt = self.optimize(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)
energy_optimized, ind, energies_during_opt = self.optimize_parallel(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)

results = {
'energy_optimized': energy_optimized,
'param_optimized':params,
'all_energies':energies_during_opt,
'number_of_cycles':ind,
'convergence_tolerance':self.conv_tol

}

return results

def timing(f):
@wraps(f)
def wrap(self,*args,**kw):
ts=time()
result = f(self,*args,**kw)
te = time()
dt = te-ts
print('function_time'%(f.__name__,args,kw,te-ts))
self.time.append({'seconds': dt})
return result
return wrap

def optimize_conver(self,params,optm='Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm, opt_rate= opt_rate)
costs = []

conv = np.ones(self.n_excited +1)

KP_callback_energies = np.zeros(self.n_excited+1,self.max_iterations)

prev = np.ones(self.n_excited+1)* 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(
self.total_cost,self.params,single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params,single_cost= self.single_cost, w= self.w)

for exc in range(self.n_excited+1):
if conv[exc] == self.conv_tol:
en = self.single_cost(self.params, state_idx = exc)
conv[exc] = np.abs(en-prev[exc])
prev[exc] = en

KP_callback_energies[exc, i] = en

if i%1==0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', prev)

if np.all(conv = self.conv_tol):
break

print("optimization convergence after ",i,"cycles1")
energy_optimized = prev

return energy_optimized, i, KP_callback_energies

@timing
def optimize(self,params,optm = 'Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm,opt_rate)
costs = []

conv = 10
KP_callback_energies = np.zeros((self.n_excited+1,self.max_iterations))
low_energy = 1e3
param_low_energy = params

prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w = self.w)
conv = np.abs(prev_energy - energy)

KP_callback_energies[0,i] = prev_energy

if energy < low_energy:
print('Energy lowered, Actual low energy = ', energy)
low_energy = energy
param_low_energy = self.params

if i%1 == 0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', energy)

if(conv<= self.conv_tol):
break

print("optimization converged after ", i , "cycles1")

if energy > low_energy:
self.params = param_low_energy
print('Energy non_converged after maximum iterations... ')

energy_optimized = np.zeros(self.num_excited + 1)
for exc in range(self.num_excited+1):
energy_optimized[exc] = self.single_cost(self.params, state_idx = exc)

return energy_optimized, i, KP_callback_energies

@timing
self.params = params
opt = self.optimizers(optm, opt_rate = opt_rate)

costs = []

self.conv_tol_local = 1e-2
conv = 10

KP_callback_energies = []
en = np.zeros(self.n_excited+1)
prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost= self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w= self.w)

KP_callback_energies.append(energy)

if conv > self.conv_tol_local:
conv = np.abs(prev_energy = energy)
prev = energy
elif  (self.conv_tol_local > self.conv_tol and conv <= self.conv_tol_local):
opt_rate = opt_rate/2
self.conv_tol_local = self.conv_tol_local/10
opt = self.optimizers(optm,opt_rate = opt_rate)
conv = np.abs(prev_energy - energy)
prev = energy

elif self.conv_tol_local<= self.conv_tol and conv <= self.conv_tol:
for exc in range (self.n_excited +1):
en[exc] = self.single_cost(self.params, state_idx = exc)

if i%1 ==0:
print('iteration', i)
print('conv=', conv)
print('energy', energy)
print('step_size= ', opt_rate)
print('conv_tol_local = ', self.conv_tol_local)

print("optimization converged after ", i, "cycles1")
print("optimized energies ", en)
return en, i, KP_callback_energies

def optimizers(self, optm, opt_rate, eps=1e-8):

else:
raise ValueError("Unsupported optimizer: {}".format(optm))
return opt
``````

if name==‘main’:
num_layers = 5 # number of entangling layers of the ansatz
num_qubits = 2 # number of qubits
point_path = 1 # number of points in Brillouin Zone path
num_excited = num_qubits**2 - 1

``````vqe = SSVQE(index=0, num_qubits=num_qubits, num_excited=num_excited, npoints_path=1, machine="PennyLane_statevector")
params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3), requires_grad=True)

print('params', params)

res = vqe.run(params, max_iterations=2000)
``````

Can you debug this code? Because it is showing same error again

Hi @Kaushik,

I’m sorry if my message was confusing. I didn’t mean to say that you should roll back the version of PennyLane. You should always try to use the latest version which in this case is v0.35.1.

My suggestion is that you keep it as close as possible to the original code here since it runs properly with just removing the line `single_cost = qml.ExpvalCost(...)` and adding a qnode for `single_cost`:

``````@qml.qnode(dev)
def single_cost(params, state_idx=0):
ansatz(params,wires=range(num_qubits),state_idx=state_idx)
return qml.expval(H)
``````

If you want to make any additional changes I recommend that you make them one by one and specify exactly what you changed because otherwise it’s very hard to know. For your last error though it’s clear that you’re optimizing something that is not a scalar so this needs to change.

My recommendation would be to go back to PennyLane version 0.35.1, go back to the original code here and change only single_cost. Then if you need to make any changes make them one by one and noting exactly what you changed. Then it will be easier to debug.

I hope this helps!

1 Like

How can I solve this error

AttributeError: ‘ExpectationMP’ object has no attribute ‘get’.

run method contains this

results = {
‘energy_optimized’: energy_optimized,
‘param_optimized’: params,
‘all_energies’: energies_during_opt,
‘number_of_cycles’: ind,
‘convergence_tolerance’: self.conv_tol
}

Later I used

if name==‘main’:
num_layers = 5 # number of entangling layers of the ansatz
num_qubits = 2 # number of qubits
point_path = 1 # number of points in Brillouin Zone path
num_excited = num_qubits**2 - 1
params = np.random.uniform(low =0, high=2*np.pi, size=(num_layers, num_qubits,3))

for i in range(point_path):
VQE = SSVQE(index = i, verbose = 0, num_qubits= num_qubits,
num_excited = num_excited, npoints_path=point_path, machine = “PennyLane_statevector”,
num_layers = num_layers)
results = VQE.run(params, max_iterations = 2000,
conv_tol = 1e-4, optimizer = ‘Adam’, n_excited = num_excited, opt_rate = 0.01,
method = ‘simple’)

``````params = results.get(params)
``````

import pandas as pd
import scipy as scp

from pennylane import numpy as np
import matplotlib.pyplot as plt
from math import pi

import os
from pennylane import numpy as np
import pennylane as qml
from pennylane.templates import RandomLayers
from pennylane import expval, var, device

from mitiq.zne.scaling import fold_global
from mitiq.zne.inference import RichardsonFactory
from mitiq.zne.scaling import fold_gates_at_random as folding
from pennylane.transforms import mitigate_with_zne
from mitiq.zne import execute_with_zne
from mitiq.zne.scaling import fold_gates_at_random as folding
from qiskit.providers.fake_provider import FakeLima
from qiskit.providers.aer.noise import NoiseModel

from ase.build import bulk
from ase.lattice import FCC
from pennylane import numpy as np
from qiskit.providers.fake_provider import FakeLima
from multiprocessing import pool

from functools import wraps
from time import time

from qiskit import Aer
from optimparallel import minimize_parallel
from qiskit import IBMQ

class KP:
def init(self, ep0=1.5292, delta=0.340, a=5.653, Ep=22.71, verbose=1, npoints_path=15):

``````    self.RY =1
self.ep0= 1.5292
self.delta = 0.341
self.a=a
self.verbose = verbose
self.npoints_path = npoints_path
self.Ep = 22.71
self.gamma1 = 7.03
self.gamma2 = 2.33
self.gamma3 = 3.03
self.mass = 0.0665
self.P = 9.75

def lattice(self,atom = 'Si',structure = 'diamond', path = 'XGL'):
self.atom =atom
self.structure = structure
self.pathPoints = path

struc = bulk(self.atom,self.structure, a= self.a)
self.lat = struc.cell.get_bravais_lattice()

self.path = struc.cell.bandpath(self.pathPoints, npoints=self.npoints_path)
pt = FCC(self.a).bandpath(self.pathPoints, npoints = self.npoints_path)

self.p_axis = pt.get_linear_kpoint_axis(eps = 1e-5)[0]
self.p_labels_vert = pt.get_linear_kpoint_axis(eps = 1e-5)[1]
self.p_labels_stg = pt.get_linear_kpoint_axis(eps = 1e-5)[2]

if self.verbose == 0:
print('Symmetry points =  ',list(self.lat.get_special_points()))
print('k-vector-path = ', self.p_axis)
print('Path vertices = ', self.p_labels_vert)
print('Path labels = ', self.p_labels_stg)

#creating a dataframe to stroe the path
self.data = pd.DataFrame(self.path.kpts,columns=['kx','ky','kz'])
self.data['k'] = np.sqrt((self.data['kx'])**2+(self.data['kx'])**2+(self.data['kx'])**2)

def Hamilton_GaAs(self, index = 0, nqbits=3, custom_lattice = False)->np.array:
if not custom_lattice:
self.lattice()
else:
print("define a custom lattice")

k = self.data.iloc[index].k
kx = self.data.iloc[index].kx
ky = self.data.iloc[index].ky
kz = self.data.iloc[index].kz

kmais = kx + 1j * ky
kmenos = kx - 1j * ky

e = 1 / self.mass - (self.Ep/3) * ((2 / self.ep0) + 1 / (self.ep0 + self.delta))
P = 9.75

Q = - ((self.gamma1 + self.gamma2)*(kx**2 - ky**2) - (self.gamma1 - 2*self.gamma2)*kz**2 )
R = -np.sqrt(3)*(self.gamma2*(kx**2 - ky**2) + 2*1j*self.gamma3*kx*ky)
Ec = self.ep0 + e*(kx**2 + ky**2 + kz**2)
Pz = self.P * kz

T = - ((self.gamma1 - self.gamma2)*(kx**2 + ky**2) + (self.gamma1 + 2*self.gamma2)*kz**2 )
S = 1j * (2*np.sqrt(3) * self.gamma3 * kz * kmenos)
Pmais = self.P * kmais / np.sqrt(2)
Pmenos = self.P * kmenos / np.sqrt(2)

H = np.zeros((4,4), dtype=np.complex64)

H[0,0] = T/2
H[0,1] = - S
H[0,2] = - 1j * (T-Q) / np.sqrt(2)
H[0,3] = - 1j * np.sqrt(2/3) * Pz
H[1,1] = Q/2
H[1,2] = -1j * np.conjugate(S) / np.sqrt(2)
H[1,3] = - Pmais

H[2,2] = ((Q+T)/2 - self.delta) / 2
H[2,3] = -Pz  / np.sqrt(3)

H[3,3] = Ec/2

self.H = H + np.transpose(np.conjugate(H))
return self.H[:2**nqbits,:2**nqbits]
``````

class SSVQE:

``````def __init__(self, index=0, ep0=1.5292, delta=0.752, a=5.653, num_qubits=2, verbose=1, npoints_path=15, machine=None, num_layers=2, num_excited=0):

self.time = []
self.num_qubits= num_qubits
self.index=index
self.verbose=verbose
self.npoints_path= npoints_path
self.ep0=ep0
self.delta=delta
self.a=a
self.HKP= KP(ep0=self.ep0, delta=self.delta, a=self.a, verbose=self.verbose, npoints_path= self.npoints_path)
self.HH = self.HKP.Hamilton_GaAs(index=self.index,nqbits =self.num_qubits)
self.data = self.HKP.data
self.machine= machine
self.num_layers= num_layers
self.num_excited= num_excited

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

if self.verbose ==1:
print('Hamiltonian:')
print(self.HH)
print('Number of Qubits:', self.num_qubits)
print('Running on ', machine)
self.epoch2print =50
elif self.verbose == 0:
self.epoch2print = 200
coeffs, obs_list = qml.pauli.conversion._generalized_pauli_decompose(self.HH)

obs_groupings = qml.pauli.group_observables(observables=obs_list, grouping_type="qwc", method="rlf")
print("Number of required measurements after optimization", len(obs_groupings))

H = qml.Hamiltonian(coeffs, obs_list)

def single_cost(self,params, state_idx=0):
self.ansatz(params,wires=range(num_qubits),state_idx=state_idx)
coeffs, obs_list = qml.pauli.conversion._generalized_pauli_decompose(self.HH)

obs_groupings = qml.pauli.group_observables(observables=obs_list, grouping_type="qwc", method="rlf")
H = qml.Hamiltonian(coeffs, obs_list)
return qml.expval(H)

def states(self, nq=None)->list:
if not nq:
nq = self.num_qubits
st = []
for i in range(2 ** nq):
formStr = '0' + repr(nq) + 'b'
st.append(format(i, formStr))
return st

def ansatz(self, params, wires, state_idx=0)-> None:
state = self.states(nq =self.num_qubits)

for ind_qb, qb in enumerate(list(state[state_idx])):
if qb =='1':
qml.PauliX(wires=wires[ind_qb])

qml.templates.StronglyEntanglingLayers(params, wires = range(self.num_qubits))

def total_cost(self,params, **kwargs):
single_cost = kwargs.get('single_cost')
w = kwargs.get('w')
cost = 0
for state_idx in range(2**self.num_qubits):
cost +=w[state_idx]*single_cost(params, state_idx=state_idx)
return cost

def run(self, params, max_iterations =1000, conv_tol = 1e-5, n_excited = 1, optimizer = 'Adam', opt_rate = 0.1,method= 'simple',processes=None):
self.n_excited = n_excited
self.max_iterations = max_iterations
self.conv_tol = conv_tol
self.params = params

coeffs, obs_list = qml.pauli.conversion._generalized_pauli_decompose(self.HH)

obs_groupings = qml.pauli.group_observables(observables=obs_list, grouping_type="qwc", method="rlf")
print("Number of required measurements after optimization", len(obs_groupings))

H = qml.Hamiltonian(coeffs, obs_list)

eigen,_ = np.linalg.eigh(self.HH)
energies = np.zeros(2)

if self.machine == "PennyLane_statevector":
self.dev = qml.device("default.qubit", wires = self.num_qubits)
elif self.machine == "PennyLane_simulator":
self.dev = qml.device("default.mixed", wires = self.num_qubits, shots= 1024)
elif self.machine == "qasm_Statevector":
self.dev = qml.device('qiskit.aer', wires=self.num_qubits, backened='aer_simulator_Statevector')

self.w = np.arange(2**self.num_qubits, 0, -1)

if method == "simple":
energy_optimized, ind, energies_during_opt = self.optimize(
params,optm = optimizer, opt_rate= opt_rate, conv_tol = self.conv_tol)

results = {
'energy_optimized': energy_optimized,
'param_optimized': params,
'all_energies': energies_during_opt,
'number_of_cycles': ind,
'convergence_tolerance': self.conv_tol
}

return results

def timing(f):
@wraps(f)
def wrap(self,*args,**kw):
ts=time()
result = f(self,*args,**kw)
te = time()
dt = te-ts
print('function_time'%(f.__name__,args,kw,te-ts))
self.time.append({'seconds': dt})
return result
return wrap

def optimize_conver(self,params,optm='Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm, opt_rate= opt_rate)
costs = []

conv = np.ones(self.n_excited +1)

KP_callback_energies = np.zeros(self.n_excited+1,self.max_iterations)

prev = np.ones(self.n_excited+1)* 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(
self.total_cost,self.params,single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params,single_cost= self.single_cost, w= self.w)

for exc in range(self.n_excited+1):
if conv[exc] == self.conv_tol:
en = self.single_cost(self.params, state_idx = exc)
conv[exc] = np.abs(en-prev[exc])
prev[exc] = en

KP_callback_energies[exc, i] = en

if i%1==0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', prev)

if np.all(conv = self.conv_tol):
break

print("optimization convergence after ",i,"cycles1")
energy_optimized = prev

return energy_optimized, i, KP_callback_energies

@timing
def optimize(self,params,optm = 'Adam', opt_rate = 0.1, conv_tol = 1e-3):
self.params = params
opt = self.optimizers(optm,opt_rate)
costs = []

conv = 10
KP_callback_energies = np.zeros((self.n_excited+1,self.max_iterations))
low_energy = 1e3
param_low_energy = params

prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost = self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w = self.w)
conv = np.abs(prev_energy - energy)

KP_callback_energies[0,i] = prev_energy

if energy < low_energy:
print('Energy lowered, Actual low energy = ', energy)
low_energy = energy
param_low_energy = self.params

if i%1 == 0:
print('iteration = ', i)
print('conv = ', conv)
print('energy = ', energy)

if(conv<= self.conv_tol):
break

print("optimization converged after ", i , "cycles1")

if energy > low_energy:
self.params = param_low_energy
print('Energy non_converged after maximum iterations... ')

energy_optimized = np.zeros(self.num_excited + 1)
for exc in range(self.num_excited+1):
energy_optimized[exc] = self.single_cost(self.params, state_idx = exc)

return energy_optimized, i, KP_callback_energies

@timing
self.params = params
opt = self.optimizers(optm, opt_rate = opt_rate)

costs = []

self.conv_tol_local = 1e-2
conv = 10

KP_callback_energies = []
en = np.zeros(self.n_excited+1)
prev = 1e3
for i in range(self.max_iterations):
self.params,prev_energy = opt.step_and_cost(self.total_cost, self.params, single_cost= self.single_cost, w= self.w)
energy = self.total_cost(self.params, single_cost = self.single_cost, w= self.w)

KP_callback_energies.append(energy)

if conv > self.conv_tol_local:
conv = np.abs(prev_energy = energy)
prev = energy
elif  (self.conv_tol_local > self.conv_tol and conv <= self.conv_tol_local):
opt_rate = opt_rate/2
self.conv_tol_local = self.conv_tol_local/10
opt = self.optimizers(optm,opt_rate = opt_rate)
conv = np.abs(prev_energy - energy)
prev = energy

elif self.conv_tol_local<= self.conv_tol and conv <= self.conv_tol:
for exc in range (self.n_excited +1):
en[exc] = self.single_cost(self.params, state_idx = exc)

if i%1 ==0:
print('iteration', i)
print('conv=', conv)
print('energy', energy)
print('step_size= ', opt_rate)
print('conv_tol_local = ', self.conv_tol_local)

print("optimization converged after ", i, "cycles1")
print("optimized energies ", en)
return en, i, KP_callback_energies

def optimizers(self, optm, opt_rate, eps=1e-8):

else:
raise ValueError("Unsupported optimizer: {}".format(optm))
return opt
``````

if name==‘main’:
num_layers = 5 # number of entangling layers of the ansatz
num_qubits = 2 # number of qubits
point_path = 1 # number of points in Brillouin Zone path
num_excited = num_qubits**2 - 1
params = np.random.uniform(low =0, high=2*np.pi, size=(num_layers, num_qubits,3))

for i in range(point_path):
VQE = SSVQE(index = i, verbose = 0, num_qubits= num_qubits,
num_excited = num_excited, npoints_path=point_path, machine = “PennyLane_statevector”,
num_layers = num_layers)
results = VQE.run(params, max_iterations = 2000,
conv_tol = 1e-4, optimizer = ‘Adam’, n_excited = num_excited, opt_rate = 0.01,
method = ‘simple’)
print(f"Results for point {i}: {results}")

In this program I took out the single_cost outside the run function
But it is showing error

File c:\users\kaushik das\untitled2.py:222 in total_cost
cost +=w[state_idx]*single_cost(params, state_idx=state_idx)

File ~\anaconda3\Lib\site-packages\pennylane\numpy\tensor.py:155 in array_ufunc
res = super().array_ufunc(ufunc, method, *args, **kwargs)

TypeError: unsupported operand type(s) for *: ‘int’ and ‘ExpectationMP’

Hi @Kaushik, thank you for your question.

Unfortunately your code is too big for me to be able to identify the issue.

Note that ExpectationMP is the return type for qml.expval() so the errors you’re getting indicate that you’re doing some unsupported processing with qml.expval().

In this code single_cost is returning ExpectationMP type value,

cost +=w[state_idx]*single_cost(params, state_idx=state_idx)

In this line we are multiplying an integer with ExpectationMP . w[state_idx] is returning int value. So it is showing error

TypeError:unsupported operand type(s) for *: ‘int’ and ‘ExpectationMP’

How can I solve this problem?