Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency of TimeEvolutionResult.observables #9905

Closed
Cryoris opened this issue Apr 4, 2023 · 2 comments
Closed

Inconsistency of TimeEvolutionResult.observables #9905

Cryoris opened this issue Apr 4, 2023 · 2 comments
Labels
bug Something isn't working mod: algorithms Related to the Algorithms module

Comments

@Cryoris
Copy link
Contributor

Cryoris commented Apr 4, 2023

Environment

  • Qiskit Terra version: 0.24
  • Python version: 3.10
  • Operating system: mac OS

What is happening?

As noticed in #8271 (comment), the value of TimeEvolutionResult.observables differs for the different available implementations.

How can we reproduce the issue?

Here's a snippet for comparison

import numpy as np
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import RealAmplitudes
from qiskit.algorithms.state_fidelities import ComputeUncompute
from qiskit.algorithms.optimizers import L_BFGS_B
from qiskit.primitives import Sampler, Estimator
from qiskit.quantum_info import Pauli
from qiskit.algorithms.time_evolvers import (
    TimeEvolutionProblem,
    PVQD,
    VarQRTE,
    SciPyRealEvolver,
    TrotterQRTE,
)

hamiltonian = Pauli("Y")
observables = [Pauli("X"), Pauli("Z")]

ansatz = RealAmplitudes(1, reps=0)
initial_parameters = np.zeros(ansatz.num_parameters)

problem = TimeEvolutionProblem(hamiltonian, time=1, aux_operators=observables)

num_timesteps = 10

fidelity = ComputeUncompute(Sampler())
pvqd = PVQD(
    fidelity,
    ansatz,
    initial_parameters,
    estimator=Estimator(),
    num_timesteps=num_timesteps,
    optimizer=L_BFGS_B(),
)
print("PVQD:")
print(pvqd.evolve(problem).observables)

varqrte = VarQRTE(ansatz, initial_parameters, estimator=Estimator())
print("VarQRTE:")
print(varqrte.evolve(problem).observables)

initial_state = QuantumCircuit(1)
problem.initial_state = ansatz.bind_parameters(initial_parameters)
scipy = SciPyRealEvolver(num_timesteps)
print("SciPy:")
print(scipy.evolve(problem).observables)

trotter = TrotterQRTE(estimator=Estimator())
print("Trotter:")
print(trotter.evolve(problem).observables)

which prints

PVQD:
[array([0., 1.]), array([0.19866933, 0.98006658]), array([0.38941834, 0.92106099]), array([0.56464247, 0.82533562]), array([0.71735609, 0.69670671]), array([0.84147098, 0.54030231]), array([0.93203908, 0.36235776]), array([0.98544973, 0.16996715]), array([ 0.9995736 , -0.02919952]), array([ 0.97384763, -0.22720209]), array([ 0.90929743, -0.41614683])]
VarQRTE:
[[(0.0, {}), (1.0, {})]]
SciPy:
[(array([0.        +0.j, 0.19866933+0.j, 0.38941834+0.j, 0.56464247+0.j,
       0.71735609+0.j, 0.84147098+0.j, 0.93203909+0.j, 0.98544973+0.j,
       0.9995736 +0.j, 0.97384763+0.j, 0.90929743+0.j]), array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])), (array([ 1.        +0.j,  0.98006658+0.j,  0.92106099+0.j,  0.82533561+0.j,
        0.69670671+0.j,  0.54030231+0.j,  0.36235775+0.j,  0.16996714+0.j,
       -0.02919952+0.j, -0.22720209+0.j, -0.41614684+0.j]), array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]))]
Trotter:
[[(0.0, {}), (1.0, {})], [(0.9092974268256818, {}), (-0.4161468365471423, {})]]

What should happen?

The result types should be consistent. I think from a user perspective, the most convenient would be to capture the expectation values of a single observable over all timesteps in an array, which would allow computing averages or plotting very easily. For example, the format of the SciPyEvolvers seems like a good idea:

observables = [
  (values_observable1, stddevs_observable1),
  (values_observable2, stddevs_observable2),
  ...
]

Any suggestions?

No response

@Cryoris Cryoris added bug Something isn't working mod: algorithms Related to the Algorithms module labels Apr 4, 2023
@woodsp-ibm
Copy link
Member

PVQD result seems to redefine observables from its parent class when it describes it, which I would agree is more a bug. Time evolution result says

   observables (ListOrDict[tuple[np.ndarray, np.ndarray]] | None): Optional list of
       observables for which expected on an evolved state are calculated at each timestep.
       These values are in fact lists of tuples formatted as (mean, standard deviation).

where the ListOrDict presumably matches to input type of ListOrDict passed in

The text describing things could certaining be improved too.

Given people may have code using the results as-is we may need some transition setting to go over to something that is consistent, if its not what we currently state. In this case it seems more a feature change than a bug.

PVQDResult also does not have its Attributes documented (its parent does but new ones it adds are not listed). Also it seems to pass some of the parent attributes up through init, and some it sets directly - not sure why.

@ElePT
Copy link
Contributor

ElePT commented Aug 22, 2023

Transferred to new repo: qiskit-community/qiskit-algorithms#59

@ElePT ElePT closed this as not planned Won't fix, can't repro, duplicate, stale Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mod: algorithms Related to the Algorithms module
Projects
None yet
Development

No branches or pull requests

4 participants