Hi Eric, thanks for the reply
Sorry for sending long code like this. But I think I still don’t understand how the workflow works in Perceval. Any help in this regard will be valuable.
# imports
from tqdm.auto import tqdm
import perceval as pcvl
import qutip as qt
import numpy as np
from scipy.optimize import minimize
import random
import math
import matplotlib.pyplot as plt
simulator = pcvl.Simulator(pcvl.NaiveBackend())
# variational circuit from qiskit
from qiskit import QuantumCircuit
import numpy as np
from perceval.converters import QiskitConverter
from perceval.components import catalog
def ansatz(params, qubits=4, depth=2):
# Inicializando o circuito
qc = QuantumCircuit(qubits)
# Aplicando rotações iniciais (RY) com os parâmetros
for q in range(qubits):
qc.ry(params[q], q)
# Construindo as camadas de entanglement e rotações
for d in range(1, depth + 1):
# Aplicando CNOTs para entanglement
for q in range(qubits - 1):
qc.cx(q, q + 1)
# Aplicando rotações adicionais (RY) com novos parâmetros
for q in range(qubits):
qc.ry(params[d * qubits + q], q)
return qc
# Exemplo de uso
qubits = 4
depth = 2
# Gerando parâmetros aleatórios para o exemplo
params = np.random.rand(depth * qubits + qubits) * 2 * np.pi
# Construindo o circuito com o ansatz
circuit = ansatz(params, qubits, depth)
# Desenhando o circuito
circuit.draw(output='mpl')
qiskit_convertor = QiskitConverter(catalog)
VQE_ansatz = qiskit_convertor.convert(circuit)
pcvl.pdisplay(VQE_ansatz)
# parameters
List_Parameters=[]
theta1 = pcvl.P("theta1", min_v=0, max_v=2*math.pi, periodic=True)
theta2 = pcvl.P("theta2", min_v=0, max_v=2*math.pi, periodic=True)
theta3 = pcvl.P("theta3", min_v=0, max_v=2*math.pi, periodic=True)
theta4 = pcvl.P("theta4", min_v=0, max_v=2*math.pi, periodic=True)
theta5 = pcvl.P("theta5", min_v=0, max_v=2*math.pi, periodic=True)
theta6 = pcvl.P("theta6", min_v=0, max_v=2*math.pi, periodic=True)
theta7 = pcvl.P("theta7", min_v=0, max_v=2*math.pi, periodic=True)
theta8 = pcvl.P("theta8", min_v=0, max_v=2*math.pi, periodic=True)
theta9 = pcvl.P("theta9", min_v=0, max_v=2*math.pi, periodic=True)
theta10 = pcvl.P("theta10", min_v=0, max_v=2*math.pi, periodic=True)
theta11 = pcvl.P("theta11", min_v=0, max_v=2*math.pi, periodic=True)
theta12 = pcvl.P("theta12", min_v=0, max_v=2*math.pi, periodic=True)
List_Parameters.append(pcvl.Parameter("theta1"))
List_Parameters.append(pcvl.Parameter("theta2"))
List_Parameters.append(pcvl.Parameter("theta3"))
List_Parameters.append(pcvl.Parameter("theta4"))
List_Parameters.append(pcvl.Parameter("theta5"))
List_Parameters.append(pcvl.Parameter("theta6"))
List_Parameters.append(pcvl.Parameter("theta7"))
List_Parameters.append(pcvl.Parameter("theta8"))
List_Parameters.append(pcvl.Parameter("theta9"))
List_Parameters.append(pcvl.Parameter("theta10"))
List_Parameters.append(pcvl.Parameter("theta11"))
List_Parameters.append(pcvl.Parameter("theta12"))
# states
#Input states of the photonic circuit
input_states = {
pcvl.BasicState([1,0,1,0,1,0,1,0]):"|0000>"}
#Outputs in the computational basis
output_states = {
pcvl.BasicState([1,0,1,0,1,0,1,0]):"|0000>",
pcvl.BasicState([1,0,1,0,1,0,0,1]):"|0001>",
pcvl.BasicState([1,0,1,0,0,1,1,0]):"|0010>",
pcvl.BasicState([1,0,1,0,0,1,0,1]):"|0011>",
pcvl.BasicState([1,0,0,1,1,0,1,0]):"|0100>",
pcvl.BasicState([1,0,0,1,1,0,0,1]):"|0101>",
pcvl.BasicState([1,0,0,1,0,1,1,0]):"|0110>",
pcvl.BasicState([1,0,0,1,0,1,0,1]):"|0111>",
pcvl.BasicState([0,1,1,0,1,0,1,0]):"|1000>",
pcvl.BasicState([0,1,1,0,1,0,0,1]):"|1001>",
pcvl.BasicState([0,1,1,0,0,1,1,0]):"|1010>",
pcvl.BasicState([0,1,1,0,0,1,0,1]):"|1011>",
pcvl.BasicState([0,1,0,1,1,0,1,0]):"|1100>",
pcvl.BasicState([0,1,0,1,1,0,0,1]):"|1101>",
pcvl.BasicState([0,1,0,1,0,1,1,0]):"|1110>",
pcvl.BasicState([0,1,0,1,0,1,0,1]):"|1111>"}
# hamiltonian
H_coef = np.matrix([0.15678558607249998, # ZIII
0.028064070963899998, # IZII
0.056759040681399996, # IIZI
0.14976534056, # IIIZ
0.5001297664055, # ZZII
0.5000901235775, # ZIZI
0.5001608621845, # ZIIZ
0.5000371605536, # IZZI
0.5001139557625, # IZIZ
0.500068957711]) # IIZZ
# representação matricial do hamiltoniano
Z = np.array([[1,0],[0,-1]])
I = np.identity(2)
II = np.kron(I,I)
IZ = np.kron(I,Z)
ZI = np.kron(Z,I)
ZZ = np.kron(Z,Z)
Z0 = np.kron(ZI,II)
Z1 = np.kron(IZ,II)
Z2 = np.kron(II,ZI)
Z3 = np.kron(II,IZ)
Z0_Z1 = np.kron(ZZ,II)
Z0_Z2 = np.kron(ZI,ZI)
Z0_Z3 = np.kron(ZI,IZ)
Z1_Z2 = np.kron(IZ,ZI)
Z1_Z3 = np.kron(IZ,ZI)
Z2_Z3 = np.kron(II,ZZ)
H_elem = np.array([Z0, Z1, Z2, Z3, Z0_Z1, Z0_Z2, Z0_Z3, Z1_Z2, Z1_Z3, Z2_Z3])
H_coef = np.array([0.15678558607249998, 0.028064070963899998, 0.056759040681399996,
0.14976534056, 0.5001297664055, 0.5000901235775,
0.5001608621845, 0.5000371605536, 0.5001139557625,
0.500068957711])
Z = np.array([[1, 0], [0, -1]])
I = np.identity(2)
II = np.kron(I, I)
IZ = np.kron(I, Z)
ZI = np.kron(Z, I)
ZZ = np.kron(Z, Z)
Z0 = np.kron(ZI, II)
Z1 = np.kron(IZ, II)
Z2 = np.kron(II, ZI)
Z3 = np.kron(II, IZ)
Z0_Z1 = np.kron(ZZ, II)
Z0_Z2 = np.kron(ZI, ZI)
Z0_Z3 = np.kron(ZI, IZ)
Z1_Z2 = np.kron(IZ, ZI)
Z1_Z3 = np.kron(IZ, IZ)
Z2_Z3 = np.kron(II, ZZ)
H_elem = np.array([Z0, Z1, Z2, Z3, Z0_Z1, Z0_Z2, Z0_Z3, Z1_Z2, Z1_Z3, Z2_Z3])
H = np.sum([H_coef[i] * H_elem[i] for i in range(len(H_coef))], axis=0)
# loss function
def minimize_loss(lp=None):
# Updating the parameters on the chip
for idx, p in enumerate(lp):
List_Parameters[idx].set_value(p)
#Simulation, Quantum processing part of the VQE
simulator.set_circuit(VQE_ansatz)
# Collecting the output state of the circuit
psi = []
for input_state in input_states:
for output_state in output_states:
psi.append(simulator.prob_amplitude(input_state,output_state))
#Evaluating the mean value of the Hamiltonian. # The Hamiltonians H is defined in the following block
psi_prime=np.dot(H,psi)
loss = np.real(sum(sum(np.conjugate(psi)*np.array(psi_prime[0]))))/(sum([i*np.conjugate(i) for i in psi]))
loss=np.real(loss)
tq.set_description('%g / %g loss function=%g' % (R, len(H), loss))
return(loss)
# optimization process
tq = tqdm(desc='Minimizing...') #Displaying progress bar
E =[]
init_param=[]
H
if len(init_param) == 0:
init_param = [2*np.pi*random.random() for _ in List_Parameters]
else:
for i in range(len(init_param)):
init_param[i] = VQE_ansatz.get_parameters()[i]._value
# Finding the ground state eigen value of H
result = minimize(minimize_loss, init_param, method='Nelder-Mead')
E1.append(result.get('fun'))
tq.set_description('Finished' )
print(E)
Obrigado,
Ramses