Source code for qiskit_nature.second_q.algorithms.initial_points.hf_initial_point

# This code is part of a Qiskit project.
#
# (C) Copyright IBM 2022, 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""The HFInitialPoint class to compute an initial point for the VQE Ansatz parameters."""

from __future__ import annotations

import warnings

import numpy as np

from qiskit_nature.second_q.problems import BaseProblem, ElectronicStructureProblem
from qiskit_nature.exceptions import QiskitNatureError
from qiskit_nature.second_q.circuit.library import UCC

from .initial_point import InitialPoint


[docs]class HFInitialPoint(InitialPoint): r"""Compute the Hartree-Fock (HF) initial point. A class that provides an all-zero initial point for the ``VQE`` parameter values. If used in concert with the :class:`~qiskit_nature.second_q.circuit.library.initial_states.hartree_fock.HartreeFock` initial state (which will be prepended to the :class:`~qiskit_nature.second_q.circuit.library.ansatzes.ucc.UCC` circuit) the all-zero initial point will correspond to the HF initial point. """ def __init__(self) -> None: super().__init__() self._ansatz: UCC | None = None self._reference_energy: float = 0.0 self._parameters: np.ndarray | None = None @property def ansatz(self) -> UCC: """The UCC ansatz. The ``excitation_list`` and ``reps`` used by the :class:`~qiskit_nature.circuit.library.ansatzes.ucc.UCC` ansatz is obtained to ensure that the shape of the initial point is appropriate. """ return self._ansatz @ansatz.setter def ansatz(self, ansatz: UCC) -> None: self._invalidate() self._ansatz = ansatz @property def problem(self) -> BaseProblem | None: """The problem. The problem is not required to compute the HF initial point. If it is provided we will attempt to obtain the HF ``reference_energy``. """ return self._problem @problem.setter def problem(self, problem: BaseProblem) -> None: if not isinstance(problem, ElectronicStructureProblem): raise QiskitNatureError( "Only an `ElectronicStructureProblem` is compatible with the HFInitialPoint, not a" f" problem of type, {type(problem)}." ) electronic_energy = problem.hamiltonian if electronic_energy is None: warnings.warn( "The ElectronicEnergy was not obtained from the problem. " "The problem and reference_energy will not be set." ) return self._reference_energy = problem.reference_energy if not None else 0.0 self._problem = problem
[docs] def to_numpy_array(self) -> np.ndarray: """The initial point as an array.""" if self._parameters is None: self.compute() return self._parameters
[docs] def compute( self, ansatz: UCC | None = None, problem: BaseProblem | None = None, ) -> None: """Compute the initial point parameter for each excitation. See class documentation for more information. Args: problem: The :attr:`problem`. ansatz: The :attr:`ansatz`. Raises: QiskitNatureError: If :attr:`ansatz` is not set. """ if problem is not None: self.problem = problem if ansatz is not None: self.ansatz = ansatz if self._ansatz is None: raise QiskitNatureError( "The ansatz property has not been set. " "Not enough information has been provided to compute the initial point. " "Set the ansatz or call compute with it as an argument. " ) self._compute()
def _compute(self) -> None: """Computes the HF initial point array for a given excitation list. In the Hartree-Fock case this is simply an all-zero array. Returns: An all-zero array with the same length as the excitation list. """ # Ansatz operators must be built to compute the excitation list. _ = self._ansatz.operators self._parameters = np.zeros( self._ansatz.reps * len(self._ansatz.excitation_list), dtype=float ) @property def total_energy(self) -> float: """The Hartree-Fock reference energy. If the reference energy was not obtained from :class:`~qiskit_nature.second_q.hamiltonians.ElectronicEnergy` this will be equal to zero. """ return self._reference_energy def _invalidate(self): """Invalidate any previous computation.""" self._parameters = None