diff --git a/docs/apidocs/qiskit.optimization.algorithms.rst b/docs/apidocs/qiskit.optimization.algorithms.rst new file mode 100644 index 0000000000..bb7ba4dcc0 --- /dev/null +++ b/docs/apidocs/qiskit.optimization.algorithms.rst @@ -0,0 +1,6 @@ +.. _qiskit-optimization-algorithms: + +.. automodule:: qiskit.optimization.algorithms + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/docs/apidocs/qiskit.optimization.applications.ising.rst b/docs/apidocs/qiskit.optimization.applications.ising.rst new file mode 100644 index 0000000000..ff1ebb7629 --- /dev/null +++ b/docs/apidocs/qiskit.optimization.applications.ising.rst @@ -0,0 +1,6 @@ +.. _qiskit-optimization-applications-ising: + +.. automodule:: qiskit.optimization.applications.ising + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/docs/apidocs/qiskit.optimization.applications.rst b/docs/apidocs/qiskit.optimization.applications.rst new file mode 100644 index 0000000000..a388e86ad5 --- /dev/null +++ b/docs/apidocs/qiskit.optimization.applications.rst @@ -0,0 +1,6 @@ +.. _qiskit-optimization-applications: + +.. automodule:: qiskit.optimization.applications + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/docs/apidocs/qiskit.optimization.converters.rst b/docs/apidocs/qiskit.optimization.converters.rst new file mode 100644 index 0000000000..f51be315d4 --- /dev/null +++ b/docs/apidocs/qiskit.optimization.converters.rst @@ -0,0 +1,6 @@ +.. _qiskit-optimization-converters: + +.. automodule:: qiskit.optimization.converters + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/docs/apidocs/qiskit.optimization.problems.rst b/docs/apidocs/qiskit.optimization.problems.rst new file mode 100644 index 0000000000..3147fb929a --- /dev/null +++ b/docs/apidocs/qiskit.optimization.problems.rst @@ -0,0 +1,6 @@ +.. _qiskit-optimization-problems: + +.. automodule:: qiskit.optimization.problems + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/qiskit/optimization/__init__.py b/qiskit/optimization/__init__.py index e302d95922..b3fec6bd07 100644 --- a/qiskit/optimization/__init__.py +++ b/qiskit/optimization/__init__.py @@ -18,22 +18,75 @@ .. currentmodule:: qiskit.optimization -Contents -======== +Qiskit Optimization covers the whole stack from high-level modeling of optimization +problems, with automatic conversion of problems to different required representations, +to a suite of easy-to-use quantum optimization algorithms that are ready to run on +classical simulators, as well as on real quantum devices via Qiskit. + +Qiskit Optimization enables easy, efficient modeling of optimization problems using `docplex +`_ +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.aqua.algorithms.QAOA`), to +`Grover Adaptive Search `_ +(:class:`~algorithms.GroverOptimizer`), leveraging +fundamental :mod:`~qiskit.aqua.algorithms` provided by Qiskit Aqua. Furthermore, the modular design +of Qiskit Optimization allows it to be easily extended and facilitates rapid development and +testing of new algorithms. Compatible classical optimizers are also provided for testing, +validation, and benchmarking. + +Qiskit Optimization supports Quadratically Constrained Quadratic Programs – for simplicity we refer +to them just as Quadratic Programs – with binary, integer, and continuous variables, as well as +equality and inequality constraints. This class of optimization problems has a vast amount of +relevant applications, while still being efficiently representable by matrices and vectors. +This class covers some very interesting sub-classes, from Convex Continuous Quadratic Programs, +which can be solved efficiently by classical optimization algorithms, to Quadratic Unconstrained +Binary Optimization QUBO) problems, which cover many NP-complete, i.e., classically intractable, +problems. .. autosummary:: :toctree: ../stubs/ :nosignatures: QuadraticProgram + +Representation of a Quadratically Constrained Quadratic Program supporting inequality and +equality constraints as well as continuous, binary, and integer variables. + +.. autosummary:: + :toctree: ../stubs/ + :nosignatures: + QiskitOptimizationError + +In addition to standard Python errors Qiskit Optimization will raise this error if circumstances +are that it cannot proceed to completion. + +.. autosummary:: + :toctree: ../stubs/ + :nosignatures: + INFINITY +A constant for infinity. + +Submodules +========== + +.. autosummary:: + :toctree: + + algorithms + applications + converters + problems + """ from .infinity import INFINITY # must be at the top of the file from .exceptions import QiskitOptimizationError -from .problems import QuadraticProgram +from .problems.quadratic_program import QuadraticProgram from ._logging import (get_qiskit_optimization_logging, set_qiskit_optimization_logging) diff --git a/qiskit/optimization/algorithms/__init__.py b/qiskit/optimization/algorithms/__init__.py index 4ede3a37cd..b793a1aef4 100644 --- a/qiskit/optimization/algorithms/__init__.py +++ b/qiskit/optimization/algorithms/__init__.py @@ -13,11 +13,10 @@ # that they have been altered from the originals. """ -=================================================================== -Optimization stack for Aqua (:mod:`qiskit.optimization.algorithms`) -=================================================================== +Optimization algorithms (:mod:`qiskit.optimization.algorithms`) +=============================================================== -Algorithms for optimization algorithms. +Algorithms for optimization problems. .. currentmodule:: qiskit.optimization.algorithms diff --git a/qiskit/optimization/algorithms/admm_optimizer.py b/qiskit/optimization/algorithms/admm_optimizer.py index bbb20897f5..ab3c3a9a73 100644 --- a/qiskit/optimization/algorithms/admm_optimizer.py +++ b/qiskit/optimization/algorithms/admm_optimizer.py @@ -19,12 +19,13 @@ from typing import List, Optional, Any import numpy as np -from qiskit.optimization import QiskitOptimizationError -from qiskit.optimization.algorithms.cplex_optimizer import CplexOptimizer -from qiskit.optimization.algorithms.optimization_algorithm import (OptimizationAlgorithm, - OptimizationResult) -from qiskit.optimization.converters import IntegerToBinary -from qiskit.optimization.problems import QuadraticProgram, Variable, Constraint, QuadraticObjective +from ..exceptions import QiskitOptimizationError +from .cplex_optimizer import CplexOptimizer +from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult +from ..problems.quadratic_program import QuadraticProgram +from ..problems.variable import Variable +from ..problems.constraint import Constraint +from ..problems.quadratic_objective import QuadraticObjective UPDATE_RHO_BY_TEN_PERCENT = 0 UPDATE_RHO_BY_RESIDUALS = 1 @@ -251,6 +252,7 @@ def solve(self, problem: QuadraticProgram) -> ADMMOptimizationResult: self._log.debug("Initial problem: %s", problem.export_as_lp_string()) # map integer variables to binary variables + from ..converters.integer_to_binary import IntegerToBinary int2bin = IntegerToBinary() problem = int2bin.encode(problem) diff --git a/qiskit/optimization/algorithms/cobyla_optimizer.py b/qiskit/optimization/algorithms/cobyla_optimizer.py index 36c5141e5c..2bdb0afe17 100644 --- a/qiskit/optimization/algorithms/cobyla_optimizer.py +++ b/qiskit/optimization/algorithms/cobyla_optimizer.py @@ -20,13 +20,15 @@ import numpy as np from scipy.optimize import fmin_cobyla -from qiskit.optimization.algorithms import OptimizationAlgorithm, OptimizationResult -from qiskit.optimization.problems import QuadraticProgram, Constraint -from qiskit.optimization import QiskitOptimizationError, INFINITY +from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult +from ..problems.quadratic_program import QuadraticProgram +from ..problems.constraint import Constraint +from ..exceptions import QiskitOptimizationError +from ..infinity import INFINITY class CobylaOptimizer(OptimizationAlgorithm): - """The SciPy COBYLA optimizer wrapped as an Qiskit ``OptimizationAlgorithm``. + """The SciPy COBYLA optimizer wrapped as an Qiskit :class:`OptimizationAlgorithm`. This class provides a wrapper for ``scipy.optimize.fmin_cobyla`` (https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.fmin_cobyla.html) @@ -34,6 +36,8 @@ class CobylaOptimizer(OptimizationAlgorithm): The arguments for ``fmin_cobyla`` are passed via the constructor. Examples: + >>> from qiskit.optimization.problems import QuadraticProgram + >>> from qiskit.optimization.algorithms import CobylaOptimizer >>> problem = QuadraticProgram() >>> # specify problem here >>> optimizer = CobylaOptimizer() diff --git a/qiskit/optimization/algorithms/cplex_optimizer.py b/qiskit/optimization/algorithms/cplex_optimizer.py index 6966aa0da3..ff29f827d6 100644 --- a/qiskit/optimization/algorithms/cplex_optimizer.py +++ b/qiskit/optimization/algorithms/cplex_optimizer.py @@ -33,12 +33,14 @@ class CplexOptimizer(OptimizationAlgorithm): - """The CPLEX optimizer wrapped as an Qiskit ``OptimizationAlgorithm``. + """The CPLEX optimizer wrapped as an Qiskit :class:`OptimizationAlgorithm`. This class provides a wrapper for ``cplex.Cplex`` (https://pypi.org/project/cplex/) to be used within Qiskit Optimization. Examples: + >>> from qiskit.optimization.problems import QuadraticProgram + >>> from qiskit.optimization.algorithms import CplexOptimizer >>> problem = QuadraticProgram() >>> # specify problem here >>> optimizer = CplexOptimizer() diff --git a/qiskit/optimization/algorithms/grover_optimizer.py b/qiskit/optimization/algorithms/grover_optimizer.py index 4c95506d28..513f00852c 100644 --- a/qiskit/optimization/algorithms/grover_optimizer.py +++ b/qiskit/optimization/algorithms/grover_optimizer.py @@ -22,13 +22,13 @@ from qiskit import QuantumCircuit from qiskit.providers import BaseBackend from qiskit.aqua import QuantumInstance -from qiskit.optimization import QiskitOptimizationError -from qiskit.optimization.algorithms import OptimizationAlgorithm -from qiskit.optimization.problems import QuadraticProgram -from qiskit.optimization.converters import (QuadraticProgramToQubo, - QuadraticProgramToNegativeValueOracle) -from qiskit.optimization.algorithms.optimization_algorithm import OptimizationResult from qiskit.aqua.algorithms.amplitude_amplifiers.grover import Grover +from ..exceptions import QiskitOptimizationError +from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult +from ..problems.quadratic_program import QuadraticProgram +from ..converters.quadratic_program_to_qubo import QuadraticProgramToQubo +from ..converters.quadratic_program_to_negative_value_oracle import \ + QuadraticProgramToNegativeValueOracle logger = logging.getLogger(__name__) diff --git a/qiskit/optimization/algorithms/minimum_eigen_optimizer.py b/qiskit/optimization/algorithms/minimum_eigen_optimizer.py index 4c34a66d21..50f4585142 100644 --- a/qiskit/optimization/algorithms/minimum_eigen_optimizer.py +++ b/qiskit/optimization/algorithms/minimum_eigen_optimizer.py @@ -26,7 +26,7 @@ from ..problems.quadratic_program import QuadraticProgram from ..converters.quadratic_program_to_operator import QuadraticProgramToOperator from ..converters.quadratic_program_to_qubo import QuadraticProgramToQubo -from .. import QiskitOptimizationError +from ..exceptions import QiskitOptimizationError class MinimumEigenOptimizerResult(OptimizationResult): @@ -67,9 +67,10 @@ def get_correlations(self): class MinimumEigenOptimizer(OptimizationAlgorithm): - """A wrapper for minimum eigen solvers from Qiskit Aqua to be used within Qiskit Optimization. + """A wrapper for minimum eigen solvers from Qiskit Aqua. - This class provides a wrapper for minimum eigen solvers from Qiskit Aqua. + This class provides a wrapper for minimum eigen solvers from Qiskit Aqua to be used within + Qiskit Optimization. It assumes a problem consisting only of binary or integer variables as well as linear equality constraints thereof. It converts such a problem into a Quadratic Unconstrained Binary Optimization (QUBO) problem by expanding integer variables into binary variables and by adding @@ -80,12 +81,19 @@ class MinimumEigenOptimizer(OptimizationAlgorithm): Hamiltonian to find a good solution for the optimization problem. Examples: - >>> problem = QuadraticProgram() - >>> # specify problem here - >>> # specify minimum eigen solver to be used, e.g., QAOA - >>> qaoa = QAOA(...) - >>> optimizer = MinEigenOptimizer(qaoa) - >>> result = optimizer.solve(problem) + Outline of how to use this class: + + .. code-block:: + + from qiskit.aqua.algorithms import QAOA + from qiskit.optimization.problems import QuadraticProgram + from qiskit.optimization.algorithms import MinimumEigenOptimizer + problem = QuadraticProgram() + # specify problem here + # specify minimum eigen solver to be used, e.g., QAOA + qaoa = QAOA(...) + optimizer = MinimumEigenOptimizer(qaoa) + result = optimizer.solve(problem) """ def __init__(self, min_eigen_solver: MinimumEigensolver, penalty: Optional[float] = None diff --git a/qiskit/optimization/algorithms/recursive_minimum_eigen_optimizer.py b/qiskit/optimization/algorithms/recursive_minimum_eigen_optimizer.py index ec6bdd745e..a6aa05d01f 100644 --- a/qiskit/optimization/algorithms/recursive_minimum_eigen_optimizer.py +++ b/qiskit/optimization/algorithms/recursive_minimum_eigen_optimizer.py @@ -39,12 +39,19 @@ class RecursiveMinimumEigenOptimizer(OptimizationAlgorithm): The algorithm is introduced in [1]. Examples: - >>> problem = QuadraticProgram() - >>> # specify problem here - >>> # specify minimum eigen solver to be used, e.g., QAOA - >>> qaoa = QAOA(...) - >>> optimizer = RecursiveMinEigenOptimizer(qaoa) - >>> result = optimizer.solve(problem) + Outline of how to use this class: + + .. code-block:: + + from qiskit.aqua.algorithms import QAOA + from qiskit.optimization.problems import QuadraticProgram + from qiskit.optimization.algorithms import RecursiveMinimumEigenOptimizer + problem = QuadraticProgram() + # specify problem here + # specify minimum eigen solver to be used, e.g., QAOA + qaoa = QAOA(...) + optimizer = RecursiveMinimumEigenOptimizer(qaoa) + result = optimizer.solve(problem) References: [1]: Bravyi et al. (2019), Obstacles to State Preparation and Variational Optimization diff --git a/qiskit/optimization/applications/__init__.py b/qiskit/optimization/applications/__init__.py index 4317685c28..ef32bbdbe7 100644 --- a/qiskit/optimization/applications/__init__.py +++ b/qiskit/optimization/applications/__init__.py @@ -11,3 +11,22 @@ # 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. + +""" +Optimization applications (:mod:`qiskit.aqua.applications`) +=========================================================== + +.. currentmodule:: qiskit.optimization.applications + +Applications for Qiskit Optimization. The present set are in the form of +Ising Hamiltonians. + +Submodules +========== + +.. autosummary:: + :toctree: + + ising + +""" diff --git a/qiskit/optimization/applications/ising/__init__.py b/qiskit/optimization/applications/ising/__init__.py index b9869755a3..f13251435f 100644 --- a/qiskit/optimization/applications/ising/__init__.py +++ b/qiskit/optimization/applications/ising/__init__.py @@ -15,7 +15,7 @@ """ Ising Models (:mod:`qiskit.optimization.applications.ising`) ============================================================ -Ising models for optimization problems +Ising models for optimization application problems .. currentmodule:: qiskit.optimization.applications.ising diff --git a/qiskit/optimization/converters/__init__.py b/qiskit/optimization/converters/__init__.py index 9d41d9c344..06688257e7 100644 --- a/qiskit/optimization/converters/__init__.py +++ b/qiskit/optimization/converters/__init__.py @@ -13,26 +13,28 @@ # that they have been altered from the originals. """ -=================================================================== -Optimization stack for Aqua (:mod:`qiskit.optimization.converters`) -=================================================================== +Optimization converters (:mod:`qiskit.optimization.converters`) +=============================================================== .. currentmodule:: qiskit.optimization.converters -Structures for converting optimization problems -=============================================== +This is selection of converters having encode, decode functionality to go between different +forms. + +Converters +========== .. autosummary:: :toctree: ../stubs/ :nosignatures: - InequalityToEquality - IntegerToBinary - QuadraticProgramToNegativeValueOracle - QuadraticProgramToOperator - QuadraticProgramToQubo - LinearEqualityToPenalty - OperatorToQuadraticProgram + InequalityToEquality + IntegerToBinary + QuadraticProgramToNegativeValueOracle + QuadraticProgramToOperator + QuadraticProgramToQubo + LinearEqualityToPenalty + OperatorToQuadraticProgram """ diff --git a/qiskit/optimization/converters/inequality_to_equality.py b/qiskit/optimization/converters/inequality_to_equality.py index 48d0064f58..b4c8c78bd6 100644 --- a/qiskit/optimization/converters/inequality_to_equality.py +++ b/qiskit/optimization/converters/inequality_to_equality.py @@ -18,6 +18,7 @@ from typing import List, Tuple, Dict, Optional import logging +from ..algorithms.optimization_algorithm import OptimizationResult from ..problems.quadratic_program import QuadraticProgram from ..problems.quadratic_objective import QuadraticObjective from ..problems.constraint import Constraint @@ -31,6 +32,8 @@ class InequalityToEquality: """Convert inequality constraints into equality constraints by introducing slack variables. Examples: + >>> from qiskit.optimization.problems import QuadraticProgram + >>> from qiskit.optimization.converters import InequalityToEquality >>> problem = QuadraticProgram() >>> # define a problem >>> conv = InequalityToEquality() @@ -54,10 +57,11 @@ def encode( op: The problem to be solved, that may contain inequality constraints. name: The name of the converted problem. mode: To chose the type of slack variables. There are 3 options for mode. - - 'integer': All slack variables will be integer variables. - - 'continuous': All slack variables will be continuous variables - - 'auto': Try to use integer variables but if it's not possible, - use continuous variables + + - 'integer': All slack variables will be integer variables. + - 'continuous': All slack variables will be continuous variables + - 'auto': Try to use integer variables but if it's not possible, + use continuous variables Returns: The converted problem, that contain only equality constraints. @@ -332,7 +336,7 @@ def _calc_quadratic_bounds(self, linear, quadratic): ) return lhs_lb, lhs_ub - def decode(self, result: 'OptimizationResult') -> 'OptimizationResult': + def decode(self, result: OptimizationResult) -> OptimizationResult: """Convert a result of a converted problem into that of the original problem. Args: diff --git a/qiskit/optimization/converters/integer_to_binary.py b/qiskit/optimization/converters/integer_to_binary.py index f09051b147..f4f148b008 100644 --- a/qiskit/optimization/converters/integer_to_binary.py +++ b/qiskit/optimization/converters/integer_to_binary.py @@ -20,6 +20,7 @@ import numpy as np +from ..algorithms.optimization_algorithm import OptimizationResult from ..exceptions import QiskitOptimizationError from ..problems.quadratic_objective import QuadraticObjective from ..problems.quadratic_program import QuadraticProgram @@ -29,13 +30,16 @@ class IntegerToBinary: - """Convert an `QuadraticProgram` into new one by encoding integer with binary variables. + """Convert a :class:`~qiskit.optimization.problems.QuadraticProgram` into new one by encoding + integer with binary variables. This bounded-coefficient encoding used in this converted is proposed in [1], Eq. (5). Examples: + >>> from qiskit.optimization.problems import QuadraticProgram + >>> from qiskit.optimization.converters import IntegerToBinary >>> problem = QuadraticProgram() - >>> problem.integer_var(name='x', lowerbound=0, upperbound=10) + >>> var = problem.integer_var(name='x', lowerbound=0, upperbound=10) >>> conv = IntegerToBinary() >>> problem2 = conv.encode(problem) @@ -202,7 +206,7 @@ def _substitute_int_var(self): self._dst.quadratic_constraint(linear, quadratic, constraint.sense, constraint.rhs - constant, constraint.name) - def decode(self, result: "OptimizationResult") -> "OptimizationResult": + def decode(self, result: OptimizationResult) -> OptimizationResult: """Convert the encoded problem (binary variables) back to the original (integer variables). Args: diff --git a/qiskit/optimization/converters/linear_equality_to_penalty.py b/qiskit/optimization/converters/linear_equality_to_penalty.py index e87f84a664..5526169859 100644 --- a/qiskit/optimization/converters/linear_equality_to_penalty.py +++ b/qiskit/optimization/converters/linear_equality_to_penalty.py @@ -17,7 +17,10 @@ import copy from typing import Optional -from ..problems import QuadraticProgram, Variable, Constraint, QuadraticObjective +from ..problems.quadratic_program import QuadraticProgram +from ..problems.variable import Variable +from ..problems.constraint import Constraint +from ..problems.quadratic_objective import QuadraticObjective from ..exceptions import QiskitOptimizationError diff --git a/qiskit/optimization/converters/operator_to_quadratic_program.py b/qiskit/optimization/converters/operator_to_quadratic_program.py index e808ff6ccc..edc35e1a12 100644 --- a/qiskit/optimization/converters/operator_to_quadratic_program.py +++ b/qiskit/optimization/converters/operator_to_quadratic_program.py @@ -19,7 +19,7 @@ import numpy as np -from qiskit.aqua.operators import WeightedPauliOperator +from qiskit.aqua.operators.legacy import WeightedPauliOperator from ..problems.quadratic_program import QuadraticProgram from ..exceptions import QiskitOptimizationError @@ -39,11 +39,12 @@ def encode(self, qubit_op: WeightedPauliOperator, offset: float = 0.0) -> Quadra """Convert a qubit operator and a shift value into a quadratic program Args: - qubit_op: The qubit operator to be converted into `QuadraticProgram` + qubit_op: The qubit operator to be converted into a + :class:`~qiskit.optimization.problems.quadratic_program.QuadraticProgram` offset: The shift value of the qubit operator Returns: - QuadraticProgram: converted from the input qubit operator and the shift value + QuadraticProgram converted from the input qubit operator and the shift value Raises: QiskitOptimizationError: If there are Pauli Xs in any Pauli term diff --git a/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py b/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py index 0d4ade34f4..4007452dcf 100644 --- a/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py +++ b/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py @@ -23,7 +23,7 @@ from qiskit.circuit.library import QFT from qiskit.aqua.components.initial_states import Custom from qiskit.aqua.components.oracles import CustomCircuitOracle -from qiskit.optimization.problems import QuadraticProgram +from ..problems.quadratic_program import QuadraticProgram logger = logging.getLogger(__name__) diff --git a/qiskit/optimization/converters/quadratic_program_to_qubo.py b/qiskit/optimization/converters/quadratic_program_to_qubo.py index 5e9e15b04e..e7abbd158e 100644 --- a/qiskit/optimization/converters/quadratic_program_to_qubo.py +++ b/qiskit/optimization/converters/quadratic_program_to_qubo.py @@ -16,17 +16,19 @@ from typing import Optional -from qiskit.optimization.problems import QuadraticProgram -from qiskit.optimization.problems.constraint import Constraint -from qiskit.optimization.converters.linear_equality_to_penalty import LinearEqualityToPenalty -from qiskit.optimization.converters.integer_to_binary import IntegerToBinary -from qiskit.optimization.exceptions import QiskitOptimizationError +from ..algorithms.optimization_algorithm import OptimizationResult +from ..problems.quadratic_program import QuadraticProgram +from ..problems.constraint import Constraint +from ..converters.linear_equality_to_penalty import LinearEqualityToPenalty +from ..exceptions import QiskitOptimizationError class QuadraticProgramToQubo: """Convert a given optimization problem to a new problem that is a QUBO. Examples: + >>> from qiskit.optimization.problems import QuadraticProgram + >>> from qiskit.optimization.converters import QuadraticProgramToQubo >>> problem = QuadraticProgram() >>> # define a problem >>> conv = QuadraticProgramToQubo() @@ -38,6 +40,7 @@ def __init__(self, penalty: Optional[float] = None) -> None: Args: penalty: Penalty factor to scale equality constraints that are added to objective. """ + from ..converters.integer_to_binary import IntegerToBinary self._int_to_bin = IntegerToBinary() self._penalize_lin_eq_constraints = LinearEqualityToPenalty() self._penalty = penalty @@ -74,7 +77,7 @@ def encode(self, problem: QuadraticProgram) -> QuadraticProgram: # return QUBO return problem_ - def decode(self, result: 'OptimizationResult') -> 'OptimizationResult': + def decode(self, result: OptimizationResult) -> OptimizationResult: """ Convert a result of a converted problem into that of the original problem. Args: diff --git a/qiskit/optimization/exceptions.py b/qiskit/optimization/exceptions.py index aa14a50fed..71baf4ca19 100644 --- a/qiskit/optimization/exceptions.py +++ b/qiskit/optimization/exceptions.py @@ -18,5 +18,5 @@ class QiskitOptimizationError(AquaError): - """Class for errors returned by Qiskit Optimization libraries functions.""" + """Class for errors returned by Qiskit Optimization.""" pass diff --git a/qiskit/optimization/problems/__init__.py b/qiskit/optimization/problems/__init__.py index f0b0495df1..c5e7c8e397 100644 --- a/qiskit/optimization/problems/__init__.py +++ b/qiskit/optimization/problems/__init__.py @@ -13,14 +13,24 @@ # that they have been altered from the originals. """ -================================================================= -Optimization stack for Aqua (:mod:`qiskit.optimization.problems`) -================================================================= +Optimization problems (:mod:`qiskit.optimization.problems`) +=========================================================== .. currentmodule:: qiskit.optimization.problems -Structures for defining an optimization problem and its solution -================================================================ +Problems +======== +Structures for defining an optimization problem and its solution. + +.. autosummary:: + :toctree: ../stubs/ + :nosignatures: + + QuadraticProgram + +Note: + The following classes are not intended to be instantiated directly. + Objects of these types are available within an instantiated :class:`QuadraticProgram`. .. autosummary:: :toctree: ../stubs/ @@ -32,12 +42,8 @@ QuadraticExpression QuadraticConstraint QuadraticObjective - QuadraticProgram Variable -N.B. All classes but `QuadraticProgram` are not to be instantiated directly. -Objects of those types are available within an instantiated `QuadraticProgram`. - """ from .constraint import Constraint diff --git a/qiskit/optimization/problems/constraint.py b/qiskit/optimization/problems/constraint.py index fa7390beb8..36ae94feb6 100644 --- a/qiskit/optimization/problems/constraint.py +++ b/qiskit/optimization/problems/constraint.py @@ -16,7 +16,7 @@ from abc import abstractmethod from enum import Enum -from typing import Union, List, Dict +from typing import Union, List, Dict, Any from numpy import ndarray @@ -63,7 +63,7 @@ class Constraint(QuadraticProgramElement): Sense = ConstraintSense - def __init__(self, quadratic_program: 'QuadraticProgram', name: str, sense: ConstraintSense, + def __init__(self, quadratic_program: Any, name: str, sense: ConstraintSense, rhs: float) -> None: """ Initializes the constraint. diff --git a/qiskit/optimization/problems/linear_constraint.py b/qiskit/optimization/problems/linear_constraint.py index 467d30f952..6b55abaff0 100644 --- a/qiskit/optimization/problems/linear_constraint.py +++ b/qiskit/optimization/problems/linear_constraint.py @@ -14,20 +14,23 @@ """Linear Constraint.""" -from typing import Union, List, Dict +from typing import Union, List, Dict, Any from numpy import ndarray from scipy.sparse import spmatrix -from qiskit.optimization.problems.constraint import Constraint -from qiskit.optimization.problems.linear_expression import LinearExpression +from .constraint import Constraint, ConstraintSense +from .linear_expression import LinearExpression class LinearConstraint(Constraint): """ Representation of a linear constraint.""" + # Note: added, duplicating in effect that in Constraint, to avoid issues with Sphinx + Sense = ConstraintSense + def __init__(self, - quadratic_program: "QuadraticProgram", name: str, + quadratic_program: Any, name: str, linear: Union[ndarray, spmatrix, List[float], Dict[Union[str, int], float]], sense: Constraint.Sense, rhs: float diff --git a/qiskit/optimization/problems/linear_expression.py b/qiskit/optimization/problems/linear_expression.py index 945aacbdb5..03d0e7f2a2 100644 --- a/qiskit/optimization/problems/linear_expression.py +++ b/qiskit/optimization/problems/linear_expression.py @@ -14,19 +14,19 @@ """Linear expression interface.""" -from typing import List, Union, Dict +from typing import List, Union, Dict, Any from numpy import ndarray from scipy.sparse import spmatrix, dok_matrix -from qiskit.optimization import QiskitOptimizationError -from qiskit.optimization.problems.quadratic_program_element import QuadraticProgramElement +from .quadratic_program_element import QuadraticProgramElement +from ..exceptions import QiskitOptimizationError class LinearExpression(QuadraticProgramElement): """ Representation of a linear expression by its coefficients.""" - def __init__(self, quadratic_program: "QuadraticProgram", + def __init__(self, quadratic_program: Any, coefficients: Union[ndarray, spmatrix, List[float], Dict[Union[int, str], float]]) -> None: """Creates a new linear expression. diff --git a/qiskit/optimization/problems/quadratic_constraint.py b/qiskit/optimization/problems/quadratic_constraint.py index f87cbab6ba..a4078e485a 100644 --- a/qiskit/optimization/problems/quadratic_constraint.py +++ b/qiskit/optimization/problems/quadratic_constraint.py @@ -14,21 +14,24 @@ """Quadratic Constraint.""" -from typing import Union, List, Dict, Tuple +from typing import Union, List, Dict, Tuple, Any from numpy import ndarray from scipy.sparse import spmatrix -from qiskit.optimization.problems.constraint import Constraint -from qiskit.optimization.problems.linear_expression import LinearExpression -from qiskit.optimization.problems.quadratic_expression import QuadraticExpression +from .constraint import Constraint, ConstraintSense +from .linear_expression import LinearExpression +from .quadratic_expression import QuadraticExpression class QuadraticConstraint(Constraint): """ Representation of a quadratic constraint.""" + # Note: added, duplicating in effect that in Constraint, to avoid issues with Sphinx + Sense = ConstraintSense + def __init__(self, - quadratic_program: "QuadraticProgram", name: str, + quadratic_program: Any, name: str, linear: Union[ndarray, spmatrix, List[float], Dict[Union[str, int], float]], quadratic: Union[ndarray, spmatrix, List[List[float]], Dict[Tuple[Union[int, str], Union[int, str]], float]], diff --git a/qiskit/optimization/problems/quadratic_expression.py b/qiskit/optimization/problems/quadratic_expression.py index d219f1f6b4..43555e0af9 100644 --- a/qiskit/optimization/problems/quadratic_expression.py +++ b/qiskit/optimization/problems/quadratic_expression.py @@ -14,20 +14,20 @@ """Quadratic expression interface.""" -from typing import List, Union, Dict, Tuple +from typing import List, Union, Dict, Tuple, Any import numpy as np from numpy import ndarray from scipy.sparse import spmatrix, dok_matrix, tril, triu -from qiskit.optimization import QiskitOptimizationError -from qiskit.optimization.problems.quadratic_program_element import QuadraticProgramElement +from .quadratic_program_element import QuadraticProgramElement +from ..exceptions import QiskitOptimizationError class QuadraticExpression(QuadraticProgramElement): """ Representation of a quadratic expression by its coefficients.""" - def __init__(self, quadratic_program: "QuadraticProgram", + def __init__(self, quadratic_program: Any, coefficients: Union[ndarray, spmatrix, List[List[float]], Dict[Tuple[Union[int, str], Union[int, str]], float]]) -> None: """Creates a new quadratic expression. diff --git a/qiskit/optimization/problems/quadratic_objective.py b/qiskit/optimization/problems/quadratic_objective.py index 7d2f9f32fd..82b16e192b 100644 --- a/qiskit/optimization/problems/quadratic_objective.py +++ b/qiskit/optimization/problems/quadratic_objective.py @@ -15,14 +15,14 @@ """Quadratic Objective.""" from enum import Enum -from typing import Union, List, Dict, Tuple +from typing import Union, List, Dict, Tuple, Any from numpy import ndarray from scipy.sparse import spmatrix -from qiskit.optimization.problems.quadratic_program_element import QuadraticProgramElement -from qiskit.optimization.problems.linear_constraint import LinearExpression -from qiskit.optimization.problems.quadratic_expression import QuadraticExpression +from .linear_constraint import LinearExpression +from .quadratic_expression import QuadraticExpression +from .quadratic_program_element import QuadraticProgramElement class ObjSense(Enum): @@ -38,7 +38,7 @@ class QuadraticObjective(QuadraticProgramElement): Sense = ObjSense - def __init__(self, quadratic_program: "QuadraticProgram", + def __init__(self, quadratic_program: Any, constant: float = 0.0, linear: Union[ndarray, spmatrix, List[float], Dict[Union[str, int], float]] = None, quadratic: Union[ndarray, spmatrix, List[List[float]], diff --git a/qiskit/optimization/problems/quadratic_program.py b/qiskit/optimization/problems/quadratic_program.py index 90c0109124..d8ce685f45 100644 --- a/qiskit/optimization/problems/quadratic_program.py +++ b/qiskit/optimization/problems/quadratic_program.py @@ -29,14 +29,15 @@ from numpy import ndarray from scipy.sparse import spmatrix -from qiskit.optimization import INFINITY, QiskitOptimizationError -from qiskit.optimization.problems.constraint import Constraint -from qiskit.optimization.problems.linear_constraint import LinearConstraint -from qiskit.optimization.problems.linear_expression import LinearExpression -from qiskit.optimization.problems.quadratic_constraint import QuadraticConstraint -from qiskit.optimization.problems.quadratic_expression import QuadraticExpression -from qiskit.optimization.problems.quadratic_objective import QuadraticObjective -from qiskit.optimization.problems.variable import Variable +from .constraint import Constraint +from .linear_constraint import LinearConstraint +from .linear_expression import LinearExpression +from .quadratic_constraint import QuadraticConstraint +from .quadratic_expression import QuadraticExpression +from .quadratic_objective import QuadraticObjective +from .variable import Variable +from ..exceptions import QiskitOptimizationError +from ..infinity import INFINITY logger = logging.getLogger(__name__) @@ -48,15 +49,15 @@ class QuadraticProgramStatus(Enum): class QuadraticProgram: - """Representation of a Quadratically Constrained Quadratic Program supporting inequality and - equality constraints as well as continuous, binary, and integer variables. - """ + """Quadratically Constrained Quadratic Program representation. + This representation supports inequality and equality constraints, + as well as continuous, binary, and integer variables. + """ Status = QuadraticProgramStatus def __init__(self, name: str = '') -> None: - """Constructs a quadratic program. - + """ Args: name: The name of the quadratic program. """ diff --git a/qiskit/optimization/problems/quadratic_program_element.py b/qiskit/optimization/problems/quadratic_program_element.py index f17bea036a..662475e549 100644 --- a/qiskit/optimization/problems/quadratic_program_element.py +++ b/qiskit/optimization/problems/quadratic_program_element.py @@ -14,20 +14,29 @@ """Interface for all objects that have a parent QuadraticProgram.""" +from typing import Any + class QuadraticProgramElement: """Interface class for all objects that have a parent QuadraticProgram.""" - def __init__(self, quadratic_program: "QuadraticProgram") -> None: + def __init__(self, quadratic_program: Any) -> None: """ Initialize object with parent QuadraticProgram. Args: quadratic_program: The parent QuadraticProgram. + Raises: + TypeError: QuadraticProgram instance expected. """ + from .quadratic_program import QuadraticProgram + + if not isinstance(quadratic_program, QuadraticProgram): + raise TypeError('QuadraticProgram instance expected') + self._quadratic_program = quadratic_program @property - def quadratic_program(self) -> "QuadraticProgram": + def quadratic_program(self) -> Any: """Returns the parent QuadraticProgram. Returns: @@ -36,10 +45,18 @@ def quadratic_program(self) -> "QuadraticProgram": return self._quadratic_program @quadratic_program.setter - def quadratic_program(self, quadratic_program: "QuadraticProgram") -> None: + def quadratic_program(self, quadratic_program: Any) -> None: """Sets the parent QuadraticProgram. Args: quadratic_program: The parent QuadraticProgram. + Raises: + TypeError: QuadraticProgram instance expected. """ + # pylint: disable=cyclic-import + from .quadratic_program import QuadraticProgram + + if not isinstance(quadratic_program, QuadraticProgram): + raise TypeError('QuadraticProgram instance expected') + self._quadratic_program = quadratic_program diff --git a/qiskit/optimization/problems/variable.py b/qiskit/optimization/problems/variable.py index 97cd8e685b..f1516f10d6 100644 --- a/qiskit/optimization/problems/variable.py +++ b/qiskit/optimization/problems/variable.py @@ -15,10 +15,11 @@ """Variable interface""" from enum import Enum -from typing import Tuple, Union +from typing import Tuple, Union, Any -from qiskit.optimization import INFINITY, QiskitOptimizationError -from qiskit.optimization.problems.quadratic_program_element import QuadraticProgramElement +from .quadratic_program_element import QuadraticProgramElement +from ..exceptions import QiskitOptimizationError +from ..infinity import INFINITY class VarType(Enum): @@ -33,7 +34,7 @@ class Variable(QuadraticProgramElement): Type = VarType - def __init__(self, quadratic_program: 'QuadraticProgram', name: str, + def __init__(self, quadratic_program: Any, name: str, lowerbound: Union[float, int] = 0, upperbound: Union[float, int] = INFINITY, vartype: VarType = VarType.CONTINUOUS) -> None: