diff --git a/qiskit/algorithms/quantum_time_evolution/real/implementations/trotterization/trotter_qrte.py b/qiskit/algorithms/quantum_time_evolution/real/implementations/trotterization/trotter_qrte.py index 74dd88d29631..fdc0d77439c3 100644 --- a/qiskit/algorithms/quantum_time_evolution/real/implementations/trotterization/trotter_qrte.py +++ b/qiskit/algorithms/quantum_time_evolution/real/implementations/trotterization/trotter_qrte.py @@ -9,53 +9,99 @@ # 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. + +"""An algorithm to implement a Trotterization real time-evolution.""" + import numbers from collections import defaultdict from typing import Union, Optional -from qiskit.algorithms.quantum_time_evolution.builders.implementations.trotterizations.trotter_mode_enum import ( - TrotterModeEnum, -) -from qiskit.algorithms.quantum_time_evolution.builders.implementations.trotterizations.trotterization_factory import ( - TrotterizationFactory, -) from qiskit.algorithms.quantum_time_evolution.real.qrte import Qrte from qiskit.algorithms.quantum_time_evolution.results.evolution_gradient_result import ( EvolutionGradientResult, ) from qiskit.algorithms.quantum_time_evolution.results.evolution_result import EvolutionResult from qiskit.circuit import Parameter, ParameterExpression -from qiskit.opflow import OperatorBase, StateFn, Gradient, commutator, SummedOp, PauliSumOp, PauliOp +from qiskit.opflow import OperatorBase, StateFn, Gradient, commutator, SummedOp, PauliSumOp, \ + PauliOp, CircuitOp +from qiskit.circuit.library import PauliEvolutionGate +from qiskit.synthesis import ProductFormula, LieTrotter class TrotterQrte(Qrte): - def __init__(self, mode: TrotterModeEnum, reps: int = 1): - self._mode = mode - self._reps = reps + """ TODO write documentation + + Examples: + + .. jupyter-execute:: + + from qiskit.opflow import X, Y, Zero + from qiskit.algorithms.quantum_time_evolution.real.implementations.\ + trotterization.trotter_qrte import TrotterQrte + + operator = X + Z + # LieTrotter with 1 rep + trotter_qrte = TrotterQrte() + initial_state = Zero + evolved_state = trotter_qrte.evolve(operator, 1, initial_state) + """ + def __init__(self, product_formula: ProductFormula = LieTrotter()): + """ + Args: + product_formula: A Lie-Trotter-Suzuki product formula. The default is the Lie-Trotter + first order product formula with a single repetition. + """ + self.product_formula = product_formula def evolve( self, - hamiltonian: OperatorBase, + hamiltonian, time: float, initial_state: StateFn = None, observable: OperatorBase = None, t_param: Parameter = None, hamiltonian_value_dict=None, ) -> EvolutionResult: + """ + Args: + hamiltonian (Pauli | PauliOp | SparsePauliOp | PauliSumOp | list): + The operator to evolve. Can also be provided as list of non-commuting + operators where the elements are sums of commuting operators. + For example: ``[XY + YX, ZZ + ZI + IZ, YY]``. + time: The evolution time. + initial_state: TODO. + observable: TODO. + t_param: Not accepted in this class. + hamiltonian_value_dict: TODO + + Returns: + The evolved hamiltonian applied to either an initial state or an observable. + + Raises: + ValueError: If t_param is not set to None (feature not currently supported). + """ + if t_param is not None: + raise ValueError("TrotterQrte does not accept a time dependent hamiltonian," + "t_param should be set to None.") hamiltonian = self._try_binding_params(hamiltonian, hamiltonian_value_dict) self._validate_input(initial_state, observable) - - trotter = TrotterizationFactory.build(self._mode, self._reps) - trotterized_evolution_op = trotter.build(time * hamiltonian) + # the evolution gate + evolution_gate = CircuitOp(PauliEvolutionGate(hamiltonian, time, + synthesis=self.product_formula)) if initial_state is not None: - return (trotterized_evolution_op @ initial_state).eval() + return (evolution_gate @ initial_state).eval() if observable is not None: - return trotterized_evolution_op.adjoint() @ observable @ trotterized_evolution_op + # TODO Temporary patch due to terra bug + evolution_gate_adjoint = CircuitOp(PauliEvolutionGate(hamiltonian[::-1], -time, + synthesis=self.product_formula)) + # return evolution_gate.adjoint() @ observable @ evolution_gate + return evolution_gate_adjoint @ observable @ evolution_gate def _try_binding_params(self, hamiltonian, hamiltonian_value_dict): - # PauliSumOp does not allow parametrized coefficients + # PauliSumOp does not allow parametrized coefficients but after binding the parameters + # we need to convert it into a PauliSumOp for the PauliEvolutionGate if isinstance(hamiltonian, SummedOp): op_list = [] for op in hamiltonian.oplist: @@ -69,7 +115,7 @@ def _try_binding_params(self, hamiltonian, hamiltonian_value_dict): f"these parameters encountered: {op_bound.parameters}." ) op_list.append(op_bound) - return SummedOp(op_list) + return sum(op_list) # for an observable, we might have an OperatorBase... TODO elif isinstance(hamiltonian, PauliOp): return hamiltonian.bind_parameters(hamiltonian_value_dict) @@ -82,7 +128,7 @@ def _validate_input(self, initial_state, observable): "TrotterQrte requires an initial state or an observable to be evolved; None " "provided." ) - elif initial_state is not None and observable is not None: + if initial_state is not None and observable is not None: raise ValueError( "TrotterQrte requires an initial state or an observable to be evolved; both " "provided." diff --git a/test/python/algorithms/quantum_time_evolution/real/implementations/trotterization/test_trotter_qrte.py b/test/python/algorithms/quantum_time_evolution/real/implementations/trotterization/test_trotter_qrte.py index 81d01e644456..47541ff89a35 100644 --- a/test/python/algorithms/quantum_time_evolution/real/implementations/trotterization/test_trotter_qrte.py +++ b/test/python/algorithms/quantum_time_evolution/real/implementations/trotterization/test_trotter_qrte.py @@ -9,21 +9,20 @@ # 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 Trotter Qrte. """ + import unittest +from test.python.opflow import QiskitOpflowTestCase import numpy as np from numpy.testing import assert_raises +from scipy.linalg import expm -from qiskit.algorithms.quantum_time_evolution.builders.implementations.trotterizations.trotter_mode_enum import ( - TrotterModeEnum, -) -from qiskit.algorithms.quantum_time_evolution.real.implementations.trotterization.trotter_qrte import ( - TrotterQrte, -) +from qiskit.algorithms.quantum_time_evolution.real.implementations.trotterization.trotter_qrte \ + import TrotterQrte from qiskit.quantum_info import Statevector from qiskit.utils import algorithm_globals -from test.python.opflow import QiskitOpflowTestCase from qiskit.circuit import Parameter from qiskit.opflow import ( X, @@ -35,6 +34,7 @@ I, Y, ) +from qiskit.synthesis import SuzukiTrotter, QDrift class TestTrotterQrte(QiskitOpflowTestCase): @@ -43,55 +43,58 @@ class TestTrotterQrte(QiskitOpflowTestCase): def test_trotter_qrte_trotter(self): """Test for trotter qrte.""" operator = X + Z - mode = TrotterModeEnum.TROTTER - trotter_qrte = TrotterQrte(mode) + # LieTrotter with 1 rep + trotter_qrte = TrotterQrte() initial_state = Zero evolved_state = trotter_qrte.evolve(operator, 1, initial_state) - expected_evolved_state = VectorStateFn( - Statevector([0.29192658 - 0.45464871j, -0.70807342 - 0.45464871j], dims=(2,)) - ) + # Calculate the expected state + expected_state = expm(-1j * Z.to_matrix()) @ expm(-1j * X.to_matrix()) @ \ + initial_state.to_matrix() + expected_evolved_state = VectorStateFn(Statevector(expected_state, dims=(2,))) np.testing.assert_equal(evolved_state, expected_evolved_state) def test_trotter_qrte_trotter_2(self): """Test for trotter qrte.""" - operator = X + Z - mode = TrotterModeEnum.TROTTER - trotter_qrte = TrotterQrte(mode) - initial_state = StateFn([1, 0]) + operator = [(X ^ Y) + (Y ^ X), (Z ^ Z) + (Z ^ I) + (I ^ Z), Y ^ Y] + # LieTrotter with 1 rep + trotter_qrte = TrotterQrte() + initial_state = StateFn([1, 0, 0, 0]) evolved_state = trotter_qrte.evolve(operator, 1, initial_state) - expected_evolved_state = VectorStateFn( - Statevector([0.29192658 - 0.45464871j, -0.70807342 - 0.45464871j], dims=(2,)) - ) + # Calculate the expected state + expected_state = initial_state.to_matrix() + for op in operator: + expected_state = expm(-1j * op.to_matrix()) @ expected_state + expected_evolved_state = VectorStateFn(Statevector(expected_state, dims=(2, 2))) np.testing.assert_equal(evolved_state, expected_evolved_state) def test_trotter_qrte_trotter_observable(self): """Test for trotter qrte with an observable.""" operator = X + Z - mode = TrotterModeEnum.TROTTER - trotter_qrte = TrotterQrte(mode) + # LieTrotter with 1 rep + trotter_qrte = TrotterQrte() observable = X evolved_observable = trotter_qrte.evolve(operator, 1, observable=observable) evolved_observable = evolved_observable.to_matrix_op() - expected_evolved_observable = MatrixOp( - [ - [2.99928030e-17 - 4.67110231e-17j, -4.16146837e-01 + 9.09297427e-01j], - [-4.16146837e-01 - 9.09297427e-01j, 0.00000000e00 + 0.00000000e00j], - ] - ) + # Calculate the expected operator + expected_op = expm(-1j * Z.to_matrix()) @ expm(-1j * X.to_matrix()) + expected_evolved_observable = MatrixOp(expected_op.conj().T @ observable.to_matrix() + @ expected_op) + np.testing.assert_equal(evolved_observable, expected_evolved_observable) def test_trotter_qrte_suzuki(self): """Test for trotter qrte with Suzuki.""" operator = X + Z - mode = TrotterModeEnum.SUZUKI - trotter_qrte = TrotterQrte(mode) + # 2nd order Suzuki with 1 rep + trotter_qrte = TrotterQrte(SuzukiTrotter()) initial_state = Zero evolved_state = trotter_qrte.evolve(operator, 1, initial_state) - expected_evolved_state = VectorStateFn( - Statevector([0.29192658 - 0.45464871j, 0.0 - 0.84147098j], dims=(2,)) - ) + # Calculate the expected state + expected_state = expm(-1j * X.to_matrix() * 0.5) @ expm(-1j * Z.to_matrix()) \ + @ expm(-1j * X.to_matrix() * 0.5) @ initial_state.to_matrix() + expected_evolved_state = VectorStateFn(Statevector(expected_state, dims=(2,))) np.testing.assert_equal(evolved_state, expected_evolved_state) @@ -99,43 +102,46 @@ def test_trotter_qrte_qdrift(self): """Test for trotter qrte with QDrift.""" algorithm_globals.random_seed = 0 operator = X + Z - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) + # QDrift with one repetition + trotter_qrte = TrotterQrte(QDrift()) initial_state = Zero evolved_state = trotter_qrte.evolve(operator, 1, initial_state) - expected_evolved_state = VectorStateFn( - Statevector([0.23071786 - 0.69436148j, -0.4646314 - 0.49874749j], dims=(2,)) - ) - - np.testing.assert_equal(evolved_state, expected_evolved_state) - - def test_trotter_qrte_trotter_binding(self): - """Test for trotter qrte with binding.""" - t_param = Parameter("t") - operator = X * t_param + Z - hamiltonian_value_dict = {t_param: 1} - mode = TrotterModeEnum.TROTTER - trotter_qrte = TrotterQrte(mode) - initial_state = Zero - evolved_state = trotter_qrte.evolve( - operator, - 1, - initial_state, - t_param=t_param, - hamiltonian_value_dict=hamiltonian_value_dict, - ) - expected_evolved_state = VectorStateFn( - Statevector([0.29192658 - 0.45464871j, -0.70807342 - 0.45464871j], dims=(2,)) - ) + sampled_ops = [Z, X, X, X, Z, Z, Z, Z] + evo_time = 0.25 + # Calculate the expected state + expected_state = initial_state.to_matrix() + for op in sampled_ops: + expected_state = expm(-1j * op.to_matrix() * evo_time) @ expected_state + expected_evolved_state = VectorStateFn(Statevector(expected_state, dims=(2,))) np.testing.assert_equal(evolved_state, expected_evolved_state) + # TODO this test is disabled for the time being - no t_param for TrotterQrte + # def test_trotter_qrte_trotter_binding(self): + # """Test for trotter qrte with binding.""" + # t_param = Parameter("t") + # operator = X * t_param + Z + # hamiltonian_value_dict = {t_param: 1} + # trotter_qrte = TrotterQrte() + # initial_state = Zero + # evolved_state = trotter_qrte.evolve( + # operator, + # 1, + # initial_state, + # t_param=t_param, + # hamiltonian_value_dict=hamiltonian_value_dict, + # ) + # expected_evolved_state = VectorStateFn( + # Statevector([0.29192658 - 0.45464871j, -0.70807342 - 0.45464871j], dims=(2,)) + # ) + # + # np.testing.assert_equal(evolved_state, expected_evolved_state) + # def test_trotter_qrte_trotter_binding_missing_dict(self): """Test for trotter qrte with binding and missing dictionary..""" t_param = Parameter("t") operator = X * t_param + Z - mode = TrotterModeEnum.TROTTER - trotter_qrte = TrotterQrte(mode) + trotter_qrte = TrotterQrte() initial_state = Zero with assert_raises(ValueError): _ = trotter_qrte.evolve(operator, 1, initial_state, t_param=t_param) @@ -144,8 +150,7 @@ def test_trotter_qrte_trotter_binding_missing_param(self): """Test for trotter qrte with binding and missing param.""" t_param = Parameter("t") operator = X * t_param + Z - mode = TrotterModeEnum.TROTTER - trotter_qrte = TrotterQrte(mode) + trotter_qrte = TrotterQrte() initial_state = Zero with assert_raises(ValueError): _ = trotter_qrte.evolve(operator, 1, initial_state) @@ -155,8 +160,7 @@ def test_trotter_qrte_gradient_summed_op_qdrift(self): theta1 = Parameter("theta1") theta2 = Parameter("theta2") operator = theta1 * (I ^ Z ^ I) + theta2 * (Z ^ I ^ I) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) + trotter_qrte = TrotterQrte(QDrift()) initial_state = Zero time = 5 gradient_object = None @@ -174,91 +178,90 @@ def test_trotter_qrte_gradient_summed_op_qdrift(self): expected_gradient = {theta1: 0j, theta2: 0j} np.testing.assert_equal(gradient, expected_gradient) - # TODO fails due to Terra bug - def test_trotter_qrte_gradient_summed_op_qdrift_2(self): - """Test for trotter qrte gradient with SummedOp and QDrift with commuting operators.""" - theta1 = Parameter("theta1") - theta2 = Parameter("theta2") - operator = (theta1 * (Y ^ Z ^ Y)) + theta2 * (Z ^ X ^ X) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) - initial_state = Zero - time = 5 - gradient_object = None - observable = X ^ Y ^ Z - value_dict = {theta1: 2, theta2: 3} - gradient = trotter_qrte.gradient( - operator, - time, - initial_state, - gradient_object, - observable, - hamiltonian_value_dict=value_dict, - gradient_params=[theta1, theta2], - ) - expected_gradient = {theta1: 0j, theta2: 0j} - print(gradient) - # np.testing.assert_equal(gradient, expected_gradient) - - # TODO fails due to Terra bug - def test_trotter_qrte_gradient_summed_op_qdrift_3(self): - """Test for trotter qrte gradient with SummedOp and QDrift with commuting operators.""" - theta1 = Parameter("theta1") - theta2 = Parameter("theta2") - operator = (theta1 * (Y ^ Z ^ Y)) + theta2 * (Z ^ X ^ X) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) - initial_state = Zero - time = 5 - gradient_object = None - observable = -1j * (X ^ Y ^ Z) - value_dict = {theta1: 2, theta2: 3} - gradient = trotter_qrte.gradient( - operator, - time, - initial_state, - gradient_object, - observable, - hamiltonian_value_dict=value_dict, - gradient_params=[theta1, theta2], - ) - expected_gradient = {theta1: 0j, theta2: 0j} - print(gradient) - # np.testing.assert_equal(gradient, expected_gradient) - - # TODO fails due to Terra bug - def test_trotter_qrte_gradient_summed_op_qdrift_4(self): - """Test for trotter qrte gradient with SummedOp and QDrift with commuting operators - with complex parameter binding.""" - theta1 = Parameter("theta1") - theta2 = Parameter("theta2") - operator = theta1 * (Z) + theta2 * (Y) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) - initial_state = Zero - time = 5 - gradient_object = None - observable = X - value_dict = {theta1: 2, theta2: 3} - gradient = trotter_qrte.gradient( - operator, - time, - initial_state, - gradient_object, - observable, - hamiltonian_value_dict=value_dict, - gradient_params=[theta1, theta2], - ) - expected_gradient = {theta1: 0j, theta2: 0j} - print(gradient) - # np.testing.assert_equal(gradient, expected_gradient) + # # TODO fails due to Terra bug + # def test_trotter_qrte_gradient_summed_op_qdrift_2(self): + # """Test for trotter qrte gradient with SummedOp and QDrift with commuting operators.""" + # theta1 = Parameter("theta1") + # theta2 = Parameter("theta2") + # operator = (theta1 * (Y ^ Z ^ Y)) + theta2 * (Z ^ X ^ X) + # mode = TrotterModeEnum.QDRIFT + # trotter_qrte = TrotterQrte(mode) + # initial_state = Zero + # time = 5 + # gradient_object = None + # observable = X ^ Y ^ Z + # value_dict = {theta1: 2, theta2: 3} + # gradient = trotter_qrte.gradient( + # operator, + # time, + # initial_state, + # gradient_object, + # observable, + # hamiltonian_value_dict=value_dict, + # gradient_params=[theta1, theta2], + # ) + # expected_gradient = {theta1: 0j, theta2: 0j} + # print(gradient) + # # np.testing.assert_equal(gradient, expected_gradient) + # + # # TODO fails due to Terra bug + # def test_trotter_qrte_gradient_summed_op_qdrift_3(self): + # """Test for trotter qrte gradient with SummedOp and QDrift with commuting operators.""" + # theta1 = Parameter("theta1") + # theta2 = Parameter("theta2") + # operator = (theta1 * (Y ^ Z ^ Y)) + theta2 * (Z ^ X ^ X) + # mode = TrotterModeEnum.QDRIFT + # trotter_qrte = TrotterQrte(mode) + # initial_state = Zero + # time = 5 + # gradient_object = None + # observable = -1j * (X ^ Y ^ Z) + # value_dict = {theta1: 2, theta2: 3} + # gradient = trotter_qrte.gradient( + # operator, + # time, + # initial_state, + # gradient_object, + # observable, + # hamiltonian_value_dict=value_dict, + # gradient_params=[theta1, theta2], + # ) + # expected_gradient = {theta1: 0j, theta2: 0j} + # print(gradient) + # # np.testing.assert_equal(gradient, expected_gradient) + # + # # TODO fails due to Terra bug + # def test_trotter_qrte_gradient_summed_op_qdrift_4(self): + # """Test for trotter qrte gradient with SummedOp and QDrift with commuting operators + # with complex parameter binding.""" + # theta1 = Parameter("theta1") + # theta2 = Parameter("theta2") + # operator = theta1 * (Z) + theta2 * (Y) + # mode = TrotterModeEnum.QDRIFT + # trotter_qrte = TrotterQrte(mode) + # initial_state = Zero + # time = 5 + # gradient_object = None + # observable = X + # value_dict = {theta1: 2, theta2: 3} + # gradient = trotter_qrte.gradient( + # operator, + # time, + # initial_state, + # gradient_object, + # observable, + # hamiltonian_value_dict=value_dict, + # gradient_params=[theta1, theta2], + # ) + # expected_gradient = {theta1: 0j, theta2: 0j} + # print(gradient) + # # np.testing.assert_equal(gradient, expected_gradient) def test_trotter_qrte_gradient_summed_op_qdrift_no_param(self): """Test for trotter qrte gradient with SummedOp and QDrift; missing param.""" theta1 = Parameter("theta1") operator = theta1 * (I ^ Z ^ I) + 5 * (Z ^ I ^ I) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) + trotter_qrte = TrotterQrte(QDrift()) initial_state = Zero time = 5 gradient_object = None @@ -276,60 +279,61 @@ def test_trotter_qrte_gradient_summed_op_qdrift_no_param(self): expected_gradient = {theta1: 0j} np.testing.assert_equal(gradient, expected_gradient) - def test_trotter_qrte_gradient_summed_op_qdrift_t_param_grad(self): - """Test for trotter qrte gradient with SummedOp and QDrift; gradient not on all - parameters.""" - t_param = Parameter("t_param") - theta1 = Parameter("theta1") - operator = t_param * (I ^ Z ^ I) + theta1 * (Z ^ I ^ I) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) - initial_state = Zero - time = 5 - gradient_object = None - observable = Z - value_dict = {theta1: 2, t_param: 5} - gradient = trotter_qrte.gradient( - operator, - time, - initial_state, - gradient_object, - observable, - t_param=t_param, - hamiltonian_value_dict=value_dict, - gradient_params=[t_param], - ) - - expected_gradient = {t_param: (4.7628567756419216e-12 + 0j)} - np.testing.assert_equal(gradient, expected_gradient) - - def test_trotter_qrte_gradient_summed_op_qdrift_t_param_theta(self): - """Test for trotter qrte gradient with SummedOp and QDrift; gradient on t_param and - another parameter.""" - t_param = Parameter("t_param") - theta1 = Parameter("theta1") - operator = t_param * (I ^ Z ^ I) + theta1 * (Z ^ I ^ I) - mode = TrotterModeEnum.QDRIFT - trotter_qrte = TrotterQrte(mode) - initial_state = Zero - time = 5 - gradient_object = None - observable = Z - value_dict = {theta1: 2, t_param: 5} - gradient = trotter_qrte.gradient( - operator, - time, - initial_state, - gradient_object, - observable, - t_param=t_param, - hamiltonian_value_dict=value_dict, - gradient_params=[t_param, theta1], - ) - - # expected_gradient = {t_param: (4.7628567756419216e-12+0j)} - # np.testing.assert_equal(gradient, expected_gradient) - print(gradient) + # TODO this test is disabled for the time being - no t_param for TrotterQrte + # def test_trotter_qrte_gradient_summed_op_qdrift_t_param_grad(self): + # """Test for trotter qrte gradient with SummedOp and QDrift; gradient not on all + # parameters.""" + # t_param = Parameter("t_param") + # theta1 = Parameter("theta1") + # operator = t_param * (I ^ Z ^ I) + theta1 * (Z ^ I ^ I) + # trotter_qrte = TrotterQrte(QDrift()) + # initial_state = Zero + # time = 5 + # gradient_object = None + # observable = Z + # value_dict = {theta1: 2, t_param: 5} + # gradient = trotter_qrte.gradient( + # operator, + # time, + # initial_state, + # gradient_object, + # observable, + # t_param=t_param, + # hamiltonian_value_dict=value_dict, + # gradient_params=[t_param], + # ) + # + # expected_gradient = {t_param: (4.729550084903167e-12 + 0j)} + # np.testing.assert_equal(gradient, expected_gradient) + # + # TODO this test is disabled for the time being - no t_param for TrotterQrte + # def test_trotter_qrte_gradient_summed_op_qdrift_t_param_theta(self): + # """Test for trotter qrte gradient with SummedOp and QDrift; gradient on t_param and + # another parameter.""" + # t_param = Parameter("t_param") + # theta1 = Parameter("theta1") + # operator = t_param * (I ^ Z ^ I) + theta1 * (Z ^ I ^ I) + # mode = TrotterModeEnum.QDRIFT + # trotter_qrte = TrotterQrte(mode) + # initial_state = Zero + # time = 5 + # gradient_object = None + # observable = Z + # value_dict = {theta1: 2, t_param: 5} + # gradient = trotter_qrte.gradient( + # operator, + # time, + # initial_state, + # gradient_object, + # observable, + # t_param=t_param, + # hamiltonian_value_dict=value_dict, + # gradient_params=[t_param, theta1], + # ) + # + # # expected_gradient = {t_param: (4.7628567756419216e-12+0j)} + # # np.testing.assert_equal(gradient, expected_gradient) + # print(gradient) if __name__ == "__main__":