Questions on QSVT algorithm and Pennylane implementation

Hi,

I have a couple questions on QSVT algorithm and Pennylane’s implementation. Referring to Theorem 26 from the paper Quantum singular value transformation and beyond: exponential improvements for quantum matrix arithmetics by Gilyén et al.

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.

  1. 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.

  2. 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?

Looking forward to your kind reply. Thank you.

Hi @jag,

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.

Hi @jag ! Taking a look to the documentation I saw that QSVT works if A is hermitian
Here is an updated script to check that it is actually working :grinning_face_with_smiling_eyes:

import numpy as np
import pennylane as qml
import scipy

gen = np.random.default_rng(42)
A = gen.normal(size=(4, 4)) 
A = (A + A.T) / 2 # generating hermitian matrix

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=1)

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)
Classical output:
 [[ 0.30471708 -1.49550965  0.36682502  0.50329771]
 [-1.49550965 -1.30217951 -0.36260176  0.40549931]
 [ 0.36682502 -0.36260176  0.87939797  0.62265064]
 [ 0.50329771  0.40549931  0.62265064 -0.85929246]]

norm of A: 3.5657902238248567

Quantum_output:
 [[ 0.30471708 -1.49550965  0.36682502  0.50329771]
 [-1.49550965 -1.30217951 -0.36260176  0.40549931]
 [ 0.36682502 -0.36260176  0.87939797  0.62265064]
 [ 0.50329771  0.40549931  0.62265064 -0.85929246]]

Also note that you have to use the norm-1 instead of the norm-2

1 Like

Hi @CatalinaAlbornoz and @Guillermo_Alonso,

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.

  1. 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?
  2. 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?

Thank you.

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 :grinning_face_with_smiling_eyes:

On the other hand, yes, for complex matrices it would be that, but it’ll be harder to interpret the resulting matrix