ctrl(op, control, control_values=None, work_wires=None)[source]

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

  • op (function or Operator) – A single operator or a function that applies pennylane operators.

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

  • control_values (bool or list[bool]) – The value(s) the control wire(s) should take. Integers other than 0 or 1 will be treated as int(bool(x)).

  • work_wires (Any) – Any auxiliary wires that can be used in the decomposition


If an Operator is provided, returns a Controlled version of the Operator. If a function is provided, returns a function with the same call signature that creates a controlled version of the provided function.

Return type

(function or Operator)

See also



@qml.qnode(qml.device('default.qubit', wires=range(4)))
def circuit(x):
    qml.ctrl(qml.RX, (1,2,3), control_values=(0,1,0))(x, wires=0)
    return qml.expval(qml.PauliZ(0))
>>> print(qml.draw(circuit)("x"))
0: ────╭RX(x)─┤  <Z>
1: ────├○─────┤
2: ──X─├●─────┤
3: ────╰○─────┤
>>> x = np.array(1.2)
>>> circuit(x)
tensor(0.36235775, requires_grad=True)
>>> qml.grad(circuit)(x)
tensor(-0.93203909, requires_grad=True)

ctrl() works on both callables like qml.RX or a quantum function and individual Operator’s.

>>> qml.ctrl(qml.Hadamard(0), (1,2))
Controlled(Hadamard(wires=[0]), control_wires=[1, 2])

Controlled operations work with all other forms of operator math and simplification:

>>> op = qml.ctrl(qml.RX(1.2, wires=0) ** 2 @ qml.RY(0.1, wires=0), control=1)
>>> qml.simplify(qml.adjoint(op))
Controlled(RY(12.466370614359173, wires=[0]) @ RX(10.166370614359172, wires=[0]), control_wires=[1])