Jaspify#

jaspify(func: Callable | bool | None = None, terminal_sampling: bool = False) → Callable[source]#

Qrisp’s built-in Jasp simulator: interprets a traced program equation-by-equation in Python.

Among a variety of simulation tricks, the simulator can leverage state sparsity, allowing simulations with up to hundreds of qubits!

To be called as a decorator of a Jasp-traceable function.

Note

If you are developing a hybrid algorithm like QAOA or VQE that relies heavily on sampling, please activate the terminal_sampling feature.

Parameters:
funccallable

The function to simulate.

terminal_samplingbool, optional

Whether to leverage the terminal sampling strategy. Significantly fast for all sampling tasks but can yield incorrect results in some situations. Check out Terminal Sampling for more details. The default is False.

Returns:
callable

A function performing the simulation.

Examples

We simulate a function creating a simple GHZ state, which collapses to either 0 or 31 upon measurement:

>>> from qrisp import *
>>> from qrisp.jasp import *
>>> @jaspify
... def main():
...     qf = QuantumFloat(5)
...     h(qf[0])
...     for i in range(1, 5):
...         cx(qf[0], qf[i])
...     return measure(qf)
>>> main()
31

To highlight the speed of the terminal sampling feature, we Sampling from a uniform superposition:

>>> def state_prep():
...     qf = QuantumFloat(5)
...     h(qf)
...     return qf
>>> @jaspify
... def without_terminal_sampling():
...     sampling_func = sample(state_prep, shots=10000)
...     return sampling_func()
>>> @jaspify(terminal_sampling=True)
... def with_terminal_sampling():
...     sampling_func = sample(state_prep, shots=10000)
...     return sampling_func()

Benchmarking the two shows the difference (illustrative, machine-dependent):

>>> import time
>>> t0 = time.time(); res = without_terminal_sampling(); time.time() - t0
43.78982925
>>> t0 = time.time(); res = with_terminal_sampling(); time.time() - t0
0.550775527