Skip to content

Commit 2c719af

Browse files
DSGualadoctorperceptrondaniela-angulo
authored
Update qsvt demos (#1522)
Updating a couple of QSVT demos after we got the following feedback * Intro to QSVT - drawing gave a black box QSVT/QSP circuit - would like to see a clear+explained circuit diagram * Added a `qml.draw_mpl` call that shows the decomposition and alternating structure of QSVT. Added language about quantum circuits around that section linking the structure of the diagram to the equations. * Intro to QSVT - would like more explanation on transition from scalar to matrix (small a to capital A) * Added a small sentence about block encodings. But this could still be explained more * Intro to QSVT - confusion about what how each point in the graph is obtained - explain that each one is a different circuit that encodes a different value * Expanded the description in the legends and the text. * QSVT in Practice - difficult to follow the difference between x and vector x (P(X) = s * 1/x) * Added a note emphasizing this difference Also fixes an [issue with an incorrect formula](https://discuss.pennylane.ai/t/qsvt-for-odd-degree-polynomial-mathematical-expansion/9224) --------- Co-authored-by: Paul Finlay <50180049+doctorperceptron@users.noreply.github.com> Co-authored-by: Daniela Angulo <42325731+daniela-angulo@users.noreply.github.com>
1 parent 2ea3d63 commit 2c719af

4 files changed

Lines changed: 36 additions & 13 deletions

File tree

demonstrations_v2/tutorial_apply_qsvt/demo.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ def my_circuit():
7676
# This ultimately requires computing :math:`\vec{x} = A^{-1} \cdot \vec{b},` where for simplicity we
7777
# assume that :math:`A` is invertible.
7878
#
79+
# .. note::
80+
# Follow the notation in this section carefully.
81+
# :math:`x` is a scalar and :math:`\vec{x}` is a vector. Sometimes we talk about the scalar
82+
# function :math:`P(x) = s \cdot \frac{1}{x}` and sometimes we talk about the vector
83+
# function :math:`A \cdot \vec{x} = \vec{b}.`
84+
#
7985
# :math:`A^{-1}` can be constructed directly by inverting the singular values of :math:`A^{T}.` We can
8086
# leverage QSVT to accomplish this by finding the phase angles which apply a polynomial approximation
8187
# to the transformation :math:`\frac{1}{x}.` This may seem simple in theory, but in practice there are

demonstrations_v2/tutorial_apply_qsvt/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"executable_stable": true,
1212
"executable_latest": true,
1313
"dateOfPublication": "2023-08-22T00:00:00+00:00",
14-
"dateOfLastModification": "2025-09-22T15:48:14+00:00",
14+
"dateOfLastModification": "2026-02-23T15:48:14+00:00",
1515
"categories": [
1616
"Quantum Computing",
1717
"Algorithms",

demonstrations_v2/tutorial_intro_qsvt/demo.py

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,16 @@
8888
8989
Let's look at a simple example of how quantum signal processing can be implemented using
9090
PennyLane. We aim to perform a transformation by the Legendre polynomial
91-
:math:`(5 x^3 - 3x)/2`.
91+
:math:`P(a) = (5 a^3 - 3a)/2`.
9292
As you will soon learn, QSP can be viewed as a special case of QSVT. We thus use the :func:`~.pennylane.qsvt`
93-
operation to construct the output matrix and compare the resulting transformation to
94-
the target polynomial.
93+
operation to construct the matrix representation of the QSP transformation. In the code below, we build one matrix
94+
for each value of :math:`a` that we test. If the top-left entry of the matrix matches :math:`P(a)` for all
95+
input values, then our QSP transformation successfully implements the desired matrix,
9596
97+
.. math:: \begin{pmatrix}
98+
P(a) & *\\
99+
* & *
100+
\end{pmatrix}.
96101
"""
97102

98103
import pennylane as qml
@@ -113,8 +118,9 @@ def qsvt_output(a):
113118
qsvt = [np.real(qsvt_output(a)) for a in a_vals] # neglect small imaginary part
114119
target = [np.polyval(target_poly[::-1], a) for a in a_vals] # evaluate polynomial
115120

116-
plt.plot(a_vals, target, label="target")
117-
plt.plot(a_vals, qsvt, "*", label="qsvt")
121+
plt.plot(a_vals, target, label="target polynomial: (5a^3 - 3a)/2")
122+
plt.plot(a_vals, qsvt, "*", label="QSP: top left entry of matrix")
123+
plt.xlabel('a')
118124

119125
plt.legend()
120126
plt.show()
@@ -143,7 +149,8 @@ def qsvt_output(a):
143149
#
144150
# Any such method of encoding a matrix inside a larger unitary is known as a **block encoding**. In our construction,
145151
# the matrix :math:`A` is encoded in the top-left block, hence the name. PennyLane supports
146-
# the :class:`~pennylane.BlockEncode` operation that follows the construction above. Let's test
152+
# the :class:`~pennylane.BlockEncode` operation that follows the construction above. This operation serves to block-encode
153+
# both scalars and matrices. Let's test
147154
# it out with an example encoding first a square matrix:
148155

149156
# square matrix
@@ -225,7 +232,7 @@ def qsvt_output(a):
225232
# where we use braket notation to denote the left and right singular vectors.
226233
# For technical reasons, the sequence looks slightly different when the polynomial degree is odd:
227234
#
228-
# .. math:: \tilde{\Pi}_{\phi_1}\left[\prod_{k=1}^{(d-1)/2}\Pi_{\phi_{2k}}U(A)^\dagger \tilde{\Pi}_{\phi_{2k+1}} U(A)\right]\Pi_{\phi_{d+1}}=
235+
# .. math:: \tilde{\Pi}_{\phi_1}U(A)\left[\prod_{k=1}^{(d-1)/2}\Pi_{\phi_{2k}}U(A)^\dagger \tilde{\Pi}_{\phi_{2k+1}} U(A)\right]\Pi_{\phi_{d+1}}=
229236
# \begin{pmatrix}
230237
# P(A) & *\\
231238
# * & *
@@ -241,22 +248,32 @@ def qsvt_output(a):
241248
# implemented in polynomial time in the number of qubits, the resulting
242249
# quantum algorithm will also run in polynomial time. This is very powerful.
243250
#
244-
# In PennyLane, implementing the QSVT transformation is as simple as using :func:`~.pennylane.qsvt`. Let's revisit
251+
# In PennyLane, implementing a quantum circuit for the QSVT transformation is as simple as using :func:`~.pennylane.qsvt`.
252+
# Under the hood, it uses :class:`~pennylane.BlockEncode` and :class:`~pennylane.PCPhase` operations to implement QSVT as described
253+
# in the equations above. Now let's revisit
245254
# our previous example and transform a matrix according to the same Legendre polynomial. We'll use a diagonal matrix
246255
# with eigenvalues evenly distributed between -1 and 1, allowing us to easily check the transformation.
247256

248-
249257
eigvals = np.linspace(-1, 1, 16)
250258
A = np.diag(eigvals) # 16-dim matrix
251259
wire_order = list(range(5))
260+
261+
qml.draw_mpl(qml.transforms.decompose(qml.qsvt))(A, target_poly, encoding_wires=wire_order, block_encoding="embedding")
262+
plt.show()
263+
264+
###############################################################################
265+
# Now, let's see how each eigenvalue of :math:`A` is transformed by QSVT. We will plot the original eigenvalues
266+
# and the corresponding eigenvalues of the top-left block of the QSVT matrix.
267+
252268
U_A = qml.matrix(qml.qsvt, wire_order=wire_order)(
253269
A, target_poly, encoding_wires=wire_order, block_encoding="embedding"
254270
) # block-encoded in 5-qubit system
255271

256272
qsvt_A = np.real(np.diagonal(U_A))[:16] # retrieve transformed eigenvalues
257273

258-
plt.plot(a_vals, target, label="target")
259-
plt.plot(eigvals, qsvt_A, "*", label="qsvt")
274+
plt.plot(a_vals, target, label="target polynomial: (5a^3 - 3a)/2")
275+
plt.plot(eigvals, qsvt_A, "*", label="eigenvalue after QSVT")
276+
plt.xlabel('a, eigenvalue before transformation')
260277

261278
plt.legend()
262279
plt.show()

demonstrations_v2/tutorial_intro_qsvt/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"executable_stable": true,
99
"executable_latest": true,
1010
"dateOfPublication": "2023-05-23T00:00:00+00:00",
11-
"dateOfLastModification": "2025-09-22T15:48:14+00:00",
11+
"dateOfLastModification": "2026-02-23T15:48:14+00:00",
1212
"categories": [
1313
"Algorithms",
1414
"Quantum Computing"

0 commit comments

Comments
 (0)