PennyLane
  • Why PennyLane
  • Getting Started
  • Documentation
  • Ecosystem
Install
Install
  1. Compilation/
  2. Diagonal unitary decomposition

Diagonal unitary decomposition

OverviewDetailsResources

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]:

Decomposition of a diagonal unitary operator into multiplexed rotations SelectPauliRot

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).

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.

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},
  howpublished={\url{https://pennylane.ai/compilation/diagonal-unitary-decomp}},
  year={2025}
}

Page author(s)

David Wierichs
David Wierichs

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.

PennyLane

PennyLane is an open-source software framework for quantum machine learning, quantum chemistry, and quantum computing, with the ability to run on all hardware. Built with ❤️ by Xanadu.

Stay updated with our newsletter

For researchers

  • Research
  • Features
  • Demos
  • Compilation
  • Datasets
  • Performance
  • Learn
  • Videos
  • Documentation
  • Teach

For learners

  • Learn
  • Codebook
  • Teach
  • Videos
  • Challenges
  • Demos
  • Compilation
  • Glossary

For developers

  • Features
  • Documentation
  • API
  • GitHub
  • Datasets
  • Demos
  • Compilation
  • Performance
  • Devices
  • Catalyst

© Copyright 2025 | Xanadu | All rights reserved

TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.

Privacy Policy|Terms of Service|Cookie Policy|Code of Conduct