From 52bb078953fedd4b32fdb5ee30032111352ce256 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 1 Apr 2022 11:02:32 +0200 Subject: [PATCH 1/4] Revert "Revert "Implemented general Quantum Time Evolution Framework interfaces. (#7669)" (#7845)" This reverts commit 1b6c1b30f869d682f893138dd5b331c24e659899. Co-authored-by: dlasecki --- qiskit/algorithms/__init__.py | 23 ++++++ qiskit/algorithms/aux_ops_evaluator.py | 2 +- .../algorithms/eigen_solvers/eigen_solver.py | 8 +- .../eigen_solvers/numpy_eigen_solver.py | 3 +- qiskit/algorithms/evolvers/__init__.py | 21 +++++ .../algorithms/evolvers/evolution_problem.py | 58 ++++++++++++++ .../algorithms/evolvers/evolution_result.py | 40 ++++++++++ qiskit/algorithms/evolvers/evolver.py | 36 +++++++++ .../algorithms/evolvers/imaginary/__init__.py | 11 +++ .../evolvers/imaginary/imaginary_evolver.py | 21 +++++ qiskit/algorithms/evolvers/real/__init__.py | 11 +++ .../algorithms/evolvers/real/real_evolver.py | 21 +++++ qiskit/algorithms/list_or_dict.py | 18 +++++ .../minimum_eigen_solver.py | 8 +- .../numpy_minimum_eigen_solver.py | 3 +- .../algorithms/minimum_eigen_solvers/vqe.py | 3 +- .../time-evo-framework-9d58827bdbbebd62.yaml | 13 ++++ test/python/algorithms/evolvers/__init__.py | 11 +++ .../evolvers/test_evolution_problem.py | 76 +++++++++++++++++++ .../evolvers/test_evolution_result.py | 48 ++++++++++++ .../algorithms/test_aux_ops_evaluator.py | 2 +- 21 files changed, 422 insertions(+), 15 deletions(-) create mode 100644 qiskit/algorithms/evolvers/__init__.py create mode 100644 qiskit/algorithms/evolvers/evolution_problem.py create mode 100644 qiskit/algorithms/evolvers/evolution_result.py create mode 100644 qiskit/algorithms/evolvers/evolver.py create mode 100644 qiskit/algorithms/evolvers/imaginary/__init__.py create mode 100644 qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py create mode 100644 qiskit/algorithms/evolvers/real/__init__.py create mode 100644 qiskit/algorithms/evolvers/real/real_evolver.py create mode 100644 qiskit/algorithms/list_or_dict.py create mode 100644 releasenotes/notes/time-evo-framework-9d58827bdbbebd62.yaml create mode 100644 test/python/algorithms/evolvers/__init__.py create mode 100644 test/python/algorithms/evolvers/test_evolution_problem.py create mode 100644 test/python/algorithms/evolvers/test_evolution_result.py diff --git a/qiskit/algorithms/__init__.py b/qiskit/algorithms/__init__.py index 73d8544ce244..0c3ed197f2c6 100644 --- a/qiskit/algorithms/__init__.py +++ b/qiskit/algorithms/__init__.py @@ -93,6 +93,22 @@ NumPyEigensolver +Evolvers +-------- + +Algorithms to evolve quantum states in time. Both real and imaginary time evolution is possible +with algorithms that support them. For machine learning, Quantum Imaginary Time Evolution might be +used to train Quantum Boltzmann Machine Neural Networks for example. + +.. autosummary:: + :toctree: ../stubs/ + :nosignatures: + + RealEvolver + ImaginaryEvolver + EvolutionResult + EvolutionProblem + Factorizers ----------- @@ -188,6 +204,9 @@ """ from .algorithm_result import AlgorithmResult +from .evolvers import EvolutionResult, EvolutionProblem +from .evolvers.real.real_evolver import RealEvolver +from .evolvers.imaginary.imaginary_evolver import ImaginaryEvolver from .variational_algorithm import VariationalAlgorithm, VariationalResult from .amplitude_amplifiers import Grover, GroverResult, AmplificationProblem, AmplitudeAmplifier from .amplitude_estimators import ( @@ -245,6 +264,10 @@ "MaximumLikelihoodAmplitudeEstimationResult", "EstimationProblem", "NumPyEigensolver", + "RealEvolver", + "ImaginaryEvolver", + "EvolutionResult", + "EvolutionProblem", "LinearSolverResult", "Eigensolver", "EigensolverResult", diff --git a/qiskit/algorithms/aux_ops_evaluator.py b/qiskit/algorithms/aux_ops_evaluator.py index c72958ace3a5..a57ac5198f10 100644 --- a/qiskit/algorithms/aux_ops_evaluator.py +++ b/qiskit/algorithms/aux_ops_evaluator.py @@ -16,7 +16,7 @@ import numpy as np from qiskit import QuantumCircuit -from qiskit.algorithms.eigen_solvers.eigen_solver import ListOrDict +from qiskit.algorithms.minimum_eigen_solvers.minimum_eigen_solver import ListOrDict from qiskit.opflow import ( CircuitSampler, ListOp, diff --git a/qiskit/algorithms/eigen_solvers/eigen_solver.py b/qiskit/algorithms/eigen_solvers/eigen_solver.py index bdb8933ac5ea..28ca3e9d1f8b 100644 --- a/qiskit/algorithms/eigen_solvers/eigen_solver.py +++ b/qiskit/algorithms/eigen_solvers/eigen_solver.py @@ -13,15 +13,13 @@ """The Eigensolver interface""" from abc import ABC, abstractmethod -from typing import Dict, Optional, List, Union, Tuple, TypeVar +from typing import Optional, List, Tuple import numpy as np + from qiskit.opflow import OperatorBase from ..algorithm_result import AlgorithmResult - -# Introduced new type to maintain readability. -_T = TypeVar("_T") # Pylint does not allow single character class names. -ListOrDict = Union[List[Optional[_T]], Dict[str, _T]] +from ..list_or_dict import ListOrDict class Eigensolver(ABC): diff --git a/qiskit/algorithms/eigen_solvers/numpy_eigen_solver.py b/qiskit/algorithms/eigen_solvers/numpy_eigen_solver.py index c30504b676d3..4abbe7ed4a26 100755 --- a/qiskit/algorithms/eigen_solvers/numpy_eigen_solver.py +++ b/qiskit/algorithms/eigen_solvers/numpy_eigen_solver.py @@ -21,7 +21,8 @@ from qiskit.opflow import I, ListOp, OperatorBase, StateFn from qiskit.utils.validation import validate_min from ..exceptions import AlgorithmError -from .eigen_solver import Eigensolver, EigensolverResult, ListOrDict +from .eigen_solver import Eigensolver, EigensolverResult +from ..list_or_dict import ListOrDict logger = logging.getLogger(__name__) diff --git a/qiskit/algorithms/evolvers/__init__.py b/qiskit/algorithms/evolvers/__init__.py new file mode 100644 index 000000000000..990c787b7c15 --- /dev/null +++ b/qiskit/algorithms/evolvers/__init__.py @@ -0,0 +1,21 @@ +# 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. + +"""Quantum Time Evolution package.""" + +from .evolution_result import EvolutionResult +from .evolution_problem import EvolutionProblem + +__all__ = [ + "EvolutionResult", + "EvolutionProblem", +] diff --git a/qiskit/algorithms/evolvers/evolution_problem.py b/qiskit/algorithms/evolvers/evolution_problem.py new file mode 100644 index 000000000000..f926dbdf3d96 --- /dev/null +++ b/qiskit/algorithms/evolvers/evolution_problem.py @@ -0,0 +1,58 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 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. + +"""Evolution problem class.""" + +from typing import Union, Optional, Dict + +from qiskit import QuantumCircuit +from qiskit.circuit import Parameter +from qiskit.opflow import OperatorBase, StateFn +from ..list_or_dict import ListOrDict + + +class EvolutionProblem: + """Evolution problem class. + + This class is the input to time evolution algorithms and contains + information on e.g. the total evolution time and under which Hamiltonian + the state is evolved. + """ + + def __init__( + self, + hamiltonian: OperatorBase, + time: float, + initial_state: Union[StateFn, QuantumCircuit], + aux_operators: Optional[ListOrDict[OperatorBase]] = None, + t_param: Optional[Parameter] = None, + hamiltonian_value_dict: Optional[Dict[Parameter, Union[complex]]] = None, + ): + """ + Args: + hamiltonian: The Hamiltonian under which to evolve the system. + time: Total time of evolution. + initial_state: Quantum state to be evolved. + aux_operators: Optional list of auxiliary operators to be evaluated with the + evolved ``initial_state`` and their expectation values returned. + t_param: Time parameter in case of a time-dependent Hamiltonian. This + free parameter must be within the ``hamiltonian``. + hamiltonian_value_dict: If the Hamiltonian contains free parameters, this + dictionary maps all these parameters to values. + """ + + self.hamiltonian = hamiltonian + self.time = time + self.initial_state = initial_state + self.aux_operators = aux_operators + self.t_param = t_param + self.hamiltonian_value_dict = hamiltonian_value_dict diff --git a/qiskit/algorithms/evolvers/evolution_result.py b/qiskit/algorithms/evolvers/evolution_result.py new file mode 100644 index 000000000000..ead37fd98dfc --- /dev/null +++ b/qiskit/algorithms/evolvers/evolution_result.py @@ -0,0 +1,40 @@ +# 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. + +"""Class for holding evolution result.""" + +from typing import Optional, Union, Tuple + +from qiskit import QuantumCircuit +from qiskit.algorithms.list_or_dict import ListOrDict +from qiskit.opflow import StateFn +from ..algorithm_result import AlgorithmResult + + +class EvolutionResult(AlgorithmResult): + """Class for holding evolution result.""" + + def __init__( + self, + evolved_state: Union[StateFn, QuantumCircuit], + aux_ops_evaluated: Optional[ListOrDict[Tuple[complex, complex]]] = None, + ): + """ + Args: + evolved_state: An evolved quantum state. + aux_ops_evaluated: Optional list of observables for which expected values on an evolved + state are calculated. These values are in fact tuples formatted as (mean, standard + deviation). + """ + + self.evolved_state = evolved_state + self.aux_ops_evaluated = aux_ops_evaluated diff --git a/qiskit/algorithms/evolvers/evolver.py b/qiskit/algorithms/evolvers/evolver.py new file mode 100644 index 000000000000..06b1f22d56bd --- /dev/null +++ b/qiskit/algorithms/evolvers/evolver.py @@ -0,0 +1,36 @@ +# 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. + +"""Interface for quantum time evolution.""" + +from abc import ABC, abstractmethod + +from . import EvolutionProblem +from . import EvolutionResult + + +class Evolver(ABC): + """Interface class for quantum time evolution.""" + + @abstractmethod + def evolve(self, evolution_problem: EvolutionProblem) -> EvolutionResult: + """ + Evolves an initial state in the evolution_problem according to a Hamiltonian provided. + + Args: + evolution_problem: ``EvolutionProblem`` instance that includes definition of an evolution + problem. + + Returns: + Evolution result which includes an evolved quantum state. + """ + raise NotImplementedError() diff --git a/qiskit/algorithms/evolvers/imaginary/__init__.py b/qiskit/algorithms/evolvers/imaginary/__init__.py new file mode 100644 index 000000000000..b3ac36d2a6d9 --- /dev/null +++ b/qiskit/algorithms/evolvers/imaginary/__init__.py @@ -0,0 +1,11 @@ +# 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. diff --git a/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py b/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py new file mode 100644 index 000000000000..4b1ab96eecdf --- /dev/null +++ b/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py @@ -0,0 +1,21 @@ +# 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. + +"""Base class for Quantum Imaginary Time Evolution used for typing purposes.""" + +from abc import ABC + +from ..evolver import Evolver + + +class ImaginaryEvolver(Evolver, ABC): + """Base class for Quantum Imaginary Time Evolution used for typing purposes.""" diff --git a/qiskit/algorithms/evolvers/real/__init__.py b/qiskit/algorithms/evolvers/real/__init__.py new file mode 100644 index 000000000000..b3ac36d2a6d9 --- /dev/null +++ b/qiskit/algorithms/evolvers/real/__init__.py @@ -0,0 +1,11 @@ +# 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. diff --git a/qiskit/algorithms/evolvers/real/real_evolver.py b/qiskit/algorithms/evolvers/real/real_evolver.py new file mode 100644 index 000000000000..c1663ed3868c --- /dev/null +++ b/qiskit/algorithms/evolvers/real/real_evolver.py @@ -0,0 +1,21 @@ +# 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. + +"""Base class for Quantum Real Time Evolution used for typing purposes.""" + +from abc import ABC + +from ..evolver import Evolver + + +class RealEvolver(Evolver, ABC): + """Base class for Quantum Real Time Evolution used for typing purposes.""" diff --git a/qiskit/algorithms/list_or_dict.py b/qiskit/algorithms/list_or_dict.py new file mode 100644 index 000000000000..95314dd79a3b --- /dev/null +++ b/qiskit/algorithms/list_or_dict.py @@ -0,0 +1,18 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 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. + +"""Introduced new type to maintain readability.""" + +from typing import TypeVar, List, Union, Optional, Dict + +_T = TypeVar("_T") # Pylint does not allow single character class names. +ListOrDict = Union[List[Optional[_T]], Dict[str, _T]] diff --git a/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py b/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py index 545cf289643b..7cdd245b7076 100644 --- a/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py +++ b/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py @@ -13,15 +13,13 @@ """The Minimum Eigensolver interface""" from abc import ABC, abstractmethod -from typing import Dict, Optional, List, Union, Tuple, TypeVar +from typing import Optional, Tuple import numpy as np + from qiskit.opflow import OperatorBase from ..algorithm_result import AlgorithmResult - -# Introduced new type to maintain readability. -_T = TypeVar("_T") # Pylint does not allow single character class names. -ListOrDict = Union[List[Optional[_T]], Dict[str, _T]] +from ..list_or_dict import ListOrDict class MinimumEigensolver(ABC): diff --git a/qiskit/algorithms/minimum_eigen_solvers/numpy_minimum_eigen_solver.py b/qiskit/algorithms/minimum_eigen_solvers/numpy_minimum_eigen_solver.py index 369485976cdf..5515ba92d745 100644 --- a/qiskit/algorithms/minimum_eigen_solvers/numpy_minimum_eigen_solver.py +++ b/qiskit/algorithms/minimum_eigen_solvers/numpy_minimum_eigen_solver.py @@ -18,7 +18,8 @@ from qiskit.opflow import OperatorBase from ..eigen_solvers.numpy_eigen_solver import NumPyEigensolver -from .minimum_eigen_solver import MinimumEigensolver, MinimumEigensolverResult, ListOrDict +from .minimum_eigen_solver import MinimumEigensolver, MinimumEigensolverResult +from ..list_or_dict import ListOrDict logger = logging.getLogger(__name__) diff --git a/qiskit/algorithms/minimum_eigen_solvers/vqe.py b/qiskit/algorithms/minimum_eigen_solvers/vqe.py index 4be503b25e76..e401a2b007cd 100755 --- a/qiskit/algorithms/minimum_eigen_solvers/vqe.py +++ b/qiskit/algorithms/minimum_eigen_solvers/vqe.py @@ -40,9 +40,10 @@ from qiskit.utils.validation import validate_min from qiskit.utils.backend_utils import is_aer_provider from qiskit.utils import QuantumInstance, algorithm_globals +from ..list_or_dict import ListOrDict from ..optimizers import Optimizer, SLSQP, OptimizerResult from ..variational_algorithm import VariationalAlgorithm, VariationalResult -from .minimum_eigen_solver import MinimumEigensolver, MinimumEigensolverResult, ListOrDict +from .minimum_eigen_solver import MinimumEigensolver, MinimumEigensolverResult from ..exceptions import AlgorithmError from ..aux_ops_evaluator import eval_observables diff --git a/releasenotes/notes/time-evo-framework-9d58827bdbbebd62.yaml b/releasenotes/notes/time-evo-framework-9d58827bdbbebd62.yaml new file mode 100644 index 000000000000..06bc667a96d5 --- /dev/null +++ b/releasenotes/notes/time-evo-framework-9d58827bdbbebd62.yaml @@ -0,0 +1,13 @@ +--- +features: + - | + Interfaces for the unified framework for Quantum Time Evolution are introduced. + :class:`~qiskit.algorithms.EvolutionProblem` defines an evolution problem and + can be passed to any evolution algorithm available in the framework. + :class:`~qiskit.algorithms.ImaginaryEvolver` and + :class:`~qiskit.algorithms.RealEvolver` are interfaces for + imaginary and real time evolution cases respectively. They serve as a base for any time + evolution algorithm for evolving quantum states, including evolutions based on + time-dependent Hamiltonians. + :class:`~qiskit.algorithms.EvolutionResult` is introduced as a result object + for quantum time evolution algorithms. diff --git a/test/python/algorithms/evolvers/__init__.py b/test/python/algorithms/evolvers/__init__.py new file mode 100644 index 000000000000..fdb172d367f0 --- /dev/null +++ b/test/python/algorithms/evolvers/__init__.py @@ -0,0 +1,11 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 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. diff --git a/test/python/algorithms/evolvers/test_evolution_problem.py b/test/python/algorithms/evolvers/test_evolution_problem.py new file mode 100644 index 000000000000..cdd472247045 --- /dev/null +++ b/test/python/algorithms/evolvers/test_evolution_problem.py @@ -0,0 +1,76 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 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 evolver problem class.""" +import unittest + +from test.python.algorithms import QiskitAlgorithmsTestCase +from qiskit.algorithms.evolvers.evolution_problem import EvolutionProblem +from qiskit.circuit import Parameter +from qiskit.opflow import Y, Z, One, X + + +class TestEvolutionProblem(QiskitAlgorithmsTestCase): + """Test evolver problem class.""" + + def test_init_default(self): + """Tests that all default fields are initialized correctly.""" + hamiltonian = Y + time = 2.5 + initial_state = One + + evo_problem = EvolutionProblem(hamiltonian, time, initial_state) + + expected_hamiltonian = Y + expected_time = 2.5 + expected_initial_state = One + expected_aux_operators = None + expected_t_param = None + expected_hamiltonian_value_dict = None + + self.assertEqual(evo_problem.hamiltonian, expected_hamiltonian) + self.assertEqual(evo_problem.time, expected_time) + self.assertEqual(evo_problem.initial_state, expected_initial_state) + self.assertEqual(evo_problem.aux_operators, expected_aux_operators) + self.assertEqual(evo_problem.t_param, expected_t_param) + self.assertEqual(evo_problem.hamiltonian_value_dict, expected_hamiltonian_value_dict) + + def test_init_all(self): + """Tests that all fields are initialized correctly.""" + t_parameter = Parameter("t") + hamiltonian = t_parameter * Z + Y + time = 2 + initial_state = One + aux_operators = [X, Y] + hamiltonian_value_dict = {t_parameter: 3.2} + + evo_problem = EvolutionProblem( + hamiltonian, time, initial_state, aux_operators, t_parameter, hamiltonian_value_dict + ) + + expected_hamiltonian = Y + t_parameter * Z + expected_time = 2 + expected_initial_state = One + expected_aux_operators = [X, Y] + expected_t_param = t_parameter + expected_hamiltonian_value_dict = {t_parameter: 3.2} + + self.assertEqual(evo_problem.hamiltonian, expected_hamiltonian) + self.assertEqual(evo_problem.time, expected_time) + self.assertEqual(evo_problem.initial_state, expected_initial_state) + self.assertEqual(evo_problem.aux_operators, expected_aux_operators) + self.assertEqual(evo_problem.t_param, expected_t_param) + self.assertEqual(evo_problem.hamiltonian_value_dict, expected_hamiltonian_value_dict) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/python/algorithms/evolvers/test_evolution_result.py b/test/python/algorithms/evolvers/test_evolution_result.py new file mode 100644 index 000000000000..5500b283a1cb --- /dev/null +++ b/test/python/algorithms/evolvers/test_evolution_result.py @@ -0,0 +1,48 @@ +# This code is part of Qiskit. +# +# (C) Copyright IBM 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. +"""Class for testing evolution result.""" +import unittest + +from test.python.algorithms import QiskitAlgorithmsTestCase +from qiskit.algorithms.evolvers.evolution_result import EvolutionResult +from qiskit.opflow import Zero + + +class TestEvolutionResult(QiskitAlgorithmsTestCase): + """Class for testing evolution result and relevant metadata.""" + + def test_init_state(self): + """Tests that a class is initialized correctly with an evolved_state.""" + evolved_state = Zero + evo_result = EvolutionResult(evolved_state=evolved_state) + + expected_state = Zero + expected_aux_ops_evaluated = None + + self.assertEqual(evo_result.evolved_state, expected_state) + self.assertEqual(evo_result.aux_ops_evaluated, expected_aux_ops_evaluated) + + def test_init_observable(self): + """Tests that a class is initialized correctly with an evolved_observable.""" + evolved_state = Zero + evolved_aux_ops_evaluated = [(5j, 5j), (1.0, 8j), (5 + 1j, 6 + 1j)] + evo_result = EvolutionResult(evolved_state, evolved_aux_ops_evaluated) + + expected_state = Zero + expected_aux_ops_evaluated = [(5j, 5j), (1.0, 8j), (5 + 1j, 6 + 1j)] + + self.assertEqual(evo_result.evolved_state, expected_state) + self.assertEqual(evo_result.aux_ops_evaluated, expected_aux_ops_evaluated) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/python/algorithms/test_aux_ops_evaluator.py b/test/python/algorithms/test_aux_ops_evaluator.py index b43f5b5bec82..db6f231d9840 100644 --- a/test/python/algorithms/test_aux_ops_evaluator.py +++ b/test/python/algorithms/test_aux_ops_evaluator.py @@ -18,7 +18,7 @@ import numpy as np from ddt import ddt, data -from qiskit.algorithms.eigen_solvers.eigen_solver import ListOrDict +from qiskit.algorithms.list_or_dict import ListOrDict from qiskit.providers import BaseBackend, Backend from qiskit.quantum_info import Statevector from qiskit.algorithms import eval_observables From 6c23888fefbd920def0214acbbb5fccbddfed9d0 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Tue, 5 Apr 2022 17:59:25 +0200 Subject: [PATCH 2/4] remove Evolver base class --- qiskit/algorithms/evolvers/evolver.py | 36 ------------------- .../evolvers/imaginary/imaginary_evolver.py | 26 +++++++++++--- .../algorithms/evolvers/real/real_evolver.py | 26 +++++++++++--- 3 files changed, 42 insertions(+), 46 deletions(-) delete mode 100644 qiskit/algorithms/evolvers/evolver.py diff --git a/qiskit/algorithms/evolvers/evolver.py b/qiskit/algorithms/evolvers/evolver.py deleted file mode 100644 index 06b1f22d56bd..000000000000 --- a/qiskit/algorithms/evolvers/evolver.py +++ /dev/null @@ -1,36 +0,0 @@ -# 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. - -"""Interface for quantum time evolution.""" - -from abc import ABC, abstractmethod - -from . import EvolutionProblem -from . import EvolutionResult - - -class Evolver(ABC): - """Interface class for quantum time evolution.""" - - @abstractmethod - def evolve(self, evolution_problem: EvolutionProblem) -> EvolutionResult: - """ - Evolves an initial state in the evolution_problem according to a Hamiltonian provided. - - Args: - evolution_problem: ``EvolutionProblem`` instance that includes definition of an evolution - problem. - - Returns: - Evolution result which includes an evolved quantum state. - """ - raise NotImplementedError() diff --git a/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py b/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py index 4b1ab96eecdf..7743597c1e31 100644 --- a/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py +++ b/qiskit/algorithms/evolvers/imaginary/imaginary_evolver.py @@ -10,12 +10,28 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Base class for Quantum Imaginary Time Evolution used for typing purposes.""" +"""Interface for Quantum Imaginary Time Evolution.""" -from abc import ABC +from abc import ABC, abstractmethod -from ..evolver import Evolver +from ..evolution_problem import EvolutionProblem +from ..evolution_result import EvolutionResult -class ImaginaryEvolver(Evolver, ABC): - """Base class for Quantum Imaginary Time Evolution used for typing purposes.""" +class ImaginaryEvolver(ABC): + """Interface for Quantum Imaginary Time Evolution.""" + + @abstractmethod + def evolve(self, evolution_problem: EvolutionProblem) -> EvolutionResult: + r"""Perform imaginary time evolution :math:`\exp(-\tau H)|\Psi\rangle`. + + Evolves an initial state :math:`|\Psi\rangle` for an imaginary time :math:`\tau` + under a Hamiltonian :math:`H`, as provided in the ``evolution_problem``. + + Args: + evolution_problem: The definition of the evolution problem. + + Returns: + Evolution result which includes an evolved quantum state. + """ + raise NotImplementedError() diff --git a/qiskit/algorithms/evolvers/real/real_evolver.py b/qiskit/algorithms/evolvers/real/real_evolver.py index c1663ed3868c..b6c2f2b989dc 100644 --- a/qiskit/algorithms/evolvers/real/real_evolver.py +++ b/qiskit/algorithms/evolvers/real/real_evolver.py @@ -10,12 +10,28 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Base class for Quantum Real Time Evolution used for typing purposes.""" +"""Interface for Quantum Real Time Evolution.""" -from abc import ABC +from abc import ABC, abstractmethod -from ..evolver import Evolver +from ..evolution_problem import EvolutionProblem +from ..evolution_result import EvolutionResult -class RealEvolver(Evolver, ABC): - """Base class for Quantum Real Time Evolution used for typing purposes.""" +class RealEvolver(ABC): + """Interface for Quantum Real Time Evolution.""" + + @abstractmethod + def evolve(self, evolution_problem: EvolutionProblem) -> EvolutionResult: + r"""Perform real time evolution :math:`\exp(-i t H)|\Psi\rangle`. + + Evolves an initial state :math:`|\Psi\rangle` for a time :math:`t` + under a Hamiltonian :math:`H`, as provided in the ``evolution_problem``. + + Args: + evolution_problem: The definition of the evolution problem. + + Returns: + Evolution result which includes an evolved quantum state. + """ + raise NotImplementedError() From ae1ff76960266fe1332660e4b58eaec5432bd8b5 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Tue, 5 Apr 2022 22:44:33 +0200 Subject: [PATCH 3/4] Don't import list or dict from MES Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com> --- qiskit/algorithms/aux_ops_evaluator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/algorithms/aux_ops_evaluator.py b/qiskit/algorithms/aux_ops_evaluator.py index a57ac5198f10..97e8857ffd8e 100644 --- a/qiskit/algorithms/aux_ops_evaluator.py +++ b/qiskit/algorithms/aux_ops_evaluator.py @@ -16,7 +16,7 @@ import numpy as np from qiskit import QuantumCircuit -from qiskit.algorithms.minimum_eigen_solvers.minimum_eigen_solver import ListOrDict +from .list_or_dict import ListOrDict from qiskit.opflow import ( CircuitSampler, ListOp, From 04a05280fd497d557ae2810d442f228c6b09f80e Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Wed, 6 Apr 2022 10:48:03 +0200 Subject: [PATCH 4/4] fix import order --- qiskit/algorithms/aux_ops_evaluator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiskit/algorithms/aux_ops_evaluator.py b/qiskit/algorithms/aux_ops_evaluator.py index 97e8857ffd8e..3947c976f8ce 100644 --- a/qiskit/algorithms/aux_ops_evaluator.py +++ b/qiskit/algorithms/aux_ops_evaluator.py @@ -16,7 +16,6 @@ import numpy as np from qiskit import QuantumCircuit -from .list_or_dict import ListOrDict from qiskit.opflow import ( CircuitSampler, ListOp, @@ -28,6 +27,8 @@ from qiskit.quantum_info import Statevector from qiskit.utils import QuantumInstance +from .list_or_dict import ListOrDict + def eval_observables( quantum_instance: Union[QuantumInstance, BaseBackend, Backend],