Error al ejecutar el algoritmo HHL en Qiskit

Oct 12 2020

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

2 MartinVesely Oct 20 2020 at 20:34

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 .