qml.DiagonalQubitUnitary and qml.QubitUnitary cannot be trained?


While checking the documentation, I found that DiagonalQubitUnitary doesn’t even have a gradient recipe? How can I make a custom Unitary matrix with variable parameters for training?

def my_func(feat, para):
    qml.MottonenStatePreparation(state_vector=feat, wires=wires)
    diag = []
    for i in range(dim1):
    diag = np.array(diag, requires_grad=True)
    qml.DiagonalQubitUnitary(diag, wires=wires)
    return qml.eval...


The above image is part of my code. I set dim1 a classical parameter (in the hope that it will be trained). By determining the positives and negatives of the parameters, thus forming the diagonal unitary matrix I want. But in training, I found that the dim1 parameter is not iteratively updated. I don’t know if it’s because qml.DiagonalQubitUnitary is not differentiable or my parameters are not updated by the optimizer. This one phenomenon induced me to think how for a quantum-classical hybrid algorithm, where some of the parameters are not embedded in quantum gates, is it also possible to train it?


A key question, on hardware, how to decompose a custom diagonal unitary containing parameters into basic gatesets and participate in machine learning training.

In fact, I really need a trainable custom diag unitary matrix like this:
which is trainable into another diag unitary matrix.

Totally, how to let qml.DiagonalQubitUnitary and qml.QubitUnitary be trainable?

@isaacdevlugt @Maria_Schuld @CatalinaAlbornoz @Guillermo_Alonso @Diego @kevinkawchak

Hi @RX1 !
Indeed, DiagonalQubitUnitary has differentiability problems since it is working with complex numbers on the diagonal. What you want from what I understand is that it is both trainable and differentiable. Therefore your function has to be continuous and you need to encode a diagonal matrix with elements of the form e^{i \theta}. This can be achieved by putting anstazs where the gates are RZs, CRZs, CCRZs and so on. (You can test using qml.matrix to see that it is indeed diagonal.)
I hope that helps!

This additionally increases the complexity of the algorithm I designed if it follows the diagonal matrix decomposition into the form of a quantum gate. Since the diagonal elements in the diagonal matrix will change with training, the decomposition will also change, and it is impossible for me to list thousands of categorization scenarios, so please ask if there is an automatic decomposition. I think the issue I raised is an important one that Pennylane needs to be updated in a timely manner.

If you use RZs and CRZs, the decomposition will not change. It is a way to create continuity between the different oracles :slight_smile:

Hi @RX1 ! :smile: I’ve been talking with my colleague Tom and what you propose is differentiable if you use jax, here is an example:

import pennylane as qml
from jax import numpy as np
import jax

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

def f(x):
    qml.DiagonalQubitUnitary(qml.math.exp(1j * x), wires=range(1))
    return qml.expval(qml.PauliX(0))

x = np.array([3., 9.])


Does this solve your problem?

My algorithm can only make the elements of this unitary diagonal matrix to be 1 or -1, no other complex numbers can occur, it is discrete in terms of the result and continuous in terms of the training parameters. Is this achievable?

Unfortunately there is no continuous way to do what you propose. You are going to have to go through the complex numbers. Maybe you can add another error function that encourages the parameters to converge to 0 or \pi (-1 and 1).