qsvt(A, angles, wires, convention=None)[source]

Implements the quantum singular value transformation (QSVT) circuit.


BlockEncode and PCPhase used in this implementation of QSVT are matrix-based operators and well-suited for simulators. To implement QSVT with user-defined circuits for the block encoding and projector-controlled phase shifts, use the QSVT template.

Given a matrix \(A\), and a list of angles \(\vec{\phi}\), this function applies a circuit for the quantum singular value transformation using BlockEncode and PCPhase.

When the number of angles is even (\(d\) is odd), the QSVT circuit is defined as:

\[U_{QSVT} = \tilde{\Pi}_{\phi_1}U\left[\prod^{(d-1)/2}_{k=1}\Pi_{\phi_{2k}}U^\dagger \tilde{\Pi}_{\phi_{2k+1}}U\right]\Pi_{\phi_{d+1}},\]

and when the number of angles is odd (\(d\) is even):

\[U_{QSVT} = \left[\prod^{d/2}_{k=1}\Pi_{\phi_{2k-1}}U^\dagger\tilde{\Pi}_{\phi_{2k}}U\right] \Pi_{\phi_{d+1}}.\]

Here, \(U\) denotes a block encoding of \(A\) via BlockEncode and \(\Pi_\phi\) denotes a projector-controlled phase shift with angle \(\phi\) via PCPhase.

This circuit applies a polynomial transformation (\(Poly^{SV}\)) to the singular values of the block encoded matrix:

\[\begin{split}\begin{align} U_{QSVT}(A, \phi) &= \begin{bmatrix} Poly^{SV}(A) & \cdot \\ \cdot & \cdot \end{bmatrix}. \end{align}\end{split}\]

The polynomial transformation is determined by a combination of the block encoding and choice of angles, \(\vec{\phi}\). The convention used by BlockEncode is commonly refered to as the reflection convention or \(R\) convention. Another equivalent convention for the block encoding is the \(Wx\) or rotation convention.

Depending on the choice of convention for blockencoding, the same phase angles will produce different polynomial transformations. We provide the functionality to swap between blockencoding conventions and to transform the phase angles accordingly using the convention keyword argument.

  • A (tensor_like) – the general \((n \times m)\) matrix to be encoded

  • angles (tensor_like) – a list of angles by which to shift to obtain the desired polynomial

  • wires (Iterable[int, str], Wires) – the wires the template acts on

  • convention (string) – can be set to "Wx" to convert quantum signal processing angles in the Wx convention to QSVT angles.


To implement QSVT in a circuit, we can use the following method:

>>> dev = qml.device("default.qubit", wires=2)
>>> A = np.array([[0.1, 0.2], [0.3, 0.4]])
>>> angles = np.array([0.1, 0.2, 0.3])
>>> @qml.qnode(dev)
... def example_circuit(A):
...     qml.qsvt(A, angles, wires=[0, 1])
...     return qml.expval(qml.PauliZ(wires=0))

The resulting circuit implements QSVT.

>>> print(qml.draw(example_circuit)(A))
0: ─╭QSVT─┤  <Z>
1: ─╰QSVT─┤

To see the implementation details, we can expand the circuit:

>>> q_script = qml.tape.QuantumScript(ops=[qml.qsvt(A, angles, wires=[0, 1])])
>>> print(q_script.expand().draw(decimals=2))
0: ─╭∏_ϕ(0.30)─╭BlockEncode(M0)─╭∏_ϕ(0.20)─╭BlockEncode(M0)†─╭∏_ϕ(0.10)─┤
1: ─╰∏_ϕ(0.30)─╰BlockEncode(M0)─╰∏_ϕ(0.20)─╰BlockEncode(M0)†─╰∏_ϕ(0.10)─┤


Using PennyLane