Expectation Value#

expectation_value(state_prep, shots, return_dict=False, post_processor=None)[source]#

The expectation_value function allows to estimate the expectation value from a state that is specified by a preparation procedure. This preparation procedure can be supplied via a Python function that returns one or more QuantumVariables.

Parameters:
state_prepcallable

A function returning one or more QuantumVariables. The expectation value from this state will be computed. The state preparation function can only take classical values as arguments. This is because a quantum value would need to be copied for each sampling iteration, which is prohibited by the no-cloning theorem.

shotsint or jax.core.Tracer

The amount of samples to take to compute the expectation value.

post_processorcallable, optional

A classical Jax traceable function to apply to the results directly after measuring. By default no post processing is applied.

Returns:
callable

A function returning a Jax array containing the expectation value.

Raises:
Exception

Tried to sample from state preparation function taking a quantum value

Examples

We prepare the state

\[\ket{\psi_k} = \frac{1}{\sqrt{2}} \left(\ket{0}\ket{0}\ket{\text{False}} + \ket{k}\ket{k}\ket{\text{True}}\right)\]
from qrisp import *
from qrisp.jasp import *

def state_prep(k):
    a = QuantumFloat(4)
    b = QuantumFloat(4)

    qbl = QuantumBool()
    h(qbl)

    with control(qbl[0]):
        a[:] = k

    cx(a, b)

    return a, b

And compute the expectation value of the QuantumFloats

@jaspify
def main(k):

    ev_function = expectation_value(state_prep, shots = 50)

    return ev_function(k)

print(main(3))
# Yields
# [1.44 1.44]

The true value 1.5 is not reached because of shot noise. To improve the approximation, feel free to increase the shots!

To demonstrate the post_processor keyword we define a simple post processing function

def post_processor(x, y):
    return x*y

@jaspify
def main(k):

    ev_function = expectation_value(state_prep, shots = 50)

    return ev_function(k)

print(main(3))
# Yields
# 4.338

This result is expected because the inputs of post_processor are either (0,0) or (3,3) with 50% probability, so we get

\[4.5 = \frac{3\cdot 3 + 0\cdot 0}{2}\]