こんばんは、Juliaです。今回はJuliaをつかって簡単なVQEをやってみたいと思います。練習ついでです。
関数バラバラですが、特に今回は書き殴っているので、あまり気にしないでくださいませ。。。
モジュール
まずはモジュールの読み込み。ランダムを使います。
using Random
状態ベクトルと量子ゲートのテンソル
以前別のブログにも書きましたが、状態ベクトルと量子ゲートのテンソルをとる関数を作ります。
#量子ビット数Nの時の状態ベクトルを作る関数
function svq(N)
q = [1,0]
sv = q
for i=2:N
sv = kron(sv,q)
end
return sv
end
#量子ゲート同士のテンソル積をとる関数
function svg(gates)
sv = gates[1]
for i=2:length(gates)
sv = kron(sv,gates[i])
end
return sv
end
ゲート
単位ベクトルとアダマールゲート、CXを作ります。アダマールゲートは確認用です。
#単位ベクトルとCXゲート
i = [1 0;0 1]
h = 1/sqrt(2)*[1 1;1 -1]
cx = [1 0 0 0;0 1 0 0;0 0 0 1;0 0 1 0]
#まずはもつれの確認
svg([cx])*svg([h,i])*svq(2)
もつれ状態の確認をします。
4-element Array{Float64,1}:
0.7071067811865475
0.0
0.0
0.7071067811865475
よくできました。
任意回転ゲート
VQEで利用する任意回転ゲートを作ってみます。
#RXゲート
function rx(theta)
return [cos(theta/2) -im*sin(theta/2);-im*sin(theta/2) cos(theta/2)]
end
ちょっと確認してみます。
#確認
rx(3)
2×2 Array{Complex{Float64},2}:
0.0707372+0.0im 0.0-0.997495im
0.0-0.997495im 0.0707372+0.0im
こんな感じです。次にRZゲート
#RZゲート
function rz(theta)
return [exp(-im*theta/2) 0;0 exp(im*theta/2)]
end
#確認
rz(3)
2×2 Array{Complex{Float64},2}:
0.0707372-0.997495im 0.0+0.0im
0.0+0.0im 0.0707372+0.997495im
できました。
変数の準備
早速任意回転ゲートに利用する変数を準備します。今回は回路に4つの変数を使おうと思います。
#量子回路作成。変数4つ
rng = MersenneTwister(4649)
a = rand(rng,4)*2pi
できました。
4-element Array{Float64,1}:
4.231809330647649
4.790879797879168
1.6829449564232228
2.2437547135241873
ハミルトニアンの期待値を求める
一つにまとめてしまいました。まずは2量子ビットの回路にそれぞれRXとRZを適用し、最後にCXでもつれさせます。 今回は状態ベクトルからZの期待値を求めて、ハミルトニアンに代入します。
function hami(aa)
#量子回路
res = cx*svg([rx(aa[3]),rx(aa[4])])*svg([rx(aa[1]),rx(aa[2])])*svq(2)
#各要素の絶対値の二乗
res2 = abs.(res).^2
#Z1とZ2の期待値をそれぞれ計算
mat = [1 -1 1 -1;1 1 -1 -1]
Z = mat*res2
return Z[1]-Z[2]-2*Z[1]*Z[2]
end
hami(a)
こうすると、初期状態では、
-1.523070849121153
の値が出ました。
勾配法のループを回す
数値微分の差分をh、パラメータ更新の学習率をeとして、今回は数値微分で行います(もちろん他の方法もあります)。
h = 0.001
e = 0.01
function grad(a)
arr = []
a1 = hami(a)
for i=1:4
aa = copy(a)
aa[i] += h
push!(arr, a[i] - e*(hami(aa) - a1)/h)
end
#println(a1)
return arr
end
早速これを1000回のループで回すと、
for i=1:1000
a = grad(a)
end
計算が完了し、最終的な期待値は、
hami(a)
-1.9999993750000904
このようになりました。
如何でしたでしょうか?手作業ですが、VQEを実装してみました。今後はもう少し高度で汎用性の高い実装をしてみたいと思います。では、Juliaを楽しみましょう!