Source code for qiskit_algorithms.minimum_eigensolvers.numpy_minimum_eigensolver

# 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
# 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 NumPy minimum eigensolver algorithm and result."""

from __future__ import annotations

from typing import Callable, Union, Tuple, Dict, List, Optional
import logging
import numpy as np

from qiskit.quantum_info import Statevector
from qiskit.quantum_info.operators.base_operator import BaseOperator

from ..eigensolvers.numpy_eigensolver import NumPyEigensolver
from .minimum_eigensolver import MinimumEigensolver, MinimumEigensolverResult
from ..list_or_dict import ListOrDict

logger = logging.getLogger(__name__)

# future type annotations not supported in type aliases in 3.8
FilterType = Callable[
    [Union[List, np.ndarray], float, Optional[ListOrDict[Tuple[float, Dict[str, float]]]]], bool

[docs]class NumPyMinimumEigensolver(MinimumEigensolver): """ The NumPy minimum eigensolver algorithm. """ def __init__( self, filter_criterion: FilterType | None = None, ) -> None: """ Args: filter_criterion: Callable that allows to filter eigenvalues/eigenstates. The minimum eigensolver is only searching over feasible states and returns an eigenstate that has the smallest eigenvalue among feasible states. The callable has the signature ``filter(eigenstate, eigenvalue, aux_values)`` and must return a boolean to indicate whether to consider this value or not. If there is no feasible element, the result can even be empty. """ self._eigensolver = NumPyEigensolver(filter_criterion=filter_criterion) @property def filter_criterion( self, ) -> FilterType | None: """Returns the criterion for filtering eigenstates/eigenvalues.""" return self._eigensolver.filter_criterion @filter_criterion.setter def filter_criterion( self, filter_criterion: FilterType, ) -> None: self._eigensolver.filter_criterion = filter_criterion
[docs] @classmethod def supports_aux_operators(cls) -> bool: return NumPyEigensolver.supports_aux_operators()
[docs] def compute_minimum_eigenvalue( self, operator: BaseOperator, aux_operators: ListOrDict[BaseOperator] | None = None, ) -> NumPyMinimumEigensolverResult: super().compute_minimum_eigenvalue(operator, aux_operators) eigensolver_result = self._eigensolver.compute_eigenvalues(operator, aux_operators) result = NumPyMinimumEigensolverResult() if eigensolver_result.eigenvalues is not None and len(eigensolver_result.eigenvalues) > 0: result.eigenvalue = eigensolver_result.eigenvalues[0] result.eigenstate = eigensolver_result.eigenstates[0] if eigensolver_result.aux_operators_evaluated: result.aux_operators_evaluated = eigensolver_result.aux_operators_evaluated[ 0 ] # type: ignore[assignment] logger.debug("NumPy minimum eigensolver result: %s", result) return result
[docs]class NumPyMinimumEigensolverResult(MinimumEigensolverResult): """NumPy minimum eigensolver result.""" def __init__(self) -> None: super().__init__() self._eigenstate: Statevector | None = None @property def eigenstate(self) -> Statevector | None: """Returns the eigenstate corresponding to the computed minimum eigenvalue.""" return self._eigenstate @eigenstate.setter def eigenstate(self, value: Statevector) -> None: self._eigenstate = value