Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.04k stars 2.32k forks source link

Expectation value re-design #6864

Closed Cryoris closed 2 years ago

Cryoris commented 3 years ago

Related to #6451

Summary

Taking expectation values for opflow operators on a backend/simulator currently looks like

# define the expectation value
state = StateFn(...) # can be a circuit-based state or defined via a statevector or dictionary
operator = # some opflow operator, e.g. PauliSumOp
expectation = StateFn(operator, is_measurement=True) @ state

# define how to evaluate
expectation_converter = # method to evaluate the expected value, e.g. PauliExpectation, CVaRExpectation, AerPauliExpectation, ...
circuit_sampler = CircuitSampler(backend)  # backend or simulator to execute the circuits

# constructs opflow objects needed to evaluate the expectation value
# e.g. creates circuits to measure in different Pauli bases
converted = expectation_converter.convert(expectation) 

# evaluate the circuits (optionally with parameters, if the state had free parameters so far)
sampled = circuit_sampler.convert(converted, parameters)

# get final result
result = sampled.eval()

This workflow requires users to know about several classes before being able to calculate expectation values and constructs and copies potentially heavy opflow objects multiple times. We'd like to create a new expectation value class to (1) simplify and speed up the current flow and (2) create one universal interface for Qiskit (instead of having a quantum-info way and opflow way of doing it).

This must be (and currently is) synced with the development of expectation values in Qiskit Experiments.

On the high level, we'd like to calculate circuit-based expectation values as (this is just a sketch, naming etc. is not fixed)

exp_val = ExpectationValue(operator, circuit, backend)  # ExpectationValue could be a subtype, like PauliExpectationValue
result = exp_val.compute(parameters)  # parameters are only included if the circuit is parameterized

This would easily allow to cache transpiled circuits, it's easy to use and variational algorithms can easily be implemented.

nonhermitian commented 3 years ago

So in the model above, is ExpectationValue tasked with forming the correct circuits for the operator, i.e. appending the needed basis transform gates? Also, do we really need a class here that one can pass parameters to, i.e why can't ExpectationValue just be a call to run the circuits on the specified backend after binding parameters that returns the results?

kdk commented 2 years ago

Closing as resolved by #7780 .