PennyLane
Install
Install

Related materials

  • Related contentIntro to QSVT
  • Related contentQSVT in Practice
  • Related contentIntro to qubitization

Contents

  1. Calculating angles
  2. QSVT on hardware
  3. Conclusion
  4. References
  5. About the author

Downloads

  • Download Python script
  • Download Notebook
  • View on GitHub
  1. Demos/
  2. Algorithms/
  3. How to implement QSVT on hardware

How to implement QSVT on hardware

Guillermo Alonso

Guillermo Alonso

Published: September 17, 2024. Last updated: December 05, 2024.

The quantum singular value transform (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 quantum application research in the ISQ era.

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.

demos/_static/demo_thumbnails/opengraph_demo_thumbnails/OGthumbnail_qsvt_hardware.png

Calculating angles

Our goal is to apply a polynomial transformation to a given Hamiltonian, i.e., \(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 linear combinations of unitaries approach via the PennyLane PrepSelPrep operation.

Calculating angles is not a trivial task, but we can use the PennyLane function poly_to_angles() to obtain them. There are also tools such as pyqsp that can do the job for us. Let’s try both tools to calculate the angles for applying the polynomial \(p(x) = -x + \frac{x^3}{2}+ \frac{x^5}{2}\).

The poly_to_angles() function in PennyLane accepts the coefficients of the polynomial, ordered from lowest to highest power, as input. We also need to define the routine for which the angles are computed, which is 'QSVT' here.

import pennylane as qml
poly = [0, -1.0, 0, 1/2, 0, 1/2]
angles_pl = qml.poly_to_angles(poly, "QSVT")
print(angles_pl)
[-5.49778714  1.57079633  1.57079633  1.90410872  1.27209312  0.75078898]

To find the angles with pyqsp we can run this code:

from pyqsp.angle_sequence import QuantumSignalProcessingPhases
import numpy as np

ang_seq = QuantumSignalProcessingPhases(np.array(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,
]

The pyqsp angles are obtained in the context of QSP and are not the same as the ones we have to use in QSVT. We can use the transform_angles() function to transform the angles:

angles_pyqsp = qml.transform_angles(ang_seq, "QSP", "QSVT")
print(angles_pyqsp)
[-7.00928792  2.20087255  2.45219588 -0.68939677  5.3424652  -0.72610261]

Note that these angles are not exactly the same as those obtained with poly_to_angles(), but they will both produce the same polynomial transformation. Using the angles computed with poly_to_angles() or pyqsp, we can now start working with the template.

QSVT on hardware

The QSVT template expects two inputs. The first one is the block encoding operator, PrepSelPrep, and the second one is a set of projection operators, 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
import numpy as np
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))
[[ 0.    +0.j      0.    -0.1026j  0.1189+0.j      0.    +0.j    ]
 [ 0.    +0.1026j  0.    +0.j      0.    +0.j     -0.1873+0.j    ]
 [ 0.1189+0.j      0.    +0.j      0.    +0.j      0.    +0.1026j]
 [ 0.    +0.j     -0.1873+0.j      0.    -0.1026j  0.    +0.j    ]]

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 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_pl[i], dim=2 ** len(H.wires), wires=control_wires + H.wires)
    for i in range(len(angles_pl))
]


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))
[[ 0.    -0.j     -0.    -0.1026j  0.1189-0.j      0.    -0.j    ]
 [-0.    +0.1026j -0.    -0.j     -0.    -0.j     -0.1873-0.j    ]
 [ 0.1189+0.j     -0.    +0.j      0.    +0.j     -0.    +0.1026j]
 [ 0.    +0.j     -0.1873+0.j     -0.    -0.1026j  0.    -0.j    ]]

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 \(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 \(p(\mathcal{H})\) as well as a polynomial \(i q(\mathcal{H}).\) To isolate \(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 this demo 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

1

John M. Martyn, Zane M. Rossi, Andrew K. Tan, Isaac L. Chuang. “A Grand Unification of Quantum Algorithms”. arXiv preprint arXiv:2105.02859.

About the author

Guillermo Alonso
Guillermo Alonso

Guillermo Alonso

Quantum Scientist specializing in quantum algorithms

Total running time of the script: (0 minutes 0.082 seconds)

Share demo

Ask a question on the forum

Related Demos

Intro to QSVT

QSVT in Practice

Intro to qubitization

Linear combination of unitaries and block encodings

Using PennyLane and Qualtran to analyze how QSP can improve measurements of molecular properties

How to track algorithmic error using PennyLane

Qutrits and quantum algorithms

Grover's Algorithm

Block encoding with matrix access oracles

Function Fitting using Quantum Signal Processing

PennyLane

PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Built by researchers, for research. Created with ❤️ by Xanadu.

Research

  • Research
  • Performance
  • Hardware & Simulators
  • Demos
  • Quantum Compilation
  • Quantum Datasets

Education

  • Teach
  • Learn
  • Codebook
  • Coding Challenges
  • Videos
  • Glossary

Software

  • Install PennyLane
  • Features
  • Documentation
  • Catalyst Compilation Docs
  • Development Guide
  • API
  • GitHub
Stay updated with our newsletter

© 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