Пример #1
0
    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)
Пример #2
0
    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