- Compilation/
Diagonal unitary decomposition
Diagonal unitary decomposition
Diagonal unitary operators appear in various compilation scenarios, most frequently in the context of unitary synthesis and state preparation.
To decompose a diagonal unitary operator (without auxiliary qubits), we may use a recursive decomposition into multiplexed R_Z gates, which is called SelectPauliRot in PennyLane. This is shown in [1], citing earlier work [2]:
Here, \Delta denotes a diagonal operator and the half-filled control nodes indicate that the R_Z rotations are controlled uniformly, or multiplexed. See the Select-U(2) compilation page for a decomposition of these multiplexers.
Inputs
- Diagonal unitary with length N=2^n for n qubits.
Outputs
- Circuit consisting of
- n-1 multiplexed R_Z rotations (
qml.SelectPauliRot), one each with k controls for 1\leq k\leq n-1, - 1 single-qubit R_Z rotation (
qml.RZ), and - a global phase (
qml.GlobalPhase).
- n-1 multiplexed R_Z rotations (
Example
Consider a diagonal unitary operator acting on three qubits, consisting of some random phases:
import pennylane as qml
import numpy as np
n = 3
wires = list(range(n))
D = np.exp(1j * np.random.random(2**n))
@qml.qnode(qml.device("reference.qubit", wires=n))
def qnode():
qml.Hadamard(0)
qml.Hadamard(2)
qml.DiagonalQubitUnitary(D, wires=wires)
return qml.expval(qml.X(0))
>>> print(qml.draw(qnode, show_matrices=False)())
0: ──╭U(M0)─┤ <X>
1: ──├U(M0)─┤
2: ──╰U(M0)─┤
We can decompose the DiagonalQubitUnitary iteratively, which we can control via the
max_expansion keyword argument of
qml.decompose.
In the first step, we obtain a SelectPauliRot gate with two controls and a two-qubit diagonal
unitary operator:
gate_set = {"DiagonalQubitUnitary", "SelectPauliRot", "RZ", "GlobalPhase"}
dec_node = qml.transforms.decompose(qnode, gate_set=gate_set, max_expansion=1)
>>> print(qml.draw(dec_node, show_matrices=False)())
0: ──╭U(M0)─╭SelectPauliRot(M1)─┤ <X>
1: ──╰U(M0)─├SelectPauliRot(M1)─┤
2: ─────────╰SelectPauliRot(M1)─┤
In the next step, the two-qubit diagonal unitary operator is decomposed into a single-qubit
diagonal unitary and a SelectPauliRot gate with one control:
dec_node = qml.transforms.decompose(qnode, gate_set=gate_set, max_expansion=2)
>>> print(qml.draw(dec_node, show_matrices=False)())
0: ──U(M0)─╭SelectPauliRot(M1)─╭SelectPauliRot(M2)─┤ <X>
1: ────────╰SelectPauliRot(M1)─├SelectPauliRot(M2)─┤
2: ────────────────────────────╰SelectPauliRot(M2)─┤
In the last step, the single-qubit diagonal unitary is broken up into a global phase and
a qml.RZ gate:
dec_node = qml.transforms.decompose(qnode, gate_set=gate_set, max_expansion=3)
>>> print(qml.draw(dec_node, show_matrices=False)())
0: ──GlobalPhase(-0.42)──RZ(0.02)─╭SelectPauliRot(M0)─╭SelectPauliRot(M1)─┤ <X>
1: ───────────────────────────────╰SelectPauliRot(M0)─├SelectPauliRot(M1)─┤
2: ───────────────────────────────────────────────────╰SelectPauliRot(M1)─┤
Typical usage
This decomposition can be useful as part of a compilation routine that splits off diagonal
operators to commute them through control/multiplexing structures. It is also used implicitly in
MottonenStapePreparation,
both in a version with qml.RY rotations to create the correct amplitudes, and as seen
above with qml.RZ rotations to apply phases.
As a concrete example, Select
operators with a single target qubit can be decomposed using arbitrary diagonal unitary
operators; for details, see the
Select-U(2) compilation page.
In turn, this page will also show how to decompose SelectPauliRot obtained from the
decomposition presented here.
If phase gradient resource states and additional auxiliary qubits are available, diagonal unitaries can instead be decomposed at the same cost as the largest multiplexed rotation above.
References
[1] "Synthesis of quantum logic circuits", Vivek Shende, Stephen Bullock, Igor Markov, quant-ph/0406176, 2004.
[2] "Smaller circuits for arbitrary n-qubit diagonal computations", Stephen S. Bullock, Igor L. Markov, quant-ph/0303039, 2003.
Cite this page
@misc{PennyLane-diagonal-unitary-decomp,
title = "Diagonal unitary decomposition",
author = "David Wierichs",
year = "2025",
howpublished = "\url{https://pennylane.ai/compilation/diagonal-unitary-decomp}"
}
Page author(s)
David Wierichs
I like to think about differentiation and representations of quantum programs, and I enjoy coding up research ideas and useful features for anyone to use in PennyLane.