Python(Qiskitサンプル_乗算について)
■乗算の方法について調べた。
ショアのアルゴリズムの、f(x) = a^r mod N では、a^r で初めに乗算が必要になる。乗算について調べると、RGQFTMultiplier という乗算器のメソッドがあったので、下のコードで試してみた。
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit.circuit.library import RGQFTMultiplier
from qiskit.visualization import plot_histogram
import matplotlib.pyplot as plt
# 5ビット乗算器(mod 2^5)
mult = RGQFTMultiplier(num_state_qubits=5, num_result_qubits=5)
qc = QuantumCircuit(15, 5)
# 入力値
x_val = 17
y_val = 19
# x レジスタ (0..4)
for i in range(5):
if (x_val >> i) & 1:
qc.x(i)
# y レジスタ (5..9)
for i in range(5):
if (y_val >> i) & 1:
qc.x(5 + i)
qc.h(0)
# 乗算回路を追加
qc.append(mult, range(15))
# 出力レジスタを測定
qc.measure(range(10, 15), range(5))
# 回路図を表示
qc.draw('mpl')
plt.show()
# Aer シミュレーション
backend = AerSimulator()
tqc = transpile(qc, backend)
result = backend.run(tqc, shots=1024).result()
counts = result.get_counts()
decimal_counts = {int(k, 2): v for k, v in counts.items()}
# ヒストグラムを表示(10進数ラベル付き)
plot_histogram(decimal_counts)
plt.show()
この実行結果が下。

このメソッドは、乗算した後で、32 (上のコードでは5ビットのため2^5 = 32)で割った余りを出力するものとのこと。上のコードでは、17×19 = 323 又は 16×19 = 304(1ビット部分を重ね合わせにしているので)で、それぞれを32で割った余りが3、16となる。この32の部分は固定になっているらしい。任意の値が指定できれば、ショアのアルゴリズムのところにも応用できそうだけど、そうはいかないよう。
次に、割るというステップが無い単純な乗算ができないか見てみた。ChatGPTを使いながらコードの生成と修正を繰り返したけど、結局うまくいかなかった。
下のように2進法でも展開して加算していけば乗算の計算はできる。加算器 CDKMRippleCarryAdder を使ってできるようだけど、正しい結果が出なかった。

今回見た乗算と後に続く剰余の演算は、自作ではハードルが高い。Qiskitの標準パッケージにShorのものが入っているそうなので、そちらを試してみたい。

