What I understood is that QSVT creates a matrix which is a close approximation of the singular value decomposition, i.e \tilde \Pi U \Pi \approx W {\cdot} P(\Sigma) {\cdot} V^\dagger where P(\Sigma) is the singular values after the polynomial function is applied to them. So, I created a short code to experiment as below. The polynomial function that I’m applying is P(x)=x.
import numpy as np
import pennylane as qml
import scipy
gen = np.random.default_rng(42)
A = gen.uniform(-1, 1, (4, 4)) # random 4x4 matrix
# target poly: P(x) = x
target_poly = [0,1]
wire_order = list(range(5))
U, S, Vh = scipy.linalg.svd(A)
classical_output = U @ np.diag([np.polyval(target_poly[::-1], s) for s in S]) @ Vh
print("Classical output:\n", classical_output)
norm = scipy.linalg.norm(A, ord=2)
if norm > 1:
A_normalized = A / norm
print("\nnorm of A:", norm)
quantum_output = qml.matrix(qml.qsvt, wire_order=wire_order)(
A_normalized, target_poly, encoding_wires=wire_order, block_encoding="embedding"
) # block-encoded in 5-qubit system
print("\nQuantum_output:\n", quantum_output[:4, :4].real*norm)
However, the output differs between the classical and quantum computation.
Is this the expected output? My expectation is that the quantum output will be a close approximation of W {\cdot} P(\Sigma) {\cdot} V^\dagger. I’m not sure whether my understanding is correct or whether my code is wrong.
When I tried with a polynomial with an imaginary coefficient, e.g. target_poly = [0,1j], I get an error AssertionError: Array must not have an imaginary part. Is this by design of the implementation in Pennylane or is this because QSVT algorithm only works with real coefficients?
According to this paper the QSVT algorithm only works for polynomials with real coefficients and definite parity. So this limitation would be general and not specific to PennyLane’s implementation.
Regarding the first question let me get back to you.
Thank you for the helpful paper reference and the code. The code works now. I have a couple of follow-up questions which I encountered while experimenting with the QSVT algorithm and it’s implementation in Pennylane to understand it in practice.
When I tried a constant polynomial, e.g. P(x)=1 where I replace the target_poly with target_poly = [1], I get an error, i.e. AssertionError: The polynomial must have at least degree 1. In similar veins as my previous questions, is this a algorithmic limitation of QSVT or a design choice of the implementation in Pennylane?
For complex matrixes, the line to generate Hermitian matrix A = (A + A.T) / 2 will be replaced with A = (A + A.conj().T) / 2, right?
The function P(x) = 1 does not make use of block encoding—it’s equivalent to applying no operator at all. So in that case, applying QSVT doesn’t make sense
On the other hand, yes, for complex matrices it would be that, but it’ll be harder to interpret the resulting matrix