Skip to content

Commit

Permalink
Create Eigensolver interface (qiskit-community/qiskit-aqua#1277)
Browse files Browse the repository at this point in the history
  • Loading branch information
manoelmarques authored Sep 28, 2020
1 parent 87a7fd4 commit 5127aa7
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 12 deletions.
10 changes: 9 additions & 1 deletion qiskit/aqua/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@
states of a molecule and qiskit.chemistry has some algorithms that leverage chemistry specific
knowledge to do this in that application domain.
.. autosummary::
:toctree: ../stubs/
:nosignatures:
Eigensolver
EigensolverResult
.. autosummary::
:toctree: ../stubs/
:nosignatures:
Expand Down Expand Up @@ -197,7 +204,7 @@
MaximumLikelihoodAmplitudeEstimationResult)
from .classifiers import VQC, QSVM, SklearnSVM, SVM_Classical
from .distribution_learners import QGAN
from .eigen_solvers import NumPyEigensolver, ExactEigensolver, EigensolverResult
from .eigen_solvers import NumPyEigensolver, ExactEigensolver, Eigensolver, EigensolverResult
from .factorizers import Shor
from .linear_solvers import (LinearsolverResult, HHL,
HHLResult, NumPyLSsolver,
Expand All @@ -223,6 +230,7 @@
'LinearsolverResult',
'NumPyLSsolver',
'NumPyLSsolverResult',
'Eigensolver',
'EigensolverResult',
'ExactLSsolver',
'NumPyMinimumEigensolver',
Expand Down
3 changes: 2 additions & 1 deletion qiskit/aqua/algorithms/eigen_solvers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
""" Eigen Solvers Package """

from .numpy_eigen_solver import NumPyEigensolver, ExactEigensolver
from .eigen_solver_result import EigensolverResult
from .eigen_solver import Eigensolver, EigensolverResult

__all__ = ['NumPyEigensolver',
'ExactEigensolver',
'Eigensolver',
'EigensolverResult']
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,84 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""The Eigensolver result."""
"""The Eigensolver interface"""

import warnings
from typing import Dict, Optional
import numpy as np
from abc import ABC, abstractmethod
from typing import List, Optional, Union, Dict

import numpy as np
from qiskit.aqua.algorithms import AlgorithmResult
from qiskit.aqua.operators import OperatorBase, LegacyBaseOperator


class Eigensolver(ABC):
"""The Eigensolver Interface.
Algorithms that can compute eigenvalues for an operator
may implement this interface to allow different algorithms to be
used interchangeably.
"""

@abstractmethod
def compute_eigenvalues(
self,
operator: Optional[Union[OperatorBase, LegacyBaseOperator]] = None,
aux_operators: Optional[List[Optional[Union[OperatorBase,
LegacyBaseOperator]]]] = None
) -> 'EigensolverResult':
"""
Computes eigenvalues. Operator and aux_operators can be supplied here and
if not None will override any already set into algorithm so it can be reused with
different operators. While an operator is required by algorithms, aux_operators
are optional. To 'remove' a previous aux_operators array use an empty list here.
Args:
operator: If not None replaces operator in algorithm
aux_operators: If not None replaces aux_operators in algorithm
Returns:
EigensolverResult
"""
if operator is not None:
self.operator = operator # type: ignore
if aux_operators is not None:
self.aux_operators = aux_operators if aux_operators else None # type: ignore
return EigensolverResult()

def supports_aux_operators(self) -> bool:
"""Whether computing the expectation value of auxiliary operators is supported.
Returns:
True if aux_operator expectations can be evaluated, False otherwise
"""
return False

@property # type: ignore
@abstractmethod
def operator(self) -> Optional[Union[OperatorBase, LegacyBaseOperator]]:
"""Return the operator."""
raise NotImplementedError

@operator.setter # type: ignore
@abstractmethod
def operator(self, operator: Union[OperatorBase, LegacyBaseOperator]) -> None:
"""Set the operator."""
raise NotImplementedError

@property # type: ignore
@abstractmethod
def aux_operators(self) -> Optional[List[Optional[OperatorBase]]]:
"""Returns the auxiliary operators."""
raise NotImplementedError

@aux_operators.setter # type: ignore
@abstractmethod
def aux_operators(self,
aux_operators: Optional[List[Optional[Union[OperatorBase,
LegacyBaseOperator]]]]) -> None:
"""Set the auxiliary operators."""
raise NotImplementedError


class EigensolverResult(AlgorithmResult):
Expand Down
18 changes: 11 additions & 7 deletions qiskit/aqua/algorithms/eigen_solvers/numpy_eigen_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
from qiskit.aqua.algorithms import ClassicalAlgorithm
from qiskit.aqua.operators import OperatorBase, LegacyBaseOperator, I, StateFn, ListOp
from qiskit.aqua.utils.validation import validate_min
from .eigen_solver_result import EigensolverResult
from .eigen_solver import Eigensolver, EigensolverResult

logger = logging.getLogger(__name__)


# pylint: disable=invalid-name


class NumPyEigensolver(ClassicalAlgorithm):
class NumPyEigensolver(ClassicalAlgorithm, Eigensolver):
r"""
The NumPy Eigensolver algorithm.
Expand Down Expand Up @@ -74,20 +74,17 @@ def __init__(self,

@property
def operator(self) -> Optional[OperatorBase]:
""" returns operator """
return self._operator

@operator.setter
def operator(self, operator: Union[OperatorBase, LegacyBaseOperator]) -> None:
""" set operator """
if isinstance(operator, LegacyBaseOperator):
operator = operator.to_opflow()
self._operator = operator
self._check_set_k()

@property
def aux_operators(self) -> Optional[List[Optional[OperatorBase]]]:
""" returns aux operators """
return self._aux_operators

@aux_operators.setter
Expand All @@ -97,7 +94,6 @@ def aux_operators(self,
LegacyBaseOperator,
List[Optional[Union[OperatorBase,
LegacyBaseOperator]]]]]) -> None:
""" Set aux operators """
if aux_operators is None:
aux_operators = []
elif not isinstance(aux_operators, list):
Expand Down Expand Up @@ -126,7 +122,6 @@ def k(self, k: int) -> None:
self._check_set_k()

def supports_aux_operators(self) -> bool:
""" If will process auxiliary operators or not """
return True

def _check_set_k(self) -> None:
Expand Down Expand Up @@ -201,6 +196,15 @@ def _eval_aux_operators(self, wavefn, threshold: float = 1e-12) -> np.ndarray:
values.append((value, 0))
return np.array(values, dtype=object)

def compute_eigenvalues(
self,
operator: Optional[Union[OperatorBase, LegacyBaseOperator]] = None,
aux_operators: Optional[List[Optional[Union[OperatorBase,
LegacyBaseOperator]]]] = None
) -> EigensolverResult:
super().compute_eigenvalues(operator, aux_operators)
return self._run()

def _run(self):
"""
Run the algorithm to compute up to the requested k number of eigenvalues.
Expand Down

0 comments on commit 5127aa7

Please sign in to comment.