Classical Control#

ClControlEnvironment(ctrl_bls, ctrl_state=-1, invert=False)[source]#

The ClControlEnvironment enables execution of quantum code conditioned on classical values. The environment works with similar semantics as the ControlEnvironment, implying this environment can also be entered using the control keyword.

Warning

Contrary to the ControlEnvironment the ClControlEnvironment must not have “carry values”. This means that no value that is created inside this environment may be used outside of the environment.

Examples

We condition a quantum computation on the outcome of a previous measurement.

from qrisp import *
from qrisp.jasp import make_jaspr
def test_f(i):

    a = QuantumFloat(3)
    a[:] = i
    b = measure(a)

    with control(b == 4):
        x(a[0])

    return measure(a)

jaspr = make_jaspr(test_f)(1)

This jaspr receives an integer and encodes that integer into the QuantumFloat a. Subsequently a is measured and an X gate is applied onto the 0-th qubit of a if the measurement value is 4.

We can now evaluate the jaspr on several inputs

>>> jaspr(1)
1
>>> jaspr(2)
2
>>> jaspr(3)
3
>>> jaspr(4)
5

We see that in the case where 4 was encoded, the X gate was indeed executed.

To elaborate the restriction of carry values, we give an example that would be illegal:

def test_f(i):

    a = QuantumFloat(3)
    a[:] = i
    b = measure(a)

    with control(b == 4):
        c = QuantumFloat(2)

    return measure(c)

jaspr = make_jaspr(test_f)(1)

This script creates a QuantumFloat c within the classical control environment and subsequently uses c outside of the environment (in the return statement).

It is however possible to create (quantum-)values within the environment and use them still within the environment:

from qrisp import *
from qrisp.jasp import make_jaspr
def test_f(i):

    a = QuantumFloat(3)
    a[:] = i
    b = measure(a)

    with control(b == 4):
        c = QuantumFloat(2)
        h(c[0])
        d = measure(c)

        # If c is measured to 1
        # flip a and uncompute c
        with control(d == 1):
            x(a[0])
            x(c[0])

        c.delete()

    return measure(a)

jaspr = make_jaspr(test_f)(1)

This script allocates another QuantumFloat c within the ClControlEnvironment and applies an Hadamard gate to the 0-th qubit. Subsequently the whole QuantumFloat is measured. If the measurement turns out to be one, the zeroth qubit of a is flipped (similar to the above examples) and furthermore c is brought back to the \(\ket{0}\) state.

>>> jaspr(4)
5
>>> jaspr(4)
4