qml.adjoint

adjoint(fn)[source]

Create a function that applies the adjoint (inverse) of the provided operation or template.

This transform can be used to apply the adjoint of an arbitrary sequence of operations.

Parameters

fn (function) – A quantum function that applies quantum operations.

Returns

A new function that will apply the same operations but adjointed and in reverse order.

Return type

function

Example

The adjoint transforms can be used within a QNode to apply the adjoint of any quantum function. Consider the following quantum function, that applies two operations:

def my_ops(a, b, wire):
    qml.RX(a, wires=wire)
    qml.RY(b, wires=wire)

We can create a QNode that applies this quantum function, followed by the adjoint of this function:

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

@qml.qnode(dev)
def circuit(a, b):
    my_ops(a, b, wire=0)
    qml.adjoint(my_ops)(a, b, wire=0)
    return qml.expval(qml.PauliZ(0))

Printing this out, we can see that the inverse quantum function has indeed been applied:

>>> print(qml.draw(circuit)(0.2, 0.5))
 0: ──RX(0.2)──RY(0.5)──RY(-0.5)──RX(-0.2)──┤ ⟨Z⟩

The adjoint function can also be applied directly to templates and operations:

>>> qml.adjoint(qml.RX)(0.123, wires=0)
>>> qml.adjoint(qml.templates.StronglyEntanglingLayers)(weights, wires=[0, 1])

Adjoint of a function

Here, we apply the subroutine function, and then apply its inverse. Notice that in addition to adjointing all of the operations, they are also applied in reverse construction order.

def subroutine(wire):
    qml.RX(0.123, wires=wire)
    qml.RY(0.456, wires=wire)

dev = qml.device('default.qubit', wires=1)
@qml.qnode(dev)
def circuit():
    subroutine(0)
    qml.adjoint(subroutine)(0)
    return qml.expval(qml.PauliZ(0))

This creates the following circuit:

>>> circuit()
>>> print(circuit.draw())
0: --RX(0.123)--RY(0.456)--RY(-0.456)--RX(-0.123)--| <Z>

Single operation

You can also easily adjoint a single operation just by wrapping it with adjoint:

dev = qml.device('default.qubit', wires=1)
@qml.qnode(dev)
def circuit():
    qml.RX(0.123, wires=0)
    qml.adjoint(qml.RX)(0.123, wires=0)
    return qml.expval(qml.PauliZ(0))

This creates the following circuit:

>>> circuit()
>>> print(circuit.draw())
0: --RX(0.123)--RX(-0.123)--| <Z>