Exemple #1
0
    def test_hhl(self, matrix, right_hand_side, observable):
        """Test the HHL class."""
        if isinstance(matrix, QuantumCircuit):
            num_qubits = matrix.num_state_qubits
        elif isinstance(matrix, np.ndarray):
            num_qubits = int(np.log2(matrix.shape[0]))

        rhs = right_hand_side / np.linalg.norm(right_hand_side)

        # Initial state circuit
        qc = QuantumCircuit(num_qubits)
        qc.isometry(rhs, list(range(num_qubits)), None)

        hhl = HHL()
        solution = hhl.solve(matrix, qc, observable)
        approx_result = solution.observable

        # Calculate analytical value
        if isinstance(matrix, QuantumCircuit):
            exact_x = np.dot(np.linalg.inv(matrix.matrix), rhs)
        elif isinstance(matrix, np.ndarray):
            exact_x = np.dot(np.linalg.inv(matrix), rhs)
        exact_result = observable.evaluate_classically(exact_x)

        np.testing.assert_almost_equal(approx_result, exact_result, decimal=2)
Exemple #2
0
    def test_hhl_qi(self):
        """Test the HHL quantum instance getter and setter."""
        hhl = HHL()
        self.assertIsNone(hhl.quantum_instance)  # Defaults to None

        # First set a valid quantum instance and check via getter
        qinst = QuantumInstance(backend=BasicAer.get_backend("qasm_simulator"))
        hhl.quantum_instance = qinst
        self.assertEqual(hhl.quantum_instance, qinst)

        # Now set quantum instance back to None and check via getter
        hhl.quantum_instance = None
        self.assertIsNone(hhl.quantum_instance)
# ```python
# LinearSolver(...).solve(matrix, vector)
# ```
#
# The simplest implementation takes the matrix and the vector as NumPy arrays. Below we also create a `NumPyLinearSolver` (the classical algorithm) to validate our solutions.

# In[1]:

###### see this link to setup Qiskit --> https://qiskit.org/textbook/ch-prerequisites/setting-the-environment.html #####

import numpy as np
from qiskit.algorithms.linear_solvers.numpy_linear_solver import NumPyLinearSolver
from qiskit.algorithms.linear_solvers.hhl import HHL
matrix = np.array([[1, -1 / 3], [-1 / 3, 1]])
vector = np.array([1, 0])
naive_hhl_solution = HHL().solve(matrix, vector)

# For the classical solver we need to rescale the right hand side (i.e. `vector / np.linalg.norm(vector)`) to take into account the renormalisation that occurs once `vector` is encoded in a quantum state within HHL.

# In[2]:

classical_solution = NumPyLinearSolver().solve(matrix,
                                               vector / np.linalg.norm(vector))

# The `linear_solvers` package contains a folder called `matrices` intended to be a placeholder for efficient implementations of particular types of matrices. At the time of writing the only truly efficient implementation it contains (i.e. complexity scaling polynomially in the number of qubits) is the `TridiagonalToeplitz` class. Tridiagonal Toeplitz symmetric real matrices are of the following form
# $$A = \begin{pmatrix}a & b & 0 & 0\\b & a & b & 0 \\ 0 & b & a & b \\ 0 & 0 & b & a \end{pmatrix}, a,b\in\mathbb{R}$$
# (note that in this setting we do not consider non symmetric matrices since the HHL algorithm assumes that the input matrix is Hermitian).
#
# Since the matrix $A$ from our example is of this form we can create an instance of `TridiagonalToeplitz(num_qubits, a, b)` and compare the results to solving the system with an array as input.

# In[3]: