Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.21k stars 2.36k forks source link

An Accidental Bug as Applying the API `RGQFTMultiplier` #10980

Open NahidaNahida opened 1 year ago

NahidaNahida commented 1 year ago

Environment

What is happening?

I am a PhD student now working on testing quantum programs. When I applied the API RGQFTMultiplier() in a loop of for, which was input with an appropriate couple of num_state_qubits=n, num_result_qubits=m, it accidentally terminated, leaving the warning that integers to negative integer powers are not allowed. However, when I simply used the sentence out of the loop that qc = RGQFTMultiplier(2, 2), it was done in a normal manner.

How can we reproduce the issue?

There are the code lines the bug was discovered.

from qiskit.circuit.library import RGQFTMultiplier
from qiskit import Aer
import numpy as np

n_list = np.arange(1, 5)                    # the input domain of n ranges in [1, 4]
backend = Aer.get_backend('qasm_simulator')
for n in n_list:
    m_list = np.arange(n, 2 * n + 1)   # the input domain of m ranges in [n, 2 * n]
    for m in m_list:
        quad_exp = RGQFTMultiplier(num_state_qubits=n, num_result_qubits=m)

As I ran the above codes, which aim to test the quantum circuit with different reasonable integer inputs $n$ and $m$, the process turned out to terminate out of my expectation. The produced warning is shown as follows,

File [d:\anaconda3\envs\QC\lib\site-packages\qiskit\circuit\library\arithmetic\multipliers\rg_qft_multiplier.py:93](file:///D:/anaconda3/envs/QC/lib/site-packages/qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py:93), in RGQFTMultiplier.__init__(self, num_state_qubits, num_result_qubits, name)
     91     for i in range(1, num_state_qubits + 1):
     92         for k in range(1, self.num_result_qubits + 1):
---> 93             lam = (2 * np.pi) / (2 ** (i + j + k - 2 * num_state_qubits))
     94             circuit.append(
     95                 PhaseGate(lam).control(2),
     96                 [qr_a[num_state_qubits - j], qr_b[num_state_qubits - i], qr_out[k - 1]],
     97             )
     99 circuit.append(QFT(self.num_result_qubits, do_swaps=False).inverse().to_gate(), qr_out[:])

ValueError: Integers to negative integer powers are not allowed.

I recorded the values of $n$ and $m$ as $n=2, m=2$. Without doubt, they are actually integer numbers both in theory and during debugging. Then I tried to run the API sperate from my program for testing. When I ran the very simple sentence qc = RGQFTMultiplier(2, 2), nothing unexpected happened.

What should happen?

There should not be any ValueError warning as the code line is executed, given $n=2, m=2$.

Any suggestions?

I have come up with one step to fix the bug. I modified the original code source in the file named qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py in line 93. To be specific, I changed (2 ** (i + j + k - 2 * num_state_qubits)) into (2.0 ** (i + j + k - 2 * num_state_qubits)). Consequently, my program for testing never crashed anymore.

jlapeyre commented 1 year ago

Thanks for the report. As a workaround, you can try changing your two occurences of np.arange to just range. (I am unable to try this now because my installation of qiskit is building slowly and my laptop will be out of power before it finishes.) It looks like your fix may the right one, or at least good enough for now.

This kind of problem arises frequently when trying to use Python for scientific computing:

In [15]: 2 ** -3
Out[15]: 0.125

In [16]: np.int64(2) ** np.int64(-3)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In [16], line 1
----> 1 np.int64(2) ** np.int64(-3)

ValueError: Integers to negative integer powers are not allowed.
jlapeyre commented 1 year ago

@NahidaNahida , your fix is probably the right one. Since you solved it, would you like to make a pull request (PR) to fix this bug? If you don't want to do it, no problem, we can do it pretty quickly.