Create an Operation with an adjoint

In Pennylane, we can create a custom operation by creating a class inheriting pennylane.operation.Operation.

I want to do it for an operation and I want to implement the adjoint method of this operation. However, all examples of operations that I found in Pennylane implement a very simple adjoint method, like for example themselves, or themselves with a negative parameter, while my operation has a non trivial adjoint.
Is there a simple way to implement the adjoint method of the Operator, so that it just does the inverse of its matrix ?

Thanks.

Is there a file consisting of your method and can you have your PennyLane class inherit that?

Thanks for your answer.
I can show an example:

class complexGate(qml.operation.Operation):
    num_params = 1
    par_domain = "R"
    num_wires = AnyWires

    @staticmethod
    def compute_decomposition(phi, wires):
        return [complexCircuit(phi,wires)]

    def adjoint(self):
        # How can I simply use qml.adjoint(complexCircuit)(phi,wires) here ?

Hey! Here is an example that can help you :slight_smile:

import pennylane as qml

def q_func(phi, wires):
    qml.RX(phi, wires = wires[0])
    qml.PauliZ(wires = wires[1])
    
def adjoint_q_func(phi1, phi2, wires):
    qml.RX(phi1, wires = wires[0])
    qml.RX(phi2, wires = wires[1])
    qml.Hadamard(wires = wires[0])

class complexGate(qml.operation.Operation):
    num_params = 1
    par_domain = "R"
    num_wires = qml.operation.AnyWires

    @staticmethod
    def compute_decomposition(phi, wires):
        return [q_func(phi,wires)]

    def adjoint(self):
        return [adjoint_q_func(-self.data[0], 2., self.wires)]
        
    
dev = qml.device("default.qubit", wires = 2)

@qml.qnode(dev)
@qml.compile()
def circuit():
    qml.adjoint(complexGate)(1, wires = [0,1])
    return qml.state()

qml.draw_mpl(circuit, decimals = 2)()

I have painted it at the end so that you can see that it does indeed take the inverse correctly.

(Forget the @qml.compile() , it is only so that it is clear in the drawing)

Tell me if you have any problem :muscle:

2 Likes

Hey ! It works very good, I didn’t know that parameters were stored in self.data.

Thanks!

A little problem is that your example produces (when we remove the @compile) a block “complexGate” in the drawing, but then the adjoint appears as several gates, like in this example.
image
Is there a way to display a block “complexGate^-1” or something of this kind instead ?

That is something we are working on now, in future versions of pennylane you will get the dagger :muscle:

Okay, until that I will use a second class to create an adjoint operation (still using your code).
Thanks, keep on the good work!

1 Like