diff --git a/qiskit_optimization/deprecation.py b/qiskit_optimization/deprecation.py index c87ab4f7c..5dd50a9b8 100644 --- a/qiskit_optimization/deprecation.py +++ b/qiskit_optimization/deprecation.py @@ -421,3 +421,12 @@ def deprecate_function( return _deprecate_object( version, DeprecatedType.FUNCTION, new_type, new_name, additional_msg, stack_level ) + + +def clear_deprecated_objects() -> None: + """Clear deprecated object cache + + Returns: + None + """ + _DEPRECATED_OBJECTS.clear() diff --git a/test/algorithms/legacy/test_min_eigen_optimizer.py b/test/algorithms/legacy/test_min_eigen_optimizer.py index 94c397bdd..e4e7e529d 100644 --- a/test/algorithms/legacy/test_min_eigen_optimizer.py +++ b/test/algorithms/legacy/test_min_eigen_optimizer.py @@ -43,6 +43,7 @@ ) from qiskit_optimization.problems import QuadraticProgram from qiskit_optimization.runtime import VQEProgram, QAOAProgram +from qiskit_optimization.deprecation import clear_deprecated_objects @ddt @@ -382,6 +383,15 @@ def test_runtime(self, subroutine): result = opt.solve(self.op_ordering) self.assertIsInstance(result, MinimumEigenOptimizationResult) + def test_deprecation(self): + """Test deprecation warning""" + clear_deprecated_objects() + optimizer = SPSA(maxiter=100) + ry_ansatz = TwoLocal(5, "ry", "cz", reps=3, entanglement="full") + vqe_mes = VQE(ry_ansatz, optimizer=optimizer, quantum_instance=QasmSimulatorPy()) + with self.assertWarns(DeprecationWarning): + _ = MinimumEigenOptimizer(vqe_mes) + if __name__ == "__main__": unittest.main() diff --git a/test/algorithms/legacy/test_recursive_optimization.py b/test/algorithms/legacy/test_recursive_optimization.py new file mode 100644 index 000000000..efe8399e6 --- /dev/null +++ b/test/algorithms/legacy/test_recursive_optimization.py @@ -0,0 +1,201 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2018, 2022. +# +# 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. + +"""Test Recursive Min Eigen Optimizer with legacy MinimumEigensolver.""" + +import unittest +from test import QiskitOptimizationTestCase + +import numpy as np + +from qiskit import BasicAer +from qiskit.utils import algorithm_globals, QuantumInstance + +from qiskit.algorithms import NumPyMinimumEigensolver, QAOA + +import qiskit_optimization.optionals as _optionals +from qiskit_optimization.algorithms import ( + MinimumEigenOptimizer, + CplexOptimizer, + RecursiveMinimumEigenOptimizer, + WarmStartQAOAOptimizer, + SlsqpOptimizer, +) +from qiskit_optimization.algorithms.recursive_minimum_eigen_optimizer import ( + IntermediateResult, +) +from qiskit_optimization.problems import QuadraticProgram +from qiskit_optimization.converters import ( + IntegerToBinary, + InequalityToEquality, + LinearEqualityToPenalty, + QuadraticProgramToQubo, +) + + +class TestRecursiveMinEigenOptimizer(QiskitOptimizationTestCase): + """Recursive Min Eigen Optimizer Tests.""" + + @unittest.skipIf(not _optionals.HAS_CPLEX, "CPLEX not available.") + def test_recursive_min_eigen_optimizer(self): + """Test the recursive minimum eigen optimizer.""" + filename = "op_ip1.lp" + # get minimum eigen solver + min_eigen_solver = NumPyMinimumEigensolver() + + # construct minimum eigen optimizer + min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver) + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer( + min_eigen_optimizer, min_num_vars=4 + ) + + # load optimization problem + problem = QuadraticProgram() + lp_file = self.get_resource_path(filename, "algorithms/resources") + problem.read_from_lp_file(lp_file) + + # solve problem with cplex + cplex = CplexOptimizer() + cplex_result = cplex.solve(problem) + + # solve problem + result = recursive_min_eigen_optimizer.solve(problem) + + # analyze results + np.testing.assert_array_almost_equal(cplex_result.x, result.x, 4) + self.assertAlmostEqual(cplex_result.fval, result.fval) + + @unittest.skipIf(not _optionals.HAS_CPLEX, "CPLEX not available.") + def test_recursive_history(self): + """Tests different options for history.""" + filename = "op_ip1.lp" + # load optimization problem + problem = QuadraticProgram() + lp_file = self.get_resource_path(filename, "algorithms/resources") + problem.read_from_lp_file(lp_file) + + # get minimum eigen solver + min_eigen_solver = NumPyMinimumEigensolver() + + # construct minimum eigen optimizer + min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver) + + # no history + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer( + min_eigen_optimizer, + min_num_vars=4, + history=IntermediateResult.NO_ITERATIONS, + ) + result = recursive_min_eigen_optimizer.solve(problem) + self.assertIsNotNone(result.replacements) + self.assertIsNotNone(result.history) + self.assertIsNotNone(result.history[0]) + self.assertEqual(len(result.history[0]), 0) + self.assertIsNone(result.history[1]) + + # only last iteration in the history + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer( + min_eigen_optimizer, + min_num_vars=4, + history=IntermediateResult.LAST_ITERATION, + ) + result = recursive_min_eigen_optimizer.solve(problem) + self.assertIsNotNone(result.replacements) + self.assertIsNotNone(result.history) + self.assertIsNotNone(result.history[0]) + self.assertEqual(len(result.history[0]), 0) + self.assertIsNotNone(result.history[1]) + + # full history + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer( + min_eigen_optimizer, + min_num_vars=4, + history=IntermediateResult.ALL_ITERATIONS, + ) + result = recursive_min_eigen_optimizer.solve(problem) + self.assertIsNotNone(result.replacements) + self.assertIsNotNone(result.history) + self.assertIsNotNone(result.history[0]) + self.assertGreater(len(result.history[0]), 1) + self.assertIsNotNone(result.history[1]) + + @unittest.skipIf(not _optionals.HAS_CPLEX, "CPLEX not available.") + def test_recursive_warm_qaoa(self): + """Test the recursive optimizer with warm start qaoa.""" + seed = 1234 + algorithm_globals.random_seed = seed + backend = BasicAer.get_backend("statevector_simulator") + qaoa = QAOA( + quantum_instance=QuantumInstance( + backend=backend, seed_simulator=seed, seed_transpiler=seed + ), + reps=1, + ) + warm_qaoa = WarmStartQAOAOptimizer( + pre_solver=SlsqpOptimizer(), relax_for_pre_solver=True, qaoa=qaoa + ) + + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer(warm_qaoa, min_num_vars=4) + + # load optimization problem + problem = QuadraticProgram() + lp_file = self.get_resource_path("op_ip1.lp", "algorithms/resources") + problem.read_from_lp_file(lp_file) + + # solve problem with cplex + cplex = CplexOptimizer(cplex_parameters={"threads": 1, "randomseed": 1}) + cplex_result = cplex.solve(problem) + + # solve problem + result = recursive_min_eigen_optimizer.solve(problem) + + # analyze results + np.testing.assert_array_almost_equal(cplex_result.x, result.x, 4) + self.assertAlmostEqual(cplex_result.fval, result.fval) + + def test_converter_list(self): + """Test converter list""" + op = QuadraticProgram() + op.integer_var(0, 3, "x") + op.binary_var("y") + + op.maximize(linear={"x": 1, "y": 2}) + op.linear_constraint(linear={"y": 1, "x": 1}, sense="LE", rhs=3, name="xy_leq") + + # construct minimum eigen optimizer + min_eigen_solver = NumPyMinimumEigensolver() + min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver) + # a single converter + qp2qubo = QuadraticProgramToQubo() + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer( + min_eigen_optimizer, min_num_vars=2, converters=qp2qubo + ) + result = recursive_min_eigen_optimizer.solve(op) + self.assertEqual(result.fval, 4) + # a list of converters + ineq2eq = InequalityToEquality() + int2bin = IntegerToBinary() + penalize = LinearEqualityToPenalty() + converters = [ineq2eq, int2bin, penalize] + recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer( + min_eigen_optimizer, min_num_vars=2, converters=converters + ) + result = recursive_min_eigen_optimizer.solve(op) + self.assertEqual(result.fval, 4) + # invalid converters + with self.assertRaises(TypeError): + invalid = [qp2qubo, "invalid converter"] + RecursiveMinimumEigenOptimizer(min_eigen_optimizer, min_num_vars=2, converters=invalid) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/algorithms/legacy/test_warm_start_qaoa.py b/test/algorithms/legacy/test_warm_start_qaoa.py new file mode 100644 index 000000000..550cf0cc8 --- /dev/null +++ b/test/algorithms/legacy/test_warm_start_qaoa.py @@ -0,0 +1,134 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 2021, 2022. +# +# 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. + +""" Test warm start QAOA optimizer with legacy MinimumEigensolver. """ + +import unittest +from test import QiskitOptimizationTestCase + +import numpy as np + +from docplex.mp.model import Model +from qiskit import BasicAer +from qiskit.algorithms import QAOA + +import qiskit_optimization.optionals as _optionals +from qiskit_optimization.algorithms import SlsqpOptimizer +from qiskit_optimization.algorithms.goemans_williamson_optimizer import ( + GoemansWilliamsonOptimizer, +) +from qiskit_optimization.algorithms.warm_start_qaoa_optimizer import ( + MeanAggregator, + WarmStartQAOAOptimizer, +) +from qiskit_optimization.applications.max_cut import Maxcut +from qiskit_optimization.translators import from_docplex_mp + + +class TestWarmStartQAOAOptimizer(QiskitOptimizationTestCase): + """Tests for the warm start QAOA optimizer.""" + + @unittest.skipIf(not _optionals.HAS_CVXPY, "CVXPY not available.") + def test_max_cut(self): + """Basic test on the max cut problem.""" + graph = np.array( + [ + [0.0, 1.0, 2.0, 0.0], + [1.0, 0.0, 1.0, 0.0], + [2.0, 1.0, 0.0, 1.0], + [0.0, 0.0, 1.0, 0.0], + ] + ) + + presolver = GoemansWilliamsonOptimizer(num_cuts=10) + problem = Maxcut(graph).to_quadratic_program() + + backend = BasicAer.get_backend("statevector_simulator") + qaoa = QAOA(quantum_instance=backend, reps=1) + aggregator = MeanAggregator() + optimizer = WarmStartQAOAOptimizer( + pre_solver=presolver, + relax_for_pre_solver=False, + qaoa=qaoa, + epsilon=0.25, + num_initial_solutions=10, + aggregator=aggregator, + ) + result_warm = optimizer.solve(problem) + + self.assertIsNotNone(result_warm) + self.assertIsNotNone(result_warm.x) + np.testing.assert_almost_equal([0, 0, 1, 0], result_warm.x, 3) + self.assertIsNotNone(result_warm.fval) + np.testing.assert_almost_equal(4, result_warm.fval, 3) + + def test_constrained_binary(self): + """Constrained binary optimization problem.""" + model = Model() + v = model.binary_var(name="v") + w = model.binary_var(name="w") + # pylint:disable=invalid-name + t = model.binary_var(name="t") + + model.minimize(v + w + t) + model.add_constraint(2 * v + 10 * w + t <= 3, "cons1") + model.add_constraint(v + w + t >= 2, "cons2") + + problem = from_docplex_mp(model) + + backend = BasicAer.get_backend("statevector_simulator") + qaoa = QAOA(quantum_instance=backend, reps=1) + aggregator = MeanAggregator() + optimizer = WarmStartQAOAOptimizer( + pre_solver=SlsqpOptimizer(), + relax_for_pre_solver=True, + qaoa=qaoa, + epsilon=0.25, + aggregator=aggregator, + ) + result_warm = optimizer.solve(problem) + + self.assertIsNotNone(result_warm) + self.assertIsNotNone(result_warm.x) + np.testing.assert_almost_equal([1, 0, 1], result_warm.x, 3) + self.assertIsNotNone(result_warm.fval) + np.testing.assert_almost_equal(2, result_warm.fval, 3) + + def test_simple_qubo(self): + """Test on a simple QUBO problem.""" + model = Model() + # pylint:disable=invalid-name + u = model.binary_var(name="u") + v = model.binary_var(name="v") + + model.minimize((u - v + 2) ** 2) + problem = from_docplex_mp(model) + + backend = BasicAer.get_backend("statevector_simulator") + qaoa = QAOA(quantum_instance=backend, reps=1) + optimizer = WarmStartQAOAOptimizer( + pre_solver=SlsqpOptimizer(), + relax_for_pre_solver=True, + qaoa=qaoa, + epsilon=0.25, + ) + result_warm = optimizer.solve(problem) + + self.assertIsNotNone(result_warm) + self.assertIsNotNone(result_warm.x) + np.testing.assert_almost_equal([0, 1], result_warm.x, 3) + self.assertIsNotNone(result_warm.fval) + np.testing.assert_almost_equal(1, result_warm.fval, 3) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/algorithms/test_min_eigen_optimizer.py b/test/algorithms/test_min_eigen_optimizer.py index e8193623a..a5b518e78 100644 --- a/test/algorithms/test_min_eigen_optimizer.py +++ b/test/algorithms/test_min_eigen_optimizer.py @@ -19,7 +19,6 @@ import numpy as np from ddt import data, ddt, unpack from qiskit.algorithms.minimum_eigensolvers import QAOA, NumPyMinimumEigensolver, SamplingVQE -from qiskit.algorithms.minimum_eigen_solvers import VQE from qiskit.algorithms.optimizers import COBYLA, SPSA from qiskit.circuit.library import TwoLocal from qiskit.primitives import Sampler @@ -364,14 +363,6 @@ def test_runtime(self, subroutine): result = opt.solve(self.op_ordering) self.assertIsInstance(result, MinimumEigenOptimizationResult) - def test_deprecation(self): - """Test deprecation warning""" - optimizer = SPSA(maxiter=100) - ry_ansatz = TwoLocal(5, "ry", "cz", reps=3, entanglement="full") - vqe_mes = VQE(ry_ansatz, optimizer=optimizer, quantum_instance=QasmSimulatorPy()) - with self.assertWarns(DeprecationWarning): - _ = MinimumEigenOptimizer(vqe_mes) - if __name__ == "__main__": unittest.main() diff --git a/test/algorithms/test_recursive_optimization.py b/test/algorithms/test_recursive_optimization.py old mode 100755 new mode 100644 index 53e206b7b..ec8c6d9cc --- a/test/algorithms/test_recursive_optimization.py +++ b/test/algorithms/test_recursive_optimization.py @@ -10,36 +10,33 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Test Recursive Min Eigen Optimizer.""" +"""Test Recursive Min Eigen Optimizer with the primitive-based minimum eigensolver.""" import unittest from test import QiskitOptimizationTestCase import numpy as np - -from qiskit import BasicAer -from qiskit.utils import algorithm_globals, QuantumInstance - -from qiskit.algorithms import NumPyMinimumEigensolver, QAOA +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 import qiskit_optimization.optionals as _optionals from qiskit_optimization.algorithms import ( - MinimumEigenOptimizer, CplexOptimizer, + MinimumEigenOptimizer, RecursiveMinimumEigenOptimizer, - WarmStartQAOAOptimizer, SlsqpOptimizer, + WarmStartQAOAOptimizer, ) -from qiskit_optimization.algorithms.recursive_minimum_eigen_optimizer import ( - IntermediateResult, -) -from qiskit_optimization.problems import QuadraticProgram +from qiskit_optimization.algorithms.recursive_minimum_eigen_optimizer import IntermediateResult from qiskit_optimization.converters import ( - IntegerToBinary, InequalityToEquality, + IntegerToBinary, LinearEqualityToPenalty, QuadraticProgramToQubo, ) +from qiskit_optimization.problems import QuadraticProgram class TestRecursiveMinEigenOptimizer(QiskitOptimizationTestCase): @@ -133,11 +130,9 @@ def test_recursive_warm_qaoa(self): """Test the recursive optimizer with warm start qaoa.""" seed = 1234 algorithm_globals.random_seed = seed - backend = BasicAer.get_backend("statevector_simulator") qaoa = QAOA( - quantum_instance=QuantumInstance( - backend=backend, seed_simulator=seed, seed_transpiler=seed - ), + sampler=Sampler(), + optimizer=SLSQP(), reps=1, ) warm_qaoa = WarmStartQAOAOptimizer( diff --git a/test/algorithms/test_warm_start_qaoa.py b/test/algorithms/test_warm_start_qaoa.py index 39f0dba0c..be83a392b 100644 --- a/test/algorithms/test_warm_start_qaoa.py +++ b/test/algorithms/test_warm_start_qaoa.py @@ -10,22 +10,20 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" Test warm start QAOA optimizer. """ +""" Test warm start QAOA optimizer with the primitive-based minimum eigensolver. """ import unittest from test import QiskitOptimizationTestCase import numpy as np - from docplex.mp.model import Model -from qiskit import BasicAer -from qiskit.algorithms import QAOA +from qiskit.algorithms.minimum_eigensolvers import QAOA +from qiskit.algorithms.optimizers import SLSQP +from qiskit.primitives.sampler import Sampler import qiskit_optimization.optionals as _optionals from qiskit_optimization.algorithms import SlsqpOptimizer -from qiskit_optimization.algorithms.goemans_williamson_optimizer import ( - GoemansWilliamsonOptimizer, -) +from qiskit_optimization.algorithms.goemans_williamson_optimizer import GoemansWilliamsonOptimizer from qiskit_optimization.algorithms.warm_start_qaoa_optimizer import ( MeanAggregator, WarmStartQAOAOptimizer, @@ -52,8 +50,7 @@ def test_max_cut(self): presolver = GoemansWilliamsonOptimizer(num_cuts=10) problem = Maxcut(graph).to_quadratic_program() - backend = BasicAer.get_backend("statevector_simulator") - qaoa = QAOA(quantum_instance=backend, reps=1) + qaoa = QAOA(sampler=Sampler(), optimizer=SLSQP(), reps=1) aggregator = MeanAggregator() optimizer = WarmStartQAOAOptimizer( pre_solver=presolver, @@ -85,8 +82,7 @@ def test_constrained_binary(self): problem = from_docplex_mp(model) - backend = BasicAer.get_backend("statevector_simulator") - qaoa = QAOA(quantum_instance=backend, reps=1) + qaoa = QAOA(sampler=Sampler(), optimizer=SLSQP(), reps=1) aggregator = MeanAggregator() optimizer = WarmStartQAOAOptimizer( pre_solver=SlsqpOptimizer(), @@ -113,8 +109,7 @@ def test_simple_qubo(self): model.minimize((u - v + 2) ** 2) problem = from_docplex_mp(model) - backend = BasicAer.get_backend("statevector_simulator") - qaoa = QAOA(quantum_instance=backend, reps=1) + qaoa = QAOA(sampler=Sampler(), optimizer=SLSQP(), reps=1) optimizer = WarmStartQAOAOptimizer( pre_solver=SlsqpOptimizer(), relax_for_pre_solver=True,