common.title

Docs
Quantum Circuit
TYTAN CLOUD

QUANTUM GAMING


autoQAOA
Desktop RAG

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