def _compute_gradients( self, theta: List[float], vqe: VQE, ) -> List[Tuple[float, PauliSumOp]]: """ Computes the gradients for all available excitation operators. Args: 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 self._excitation_pool: # add next excitation to ansatz self._ansatz.operators = self._excitation_list + [exc] # set the current ansatz vqe.ansatz = self._ansatz ansatz_params = vqe.ansatz._parameter_table.keys() # construct the expectation operator of the VQE vqe._expect_op = vqe.construct_expectation(ansatz_params, self._main_operator) # 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)) return res
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