-
Notifications
You must be signed in to change notification settings - Fork 209
[Demo] Add: Unitary synthesis with recursive KAK decompositions #1372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
👋 Hey, looks like you've updated some demos! 🐘 Don't forget to update the Please hide this comment once the field(s) are updated. Thanks! |
Thank you for opening this pull request. You can find the built site at this link. Deployment Info:
Note: It may take several minutes for updates to this pull request to be reflected on the deployed site. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First look and this looks great, learned a lot !
I think in the first part some numerical or analytic examples could help
I dont know how much you planned for the gate counts, stating the logic of counting and then the results should be sufficient imo but feel free to go wild 😆 🚀
.. figure:: ../_static/demonstration_assets/unitary_synthesis_kak/KAK_generic.png | ||
:align: center | ||
:width: 70% | ||
:alt: Quantum circuit of a generic KAK decomposition. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a screenshot artifact :D Sorry!
I'll redo all the circuit diagrams for sure, because something will change, so they are a bit in rough shape here and there 😬
No preview :(
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main remaining concern is the Khaneja Glaser section which I'd consider hard to parse for a non-expert audience. My suggestion would be to make it as explicit as possible without bloating the section too much.
# Qubit count | ||
n = 5 | ||
# Get a random unitary on n qubits | ||
U = unitary_group.rvs(2**n, random_state=214) | ||
# Compute AIII decomposition | ||
(u_1, u_2), theta, (v_1, v_2) = aiii_decomposition(U) | ||
|
||
# Check that the decomposition is valid | ||
zero = np.zeros_like(u_1) | ||
K_1 = np.block([[u_1, zero], [zero, u_2]]) | ||
A = qml.matrix(qml.Select([qml.RY(2 * th, 0) for th in theta], control=range(1, n)), wire_order=range(n)) | ||
K_2 = np.block([[v_1, zero], [zero, v_2]]) | ||
|
||
reconstructed_U = K_1 @ A @ K_2 | ||
print(np.allclose(reconstructed_U, U)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super neat example!!!! 🚀
U_1, phi, U_2 = demultiplex(u_1, u_2) | ||
|
||
###################################################################### | ||
# The demultiplexed matrices make up :math:`K_1=u_1\oplus u_2` from above: | ||
# | ||
|
||
demultiplex_A = qml.matrix(qml.Select([qml.RZ(-2 * p, 0) for p in phi], control=range(1, n)), wire_order=range(n)) | ||
demultiplex_K_1 = np.block([[U_1, zero], [zero, U_1]]) | ||
demultiplex_K_2 = np.block([[U_2, zero], [zero, U_2]]) | ||
reconstructed_K_1 = demultiplex_K_1 @ demultiplex_A @ demultiplex_K_2 | ||
print(np.allclose(reconstructed_K_1, K_1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super neat 👌
# via :math:`E` on the last two qubits, and from the Pauli :math:`Z` into the Pauli :math:`X` basis | ||
# on the :math:`n-3` remaining qubits. | ||
# | ||
# For the second part in each recursion step, the type-A Cartan decomposition, the Cartan subalgebra |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the recursion steps are not necessarily clear to all readers, would also make it more explicit what the second part in each recursion step refers to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rephrased this a bit. In particular, I try not to mention the "two parts" of a recursion step any longer, because this only makes sense in the context of the original paper, but not so much in the phrasing of the demo.
# .. figure:: ../_static/demonstration_assets/unitary_synthesis_kak/recursive_QSD.png | ||
# :align: center | ||
# :width: 100% | ||
# :alt: Recursively applied Quantum Shannon decomposition of the unitary group on n qubits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on the rhs, the lower wire misses the n-2 collection symbol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now it has a gray line on the left 🥲
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fixed.
# beginning. They are captured by multiplexed single-qubit rotations about the Pauli :math:`Y` | ||
# axis and Pauli :math:`Z` axis, respectively, with the first of the qubits (on which the recursion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it pauli Y and pauli Z alternating? is that because cant do the same twice? would be nice if you can mention why that is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a brief comment that this results from the different Cartan subalgebras used in the two types of decompositions :) Is that the level you had in mind? :)
# each type-AIII Cartan decomposition. We showcase the transformation into the correct block | ||
# structure in form of a circuit diagram: | ||
# | ||
# .. figure:: ../_static/demonstration_assets/unitary_synthesis_kak/block_zxz_transformations.png |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
image missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, sorry about that!
# Afterwards, the block-diagonal matrices can be decomposed with the type-A decompositions, and | ||
# optimizations from the QSD can be applied, complemented by the merger of two CZ gates into | ||
# the control structure of a multiplexer (see Sec. 5 of [#Krol_BlockZXZ]_). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you show that with one or two circuit diagrams or would it bloat it too much? Images/diagrams are always easier to follow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think on could do that, more or less reproducing Sec. 5.2 here. Would that be helpful? Unfortunately, it takes quite some drawing space and/or words to get those two gates to cancel 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Included in new gate counts appendix :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great demo! 🚀
Still got some nitpicky comments here and there and would suggest to find a nicer conclusion for for the KG and BlockZXZ sections.
_static/demonstration_assets/unitary_synthesis_kak/KAK_generic.png
Outdated
Show resolved
Hide resolved
# \mathfrak{a}'_{\text{A}}(n) | ||
# =\operatorname{span}_{i\mathbb{R}} | ||
# \{Z\otimes \{\mathbb{I},X\}^{\otimes (n-3)}\otimes \mathcal{S}\}. | ||
# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The KG section still feels a bit incomplete, I think a quick sentence just stating the recursion steps would help conclude the section in a satisfying way. Perhaps also recap the
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a wrap-up circuit diagram that combines everything into one step that leads to n-1 qubit unitaries. I think that's also useful for the gate counting appendix. Let me know whether this is a sufficient conclusion! :)
# .. adminition:: Implementing a multiplexed rotation | ||
# | ||
# As a subroutine, all decompositions require us to perform a multiplexed, also called | ||
# uniformly controlled or Select-applied, single-qubit rotation, :math:`UCR_P(\vec{\theta})` | ||
# about some Pauli word :math:`P`. A possible implementation of :math:`UCR_P` is given in | ||
# the following circuit diagram: | ||
# | ||
# .. figure:: ../_static/demonstration_assets/unitary_synthesis_kak/multiplexer_decomp.png | ||
# :align: center | ||
# :width: 75% | ||
# :alt: Decomposition of a multiplexer on 3 qubits. | ||
# | ||
# It takes :math:`2^k` CNOT gates and :math:`2^k` rotation gates for :math:`k` control qubits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesnt render 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: adminition 🤦 Sorry about that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still not seeing it in the latest preview 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edit: ah you didnt update it yet, sorry :D
# .. figure:: ../_static/demonstration_assets/unitary_synthesis_kak/recursive_QSD.png | ||
# :align: center | ||
# :width: 100% | ||
# :alt: Recursively applied Quantum Shannon decomposition of the unitary group on n qubits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now it has a gray line on the left 🥲
# Afterwards, the block-diagonal matrices can be decomposed with the type-A decompositions, | ||
# which is done with the same generic technique as for the QSD. | ||
# Crucially, the transformation above appears to simplify the circuit structure by turning | ||
# some blocks into the identity, but this has no effect on the CNOT count. The enhanced | ||
# optimization performed by Krol and Al-Ars also applies to the more generic form after the | ||
# recursive Cartan decomposition | ||
# (see our gate counts appendix and Sec. 5 of [#Krol_BlockZXZ]_). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit unsatisfying conclusion in the sense that I'm not sure at this point what the section on its own is trying to convey? Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, I am not sure how to improve this :D
The block-ZXZ decomp is the same as the QSD, except for a tiny optimization trick in the appendix, and all the block stuff is pretty unnecessary.
I reworded the paragraph a bit, do you have a suggestion how to make it more conclusive?
# c_n^{\text{QSD}} &= \frac{9}{16} 4^n - 3\cdot 2^{n-1},\\ | ||
# r_n^{\text{QSD}} &= \frac{21}{16} 4^n - 3\cdot 2^{n-1}. | ||
# | ||
# Shende et al. then perform the following two optimizations: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
citation after shende et al perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, also added the analogous spots for KG and Block-ZXZ 👍
# leaves the rotation count unchanged. The solution for the CNOT count is | ||
# :math:`c_n = \tfrac{13}{24} 4^n -3\cdot 2^{n-1} + \tfrac{1}{3}`. | ||
# | ||
# Second, Shende et al. consider the stage at the recursion just before decomposing the two-qubit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also a citation here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would be a bit repetitive for my taste, no strong preference though.
# Note that all two-qubit blocks in the QSD are separated by multiplexer controls, which commute | ||
# with diagonal matrices. Therefore we can start at the right-most block, decompose it into the | ||
# above form, and pull the diagonal :math:`\Delta` to the left to absorb it into the second two-qubit | ||
# block from the right. This block can then be decomposed into the above form again, and the | ||
# diagonal contribution can be merged into the third block from the right. Continuing this, | ||
# we find that we can decompose all two-qubit blocks into 2 CNOTs and 14 rotation gates, | ||
# except for the left-most block which is decomposed in the conventional manner into 3 CNOTs and | ||
# 15 rotations. As there are :math:`4^{n-2}` two-qubit blocks, we save :math:`4^{n-2}-1` | ||
# CNOTs and rotation gates, arriving at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a bit hard to follow without circuit diagrams 😅 could at them since this is appendix anyway, but dont have to - gonna leave it up to you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a figure :)
fig, axs = plt.subplots(1, 2, figsize=(12, 4)) | ||
for c_n, r_n, label, color in zip(all_c_n, all_r_n, labels, colors): | ||
axs[0].plot(n, c_n / 4**n, label=label, color=color, lw=2) | ||
ls = ":" if label in ["QSD", "Block-ZXZ"] else "-" | ||
axs[1].plot(n, r_n / 4**n, label=label, color=color, ls=ls, lw=2) | ||
|
||
ylabels = ["Number of CNOT gates ($/4^n$)", "Number of rotations ($/4^n$)"] | ||
for ax, ylabel in zip(axs, ylabels): | ||
ax.legend() | ||
ax.set_xlabel("Number of qubits $n$") | ||
ax.set_ylabel(ylabel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice touch!
Title:
Unitary synthesis with recursive KAK decompositions
Summary:
Unitary synthesis, the process of compiling a unitary matrix into a quantum circuit, has been a topic of study for over
25 years. Three interesting techniques for unitary synthesis, namely the first, the (probably) most widely known, and the minimal-CNOT-count ("the best"), all use the same recursive KAK decomposition under the hood, as we recently
elaborated in a paper.
This demo builds on our demo on KAK decompositions (added in #1227) and explains how such decompositions can be applied recursively to construct a many-qubit circuit and how the three mentioned techniques all are powered by the same recursion.
It defers some optimization details to the literature but provides a brief gate count overview and showcases a simplified numerical implementation of all three techniques.
Relevant references:
Quite a few, see metadata file.
Possible Drawbacks:
N/A
Related GitHub Issues:
[sc-87548]
To do
If you are writing a demonstration, please answer these questions to facilitate the marketing process.
qml.liealg
features(more details here)