Phase Gradient Demo#1795
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! |
Your preview is ready 🎉!You can view your changes here
|
KetpuntoG
left a comment
There was a problem hiding this comment.
Nice job @nobese 🙌 here are some comments to help make the demo shine:)
Overall the ingredients are there, but we could give the narrative another pass. The phase gradient needs to be much more central, making its properties and how it's used clear (on page 20 of our paper, you can see a slightly more technical example: QROM-based decomposition of RZ multiplexer). You could start with the case of synthesizing a single rotation, which shows the core idea but also shows that there is no improvement in resources (great for illustrative purposes). And circuit diagrams are super important and easier to follow than the text description.
On the other hand, the strength of the phase gradient comes when it's used in a rotation multiplexer (SelectPauliRot), and I think it's key to show that difference making the reader understanding why
The goal should be to train the next generation of phase gradient experts and with some small changes we'll be on track 😎
| # | ||
| # Efficient Rotations? | ||
| # -------------------- | ||
| # As established, arbitrary rotations are expensive. Unfortunately, they are also foundational to some of the most important tools we have in quantum algorithms and computing, such as the `quantum fourier transform (QFT) <https://pennylane.ai/qml/demos/tutorial_qft>`_, `quantum read-only memory (QROM) <https://pennylane.ai/qml/demos/tutorial_intro_qrom>`_, and the `trotterization algorithm <https://pennylane.ai/challenges/a_simple_trotterization>`_. As a result, optimizing these operations in the fault-tolerant picture is very important. There have been a diverse array of optimization strategies proposed that all boil down to reducing the number of T-gates required to carry out a rotation. |
There was a problem hiding this comment.
I would say QROM does not use "rotations" so feel free to remove it :)
| # -------------------- | ||
| # As established, arbitrary rotations are expensive. Unfortunately, they are also foundational to some of the most important tools we have in quantum algorithms and computing, such as the `quantum fourier transform (QFT) <https://pennylane.ai/qml/demos/tutorial_qft>`_, `quantum read-only memory (QROM) <https://pennylane.ai/qml/demos/tutorial_intro_qrom>`_, and the `trotterization algorithm <https://pennylane.ai/challenges/a_simple_trotterization>`_. As a result, optimizing these operations in the fault-tolerant picture is very important. There have been a diverse array of optimization strategies proposed that all boil down to reducing the number of T-gates required to carry out a rotation. | ||
| # | ||
| # To emphasize the benefit of T-gate optimization, let us take the example of binary state loading, which is typically carried out through some method of phase manipulation. For QROM, for example, a :math:`N`-bit binary string can be represented by :math:`n=log_2(N)` qubits in superposition that conditionally undergo a phase shift invoked by a set of gates. To ensure fault tolerance, these rotations should be carried out using distilled T-gates, causing the system to scale as :math:`\mathcal{O}(2^nlog_2(1/\epsilon))`, where :math:`\epsilon` is the desired precision. Yikes. |
There was a problem hiding this comment.
It is a bit confusing the sentence "For QROM, for example"
N normally is the number of bit strings we can load with a QROM and we say each of those bit strings has length b. Also not sure what you mean by phase shift here
There was a problem hiding this comment.
(Okey, so I think you are using QROM = SelectPauliRot but that's not correct)
There was a problem hiding this comment.
Regarding to the \mathcal{O}(2^nlog_2(1/\epsilon)), this is true if we use a naive decomposition but in practice it is lower. Maybe you could just mention something like "using a standard approach" or "using a naive approach" without enter in more details
| # ------------------------ | ||
| # What if, instead of having to apply an individual, expensive rotation to each bit to achieve the desired outcome, we could simply add a pre-defined phase to each qubit as needed? | ||
| # | ||
| # `Phase gradient states <https://pennylane.ai/compilation/phase-gradient>`_ are a type of catalytic resource state that can be used as a substitute for typical, multiplication based rotation gate operations. For clarity, a state is "catalytic" if it is unchanged by a process that it plays a role in facilitating. To (aptly) borrow the language of chemistry, it exists to catalyze (assist) a specific process (operation). The phase gradient state can be interpreted as a catalyst for phase shifts, invoking phase accumulation on other qubits without sacrificing its own properties. The state can be represented as the conditional phase operator |
There was a problem hiding this comment.
"multiplication based rotation gate operations. " this term is not clear to me
| # | ||
| # Here, :math:`B=2^b` is the total number of possible states in the superposition, :math:`b=\log_2(1/\epsilon)` is the total number of qubits stored in the gradient register, and :math:`j` is the index of a specific qubit within the register. | ||
| # | ||
| # The phase gradient state basically acts as a conditional rotation operator in itself. What is special, however, is that this state can be prepared once, stored in an auxiliary register, and reused catalytically. To induce a phase shift, the data register (storing an integer value) can be *added* to the gradient register and, via `phase kickback <https://pennylane.ai/qml/demos/tutorial_phase_kickback>`_, the data register accumulates a phase shift proportional to its integer value. One can take the term "gradient" literally here; the phase gradient state essentially stores spatially dependent phases that can be applied to encode data as a function of qubit position. |
There was a problem hiding this comment.
"The phase gradient state basically acts as a conditional rotation operator in itself"
Note sure what that means
There was a problem hiding this comment.
What I was expecting to find on this demo after reading the title was exactly the explanation of this paragraph 😄 I do think you should enter on the details here, show a circuit diagram, so the reader knows how it works and it doesn't look like magic
The FTQC context is nice, the resources estimation is nice, but if I actually want to learn what is this of rotations with phase gradients, this is the key part 💪
(If I'm missing more context and this has been already discussed let me know)
There was a problem hiding this comment.
No, I completely agree! From previous discussions we decided we want to have all that context here, but I agree that phase gradients should stand out more. I have some ideas for how to do that!
| # | ||
| # The phase gradient state basically acts as a conditional rotation operator in itself. What is special, however, is that this state can be prepared once, stored in an auxiliary register, and reused catalytically. To induce a phase shift, the data register (storing an integer value) can be *added* to the gradient register and, via `phase kickback <https://pennylane.ai/qml/demos/tutorial_phase_kickback>`_, the data register accumulates a phase shift proportional to its integer value. One can take the term "gradient" literally here; the phase gradient state essentially stores spatially dependent phases that can be applied to encode data as a function of qubit position. | ||
| # | ||
| # This approach, as a whole, has two major optimization benefits. First, the phase gradient states only needs to be generated *once* since its catalytic nature leaves it unchanged after it interacts with the data register, meaning it will have a one-time, upfront preparation T-gate cost that is never repeated. Second, the phase shifts are applied by an addition operation rather than multiplication, meaning the phase gradient method's T-gate count scales as :math:`\mathcal{O}(n+\log_2(1/\epsilon))`. |
There was a problem hiding this comment.
you mean :math:\mathcal{O}("2^n"+\log_2(1/\epsilon)) instead of :math:\mathcal{O}(n+\log_2(1/\epsilon)) there is a QROM cost that you are not considering here I think
With some circuit diagrams every will be more clear 😎
There was a problem hiding this comment.
(maybe Im confused, what is n here?)
There was a problem hiding this comment.
Here n=log2(N) where N is the length of the input string, so I believe your suggestion is correct!
| # :align: center | ||
| # :width: 80% | ||
| # | ||
| # Though the phase gradient approach requires an investment of resources to prepare the gradient register, the additive nature of the loading procedure results in a very slow accumulation of resources. The benefit of this quickly outweighs the lack of setup cost in the simple multiplicative case, justifying the benefit of phase gradient states in rotation-based algorithms. |
There was a problem hiding this comment.
"multiplicative case"
This is still a term that I'm not sure about
| # The importance of carrying out efficient rotations has been known to the industry for some time. As a result, the phase gradient approach is not the only gate-synthesis strategy available in the quantum algorithmic toolkit. There are certainly nuances between the ideal applications of each algorithm, but a full exploration will not be included here. Instead, comparing the per-rotation gate cost reveals the relative cost of each strategy, which must be weighed against the nuance of the specific application. | ||
| # | ||
| # +----------------------------+--------------------+-----------------------------------------------------+ | ||
| # | Algorithm | Setup Cost | Gate Cost Per Rotation | |
There was a problem hiding this comment.
Setup cost and Gate cost in which units?
There was a problem hiding this comment.
Is it typical to signify that it is terms of T-Gates using units (T)?
There was a problem hiding this comment.
yes. doesn't hurt to list this "unit" in table, which I think is Guillermo's suggestion
| # | ||
| # +----------------------------+--------------------+-----------------------------------------------------+ | ||
| # | Algorithm | Setup Cost | Gate Cost Per Rotation | | ||
| # +============================+====================+=====================================================+ |
There was a problem hiding this comment.
The state of the art:https://arxiv.org/pdf/2203.10064
It may worth mentioning
| # +----------------------------+--------------------+-----------------------------------------------------+ | ||
| # | Kliuchnikov | 0 | :math:`2\log(1/\epsilon)` [#Kliuchnikov2015]_ | | ||
| # +----------------------------+--------------------+-----------------------------------------------------+ | ||
| # | Phase Gradient | :math:`4\log_2(1/ | 4 [#Gidney2018]_ | |
There was a problem hiding this comment.
these two fours Looks suspicious 😄
There was a problem hiding this comment.
haha maybe I incorporated the 1 Toffoli = 4 T-gate figure incorrectly, would it be more accurate to say the total cost is Nlog_2(1/eps)+N?
| # | ||
| # To work around this issue, non-Clifford gates can be broken down into an equivalent series of `T-gates <https://pennylane.ai/qml/demos/tutorial_achieving_universality_with_the_clifford_hierarchy>`_, which represent a fixed :math:`\frac{\pi}{4}` rotation, and auxiliary Clifford gates. While these (like arbitrary rotations) are not fault tolerant, they can be "protected" via a process called `magic state distillation <https://pennylane.ai/qml/demos/tutorial_magic_state_distillation>`_. Perhaps this all sounds a bit far fetched now that `magic <https://pennylane.ai/qml/demos/tutorial_magic_states>`_ has come into play, but the idea can be summarized as follows: non-Clifford gates tend to not have inherent fault tolerance, so the operations they represent should ideally be built out of components on which errors can be easily detected such that any error ridden qubits can be thrown away before the entire system is impacted. | ||
| # | ||
| # .. figure:: ../demonstrations_v2/efficient_rotations_with_phase_gradient_states/GateDecompBig.gif |
There was a problem hiding this comment.
The top is a snippet of the full expansion that pennylane gives. I was hoping the ellipses would make it clear that it is not the full decomposition, but maybe it is too confusing!
KetpuntoG
left a comment
There was a problem hiding this comment.
(I see still some unresolved comments but I'm leaving two extra onces before I leave 🌴)
| # :align: center | ||
| # :width: 700px | ||
| # | ||
| # *Simple multiplexed phase gradient addition* [#OBrien2025]_ |
There was a problem hiding this comment.
| # *Simple multiplexed phase gradient addition* [#OBrien2025]_ | |
| # *Simple multiplexed phase gradient addition* [#OBrien2025]_. |
| # | ||
| # .. _references: | ||
| # | ||
| # References |
There was a problem hiding this comment.
I'm still seeing some inconsistent formatting between references, e.g., in the hyperlink text
Co-authored-by: Nathan Killoran <co9olguy@users.noreply.github.com>
Co-authored-by: Nathan Killoran <co9olguy@users.noreply.github.com>
KetpuntoG
left a comment
There was a problem hiding this comment.
Looking good 💪
Here it is my last round of comments:)
Make sure you don't forget to address any previous comment. Normally it is easier to see what is missing in the "files changed" tab
| # ------------------------ | ||
| # What if, instead of having to apply an individual, expensive rotation for each bit value to achieve the desired outcome, we could simply add a pre-defined phase state to the qubits as needed? | ||
| # | ||
| # `Phase gradient states <https://pennylane.ai/compilation/phase-gradient>`_ are a type of catalytic resource state that can be used to facilitate rotations additively. For clarity, a state is "catalytic" if it is unchanged by a process that it plays a role in facilitating. To (aptly) borrow from the language of chemistry, it exists to catalyze (assist) a specific process (operation). The phase gradient state can be interpreted as a catalyst for phase shifts, invoking phase accumulation on other qubits without sacrificing its own properties. The state can be represented as |
There was a problem hiding this comment.
For consistency this may be better
| # `Phase gradient states <https://pennylane.ai/compilation/phase-gradient>`_ are a type of catalytic resource state that can be used to facilitate rotations additively. For clarity, a state is "catalytic" if it is unchanged by a process that it plays a role in facilitating. To (aptly) borrow from the language of chemistry, it exists to catalyze (assist) a specific process (operation). The phase gradient state can be interpreted as a catalyst for phase shifts, invoking phase accumulation on other qubits without sacrificing its own properties. The state can be represented as | |
| # `Phase gradient states <https://pennylane.ai/compilation/phase-gradient>`_ are a type of catalytic resource state that can be used to facilitate rotations additively. For clarity, a state is "catalytic" if it is unchanged by a process that it plays a role in facilitating. To borrow (aptly) from the language of chemistry, it exists to catalyze (assist) a specific process (operation). The phase gradient state can be interpreted as a catalyst for phase shifts, invoking phase accumulation on other qubits without sacrificing its own properties. The state can be represented as |
| # :align: center | ||
| # :width: 700px | ||
| # | ||
| # *Phase kickback can be imagined as a change in the relative phase between the data register and the phase gradient register. As depicted, a controlled addition between the two registers will result in the positional displacement of the phase gradient state which, in turn, causes the phase difference that can be associated with either state. Even though the gradient register shifts, the states in the data register can "pick up" the relative phase difference*. |
There was a problem hiding this comment.
Phase kickback is being mentioned here but introduced later
| # :class: note | ||
| # | ||
| # 1. A phase gradient state is encoded onto a register composed of :math:`b` qubits. | ||
| # 2. A semi-adder operation is performed between a data register and the gradient register. |
There was a problem hiding this comment.
Why semi-adder here and controlled-Adder before?
What is the data register? it doesn't appear in the equations
The answer is that there are two ways of applying the phase gradient: with a classical adder (+k) or a semiadder (where
There was a problem hiding this comment.
Based on the current structure of the demo, I would suggest:
- Keep the current approach of classical Adder and just update this note
- In the next paragraph, mention that with the QROM we store each
$K$ in parallel in a quantum register () and we add those quantum register to the phase gradient in parallel using a SemiAdder
| # | ||
| # *Equivalent circuits for executing a phase shift, in which the phase shift operator can be replaced with an addition step between a state :math:`k` and the phase gradient register* | ||
| # | ||
| # The phase gradient state can be interpreted as acting as a pre-defined plane of stored angles that can be accessed and invoked on a target state as desired. This state can be prepared once, stored in an auxiliary register, and reused. To induce a rotation, an integer :math:`k` simply needs to be added to the gradient register, which is done most commonly using a controlled `addition gate <https://docs.pennylane.ai/en/stable/code/api/pennylane.SemiAdder.html>`_ step, to invoke a phase shift on the target state. This procedure is summarized as |
There was a problem hiding this comment.
To induce a rotation, an integer :math:
ksimply needs to be added
how is related the angle we want to rotate and the integer
There was a problem hiding this comment.
I added some elaboration above and here, hopefully that makes this more clear!
| # | Single Qubit Gate Approximation | 0 | :math:`0.56\log_2(1/\epsilon)` [#Kliuchnikov2022]_ | :math:`0.56R \log_2(1/\epsilon)` | :math:`8.37 \times 10^{2}` | | ||
| # +---------------------------------+----------------------------+----------------------------------------------------+--------------------------------------------------------------+-----------------------------------------------------------------+ | ||
| # | ||
| # Though this comparison shows the comparatively low cost of the mumtiplexed phase gradient approach, it leaves a hanging question: why not just multiplex every method? QROM can, of course, be used to load states into a register in any computationally compatible scenario, but the fact that the phase gradient state is catalytic and accessible in a pre-configured register is what makes this efficient multiplexing approach possible. If the phase gradient state were destroyed each time it was applied to a state, it would be impossible to effectively carry out a simultaneous rotation on a register. Trying to multiplex a GridSynth process, for example, would require the simultaneous execution of gate sequences that vary with the control qubit states. This would cause the depth of the multiplexed operation to explode, eliminating any potential advantage. So, while phase gradients are expensive to prepare, they give us the luxury of a simple look-up table style approach. |
There was a problem hiding this comment.
| # Though this comparison shows the comparatively low cost of the mumtiplexed phase gradient approach, it leaves a hanging question: why not just multiplex every method? QROM can, of course, be used to load states into a register in any computationally compatible scenario, but the fact that the phase gradient state is catalytic and accessible in a pre-configured register is what makes this efficient multiplexing approach possible. If the phase gradient state were destroyed each time it was applied to a state, it would be impossible to effectively carry out a simultaneous rotation on a register. Trying to multiplex a GridSynth process, for example, would require the simultaneous execution of gate sequences that vary with the control qubit states. This would cause the depth of the multiplexed operation to explode, eliminating any potential advantage. So, while phase gradients are expensive to prepare, they give us the luxury of a simple look-up table style approach. | |
| # Though this comparison shows the comparatively low cost of the multiplexed phase gradient approach, it leaves a hanging question: why not just multiplex every method? QROM can, of course, be used to load states into a register in any computationally compatible scenario, but the fact that the phase gradient state is catalytic and accessible in a pre-configured register is what makes this efficient multiplexing approach possible. If the phase gradient state were destroyed each time it was applied to a state, it would be impossible to effectively carry out a simultaneous rotation on a register. Trying to multiplex a GridSynth process, for example, would require the simultaneous execution of gate sequences that vary with the control qubit states. This would cause the depth of the multiplexed operation to explode, eliminating any potential advantage. So, while phase gradients are expensive to prepare, they give us the luxury of a simple look-up table style approach. |
| angle_wires = list(range(n+1,n+1+b)) | ||
| gradient_wires = list(range(n+1+b,n+1+2*b)) | ||
| work_wires = list(range(n+1+2*b,n+1+2*b+(3*b))) | ||
|
|
||
| @qp.qnode(dev) | ||
| @select_pauli_rot_phase_gradient(angle_wires,gradient_wires,work_wires) | ||
| def circuit_phase_grad(): | ||
| for wire in data_wires: | ||
| qp.Hadamard(wire) | ||
| qp.SelectPauliRot(angles, data_wires, target_wire, rot_axis="Y") | ||
| return qp.probs(target_wire) |
There was a problem hiding this comment.
This should work to solve my comment in the last review
| angle_wires = list(range(n+1,n+1+b)) | |
| gradient_wires = list(range(n+1+b,n+1+2*b)) | |
| work_wires = list(range(n+1+2*b,n+1+2*b+(3*b))) | |
| @qp.qnode(dev) | |
| @select_pauli_rot_phase_gradient(angle_wires,gradient_wires,work_wires) | |
| def circuit_phase_grad(): | |
| for wire in data_wires: | |
| qp.Hadamard(wire) | |
| qp.SelectPauliRot(angles, data_wires, target_wire, rot_axis="Y") | |
| return qp.probs(target_wire) | |
| regs = qp.registers({"angle": b, "gradient": b, "work": 3*b}) | |
| @qp.qnode(dev) | |
| @select_pauli_rot_phase_gradient(regs["angle"], regs["gradient"], regs["work"]) | |
| def circuit_phase_grad(): | |
| for wire in data_wires: | |
| qp.Hadamard(wire) | |
| qp.SelectPauliRot(angles, data_wires, target_wire, rot_axis="Y") | |
| return qp.probs(target_wire) |
There was a problem hiding this comment.
My only worry with using the register approach is that it makes it slightly less legible to the reader what the dimensions of each register are (at least to someone very visual, like me). However, I did use registers in the vibronics demo, so I will add them here!
| ### Please add any additional requirements that are needed for your demo here ### | ||
| ### If you are curious about global dependencies, check the `/dependencies` directory ### No newline at end of file |
KetpuntoG
left a comment
There was a problem hiding this comment.
nice work! 😄 Approving the PR
Just take a look to this final suggestions
If something is not clear let me know 👌
| # |\nabla_b\rangle=\frac{1}{\sqrt{B}}\sum_{k=0}^{B-1}e^{-2\pi i \frac{k}{B}}|k\rangle | ||
| # | ||
| # where :math:`k` represents a target computational basis state, which one can interpret as an address marker that dictates what rotation angle is applied. In product state form, |
There was a problem hiding this comment.
since
| # | ||
| # *Equivalent circuits for executing a phase shift, in which the phase shift operator can be replaced with an addition step between a state and the phase gradient register* | ||
| # | ||
| # The phase gradient state can be interpreted as acting as a pre-defined plane of stored angles that can be accessed and invoked on a target state as desired. This state can be prepared once, stored in an auxiliary register, and reused. To induce a rotation, an the integer value of state :math:`k` simply needs to be added to the gradient register, which is done most commonly using a controlled `addition gate <https://docs.pennylane.ai/en/stable/code/api/pennylane.SemiAdder.html>`_ step, to invoke a phase shift on the target state corresponding to the "address marker" mentioned above. This procedure is summarized as |
There was a problem hiding this comment.
This sentence doesn't seem correct
an the integer value of state :math:
ksimply needs to be added
If you don't want to enter in details I would say something like
To induce a rotation, an integer value :math:k, proportional to the rotation angle, <here I would link: https://pennylane.ai/compilation/phase-gradient for more details> needs to be added to the gradient register, which is done most commonly using a controlled `addition gate
| # &= (\alpha|0\rangle+\beta e^{-\frac{2\pi i k}{B}} |1\rangle)|\nabla_b\rangle. | ||
| # \end{aligned} | ||
| # | ||
| # Thus, the phase gradient state essentially stores spatially dependent phases that can be applied to invoke rotations as a function of qubit position. |
There was a problem hiding this comment.
(optional)
You could also ask the reader for the
Something like:
Based on this equation, could you guess the value of
| # :class: note | ||
| # | ||
| # 1. A phase gradient state is encoded onto a register composed of :math:`b` qubits. | ||
| # 2. An adder operation is performed between a data register and the gradient register. |
There was a problem hiding this comment.
| # 2. An adder operation is performed between a data register and the gradient register. | |
| # 2. An adder operation is performed between a constant $k$ and the gradient register. |
| # | ||
| # 1. A phase gradient state is encoded onto a register composed of :math:`b` qubits. | ||
| # 2. An adder operation is performed between a data register and the gradient register. | ||
| # 3. The phase gradient register shifts proportionally to the weight of the data qubit added to it. |
There was a problem hiding this comment.
| # 3. The phase gradient register shifts proportionally to the weight of the data qubit added to it. | |
| # 3. The phase gradient register shifts proportionally to the $k$ value. |
| # 1. A phase gradient state is encoded onto a register composed of :math:`b` qubits. | ||
| # 2. An adder operation is performed between a data register and the gradient register. | ||
| # 3. The phase gradient register shifts proportionally to the weight of the data qubit added to it. | ||
| # 4. The shift in the gradient register causes the data register to accumulate a relative phase via phase kickback. |
There was a problem hiding this comment.
| # 4. The shift in the gradient register causes the data register to accumulate a relative phase via phase kickback. | |
| # 4. The shift in the gradient register causes the target qubit to accumulate a relative phase via phase kickback. |
| # 4. The shift in the gradient register causes the data register to accumulate a relative phase via phase kickback. | ||
| # 5. Since position shifts are relative and do not alter structure, the catalytic phase gradient state remains unchanged and can be reused as desired. | ||
| # | ||
| # This structure can be easily extended to the more commonly used multiplexed case that we discussed at the beginning of this demonstration. In this case, we can use a `quantum read only memory (QROM) <https://pennylane.ai/demos/tutorial_intro_qrom>`_ to store each :math:`k` value in parallel in a quantum register. To carry out the rotation, it is best practice to carry out a semi-out-of-place addition using a :func:`~qp.SemiAdder` to add this quantum register to the phase gradient register. This reduces the complexity bound to :math:`\mathcal{O}(2^n+\log_2(1/\epsilon))`. This reduction in complexity combined with the catalytic nature of the phase gradient state makes this approach to gate synthesis highly resource efficient. |
There was a problem hiding this comment.
to clarify what actually the data register is
| # This structure can be easily extended to the more commonly used multiplexed case that we discussed at the beginning of this demonstration. In this case, we can use a `quantum read only memory (QROM) <https://pennylane.ai/demos/tutorial_intro_qrom>`_ to store each :math:`k` value in parallel in a quantum register. To carry out the rotation, it is best practice to carry out a semi-out-of-place addition using a :func:`~qp.SemiAdder` to add this quantum register to the phase gradient register. This reduces the complexity bound to :math:`\mathcal{O}(2^n+\log_2(1/\epsilon))`. This reduction in complexity combined with the catalytic nature of the phase gradient state makes this approach to gate synthesis highly resource efficient. | |
| # This structure can be easily extended to the more commonly used multiplexed case that we discussed at the beginning of this demonstration. In this case, we can use a `quantum read only memory (QROM) <https://pennylane.ai/demos/tutorial_intro_qrom>`_ to store each :math:`k` value in parallel in a data register. To carry out the rotation, it is best practice to carry out a semi-out-of-place addition using a :func:`~qp.SemiAdder` to add this data register to the phase gradient register. This reduces the complexity bound to :math:`\mathcal{O}(2^n+\log_2(1/\epsilon))`. This reduction in complexity combined with the catalytic nature of the phase gradient state makes this approach to gate synthesis highly resource efficient. |
| reg = qp.registers({ | ||
| "_reserved": n + 1, #Don't overwrite the previously defined wires! | ||
| "angle": b, | ||
| "gradient": b, | ||
| "work": 3 * b, | ||
| }) | ||
| angle_wires = reg["angle"] | ||
| gradient_wires = reg["gradient"] | ||
| work_wires = reg["work"] |
There was a problem hiding this comment.
Oh I see what you mean
Not ideal but I like it more in this way :)
(we are working on a better UI for this right now 😄)
| # Sizing Up Other Optimizations | ||
| # -------------------------------- | ||
| # The importance of cheaply decomposing arbitrary rotations has been known to the industry for some time. As a result, the phase gradient approach is not the only gate-synthesis strategy available in the quantum algorithmic toolkit. There are many nuances involved in asserting the ideal applications of each algorithm, but a full exploration will not be included here. Instead, comparing the per-rotation gate cost reveals the relative cost of each strategy, which must be weighed against the nuance of the specific application. Note that, for a QFT, :math:`R=N^2/2`. | ||
| # |
There was a problem hiding this comment.
Table looks perfect now 😎


How can we use phase gradient states to carry out more efficient rotations?