class TestLinearSolver(QiskitAlgorithmsTestCase): """Tests based on the linear solvers classes. This class tests * the constructed circuits """ @idata([[ TridiagonalToeplitz(2, 1, 1 / 3, trotter_steps=2), [1.0, -2.1, 3.2, -4.3], MatrixFunctional(1, 1 / 2) ], [ np.array([[1 / 2, 1 / 6, 0, 0], [1 / 6, 1 / 2, 1 / 6, 0], [0, 1 / 6, 1 / 2, 1 / 6], [0, 0, 1 / 6, 1 / 2]]), [1.0, -2.1, 3.2, -4.3], MatrixFunctional(1, 1 / 2) ], [ TridiagonalToeplitz(3, 1, -1 / 2, trotter_steps=2), [-9 / 4, -0.3, 8 / 7, 10, -5, 11.1, 13 / 11, -27 / 12], AbsoluteAverage() ]]) @unpack 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)
class TestObservables(QiskitAlgorithmsTestCase): """Tests based on the observables classes. This class tests * the constructed circuits """ @idata([[AbsoluteAverage(), [1.0, -2.1, 3.2, -4.3]], [ AbsoluteAverage(), [-9 / 4, -0.3, 8 / 7, 10, -5, 11.1, 13 / 11, -27 / 12] ]]) @unpack def test_absolute_average(self, observable, vector): """Test the absolute average observable.""" init_state = vector / np.linalg.norm(vector) num_qubits = int(np.log2(len(vector))) qc = QuantumCircuit(num_qubits) qc.isometry(init_state, list(range(num_qubits)), None) qc.append(observable.observable_circuit(num_qubits), list(range(num_qubits))) # Observable operator observable_op = observable.observable(num_qubits) state_vec = (~StateFn(observable_op) @ StateFn(qc)).eval() # Obtain result result = observable.post_processing(state_vec, num_qubits) # Obtain analytical evaluation exact = observable.evaluate_classically(init_state) np.testing.assert_almost_equal(result, exact, decimal=2) @idata([[MatrixFunctional(1, -1 / 3), [1.0, -2.1, 3.2, -4.3]], [ MatrixFunctional(2 / 3, 11 / 7), [-9 / 4, -0.3, 8 / 7, 10, -5, 11.1, 13 / 11, -27 / 12] ]]) @unpack def test_matrix_functional(self, observable, vector): """Test the matrix functional class.""" from qiskit.transpiler.passes import RemoveResetInZeroState tpass = RemoveResetInZeroState() init_state = vector / np.linalg.norm(vector) num_qubits = int(np.log2(len(vector))) # Get observable circuits obs_circuits = observable.observable_circuit(num_qubits) qcs = [] for obs_circ in obs_circuits: qc = QuantumCircuit(num_qubits) qc.isometry(init_state, list(range(num_qubits)), None) qc.append(obs_circ, list(range(num_qubits))) qcs.append(tpass(qc.decompose())) # Get observables observable_ops = observable.observable(num_qubits) state_vecs = [] # First is the norm state_vecs.append( (~StateFn(observable_ops[0]) @ StateFn(qcs[0])).eval()) for i in range(1, len(observable_ops), 2): state_vecs += [ (~StateFn(observable_ops[i]) @ StateFn(qcs[i])).eval(), (~StateFn(observable_ops[i + 1]) @ StateFn(qcs[i + 1])).eval() ] # Obtain result result = observable.post_processing(state_vecs, num_qubits) # Obtain analytical evaluation exact = observable.evaluate_classically(init_state) np.testing.assert_almost_equal(result, exact, decimal=2)
class TestLinearSolver(QiskitAlgorithmsTestCase): """Tests based on the linear solvers classes. This class tests * the constructed circuits """ @idata([ [ TridiagonalToeplitz(2, 1, 1 / 3, trotter_steps=2), [1.0, -2.1, 3.2, -4.3], MatrixFunctional(1, 1 / 2), ], [ np.array([[0, 0, 1.585, 0], [0, 0, -0.585, 1], [1.585, -0.585, 0, 0], [0, 1, 0, 0]]), [1.0, 0, 0, 0], MatrixFunctional(1, 1 / 2), ], [ [ [1 / 2, 1 / 6, 0, 0], [1 / 6, 1 / 2, 1 / 6, 0], [0, 1 / 6, 1 / 2, 1 / 6], [0, 0, 1 / 6, 1 / 2], ], [1.0, -2.1, 3.2, -4.3], MatrixFunctional(1, 1 / 2), ], [ np.array([[82, 34], [34, 58]]), np.array([[1], [0]]), AbsoluteAverage(), 3, ], [ TridiagonalToeplitz(3, 1, -1 / 2, trotter_steps=2), [-9 / 4, -0.3, 8 / 7, 10, -5, 11.1, 13 / 11, -27 / 12], AbsoluteAverage(), ], ]) @unpack def test_hhl(self, matrix, right_hand_side, observable, decimal=1): """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])) elif isinstance(matrix, list): num_qubits = int(np.log2(len(matrix))) 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, (list, np.ndarray)): if isinstance(matrix, list): matrix = np.array(matrix) 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=decimal) 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)