def test_reuse(self): """Test re-using a VQE algorithm instance.""" vqe = VQE() with self.subTest(msg='assert running empty raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.run() var_form = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') vqe.var_form = var_form with self.subTest(msg='assert missing operator raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.run() vqe.operator = self.h2_op with self.subTest(msg='assert missing backend raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.run() vqe.quantum_instance = self.statevector_simulator with self.subTest(msg='assert VQE works once all info is available'): result = vqe.run() self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) operator = PrimitiveOp( np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) with self.subTest(msg='assert minimum eigensolver interface works'): result = vqe.compute_minimum_eigenvalue(operator) self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5)
def _compute_gradients(self, excitation_pool: List[PauliSumOp], theta: List[float], vqe: VQE, ) -> List[Tuple[float, PauliSumOp]]: """ Computes the gradients for all available excitation operators. Args: excitation_pool: pool of excitation operators theta: list of (up to now) optimal parameters vqe: the variational quantum eigensolver instance used for solving Returns: List of pairs consisting of gradient and excitation operator. """ res = [] # compute gradients for all excitation in operator pool for exc in excitation_pool: # push next excitation to variational form vqe.var_form.push_hopping_operator(exc) # NOTE: because we overwrite the var_form inside of the VQE, we need to update the VQE's # internal _var_form_params, too. We can do this by triggering the var_form setter. Once # the VQE does not store this pure var_form property any longer this can be removed. vqe.var_form = vqe.var_form # We also need to invalidate the internally stored expectation operator because it needs # to be updated for the new var_form. vqe._expect_op = None # evaluate energies parameter_sets = theta + [-self._delta] + theta + [self._delta] energy_results = vqe._energy_evaluation(np.asarray(parameter_sets)) # compute gradient gradient = (energy_results[0] - energy_results[1]) / (2 * self._delta) res.append((np.abs(gradient), exc)) # pop excitation from variational form vqe.var_form.pop_hopping_operator() return res