Error al ejecutar el algoritmo HHL en Qiskit
Intenté resolver un sistema simple de dos ecuaciones lineales simultáneas con el algoritmo HHL en Qiskit. En particular, el sistema es$Ax=b$, dónde $$ A = \begin{pmatrix} 1.5 & 0.5 \\ 0.5 & 1.5 \end{pmatrix} $$ y $$ b = \begin{pmatrix} 0.9010 \\ -0.4339 \end{pmatrix} $$ La matriz $A$ es hermitiano, por lo que HHL debería afrontarlo sin problemas.
Escribí el siguiente código
%matplotlib inline
# Importing standard Qiskit libraries and configuring account
from qiskit import QuantumCircuit, execute, Aer, IBMQ
import numpy as np
from qiskit.compiler import transpile, assemble
from qiskit.tools.jupyter import *
from qiskit.visualization import *
#HHL in Qiskit
from qiskit.aqua.algorithms import HHL
matrix_A = np.array([[1.5, 0.5],[0.5, 1.5]])
vector_b = [0.9010, -0.4339]
#x = [0.8184, -0.5747] #expected result
backend = Aer.get_backend('statevector_simulator')
#num_q – Number of qubits required for the matrix Operator instance
#num_a – Number of ancillary qubits for Eigenvalues instance
hhlObject = HHL(matrix = matrix_A, vector = vector_b, quantum_instance = backend, num_q = 2, num_a = 1)
res = hhlObject.run(quantum_instance = backend)
print(res)
Sin embargo, este error ocurrió
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-4-071684a21c97> in <module>
9 hhlObject = HHL(matrix = matrix_A, vector = vector_b, quantum_instance = backend, num_q = 2, num_a = 1)
10
---> 11 res = hhlObject.run(quantum_instance = backend)
12 print(res)
/opt/conda/lib/python3.7/site-packages/qiskit/aqua/algorithms/quantum_algorithm.py in run(self, quantum_instance, **kwargs)
68 self.quantum_instance = quantum_instance
69
---> 70 return self._run()
71
72 @abstractmethod
/opt/conda/lib/python3.7/site-packages/qiskit/aqua/algorithms/linear_solvers/hhl.py in _run(self)
399 def _run(self):
400 if self._quantum_instance.is_statevector:
--> 401 self.construct_circuit(measurement=False)
402 self._statevector_simulation()
403 else:
/opt/conda/lib/python3.7/site-packages/qiskit/aqua/algorithms/linear_solvers/hhl.py in construct_circuit(self, measurement)
204
205 # InitialState
--> 206 qc += self._init_state.construct_circuit("circuit", q)
207
208 # EigenvalueEstimation (QPE)
AttributeError: 'NoneType' object has no attribute 'construct_circuit'
También intenté ejecutar el construct_circuitmétodo antes que el runmétodo, sin embargo, se devolvió el mismo error.
¿Podría decirme cómo configurar los parámetros del algoritmo HHL para ejecutarlo correctamente?
Respuestas
Sobre la base de tsgeorgios información sobre el manual Qiskit y el contenido del manual, creé el código debajo de la cual funciona como se esperaba.
#BASED ON: https://qiskit.org/textbook/ch-applications/hhl_tutorial.html#4.-Qiskit-Implementation
%matplotlib inline
# Importing standard Qiskit libraries and configuring account
from qiskit import Aer
from qiskit.circuit.library import QFT
from qiskit.aqua.components.eigs import EigsQPE
from qiskit.aqua.components.reciprocals import LookupRotation
from qiskit.aqua.operators import MatrixOperator
from qiskit.aqua.components.initial_states import Custom
import numpy as np
#Linear equations solvers
from qiskit.aqua.algorithms import HHL, NumPyLSsolver #HHL - quantum, NumPyLSolver - classical
def create_eigs(matrix, num_ancillae, num_time_slices, negative_evals):
ne_qfts = [None, None]
if negative_evals:
num_ancillae += 1
ne_qfts = [QFT(num_ancillae - 1), QFT(num_ancillae - 1).inverse()]
#Construct the eigenvalues estimation using the PhaseEstimationCircuit
return EigsQPE(MatrixOperator(matrix=matrix),
QFT(num_ancillae).inverse(),
num_time_slices=num_time_slices,
num_ancillae=num_ancillae,
expansion_mode='suzuki',
expansion_order=2,
evo_time=None,
negative_evals=negative_evals,
ne_qfts=ne_qfts)
def HHLsolver(matrix, vector, backend, no_ancillas, no_time_slices):
orig_size = len(vector_b)
#adapt the matrix to have dimension 2^k
matrix, vector, truncate_powerdim, truncate_hermitian = HHL.matrix_resize(matrix_A, vector_b)
#find eigenvalues of the matrix wih phase estimation (i.e. calc. exponential of A, apply
#phase estimation) to get exp(lamba) and then inverse QFT to get lambdas themselves
eigs = create_eigs(matrix, no_ancillas, no_time_slices, False)
#num_q – Number of qubits required for the matrix Operator instance
#num_a – Number of ancillary qubits for Eigenvalues instance
num_q, num_a = eigs.get_register_sizes()
#construct circuit for finding reciprocals of eigenvalues
reci = LookupRotation(negative_evals=eigs._negative_evals, evo_time=eigs._evo_time)
#preparing init state for HHL, i.e. the state containing vector b
init_state = Custom(num_q, state_vector=vector)
#construct circuit for HHL based on matrix A, vector B and reciprocals of eigenvalues
algo = HHL(matrix, vector, truncate_powerdim, truncate_hermitian, eigs,
init_state, reci, num_q, num_a, orig_size)
#solution on quantum computer
result = algo.run(quantum_instance = backend)
print("Solution:\t\t", np.round(result['solution'], 5))
print("Probability:\t\t %f" % result['probability_result'])
#refence solution - NumPyLSsolver = Numpy LinearSystem algorithm (classical).
result_ref = NumPyLSsolver(matrix, vector).run()
print("Classical Solution:\t", np.round(result_ref['solution'], 5))
matrix_A = np.array([[1.5, 0.5],[0.5, 1.5]])
vector_b = [0.9010, -0.4339]
#x = A^(-1)b = [0.78420, -0.55066] #expected result
processor = Aer.get_backend('statevector_simulator')
no_ancillas = 3 #number of ancilla qubits
no_time_slices = 50 #number of timeslices in exponential of matrix A (exp(i*A*t))
HHLsolver(matrix_A, vector_b, processor, no_ancillas, no_time_slices)
Reconocimiento: el código se basa en el manual de Qiskit en HHL .