Skip to content

Commit

Permalink
integrate modules from qiskit-algorithms using qiskit-machine_learnin…
Browse files Browse the repository at this point in the history
…g paradigm
  • Loading branch information
TolisChal committed Aug 27, 2024
1 parent 583f111 commit 1251e10
Show file tree
Hide file tree
Showing 24 changed files with 3,583 additions and 4 deletions.
4 changes: 2 additions & 2 deletions qiskit_optimization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@
"""

from .exceptions import QiskitOptimizationError
from .exceptions import QiskitOptimizationError, AlgorithmError
from .infinity import INFINITY # must be at the top of the file
from .problems.quadratic_program import QuadraticProgram
from .version import __version__

__all__ = ["__version__", "QuadraticProgram", "QiskitOptimizationError", "INFINITY"]
__all__ = ["__version__", "QuadraticProgram", "QiskitOptimizationError", "AlgorithmError", "INFINITY"]
45 changes: 45 additions & 0 deletions qiskit_optimization/algorithm_job.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This code is part of a Qiskit project.
#
# (C) Copyright IBM 2022, 2024.
#
# 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.

"""
AlgorithmJob class
"""
from qiskit.primitives.primitive_job import PrimitiveJob


class AlgorithmJob(PrimitiveJob):
"""
This class is introduced for typing purposes and provides no
additional function beyond that inherited from its parents.
Update: :meth:`AlgorithmJob.submit()` method added. See its
documentation for more info.
"""

def submit(self) -> None:
"""
Submit the job for execution.
For V1 primitives, Qiskit ``PrimitiveJob`` subclassed JobV1 and defined ``submit()``.
``PrimitiveJob`` was updated for V2 primitives, no longer subclasses ``JobV1``, and
now has a private ``_submit()`` method, with ``submit()`` being deprecated as of
Qiskit version 0.46. This maintains the ``submit()`` for ``AlgorithmJob`` here as
it's called in many places for such a job. An alternative could be to make
0.46 the required minimum version and alter all algorithm's call sites to use
``_submit()`` and make this an empty class again as it once was. For now this
way maintains compatibility with the current min version of 0.44.
"""
# TODO: Considering changing this in the future - see above docstring.
try:
super()._submit()
except AttributeError:
super().submit() # pylint: disable=no-member
65 changes: 65 additions & 0 deletions qiskit_optimization/algorithm_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This code is part of a Qiskit project.
#
# (C) Copyright IBM 2020, 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.

"""
This module implements the abstract base class for algorithm results.
"""

from abc import ABC
import inspect
import pprint


class AlgorithmResult(ABC):
"""Abstract Base Class for algorithm results."""

def __str__(self) -> str:
result = {}
for name, value in inspect.getmembers(self):
if (
not name.startswith("_")
and not inspect.ismethod(value)
and not inspect.isfunction(value)
and hasattr(self, name)
):

result[name] = value

return pprint.pformat(result, indent=4)

def combine(self, result: "AlgorithmResult") -> None:
"""
Any property from the argument that exists in the receiver is
updated.
Args:
result: Argument result with properties to be set.
Raises:
TypeError: Argument is None
"""
if result is None:
raise TypeError("Argument result expected.")
if result == self:
return

# find any result public property that exists in the receiver
for name, value in inspect.getmembers(result):
if (
not name.startswith("_")
and not inspect.ismethod(value)
and not inspect.isfunction(value)
and hasattr(self, name)
):
try:
setattr(self, name, value)
except AttributeError:
# some attributes may be read only
pass
23 changes: 23 additions & 0 deletions qiskit_optimization/eigensolvers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 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 Eigensolvers package"""

from .numpy_eigensolver import NumPyEigensolver, NumPyEigensolverResult
from .eigensolver import Eigensolver, EigensolverResult

__all__ = [
"NumPyEigensolver",
"NumPyEigensolverResult",
"Eigensolver",
"EigensolverResult",
]
103 changes: 103 additions & 0 deletions qiskit_optimization/eigensolvers/eigensolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# 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 eigensolver interface and result."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any
import numpy as np

from qiskit.quantum_info.operators.base_operator import BaseOperator

from ..algorithm_result import AlgorithmResult
from ..list_or_dict import ListOrDict


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: BaseOperator,
aux_operators: ListOrDict[BaseOperator] | None = None,
) -> "EigensolverResult":
"""
Computes the minimum eigenvalue. The ``operator`` and ``aux_operators`` are supplied here.
While an ``operator`` is required by algorithms, ``aux_operators`` are optional.
Args:
operator: Qubit operator of the observable.
aux_operators: Optional list of auxiliary operators to be evaluated with the
eigenstate of the minimum eigenvalue main result and their expectation values
returned. For instance, in chemistry, these can be dipole operators and total particle
count operators, so we can get values for these at the ground state.
Returns:
An eigensolver result.
"""
return EigensolverResult()

@classmethod
def supports_aux_operators(cls) -> bool:
"""Whether computing the expectation value of auxiliary operators is supported.
If the eigensolver computes the eigenvalues of the main operator, then it can compute
the expectation value of the ``aux_operators`` for that state. Otherwise they will be ignored.
Returns:
``True`` if ``aux_operator`` expectations can be evaluated, ``False`` otherwise.
"""
return False


class EigensolverResult(AlgorithmResult):
"""Eigensolver result."""

def __init__(self) -> None:
super().__init__()
self._eigenvalues: np.ndarray | None = None
self._aux_operators_evaluated: list[ListOrDict[tuple[float, dict[str, Any]]]] | None = None

@property
def eigenvalues(self) -> np.ndarray | None:
"""Return the eigenvalues."""
return self._eigenvalues

@eigenvalues.setter
def eigenvalues(self, value: np.ndarray) -> None:
"""Set the eigenvalues."""
self._eigenvalues = value

@property
def aux_operators_evaluated(
self,
) -> list[ListOrDict[tuple[float, dict[str, Any]]]] | None:
"""Return the aux operator expectation values.
These values are in fact tuples formatted as (mean, metadata).
"""
return self._aux_operators_evaluated

@aux_operators_evaluated.setter
def aux_operators_evaluated(
self, value: list[ListOrDict[tuple[float, dict[str, Any]]]]
) -> None:
"""Set the aux operator eigenvalues."""
self._aux_operators_evaluated = value
Loading

0 comments on commit 1251e10

Please sign in to comment.