qml.ctrl

ctrl(fn, control)[source]

Create a method that applies a controlled version of the provided method.

Parameters
  • fn (function) – Any python function that applies pennylane operations.

  • control (Wires) – The control wire(s).

Returns

A new function that applies the controlled equivalent of fn. The returned function takes the same input arguments as fn.

Return type

function

Example

dev = qml.device('default.qubit', wires=4)

def ops(params):
    qml.RX(params[0], wires=0)
    qml.RZ(params[1], wires=3)

ops1 = qml.ctrl(ops, control=1)
ops2 = qml.ctrl(ops, control=2)

@qml.qnode(dev)
def my_circuit():
    ops1(params=[0.123, 0.456])
    ops1(params=[0.789, 1.234])
    ops2(params=[2.987, 3.654])
    ops2(params=[2.321, 1.111])
    return qml.state()

The above code would be equivalent to

@qml.qnode(dev)
def my_circuit2():
    # ops1(params=[0.123, 0.456])
    qml.CRX(0.123, wires=[1, 0])
    qml.CRZ(0.456, wires=[1, 3])

    # ops1(params=[0.789, 1.234])
    qml.CRX(0.789, wires=[1, 0])
    qml.CRZ(1.234, wires=[1, 3])

    # ops2(params=[2.987, 3.654])
    qml.CRX(2.987, wires=[2, 0])
    qml.CRZ(3.654, wires=[2, 3])

    # ops2(params=[2.321, 1.111])
    qml.CRX(2.321, wires=[2, 0])
    qml.CRZ(1.111, wires=[2, 3])
    return qml.state()

Note

Some devices are able to take advantage of the inherient sparsity of a controlled operation. In those cases, it may be more efficient to use this transform rather than adding controls by hand. For devices that don’t have special control support, the operation is expanded to add control wires to each underlying op individually.

Nesting Controls

The ctrl transform can be nested with itself arbitrarily.

# These two ops are equivalent.
op1 = qml.ctrl(qml.ctrl(my_ops, 1), 2)
op2 = qml.ctrl(my_ops, [2, 1])