らんだむな記憶

blogというものを体験してみようか!的なー

Qiskit (33) ― 量子位相推定

Qiskit (32) - らんだむな記憶 を少し振り返る。

(2) 式は形式的に $\ket{\theta}$ という状態ベクトルがあると考えると、

$$
\begin{align*}
U_{QFT}\ket{\theta} \otimes \ket{\psi}
\end{align*}
$$

という形をしている。よって、第 1 レジスタに逆量子 Fourier 変換を作用させると、

$$
\begin{align*}
U_{QFT^{-1}}U_{QFT}\ket{\theta} \otimes \ket{\psi} = \ket{\theta} \otimes \ket{\psi}
\end{align*}
$$

が出てきて、第 1 レジスタの測定で $\ket{\theta}$ が観測されることが期待される。量子位相推定とは、位相キックバックを用いて、第 1 レジスタに形式的には $U_{QFT}\ket{\theta}$ と書けるような状態ベクトルを生成するアルゴリズムと見ることができるかもしれない。

さて、付属コードを見ていくが、実は最後のほうでバグっている。

まず、最初のほうのセルで計算している

phase = np.random.rand() * np.pi # = 2\pi\theta \in [0, np.pi]

は $2 \pi \theta$ の値であることに注意しておこう。なので、最後に最も多く観測されると期待される状態ベクトルの値は

theta = phase/(2*np.pi)
val = (2**n_encode)*theta
approx = int(Decimal(str(val)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))

である。n_encode = 3 だと精度が悪いが今回これで試すと、

phase=2.17, theta=0.35, 2^3*theta=2.77 approximated integer=011

となった。回路図を可視化すると

f:id:derwind:20220203021608p:plain

であり、シミュレータで測定すると

f:id:derwind:20220203021629p:plain

となった。期待通りである。
ところで最後のセル、つまり、書籍 p.142 の一番下のコードは

state = int(list(answer)[np.argmax(list(answer.values()))], 2)
phase_estimated = state / (2 ** n_encode) # approximated theta
print('True phase: {:.4f}'.format(phase / (2 * np.pi))) # theta
print('Estimated phase: {:.4f}'.format(phase_estimated))

などとする必要がある。results.get_counts() で得られる dict状態ベクトルの値の昇順で並んでいる保証がないためである。実際そうは並んでなかった。そして、状態ベクトルの値は 0b1 刻みで増えないので argmax では求める状態ベクトルの値 $x$ が直接は求まらない。従って、$x$ として間違った値を掴むので、$\frac{x}{2^n}$ の計算で $\theta$ の近似値を得られないということである。
ということで上記のように修正した。結果は

True phase: 0.3457
Estimated phase: 0.3750

でランダムに準備した $\theta$ に十分近い値が得られた。これで書籍 p.143 まで完了である。