Skip to content

Commit

Permalink
reopen How-to run qsvt on hardware (#1218)
Browse files Browse the repository at this point in the history
**Title:** how to run QSVT on Hardware

**Summary:** Performing polynomial transformations on matrices or
operators is a task of great interest, which we have previously
addressed in our introductory demos on QSVT and its practical
applications. In this how-to guide, we will show how we can implement
the QSVT subroutine in a hardware-compatible way, taking your
applications to the next level.


----
If you are writing a demonstration, please answer these questions to
facilitate the marketing process.

* GOALS — Why are we working on this now?

We are making a Push to QSVT as it currently gives many problems and we
want to make clear how to use it correctly.

* AUDIENCE — Who is this for?

People who know the algorithm but want to see how to implement it in
hardware.

* KEYWORDS — What words should be included in the marketing post?


QSVT, hardware, how-to

* Which of the following types of documentation is most similar to your
file?

    
- [ ] Tutorial
- [ ] Demo
- [ x ] How-to

---------

Co-authored-by: Ivana Kurečić <[email protected]>
Co-authored-by: Ali Asadi <[email protected]>
  • Loading branch information
3 people authored Sep 18, 2024
1 parent 6cb8957 commit c833d18
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions demonstrations/tutorial_qsvt_hardware.metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"title": "How to implement QSVT on hardware",
"authors": [
{
"username": "KetPuntoG"
}
],
"dateOfPublication": "2024-09-18T00:00:00+00:00",
"dateOfLastModification": "2024-09-18T00:00:00+00:00",
"categories": [
"Algorithms",
"Quantum Computing",
"How-to"
],
"tags": [],
"previewImages": [
{
"type": "thumbnail",
"uri": "/_static/demo_thumbnails/regular_demo_thumbnails/thumbnail_qsvt_hardware.png"
},
{
"type": "large_thumbnail",
"uri": "/_static/demo_thumbnails/large_demo_thumbnails/thumbnail_large_qsvt_hardware.png"
}
],
"seoDescription": "Learn how to implement QSVT on hardware.",
"doi": "",
"canonicalURL": "/qml/demos/tutorial_qsvt_hardware",
"references": [
],
"basedOnPapers": [],
"referencedByPapers": [],
"relatedContent": [
{
"type": "demonstration",
"id": "tutorial_intro_qsvt",
"weight": 1.0
},
{
"type": "demonstration",
"id": "tutorial_apply_qsvt",
"weight": 1.0
}

]
}
167 changes: 167 additions & 0 deletions demonstrations/tutorial_qsvt_hardware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
r"""How to implement QSVT on hardware
=======================================
The :doc:`quantum singular value transform (QSVT) </demos/tutorial_intro_qsvt>`
is a quantum algorithm that allows us to perform polynomial
transformations on matrices or operators, and it is rapidly becoming
a go-to algorithm for :doc:`quantum application research </demos/tutorial_apply_qsvt>`
in the `ISQ era <https://pennylane.ai/blog/2023/06/from-nisq-to-isq/>`__.
In this how-to guide, we will show how we can implement the QSVT
subroutine in a hardware-compatible way, taking your application research
to the next level.
.. figure:: ../_static/demo_thumbnails/opengraph_demo_thumbnails/OGthumbnail_qsvt_hardware.png
:align: center
:width: 50%
:target: javascript:void(0)
Calculating angles
------------------
Our goal is to apply a polynomial transformation to a given Hamiltonian, i.e., :math:`p(\mathcal{H})`. To achieve this, we must consider the two
fundamental components of the QSVT algorithm:
- **Projection angles**: A list of angles that will determine the coefficients of the polynomial to be applied.
- **Block encoding**: The strategy used to encode the Hamiltonian. We will use the :doc:`linear combinations of unitaries <demos/tutorial_lcu_blockencoding>` approach via the PennyLane :class:`~.qml.PrepSelPrep` operation.
Calculating angles is not a trivial task, but there are tools such as `pyqsp <https://github.com/ichuang/pyqsp/tree/master/pyqsp>`_ that do the job for us.
For instance, to find the angles to apply the polynomial :math:`p(x) = -x + \frac{x^3}{2}+ \frac{x^5}{2}`, we can run this code:
.. code-block:: python
from pyqsp.angle_sequence import QuantumSignalProcessingPhases
import numpy as np
# Define the polynomial, the coefficients are in the order of the polynomial degree.
poly = np.array([0,-1, 0, 0.5, 0 , 0.5])
ang_seq = QuantumSignalProcessingPhases(poly, signal_operator="Wx")
The angles obtained after execution are as follows:
"""

ang_seq = [
-1.5115007723754004,
0.6300762184670975,
0.8813995564082947,
-2.2601930971815003,
3.7716688720568885,
0.059295554419495855,
]

######################################################################
# We use these angles to apply the polynomial transformation.
# However, we are not finished yet: these angles have been calculated following the "Wx"
# convention [#unification]_, while :class:`~.qml.PrepSelPrep` follows a different one. Moreover, the angles obtained in the
# context of QSP (the ones given by ``pyqsp``) are not the same as the ones we have to use in QSVT. That is why
# we must transform the angles:

import numpy as np


def convert_angles(angles):
num_angles = len(angles)
update_vals = np.zeros(num_angles)

update_vals[0] = 3 * np.pi / 4 - (3 + len(angles) % 4) * np.pi / 2
update_vals[1:-1] = np.pi / 2
update_vals[-1] = -np.pi / 4

return angles + update_vals


angles = convert_angles(ang_seq)
print(angles)

######################################################################
# Using these angles, we can now start working with the template.
#
# QSVT on hardware
# -----------------
#
# The :class:`~.qml.QSVT` template expects two inputs. The first one is the block encoding operator, :class:`~.qml.PrepSelPrep`,
# and the second one is a set of projection operators, :class:`~.qml.PCPhase`, that encode the angles properly.
# We will see how to apply them later, but first let's define
# a Hamiltonian and manually apply the polynomial of interest:

import pennylane as qml
from numpy.linalg import matrix_power as mpow

coeffs = np.array([0.2, -0.7, -0.6])
coeffs /= np.linalg.norm(coeffs, ord=1) # Normalize the coefficients

obs = [qml.X(3), qml.X(3) @ qml.Z(4), qml.Z(3) @ qml.Y(4)]

H = qml.dot(coeffs, obs)

H_mat = qml.matrix(H, wire_order=[3, 4])

# We calculate p(H) = -H + 0.5 * H^3 + 0.5 * H^5
H_poly = -H_mat + 0.5 * mpow(H_mat, 3) + 0.5 * mpow(H_mat, 5)

print(np.round(H_poly, 4))

######################################################################
# Now that we know what the target result is, let's see how to apply the polynomial with a quantum circuit instead.
# We start by defining the proper input operators for the :class:`~.qml.QSVT` template.

# We need |log2(len(coeffs))| = 2 control wires to encode the Hamiltonian
control_wires = [1, 2]
block_encode = qml.PrepSelPrep(H, control=control_wires)

projectors = [
qml.PCPhase(angles[i], dim=2 ** len(H.wires), wires=control_wires + H.wires)
for i in range(len(angles))
]


dev = qml.device("default.qubit")

@qml.qnode(dev)
def circuit():

qml.Hadamard(0)
qml.ctrl(qml.QSVT, control=0, control_values=[1])(block_encode, projectors)
qml.ctrl(qml.adjoint(qml.QSVT), control=0, control_values=[0])(block_encode, projectors)
qml.Hadamard(0)

return qml.state()


matrix = qml.matrix(circuit, wire_order=[0] + control_wires + H.wires)()
print(np.round(matrix[: 2 ** len(H.wires), : 2 ** len(H.wires)], 4))

######################################################################
# The matrix obtained using QSVT is the same as the one obtained by applying the polynomial
# directly to the Hamiltonian! That means the circuit is encoding :math:`p(\mathcal{H})` correctly.
# The great advantage of this approach is that all the building blocks used in the circuit can be
# decomposed into basic gates easily, allowing this circuit
# to be easily executed on hardware devices with PennyLane.
#
# Please also note that QSVT encodes the desired polynomial :math:`p(\mathcal{H})` as well as
# a polynomial :math:`i q(\mathcal{H})`. To isolate :math:`p(\mathcal{H})`, we have used an auxiliary qubit and considered that
# the sum of a complex number and its conjugate gives us twice its real part. We
# recommend :doc:`this demo </demos/tutorial_apply_qsvt>` to learn more about the structure
# of the circuit.
#
# Conclusion
# ----------
# In this brief how-to we demonstrated applying QSVT on a sample Hamiltonian. Note that the algorithm is sensitive to
# the block-encoding method, so please make sure that the projection angles are converted to the proper format.
# This how-to serves as a guide for running your own workflows and experimenting with more advanced Hamiltonians and polynomial functions.
#
# References
# ----------
#
# .. [#unification]
#
# John M. Martyn, Zane M. Rossi, Andrew K. Tan, Isaac L. Chuang.
# "A Grand Unification of Quantum Algorithms".
# `arXiv preprint arXiv:2105.02859 <https://arxiv.org/abs/2105.02859>`__.
#
# About the author
# ----------------
#

0 comments on commit c833d18

Please sign in to comment.