Issue with qml.poly_to_angles(poly, "GQSP")

Hi,

I have an issue when using qml.poly_to_angles(poly, “GQSP”).

The code is okay for num = 10 or below but it doesn’t work when num is greater than 10. I need to have num = 30.

import pennylane as qml
import numpy as np
from sympy import *

num=30  # at least 30
fac=5

def taylor(num):
    taylor=np.ones(num+1)
    for i in range(1,num+1):
        taylor[i]=(-1)**i * 1/factorial(i)
    return taylor
taylor(num)

poly = taylor(num)/fac
poly

angles = qml.poly_to_angles(poly, "GQSP")
angles

If you want help with diagnosing an error, please put the full error message below:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[111], line 1
----> 1 angles = qml.poly_to_angles(poly, "GQSP")
      2 angles

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/pennylane/templates/subroutines/qsvt.py:1117, in poly_to_angles(poly, routine, angle_solver)
   1115     if not np.isclose(poly[-1], 0.0):
   1116         break
-> 1117     poly.pop()
   1119 if len(poly) == 1:
   1120     raise AssertionError("The polynomial must have at least degree 1.")

AttributeError: 'numpy.ndarray' object has no attribute 'pop'

And, finally, make sure to include the versions of your packages. Specifically, show us the output of qml.about().
Name: PennyLane
Version: 0.40.0

Thanks,
HYW

Hi @HYW,

I think you may have uncovered a bug :bug: :open_mouth:.

There’s a section of the code that tries to remove trailing zeros from the array. Given your polynomials, the larger num is, the closest poly[-1] gets to zero. So for num<=10 the code that removes trailing zeros is skipped, which is why it works. However for num>10 the code tries to remove the last zero and it breaks.

I think the source of the issue is the same as this issue, so it’s possible that using the Master (development) version of PennyLane fixes the problem. Could you please try using this version and let us know if the problem is fixed for you? Let us know if you need any help on how to use this version.

Thank you Catalina.

Could you tell me how to install Master (development) version of PennyLane?

Thank you,
HYW

Hi Catalina,

poly = taylor(num)/fac
poly = poly.tolist()
poly

angles = qml.poly_to_angles(poly, “GQSP”)
angles

I convert ploy to a list and no error exists now. However, there is a new issue.
The resulting angles for num = 10 and 11, 12, 13… are all the same. You can observe that the number of resulting angles is unchaged for num >= 10.

I understand that these high-order angles are very small but they play a vital role for my application. My application is highly related to their inverse exponential so the result is incorrect if they are ignored and neglected. Could you tell me how to keep these high-order terms? I need to set num = 30 at least.

Thank you,
HYW

Hi @HYW ! Glad to see you are using this functionality :slight_smile:
Indeed, the first thing is a bug that has been fixed, to install the latest version run the following cell:

!pip install git+https://github.com/PennyLaneAI/pennylane.git

Regarding your comments. It seems to work on my end :thinking: Notice that although the second set of angles take the value 0, the first set is updated

I hope this helps :grinning_face_with_smiling_eyes:

1 Like

Hi Guillermo,

Thank you for your help. I will examine how GQSP can be used in my application.

I also spot a bug - the order of tensor product seems wrong for the defined unitary(wires) function.
Could you fix it?

HYW

Hi!
I do see your point. However, this one is not a bug.
The two implementations you are describing are different operators.
The one using the decorator and the function is a bit confusing, but it is correct. It makes sense because when you are implementing a circuit, the implementation is sequential from top to bottom. And when you write that in equation form, like the code output, the operations are applied onto the state from right to left, as U\vert\psi\rangle=RY(\phi)RX(\theta)\vert\psi\rangle.
We will make sure to improve the documentation for qml.prod so this is clear.

1 Like

Hi Daniela,

Thnak you. Are there any commands/functions/decorators for tensor product in Pennylane? Something like U = qml.kron(RX,RY) such that U is formed by the tensor product of RX(0.3, wires=[1]) and RY(0.2, wires=[2]). I understand that the defined function “unitary(wires)” without the decorator “@qml.prod” is a tensor form itself.

HYW

Hi @HYW !

You can use “@”

Eg qml.PauliZ(0) @ qml.PauliZ(1) would give you the tensor product.

Is this what you were looking for?

Hi Catalina,

Thnak you. You are right. So the formula Daniela wrote is a “matrix multiplication” (Ry(phi) dot Rx(theta)) rather than a “tensor product” (Ry(phi) tp Rx(theta)).

I am now confused with the decorator @qml.prod that acts on the function. If the defined unitary(wires) function decorated with @qml.prod is a tensor product form, there is no so-called sequential actions because both rotation gates stay the same layer , i.e., “output state = (Ry tp Rx) dot input state” instead of “output state = Ry dot Rx dot input state”.

HYW

Hi!
I understand the confusion since I didn’t specify the subsystems in which the rotations were to be applied to. It could have been a tensor product or a matrix multiplication, and qml.prod understands this. If the operators are applied to the same wire, then order matters and it is a matrix composition. But if they are to be applied to different wires, the tensor product takes place and the order wouldn’t matter (if and only if the operators apply to different wires, of course there could more complex and general cases and PennyLane handles them well). The documentation for qml.prod says “The generalized product operation represents both the tensor product as well as matrix composition. This can be resolved naturally from the wires that the given operators act on.”

Thank you for your reply!

1 Like