Skip to content

Commit

Permalink
Improve Parameter handling in SparsePauliOp (Qiskit/qiskit#9796)
Browse files Browse the repository at this point in the history
* add reno

* Add assign_parameters and parameter in init

* add SPO.parameters and remove utils

* fix ParameterValueType typehint

* Update qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py

Co-authored-by: Ikko Hamamura <ikkoham@users.noreply.github.com>

* remove trailing print

* Elena's comments

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* fix line length

---------

Co-authored-by: Ikko Hamamura <ikkoham@users.noreply.github.com>
Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 24, 2023
1 parent 1e601ae commit 0fb378c
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 82 deletions.
23 changes: 15 additions & 8 deletions qiskit_algorithms/time_evolvers/trotterization/trotter_qrte.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
from qiskit.quantum_info import Pauli, SparsePauliOp
from qiskit.synthesis import ProductFormula, LieTrotter

from qiskit.algorithms.utils.assign_params import _assign_parameters, _get_parameters


class TrotterQRTE(RealTimeEvolver):
"""Quantum Real Time Evolution using Trotterization.
Expand Down Expand Up @@ -165,16 +163,25 @@ def evolve(self, evolution_problem: TimeEvolutionProblem) -> TimeEvolutionResult
"The time evolution problem contained ``aux_operators`` but no estimator was "
"provided. The algorithm continues without calculating these quantities. "
)

# ensure the hamiltonian is a sparse pauli op
hamiltonian = evolution_problem.hamiltonian
if not isinstance(hamiltonian, (Pauli, PauliSumOp, SparsePauliOp)):
raise ValueError(
f"TrotterQRTE only accepts Pauli | PauliSumOp, {type(hamiltonian)} provided."
f"TrotterQRTE only accepts Pauli | PauliSumOp | SparsePauliOp, {type(hamiltonian)} "
"provided."
)
if isinstance(hamiltonian, PauliSumOp):
hamiltonian = hamiltonian.primitive * hamiltonian.coeff
elif isinstance(hamiltonian, Pauli):
hamiltonian = SparsePauliOp(hamiltonian)

t_param = evolution_problem.t_param
if t_param is not None and _get_parameters(hamiltonian.coeffs) != ParameterView([t_param]):
free_parameters = hamiltonian.parameters
if t_param is not None and free_parameters != ParameterView([t_param]):
raise ValueError(
"Hamiltonian time parameter does not match evolution_problem.t_param "
"or contains multiple parameters"
f"Hamiltonian time parameters ({free_parameters}) do not match "
f"evolution_problem.t_param ({t_param})."
)

# make sure PauliEvolutionGate does not implement more than one Trotter step
Expand Down Expand Up @@ -213,9 +220,9 @@ def evolve(self, evolution_problem: TimeEvolutionProblem) -> TimeEvolutionResult
# evolution for next step
if t_param is not None:
time_value = (n + 1) * dt
bound_coeffs = _assign_parameters(hamiltonian.coeffs, [time_value])
bound_hamiltonian = hamiltonian.assign_parameters([time_value])
single_step_evolution_gate = PauliEvolutionGate(
SparsePauliOp(hamiltonian.paulis, bound_coeffs),
bound_hamiltonian,
dt,
synthesis=self.product_formula,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
from qiskit.quantum_info import SparsePauliOp
from qiskit.quantum_info.operators.base_operator import BaseOperator

from qiskit.algorithms.utils.assign_params import _assign_parameters

from ..variational_principles import VariationalPrinciple


Expand Down Expand Up @@ -115,13 +113,12 @@ def solve_lse(

if self._time_param is not None:
if time_value is not None:
bound_params_array = _assign_parameters(self._hamiltonian.coeffs, [time_value])
hamiltonian = SparsePauliOp(self._hamiltonian.paulis, bound_params_array)
hamiltonian = hamiltonian.assign_parameters([time_value])
else:
raise ValueError(
f"Providing a time_value is required for time-dependant hamiltonians, "
"Providing a time_value is required for time-dependent hamiltonians, "
f"but got time_value = {time_value}. "
f"Please provide a time_value to the solve_lse method."
"Please provide a time_value to the solve_lse method."
)

evolution_grad_lse_rhs = self._var_principle.evolution_gradient(
Expand Down
62 changes: 0 additions & 62 deletions qiskit_algorithms/utils/assign_params.py

This file was deleted.

8 changes: 2 additions & 6 deletions test/time_evolvers/test_trotter_qrte.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from numpy.testing import assert_raises

from qiskit.algorithms.time_evolvers import TimeEvolutionProblem, TrotterQRTE
from qiskit.algorithms.utils.assign_params import _assign_parameters
from qiskit.primitives import Estimator
from qiskit import QuantumCircuit
from qiskit.circuit.library import ZGate
Expand Down Expand Up @@ -245,11 +244,8 @@ def _get_expected_trotter_qrte(operator, time, num_timesteps, init_state, observ
for n in range(num_timesteps):
if t_param is not None:
time_value = (n + 1) * dt
bound_coeffs = _assign_parameters(operator.coeffs, [time_value])
ops = [
Pauli(op).to_matrix() * np.real(coeff)
for op, coeff in SparsePauliOp(operator.paulis, bound_coeffs).to_list()
]
bound = operator.assign_parameters([time_value])
ops = [Pauli(op).to_matrix() * np.real(coeff) for op, coeff in bound.to_list()]
for op in ops:
psi = expm(-1j * op * dt).dot(psi)
observable_results.append(
Expand Down

0 comments on commit 0fb378c

Please sign in to comment.