diff --git a/qiskit_optimization/__init__.py b/qiskit_optimization/__init__.py index 23c9443cd..6de15d23e 100644 --- a/qiskit_optimization/__init__.py +++ b/qiskit_optimization/__init__.py @@ -26,10 +26,11 @@ A uniform interface as well as automatic conversion between different problem representations allows users to solve problems using a large set of algorithms, from variational quantum algorithms, such as the Quantum Approximate Optimization Algorithm -(:class:`~qiskit.algorithms.minimum_eigensolver.QAOA`), to +(:class:`~qiskit_algorithms.minimum_eigensolver.QAOA`), to `Grover Adaptive Search `_ (:class:`~algorithms.GroverOptimizer`), leveraging -fundamental :mod:`~qiskit.algorithms.minimum_eigensolver` provided by Qiskit Terra. +fundamental :mod:`~qiskit_algorithms.minimum_eigensolver` provided by +`Qiskit Algorithms `_. Furthermore, the modular design of the optimization module allows it to be easily extended and facilitates rapid development and testing of new algorithms. Compatible classical optimizers are also provided for testing, @@ -85,9 +86,9 @@ """ -from .version import __version__ -from .infinity import INFINITY # must be at the top of the file from .exceptions import QiskitOptimizationError +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"] diff --git a/qiskit_optimization/algorithms/admm_optimizer.py b/qiskit_optimization/algorithms/admm_optimizer.py index 62268e3b0..0803deb6b 100644 --- a/qiskit_optimization/algorithms/admm_optimizer.py +++ b/qiskit_optimization/algorithms/admm_optimizer.py @@ -17,7 +17,7 @@ from typing import List, Optional, Tuple, cast import numpy as np -from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver +from qiskit_algorithms.minimum_eigensolvers import NumPyMinimumEigensolver from ..converters import MaximizeToMinimize from ..problems.constraint import Constraint @@ -220,7 +220,7 @@ def __init__( Args: qubo_optimizer: An instance of OptimizationAlgorithm that can effectively solve QUBO problems. If not specified then :class:`MinimumEigenOptimizer` initialized - with an instance of :class:`NumPyMinimumEigensolver` will be used. + with an instance of ``NumPyMinimumEigensolver`` will be used. continuous_optimizer: An instance of OptimizationAlgorithm that can solve continuous problems. If not specified then :class:`SlsqpOptimizer` will be used. params: An instance of ADMMParameters. diff --git a/qiskit_optimization/algorithms/grover_optimizer.py b/qiskit_optimization/algorithms/grover_optimizer.py index 80acf99b1..08b4f3199 100644 --- a/qiskit_optimization/algorithms/grover_optimizer.py +++ b/qiskit_optimization/algorithms/grover_optimizer.py @@ -19,13 +19,13 @@ import numpy as np from qiskit import QuantumCircuit, QuantumRegister -from qiskit.algorithms import AmplificationProblem -from qiskit.algorithms.amplitude_amplifiers.grover import Grover from qiskit.circuit.library import QuadraticForm from qiskit.primitives import BaseSampler from qiskit.providers import Backend from qiskit.quantum_info import partial_trace from qiskit.utils import QuantumInstance, algorithm_globals +from qiskit_algorithms import AmplificationProblem +from qiskit_algorithms.amplitude_amplifiers.grover import Grover from qiskit_optimization.algorithms.optimization_algorithm import ( OptimizationAlgorithm, @@ -168,7 +168,7 @@ def is_good_state(measurement): return oracle, is_good_state def solve(self, problem: QuadraticProgram) -> OptimizationResult: - """Tries to solves the given problem using the grover optimizer. + """Tries to solve the given problem using the grover optimizer. Runs the optimizer to try to solve the optimization problem. If the problem cannot be, converted to a QUBO, this optimizer raises an exception due to incompatibility. diff --git a/qiskit_optimization/algorithms/minimum_eigen_optimizer.py b/qiskit_optimization/algorithms/minimum_eigen_optimizer.py index 8230fc8a2..db42f790d 100644 --- a/qiskit_optimization/algorithms/minimum_eigen_optimizer.py +++ b/qiskit_optimization/algorithms/minimum_eigen_optimizer.py @@ -26,6 +26,19 @@ SamplingMinimumEigensolverResult, ) from qiskit.quantum_info import SparsePauliOp +from qiskit_algorithms.minimum_eigensolvers import VQE as TerraVQE +from qiskit_algorithms.minimum_eigensolvers import ( + NumPyMinimumEigensolver as TerraNumPyMinimumEigensolver, +) +from qiskit_algorithms.minimum_eigensolvers import ( + NumPyMinimumEigensolverResult as TerraNumPyMinimumEigensolverResult, +) +from qiskit_algorithms.minimum_eigensolvers import ( + SamplingMinimumEigensolver as TerraSamplingMinimumEigensolver, +) +from qiskit_algorithms.minimum_eigensolvers import ( + SamplingMinimumEigensolverResult as TerraSamplingMinimumEigensolverResult, +) from ..converters.quadratic_program_to_qubo import QuadraticProgramConverter, QuadraticProgramToQubo from ..exceptions import QiskitOptimizationError @@ -38,10 +51,18 @@ ) MinimumEigensolver = Union[ - SamplingMinimumEigensolver, NumPyMinimumEigensolver, LegacyMinimumEigensolver + SamplingMinimumEigensolver, + NumPyMinimumEigensolver, + LegacyMinimumEigensolver, + TerraSamplingMinimumEigensolver, + TerraNumPyMinimumEigensolver, ] MinimumEigensolverResult = Union[ - SamplingMinimumEigensolverResult, NumPyMinimumEigensolverResult, LegacyMinimumEigensolverResult + SamplingMinimumEigensolverResult, + NumPyMinimumEigensolverResult, + LegacyMinimumEigensolverResult, + TerraSamplingMinimumEigensolverResult, + TerraNumPyMinimumEigensolverResult, ] @@ -152,20 +173,26 @@ def __init__( TypeError: When one of converters has an invalid type. QiskitOptimizationError: When the minimum eigensolver does not return an eigenstate. """ - if isinstance(min_eigen_solver, VQE): + if isinstance(min_eigen_solver, (VQE, TerraVQE)): raise TypeError( "MinimumEigenOptimizer does not support this VQE. You can use " - "qiskit.algorithms.minimum_eigensolvers.SamplingVQE instead." + "qiskit_algorithms.minimum_eigensolvers.SamplingVQE instead." ) if not isinstance( min_eigen_solver, - (SamplingMinimumEigensolver, NumPyMinimumEigensolver, LegacyMinimumEigensolver), + ( + SamplingMinimumEigensolver, + NumPyMinimumEigensolver, + LegacyMinimumEigensolver, + TerraSamplingMinimumEigensolver, + TerraNumPyMinimumEigensolver, + ), ): raise TypeError( "MinimumEigenOptimizer supports " - "qiskit.algorithms.minimum_eigensolvers.SamplingMinimumEigensolver, " - "qiskit.algorithms.minimum_eigensolvers.NumPyMinimumEigensolver, and " - "qiskit.algorithms.minimum_eigen_solvers.MinimumEigensolver. " + "qiskit_algorithms.minimum_eigensolvers.SamplingMinimumEigensolver, " + "qiskit_algorithms.minimum_eigensolvers.NumPyMinimumEigensolver, and " + "qiskit_algorithms.minimum_eigen_solvers.MinimumEigensolver. " f"But {type(min_eigen_solver)} is given." ) if not min_eigen_solver.supports_aux_operators(): diff --git a/qiskit_optimization/algorithms/recursive_minimum_eigen_optimizer.py b/qiskit_optimization/algorithms/recursive_minimum_eigen_optimizer.py index c3149f3fc..ab682fc5e 100644 --- a/qiskit_optimization/algorithms/recursive_minimum_eigen_optimizer.py +++ b/qiskit_optimization/algorithms/recursive_minimum_eigen_optimizer.py @@ -17,7 +17,7 @@ from typing import Dict, List, Optional, Tuple, Union, cast import numpy as np -from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver +from qiskit_algorithms.minimum_eigensolvers import NumPyMinimumEigensolver from qiskit.utils.validation import validate_min from ..converters.quadratic_program_to_qubo import QuadraticProgramConverter, QuadraticProgramToQubo @@ -117,7 +117,7 @@ class RecursiveMinimumEigenOptimizer(OptimizationAlgorithm): .. code-block:: python - from qiskit.algorithms.minimum_eigensolver import QAOA + from qiskit_algorithms.minimum_eigensolver import QAOA from qiskit_optimization.problems import QuadraticProgram from qiskit_optimization.algorithms import ( MinimumEigenOptimizer, RecursiveMinimumEigenOptimizer @@ -161,7 +161,7 @@ def __init__( min_num_vars_optimizer: This optimizer is used after the recursive scheme for the problem with the remaining variables. Default value is :class:`~qiskit_optimization.algorithms.MinimumEigenOptimizer` created on top of - :class:`~qiskit.algorithms.minimum_eigensolver.NumPyMinimumEigensolver`. + :class:`~qiskit_algorithms.minimum_eigensolver.NumPyMinimumEigensolver`. penalty: The factor that is used to scale the penalty terms corresponding to linear equality constraints. history: Whether the intermediate results are stored. diff --git a/qiskit_optimization/algorithms/warm_start_qaoa_optimizer.py b/qiskit_optimization/algorithms/warm_start_qaoa_optimizer.py index 7e586cb23..c28cb3c63 100644 --- a/qiskit_optimization/algorithms/warm_start_qaoa_optimizer.py +++ b/qiskit_optimization/algorithms/warm_start_qaoa_optimizer.py @@ -19,8 +19,9 @@ import numpy as np from qiskit import QuantumCircuit from qiskit.algorithms import QAOA as LegacyQAOA -from qiskit.algorithms.minimum_eigensolvers import QAOA +from qiskit.algorithms.minimum_eigensolvers import QAOA as TerraQAOA from qiskit.circuit import Parameter +from qiskit_algorithms.minimum_eigensolvers import QAOA from ..converters.quadratic_program_converter import QuadraticProgramConverter from ..exceptions import QiskitOptimizationError @@ -203,7 +204,7 @@ def __init__( self, pre_solver: OptimizationAlgorithm, relax_for_pre_solver: bool, - qaoa: Union[QAOA, LegacyQAOA], + qaoa: Union[QAOA, TerraQAOA, LegacyQAOA], epsilon: float = 0.25, num_initial_solutions: int = 1, warm_start_factory: Optional[WarmStartQAOAFactory] = None, diff --git a/requirements.txt b/requirements.txt index 32d95162f..c60a2eb46 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ qiskit-terra>=0.22.4 +qiskit-algorithms>=0.1.0 scipy>=1.4 numpy>=1.17 docplex>=2.21.207,!=2.24.231 diff --git a/test/algorithms/test_grover_optimizer.py b/test/algorithms/test_grover_optimizer.py index 557190831..6addabc24 100644 --- a/test/algorithms/test_grover_optimizer.py +++ b/test/algorithms/test_grover_optimizer.py @@ -18,8 +18,8 @@ import numpy as np from ddt import data, ddt from docplex.mp.model import Model -from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver from qiskit.utils import QuantumInstance, algorithm_globals, optionals +from qiskit_algorithms.minimum_eigensolvers import NumPyMinimumEigensolver from qiskit_optimization.algorithms import ( GroverOptimizer, diff --git a/test/algorithms/test_min_eigen_optimizer.py b/test/algorithms/test_min_eigen_optimizer.py index 42fb0b12b..794c6e108 100644 --- a/test/algorithms/test_min_eigen_optimizer.py +++ b/test/algorithms/test_min_eigen_optimizer.py @@ -18,13 +18,14 @@ import numpy as np from ddt import data, ddt, unpack -from qiskit.algorithms.minimum_eigensolvers import QAOA, VQE, NumPyMinimumEigensolver, SamplingVQE -from qiskit.algorithms.optimizers import COBYLA, SPSA +from qiskit.algorithms.optimizers import SPSA as TerraSPSA from qiskit.circuit.library import TwoLocal from qiskit.primitives import Estimator, Sampler from qiskit.providers.basicaer import QasmSimulatorPy from qiskit.providers.fake_provider import FakeArmonk, FakeArmonkV2 from qiskit.utils import algorithm_globals +from qiskit_algorithms.minimum_eigensolvers import QAOA, VQE, NumPyMinimumEigensolver, SamplingVQE +from qiskit_algorithms.optimizers import COBYLA, SPSA import qiskit_optimization.optionals as _optionals from qiskit_optimization.algorithms import ( @@ -377,7 +378,7 @@ def test_runtime(self, subroutine): @data(FakeArmonk, FakeArmonkV2) def test_runtime_backend_versions(self, backend_cls): """Test the runtime client with a V1 and a V2 backend.""" - optimizer = SPSA(maxiter=1, learning_rate=0.1, perturbation=0.1) + optimizer = TerraSPSA(maxiter=1, learning_rate=0.1, perturbation=0.1) backend = backend_cls() provider = FakeVQERuntimeProvider() ansatz = TwoLocal(1, "ry", reps=0) diff --git a/test/algorithms/test_recursive_optimization.py b/test/algorithms/test_recursive_optimization.py index ec8c6d9cc..af20b6f8f 100644 --- a/test/algorithms/test_recursive_optimization.py +++ b/test/algorithms/test_recursive_optimization.py @@ -16,10 +16,10 @@ from test import QiskitOptimizationTestCase import numpy as np -from qiskit.algorithms.minimum_eigensolvers import QAOA, NumPyMinimumEigensolver -from qiskit.algorithms.optimizers import SLSQP from qiskit.primitives import Sampler from qiskit.utils import algorithm_globals +from qiskit_algorithms.minimum_eigensolvers import QAOA, NumPyMinimumEigensolver +from qiskit_algorithms.optimizers import SLSQP import qiskit_optimization.optionals as _optionals from qiskit_optimization.algorithms import ( diff --git a/test/algorithms/test_warm_start_qaoa.py b/test/algorithms/test_warm_start_qaoa.py index be83a392b..e8f586392 100644 --- a/test/algorithms/test_warm_start_qaoa.py +++ b/test/algorithms/test_warm_start_qaoa.py @@ -17,9 +17,9 @@ import numpy as np from docplex.mp.model import Model -from qiskit.algorithms.minimum_eigensolvers import QAOA -from qiskit.algorithms.optimizers import SLSQP from qiskit.primitives.sampler import Sampler +from qiskit_algorithms.minimum_eigensolvers import QAOA +from qiskit_algorithms.optimizers import SLSQP import qiskit_optimization.optionals as _optionals from qiskit_optimization.algorithms import SlsqpOptimizer diff --git a/test/converters/test_converters.py b/test/converters/test_converters.py index 92e0f1cc4..4f8d80808 100644 --- a/test/converters/test_converters.py +++ b/test/converters/test_converters.py @@ -17,8 +17,8 @@ import numpy as np from docplex.mp.model import Model -from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver from qiskit.quantum_info import SparsePauliOp +from qiskit_algorithms.minimum_eigensolvers import NumPyMinimumEigensolver import qiskit_optimization.optionals as _optionals from qiskit_optimization import QiskitOptimizationError, QuadraticProgram