BlueqatでVariational-Quantum-Eigensolver (VQE) アルゴリズムやってみる


$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
$$
量子ゲートシミュレータBlueqatの練習がてらVQEアルゴリズムで簡単なハミルトニアンの基底エネルギーを求めてみます。
Blueqatとは : https://blueqat.readthedocs.io/ja/latest/
VQEとは : http://dojo.qulacs.org/ja/latest/notebooks/5.1_variational_quantum_eigensolver.html
他に参考にしたページ:
https://qiita.com/YuichiroMinato/items/62444351b712743d83b7
http://dkopczyk.quantee.co.uk/vqe/

設定

今回はこちらの記事のように、状態$\ket{0} = (1, 0)^{\mathrm{T}}$にRY($\theta$)ゲートを作用させることで、パラメータ$\theta$に依存する状態$\ket{\psi(\theta)}$を作り、
いろんな$\theta$の値で内積$\braket{\psi(\theta)} {H \psi(\theta)}$の値を計算し、
変分法により、この内積$\braket{\psi(\theta)} {H \psi(\theta)}$が最小となる$\theta (= \theta_{\mathrm{min}})$を求めることで、基底状態$\ket{\psi(\theta_{\mathrm{min}})}$を求めることにする。
RY($\theta$)ゲートとは、状態をbloch球のy軸周りに回転させる演算である。

RY(\theta) = 
\left(
    \begin{array}{cc}
            \cos{\Big( \frac{\theta}{2}\Big)} & -\sin{\Big( \frac{\theta}{2}\Big)} \\
             \sin{\Big( \frac{\theta}{2}\Big)} &  \cos{\Big( \frac{\theta}{2}\Big)}\\
    \end{array}
\right)

また今回はハミルトニアン$H$として、こちらの記事と同じように、パウリ行列$Z$

Z = \left(
    \begin{array}{cc}
            1 & 0 \\
            0 & -1\\
    \end{array}
\right)

を用いる。
もともと$Z$は対角化されていて、その基底状態は$\ket{1} = (0, 1)^{\mathrm{T}}$(の複素数倍)とわかるので、今回のパラメータ$\theta$探索では、$\theta = \pi$が基底状態を与えるパラメータであることが求まれば成功である。
なぜなら、今回の設定では

\ket{\psi(\theta = \pi)} = \left(
    \begin{array}{cc}
            \cos{\Big( \frac{\pi}{2}\Big)} & -\sin{\Big( \frac{\pi}{2}\Big)} \\
             \sin{\Big( \frac{\pi}{2}\Big)} &  \cos{\Big( \frac{\pi}{2}\Big)}\\
    \end{array}
\right)
 \left(
    \begin{array}{c}
            1  \\
             0 \\
    \end{array}
\right)
=
\left(
    \begin{array}{cc}
            0 & -1 \\
            1 &  0\\
    \end{array}
\right)
 \left(
    \begin{array}{c}
            1  \\
             0 \\
    \end{array}
\right)
=
 \left(
    \begin{array}{c}
            0  \\
             1 \\
    \end{array}
\right)

だからである。

実際にBlueqatを使ってやってみる

jupyter notebookで行う。
Blueqatインストールしていない場合は以下でpipインストールする。

!pip3 install blueqat

今回使用するライブラリをインポート

import numpy as np
import matplotlib.pyplot as plt
from blueqat import Circuit

まずはパラメータの候補として、$0$から$2\pi$までを20等分した物を用意する。

angles = np.linspace(0.0,2*np.pi,20)
angles
# array([0.        , 0.33069396, 0.66138793, 0.99208189, 1.32277585,
#       1.65346982, 1.98416378, 2.31485774, 2.64555171, 2.97624567,
#       3.30693964, 3.6376336 , 3.96832756, 4.29902153, 4.62971549,
#       4.96040945, 5.29110342, 5.62179738, 5.95249134, 6.28318531])

まずは4個目の角度(angle[3] = 0.99208189)を使って、内積$\braket{\psi(\theta)} {H \psi(\theta)}$を計算してみる。
Blueqatでは、まず回路(Circuit())を用意し、そこにゲート(今回はRYゲート)を追加していくことでゲート回路が構築できる。
RYゲートは以下のように、ry({角度})[{作用させる量子ビット番号}]を追加させれば良い。

# 回路
Circuit().ry(angles[3])[0]

また、ゲート回路に対してrunメソッドを実行させると、その段階での状態ベクトルがnumpyで得られる。

# 初期状態なので| 0>
Circuit().run()
# array([1.+0.j])

# | 0>にRYゲートを作用させた後の状態
Circuit().ry(angles[3])[0].run()
# array([0.87947375+0.j, 0.47594739+0.j])

それでは、実際に内積$\braket{\psi(\theta)} {H \psi(\theta)}$を計算する。
まず、$\ket{\psi(\theta)}$は以下のようになり、

psi = Circuit().ry(angles[3])[0].run()
psi
# array([0.87947375+0.j, 0.47594739+0.j])

続いて、$\ket{H \psi(\theta)}$は以下のようになる。

h_psi = Circuit().ry(angles[3])[0].z[0].run()
h_psi
# array([ 0.87947375+0.j, -0.47594739+0.j])

これらより、内積$\braket{\psi(\theta)} {H \psi(\theta)}$は以下のようになる。

np.dot(psi, h_psi)
# (0.5469481581224267+0j)

それでは、この内積を最初に作った20個の角度に対して計算し、横軸を角度、縦軸を内積でプロットし、線を引くと以下のようになる。

energies = []
for angle in angles:
    psi = Circuit().ry(angle)[0].run()
    z_psi = Circuit().ry(angle)[0].z[0].run()
    energies.append(np.dot(psi, z_psi))
plt.xlabel('angle') 
plt.ylabel('Expectation value') 
plt.plot(angles, energies) 
plt.show() 

確かに$\theta = 3$付近で最小値を取っているようなので、VQEアルゴリズム成功である。
ちなみに、パラメータ$\theta$に依存する状態$\ket{\psi(\theta)}$を作るとき、RY($\theta$)ゲートの代わりにRX($\theta$)ゲートを用いてもVQEアルゴリズムは成功する。
しかし、RZ($\theta$)ゲートでは成功しない。
それはRZ($\theta$)は

RZ(\theta) = 
\left(
    \begin{array}{cc}
            e^{-i\frac{\theta}{2}} & 0 \\
             0 &  e^{ i\frac{\theta}{2}}\\
    \end{array}
\right)

という形をしているため、これによって作成される状態$\ket{\psi(\theta)}$は

\ket{\psi(\theta)} = \left(
    \begin{array}{cc}
            e^{-i\frac{\theta}{2}} & 0 \\
             0 &  e^{ i\frac{\theta}{2}}\\
    \end{array}
\right)
 \left(
    \begin{array}{c}
            1  \\
             0 \\
    \end{array}
\right)
=
 \left(
    \begin{array}{c}
            e^{-i\frac{\theta}{2}}  \\
             0 \\
    \end{array}
\right)
=
e^{-i\frac{\theta}{2}}
\left(
    \begin{array}{c}
            1  \\
             0 \\
    \end{array}
\right)

となり、どんなパラメータ$\theta$の値でも、基底状態である$\ket{1} = (0, 1)^{\mathrm{T}}$(の複素数倍)は作れないからである。

最後に

量子コンピュータ面白