2
$\begingroup$

I tried to solve a simple system of two simultaneous linear equations in with HHL algorithm in Qiskit. In particular the system is $Ax=b$, where $$ A = \begin{pmatrix} 1.5 & 0.5 \\ 0.5 & 1.5 \end{pmatrix} $$ and $$ b = \begin{pmatrix} 0.9010 \\ -0.4339 \end{pmatrix} $$ The matrix $A$ is Hermitian, so HHL should cope with it without any problems.

I wrote following code

%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)

However, this error occured

---------------------------------------------------------------------------
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'

I also tried to run construct_circuit method before run method, however, same error was returned.

Could you please tell me how to set parameters of HHL algorithm to run it correctly?

$\endgroup$
2
  • 1
    $\begingroup$ Have you read the corresponding chapter in Qiskit textbook? qiskit.org/textbook/ch-applications/hhl_tutorial.html It may be helpful. $\endgroup$
    – tsgeorgios
    Commented Oct 16, 2020 at 14:53
  • $\begingroup$ @tsgeorgios: Thanks for directing me here. It helped. Please feel free to post the comment as an answer to get the bounty. I will provide my code below. $\endgroup$ Commented Oct 20, 2020 at 13:30

1 Answer 1

3
$\begingroup$

Based on tsgeorgios information about Qiskit manual and the manual content, I created the code below which works as expected.

#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)

Acknowledgement: The code is based on Qiskit manual on HHL.

$\endgroup$
1
  • 1
    $\begingroup$ nice. thanks for posting the code. +1 $\endgroup$
    – KAJ226
    Commented Oct 20, 2020 at 19:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.