common.title

Docs
Quantum Circuit
TYTAN CLOUD

QUANTUM GAMING

Nobisuke

Dekisugi


autoQAOA
DEEPSCORE

Overview
Service overview
Terms of service

Privacy policy

Contact
Research

Sign in
Sign up
common.title

Juliaでお手製VQEを実行

Yuichiro Minato

2020/12/10 14:30

#量子ゲート #Julia #VQE

2

こんばんは、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を楽しみましょう!

© 2025, blueqat Inc. All rights reserved