LoginSignup
5
0

More than 3 years have passed since last update.

この記事に関して

ここではpythonライブラリのblueqatを用いて量子プログラミングを行っていこうと思います。
内容は公式のチュートリアルを元に作成しています。
今回は VQE を実装していきます。

VQE

詳しい理論はここに述べています。

このアルゴリズムはハミルトニアン(エルミート行列)の固有値を量子コンピュータと
古典コンピューターを用いて近似的に求めるものです。

ハミルトニアンを $H$ とし、これに対する固有値を $E_0$ とします。

このとき量子変分原理から、一般の状態 $\left|\psi\right>$ に対し、 $\left<\psi\right|H\left|\psi\right> ≧ E_0$ となります。

このことから $\left|\psi\right>$ を自由に動かして、$\left<\psi\right|H\left|\psi\right>$ の最小値を求めればいいことがわかります。

アルゴリズムの流れ

流れは以下のようになります。

1 . 自由に動かす状態は $\theta$ でパラメータ表示された状態 $\left|\psi(\theta)\right>$ とし、これと $H\left|\psi(\theta)\right>$ を量子コンピューターで計算する。

2 . 古典コンピュータで $\left<\psi(\theta)\right|H\left|\psi(\theta)\right>$ を計算する。

3 . $\left<\psi(\theta)\right|H\left|\psi(\theta)\right>$ が最小値でなければ、$\theta$ を更新する。最小値であればそれは $E_0$ の近似解である。

実装 1

blueqat を用いて実装します。
今回はハミルトニアン $H = Z$ としておきます。
$Z$ の固有値は $1, -1$ です。

$\left|\psi(\theta)\right> = R_y(\theta)\left|0\right>$ とし、$\theta$ は $(0≦\theta<2\pi)$ とします。

vqe.ipynb
from blueqat import Circuit
import numpy as np
import matplotlib.pyplot as plt
import math

# θの初期値、重み、誤差
th, w, d = 1.0, 0.4, 0.005

while True:

    d_ry = Circuit().ry(th+math.pi)[0].run()
    _ry = Circuit().ry(th)[0].run()
    hd_ry = Circuit().ry(th+math.pi)[0].z[0].run()
    h_ry = Circuit().ry(th)[0].z[0].run()

    '''
        d_ry = (-sin(θ/2) cos(θ/2)) => (d/dθ)|ψ(0)>
        _ry = (cos(θ/2) sin(θ/2)) => |ψ(0)>
        hd_ry = (-sin(θ/2) -cos(θ/2)) => (d/dθ)H|ψ(0)>
        h_ry = (cos(θ/2) -sin(θ/2)) => H|ψ(0)>
    '''

    # 位相処理
    if math.sin(th/2.0) >= 0.0:
        d_ry = -d_ry
        hd_ry = -hd_ry

    if math.cos(th/2.0) < 0.0:
        _ry = -_ry
        h_ry = -h_ry

    # 勾配
    ds_th = (np.dot(d_ry, h_ry) + np.dot(_ry, hd_ry))*(1/2.0) # -sinθ

    # θの更新
    th = th - w*ds_th*th

    # 誤差範囲
    if ds_th <= d and ds_th >= -d:
        s_th = np.dot(_ry, h_ry) # 期待値
        print(i) # 回数
        break

print(th) # θ
print(s_th) # 固有値

結果
3
(3.140573290275759+0j)
(-0.9999922075939599+0j)

上手く固有値を取り出すことができました。

実装 2

blueqat を用いて実装します。
今度はハミルトニアンを以下の行列とします。

H =
\left(\begin{array}{cc}
1 & 1 \\
1 & 1
\end{array}\right)
= I + X

この固有値は $0, 2$ です。

$\left|\psi(\theta)\right> = R_y(\theta)\left|0\right>$ とし、$\theta$ は $(0≦\theta<2\pi)$ とします。

vqe.ipynb
from blueqat import Circuit
import numpy as np
import matplotlib.pyplot as plt
import math

# θの初期値、重み、誤差
th, w, d = 2.0, 0.05, 0.01

# 格納配列
th_a, s_a = [], []

while True:

    # |ψ(θ)> の作成
    d_ry = Circuit().ry(th+math.pi)[0].run()
    _ry = Circuit().ry(th)[0].run()

    '''
        d_ry = (-sin(θ/2) cos(θ/2)) => (d/dθ)|ψ(0)>
        _ry = (cos(θ/2) sin(θ/2)) => |ψ(0)>
    '''

    # X の処理
    hd_ry = Circuit().ry(th+math.pi)[0].x[0].run()
    h_ry = Circuit().ry(th)[0].x[0].run()

    '''
        hd_ry = (cos(θ/2) -sin(θ/2)) => (d/dθ)X|ψ(0)>
        h_ry = (sin(θ/2) cos(θ/2)) => X|ψ(0)>
    '''

    # 位相処理
    if math.sin(th/2.0) >= 0.0:
        d_ry = -d_ry

    if math.sin(th/2.0) < 0.0:
        h_ry = -h_ry

    if math.cos(th/2.0) < 0.0:
        _ry = -_ry
        hd_ry = -hd_ry

    # 勾配
    ds_th = (np.dot(d_ry, _ry) + np.dot(_ry, d_ry) + np.dot(d_ry, h_ry) + np.dot(_ry, hd_ry))*(1/2.0)

    # θの更新
    th = th - w*ds_th*th

    # 誤差範囲
    if ds_th <= d and ds_th >= -d:
        s_th = np.dot(_ry, _ry) + np.dot(_ry, h_ry) # 期待値
        print(i) # 回数
        break

print(th) # θ
print(s_th) # 固有値

結果
19
(4.7057364938256585+0j)
(3.7828454340083084e-05+0j) # 3.0 × 10^-5

上手く固有値を取り出すことができました。

まとめ

今回はblueqatを用いて VQE を実装しました。
次回は QAOA をblueqatで実装してみます。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0