Skip to content

Commit

Permalink
Variational Quantum Time Evolution algorithm. (Qiskit#8152)
Browse files Browse the repository at this point in the history
* Fixed requirements-dev.txt

* Fixed some pylint.

* Fixed some pylint.

* Update Documentation variational principles

* updates documentation

* minor documentation

* Added unit tests docs and some package docs.

* Code refactoring.

* Code refactoring.

* Code refactoring.

* Update qiskit/opflow/evolutions/pauli_trotter_evolution.py

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Renamed the main folder.

* Code refactoring.

* Update qiskit/algorithms/quantum_time_evolution/variational/calculators/evolution_grad_calculator.py

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Code refactoring.

* Update qiskit/algorithms/time_evolution/variational/error_calculators/gradient_errors/error_calculator.py

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Code refactoring.

* Lint fixes.

* Code refactoring.

* Code refactoring.

* Code refactoring.

* Code refactoring.

* Code refactoring, docs fixed.

* Code refactoring, docs fixed.

* Code refactoring and docs improved.

* Exposed optimizer tolerance as an argument.

* Exposed allowed imaginary part as an argument.

* Exposed allowed numerical instability as an argument.

* Code refactoring.

* Introduced evolution_result.py class.

* Minor bugfix.

* Integrated evolution result to VarQte algorithms.

* Code refactoring.

* Black formatting fix.

* Fixed signatures.

* Fixed random seed setup.

* Fixed too long lines.

* Deleted unnecessary files.

* Some fixes in test_gradients.py

* Copyright date updated.

* Refactored getting rid of flags.

* Updated unit tests after refactoring.

* Removed a duplicated argument.

* Implemented general Quantum Time Evolution Framework interfaces.

* Updated docs.

* Reno added.

* Improved reno.

* Code refactoring.

* Code refactoring.

* Typehints added.

* Made variational_principle.py stateless.

* Updated copyright years.

* Simplified var_qte.py class.

* Refactored var_qte_linear_solver.py

* Refactored abstract_ode_function_generator.py

* Refactored var_qte_linear_solver.py

* Refactored var_qte.py

* Code formatting.

* ODE solvers and optimizers as objects, not strings.

* Update qiskit/algorithms/time_evolution/evolution_base.py

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Code refactoring.

* Introduced evolution problem classes.

* Code refactoring.

* Apply suggestions from code review

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Added unit tests.

* Lint fixed.

* Code refactoring.

* Removed error_based_ode_function_generator.py for MVP.

* Code refactoring

* Code refactoring

* Code refactoring

* Code refactoring

* Code refactoring

* Code review changes.

* Removed gradient code for now.

* Evolving observable removed. Evaluating observables added.

* Improved naming.

* Improved folder structure; filled evolvers init file.

* Added Evolvers to algorithms init file.

* Fixed missing imports.

* Code refactoring

* Fixed cyclic imports.

* Extracted ListOrDict.

* Code refactoring.

* Code refactoring.

* Fixed release note.

* Fixed inheritance order.

* Code refactoring.

* Code refactoring.

* Fixed cyclic imports.

* Name fix.

* Updated the algorithm to the latest version of interfaces.

* Code refactoring.

* Adapted unit tests to evolution problem.

* Implemented aux_ops evaluation.

* Fixed position of quantum_instance.

* Added algorithms to algorithms init.

* Imports refactoring.

* Imports refactoring.

* Updated code to the latest gradient framework.

* Code refactoring.

* Imports refactoring.

* Added gradient files.

* Code review addressed. Fixed tests.

* Switched to 1 sampler.

* Added unit tests for expected errors.

* Improved docs.

* Changed folder structure.

* Added test_evolution_grad_calculator.py unit test with bases.

* Updated interfaces.

* Added VarQite unit test with aux ops.

* Added VarQite unit test with aux ops.

* Added VarQrte unit test with aux ops.

* Update releasenotes/notes/add-variational-quantum-time-evolution-112ffeaf62782fea.yaml

Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com>

* Code refactoring.

* Code refactoring.

* Code refactoring.

* Improved docs of variational principles.

* Code refactoring.

* Code refactoring.

* Simplified var principles folder structure.

* Opened VarQte algorithms for field modification.

* Improved Sphinx docs.

* Code refactoring.

* Introduced ode_function_factory.py

* Removed hardcoded rcond.

* Renamed hamiltonian_value_dict.

* Renamed hamiltonian_value_dict.

* Extracted lengthy expected results in tests.

* Updated unit tests.

* Apply suggestions from code review

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Apply suggestions from code review

* Extended release notes.

* Removed dead code.

* Improved ode solver types.

* Moved evolve method for now.

* Shortened Var Principles names.

* Updated metric_tensor_calculator.py

* Updated docs

* Removed ordered_parameters.

* Added and corrected code examples.

* Extended unit tests.

* Extended unit tests.

* Extended unit tests.

* Improved init files.

* Improved init files.

* Improved init files.

* Improved init files.

* Improved docs.

* Import fix

* Renamed sle to lse.

* Code refactoring.

* Replaced metric tensor calculator.

* Replaced evolution gradient calculator.

* Code refactoring.

* Removed evolution_grad_calculator.py

* Removed evolution_grad_calculator.py

* Evolution grad calculator removal; code refactoring; dirty bug fix.

* Added docs.

* Code refactoring

* Improved performance of evolution grad.

* Improved performance of evolution grad, code refactoring; bug fixed.

* Improved LSE solver handling.

* Improved docs.

* Unindented reno

* Mitigated some cyclic imports.

* Unindented reno

* Improved docs

* Lint resolutions

* Fix some line-too-long in tests

* Fixed lint.

* Fixed lint.

* Apply suggestions from code review

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Code review changes.

* Added reno for a bug fix.

* Fixed lint.

* Updated docs.

* Moved lse_solver to ODE factory.

* Made ODE factory optional and defaults set.

* Added expectation method argument and set defaults to PauliExpectation.

* Limited supported methods for real_time_dependent_principle.py.

* Fix imports.

* Updated docs.

* Implemented the Forward Euler ODE solver. Implemented a unit test.

* Set Forward Euler ODE solver as a default. Updated unit tests.

* Sync with main.

* Exposed ODE number of steps.

* Code refactoring

* Code refactoring

* Code refactoring

* Exposed ode_num_t_steps to the user; reduced default ode_num_t_steps; added ForwardEulerSolver to docs.

* Updated tests.

* Fixed CI.

* Fixed docs.

* Hides OdeFunction from the user.

* Update qiskit/algorithms/evolvers/variational/var_qrte.py

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Update releasenotes/notes/add-variational-quantum-time-evolution-112ffeaf62782fea.yaml

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Removes unsupported error-based method flag for now.

* Switched num time steps to deltas in ODEs.

* Code refactoring.

* Fixed typhint.

* Switched back to num_steps for ODE.

* Slow tests and code refactoring.

* Code refactoring.

* Removed TD variational principle.

* Apply suggestions from code review

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Code refactoring.

* Improved signatures; support for list of parameter values.

* Code refactoring.

* Improved variable name.

* Updated docs.

Co-authored-by: CZ <ouf@zurich.ibm.com>
Co-authored-by: Julien Gacon <gaconju@gmail.com>
Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com>
Co-authored-by: woodsp-ibm <woodsp@us.ibm.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
6 people authored Aug 23, 2022
1 parent 4c54532 commit 2eda51e
Show file tree
Hide file tree
Showing 44 changed files with 3,832 additions and 25 deletions.
18 changes: 18 additions & 0 deletions qiskit/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@
VQD
Variational Quantum Time Evolution
----------------------------------
Classes used by variational quantum time evolution algorithms - VarQITE and VarQRTE.
.. autosummary::
:toctree: ../stubs/
evolvers.variational
Evolvers
--------
Expand All @@ -108,11 +119,14 @@
RealEvolver
ImaginaryEvolver
TrotterQRTE
VarQITE
VarQRTE
PVQD
PVQDResult
EvolutionResult
EvolutionProblem
Factorizers
-----------
Expand Down Expand Up @@ -248,6 +262,8 @@
from .exceptions import AlgorithmError
from .aux_ops_evaluator import eval_observables
from .evolvers.trotterization import TrotterQRTE
from .evolvers.variational.var_qite import VarQITE
from .evolvers.variational.var_qrte import VarQRTE
from .evolvers.pvqd import PVQD, PVQDResult

__all__ = [
Expand All @@ -273,6 +289,8 @@
"RealEvolver",
"ImaginaryEvolver",
"TrotterQRTE",
"VarQITE",
"VarQRTE",
"EvolutionResult",
"EvolutionProblem",
"LinearSolverResult",
Expand Down
12 changes: 6 additions & 6 deletions qiskit/algorithms/evolvers/evolution_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(
aux_operators: Optional[ListOrDict[OperatorBase]] = None,
truncation_threshold: float = 1e-12,
t_param: Optional[Parameter] = None,
hamiltonian_value_dict: Optional[Dict[Parameter, complex]] = None,
param_value_dict: Optional[Dict[Parameter, complex]] = None,
):
"""
Args:
Expand All @@ -50,15 +50,15 @@ def __init__(
Used when ``aux_operators`` is provided.
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.
param_value_dict: Maps free parameters in the problem to values. Depending on the
algorithm, it might refer to e.g. a Hamiltonian or an initial state.
Raises:
ValueError: If non-positive time of evolution is provided.
"""

self.t_param = t_param
self.hamiltonian_value_dict = hamiltonian_value_dict
self.param_value_dict = param_value_dict
self.hamiltonian = hamiltonian
self.time = time
self.initial_state = initial_state
Expand Down Expand Up @@ -95,9 +95,9 @@ def validate_params(self) -> None:
if self.t_param is not None:
t_param_set.add(self.t_param)
hamiltonian_dict_param_set = set()
if self.hamiltonian_value_dict is not None:
if self.param_value_dict is not None:
hamiltonian_dict_param_set = hamiltonian_dict_param_set.union(
set(self.hamiltonian_value_dict.keys())
set(self.param_value_dict.keys())
)
params_set = t_param_set.union(hamiltonian_dict_param_set)
hamiltonian_param_set = set(self.hamiltonian.parameters)
Expand Down
2 changes: 1 addition & 1 deletion qiskit/algorithms/evolvers/trotterization/trotter_qrte.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def evolve(self, evolution_problem: EvolutionProblem) -> EvolutionResult:
f"PauliSumOp | SummedOp, {type(hamiltonian)} provided."
)
if isinstance(hamiltonian, OperatorBase):
hamiltonian = hamiltonian.bind_parameters(evolution_problem.hamiltonian_value_dict)
hamiltonian = hamiltonian.bind_parameters(evolution_problem.param_value_dict)
if isinstance(hamiltonian, SummedOp):
hamiltonian = self._summed_op_to_pauli_sum_op(hamiltonian)
# the evolution gate
Expand Down
139 changes: 139 additions & 0 deletions qiskit/algorithms/evolvers/variational/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# 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.
"""
Variational Quantum Time Evolutions (:mod:`qiskit.algorithms.evolvers.variational`)
===================================================================================
Algorithms for performing Variational Quantum Time Evolution of quantum states,
which can be tailored to near-term devices.
:class:`~qiskit.algorithms.evolvers.variational.VarQTE` base class exposes an interface, compliant
with the Quantum Time Evolution Framework in Qiskit Terra, that is implemented by
:class:`~qiskit.algorithms.VarQRTE` and :class:`~qiskit.algorithms.VarQITE` classes for real and
imaginary time evolution respectively. The variational approach is taken according to a variational
principle chosen by a user.
Examples:
.. code-block::
from qiskit import BasicAer
from qiskit.circuit.library import EfficientSU2
from qiskit.opflow import SummedOp, I, Z, Y, X
from qiskit.algorithms.evolvers.variational import (
ImaginaryMcLachlanPrinciple,
)
from qiskit.algorithms import EvolutionProblem
from qiskit.algorithms import VarQITE
# define a Hamiltonian
observable = SummedOp(
[
0.2252 * (I ^ I),
0.5716 * (Z ^ Z),
0.3435 * (I ^ Z),
-0.4347 * (Z ^ I),
0.091 * (Y ^ Y),
0.091 * (X ^ X),
]
).reduce()
# define a parametrized initial state to be evolved
ansatz = EfficientSU2(observable.num_qubits, reps=1)
parameters = ansatz.parameters
# define values of initial parameters
init_param_values = np.zeros(len(ansatz.parameters))
for i in range(len(ansatz.parameters)):
init_param_values[i] = np.pi / 2
param_dict = dict(zip(parameters, init_param_values))
# define a variational principle
var_principle = ImaginaryMcLachlanPrinciple()
# optionally define a backend
backend = BasicAer.get_backend("statevector_simulator")
# define evolution time
time = 1
# define evolution problem
evolution_problem = EvolutionProblem(observable, time)
# instantiate the algorithm
var_qite = VarQITE(ansatz, var_principle, param_dict, quantum_instance=backend)
# run the algorithm/evolve the state
evolution_result = var_qite.evolve(evolution_problem)
.. currentmodule:: qiskit.algorithms.evolvers.variational
Variational Principles
----------------------
Variational principles can be used to simulate quantum time evolution by propagating the parameters
of a parameterized quantum circuit.
They can be divided into two categories:
1) Variational Quantum Imaginary Time Evolution
Given a Hamiltonian, a time and a variational ansatz, the variational principle describes a
variational principle according to the normalized Wick-rotated Schroedinger equation.
2) Variational Quantum Real Time Evolution
Given a Hamiltonian, a time and a variational ansatz, the variational principle describes a
variational principle according to the Schroedinger equation.
.. autosummary::
:toctree: ../stubs/
:template: autosummary/class_no_inherited_members.rst
VariationalPrinciple
RealVariationalPrinciple
ImaginaryVariationalPrinciple
RealMcLachlanPrinciple
ImaginaryMcLachlanPrinciple
ODE solvers
-----------
ODE solvers that implement the SciPy ODE Solver interface. The Forward Euler Solver is
a preferred choice in the presence of noise. One might also use solvers provided by SciPy directly,
e.g. RK45.
.. autosummary::
:toctree: ../stubs/
:template: autosummary/class_no_inherited_members.rst
ForwardEulerSolver
"""
from .solvers.ode.forward_euler_solver import ForwardEulerSolver
from .var_qte import VarQTE
from .variational_principles.variational_principle import VariationalPrinciple
from .variational_principles import RealVariationalPrinciple, ImaginaryVariationalPrinciple
from .variational_principles.imaginary_mc_lachlan_principle import (
ImaginaryMcLachlanPrinciple,
)
from .variational_principles.real_mc_lachlan_principle import (
RealMcLachlanPrinciple,
)


__all__ = [
"ForwardEulerSolver",
"VarQTE",
"VariationalPrinciple",
"RealVariationalPrinciple",
"ImaginaryVariationalPrinciple",
"RealMcLachlanPrinciple",
"ImaginaryMcLachlanPrinciple",
]
44 changes: 44 additions & 0 deletions qiskit/algorithms/evolvers/variational/solvers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 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.

"""
Solvers (:mod:`qiskit.algorithms.evolvers.variational.solvers`)
===============================================================
This package contains the necessary classes to solve systems of equations arising in the
Variational Quantum Time Evolution. They include ordinary differential equations (ODE) which
describe ansatz parameter propagation and systems of linear equations.
Systems of Linear Equations Solver
----------------------------------
.. autosummary::
:toctree: ../stubs/
:template: autosummary/class_no_inherited_members.rst
VarQTELinearSolver
ODE Solver
----------
.. autosummary::
:toctree: ../stubs/
:template: autosummary/class_no_inherited_members.rst
VarQTEOdeSolver
"""

from qiskit.algorithms.evolvers.variational.solvers.ode.var_qte_ode_solver import VarQTEOdeSolver
from qiskit.algorithms.evolvers.variational.solvers.var_qte_linear_solver import VarQTELinearSolver

__all__ = ["VarQTELinearSolver", "VarQTEOdeSolver"]
13 changes: 13 additions & 0 deletions qiskit/algorithms/evolvers/variational/solvers/ode/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 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.

"""ODE Solvers"""
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 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.

"""Abstract class for generating ODE functions."""

from abc import ABC, abstractmethod
from typing import Iterable, Dict, Optional
from qiskit.circuit import Parameter
from ..var_qte_linear_solver import (
VarQTELinearSolver,
)


class AbstractOdeFunction(ABC):
"""Abstract class for generating ODE functions."""

def __init__(
self,
varqte_linear_solver: VarQTELinearSolver,
error_calculator,
param_dict: Dict[Parameter, complex],
t_param: Optional[Parameter] = None,
) -> None:

self._varqte_linear_solver = varqte_linear_solver
self._error_calculator = error_calculator
self._param_dict = param_dict
self._t_param = t_param

@abstractmethod
def var_qte_ode_function(self, time: float, parameters_values: Iterable) -> Iterable:
"""
Evaluates an ODE function for a given time and parameter values. It is used by an ODE
solver.
Args:
time: Current time of evolution.
parameters_values: Current values of parameters.
Returns:
ODE gradient arising from solving a system of linear equations.
"""
pass
Loading

0 comments on commit 2eda51e

Please sign in to comment.