Juliaで動くテンソルネットワーク計算ライブラリのITensorを利用して、量子計算をしてみます。今回は例題として、量子計算で簡単なもつれ回路を作ってみます。
ITensor
Juliaで利用できるライブラリです。
@show VERSION
import Pkg; Pkg.add("BenchmarkTools",); Pkg.add("ITensors")
Juliaの環境で、パッケージを追加すればインストールされます。
using BenchmarkTools, Random, LinearAlgebra, ITensors
そして、読み込みます。
使い方
今後はより量子計算向けに改良されるでしょうから、テンソルネットワークの詳しいことは知らないでも大丈夫ですが、Tというテンソルを腕から作ります。
let
i = Index(2,"i")
j = Index(2,"j")
T = ITensor(i,j)
@show T
end
これを実行すると、
T = ITensor ord=2
Dim 1: (dim=2|id=827|"i")
Dim 2: (dim=2|id=437|"j")
NDTensors.Dense{Float64,Array{Float64,1}}
2×2
0.0 0.0
0.0 0.0
[27]:
ITensor ord=2 (dim=2|id=827|"i") (dim=2|id=437|"j")
NDTensors.Dense{Float64,Array{Float64,1}}
このように0000の2*2行列ができました。腕を簡単に増やすことができます。
i = Index(2,"i")
j = Index(3,"j")
k = Index(4,"k")
T = ITensor(i,j,k)
ITensor ord=3 (dim=2|id=986|"i") (dim=3|id=426|"j") (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
値の設定は、
T[k=>3,i=>2,j=>1] = 4.56
テンソルで指定することで、
@show T
T = ITensor ord=3
Dim 1: (dim=2|id=986|"i")
Dim 2: (dim=3|id=426|"j")
Dim 3: (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
2×3×4
[:, :, 1] =
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 2] =
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 3] =
0.0 0.0 0.0
4.56 0.0 0.0
[:, :, 4] =
0.0 0.0 0.0
0.0 0.0 0.0
[32]:
ITensor ord=3 (dim=2|id=986|"i") (dim=3|id=426|"j") (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
設定されました。簡略化して指定することもできるようです。
T[2,2,3] = 4.56;
こうすることで、
T = ITensor ord=3
Dim 1: (dim=2|id=986|"i")
Dim 2: (dim=3|id=426|"j")
Dim 3: (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
2×3×4
[:, :, 1] =
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 2] =
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 3] =
0.0 0.0 0.0
4.56 4.56 0.0
[:, :, 4] =
0.0 0.0 0.0
0.0 0.0 0.0
[34]:
ITensor ord=3 (dim=2|id=986|"i") (dim=3|id=426|"j") (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
できました。
複素数
もちろん複素数も指定できます。
T = ITensor(ComplexF64,i,j,k)
T[i=>2,k=>3,j=>1] = 7+9im
T = ITensor ord=3
Dim 1: (dim=2|id=986|"i")
Dim 2: (dim=3|id=426|"j")
Dim 3: (dim=4|id=797|"k")
NDTensors.Dense{Complex{Float64},Array{Complex{Float64},1}}
2×3×4
[:, :, 1] =
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
[:, :, 2] =
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
[:, :, 3] =
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
7.0 + 9.0im 0.0 + 0.0im 0.0 + 0.0im
[:, :, 4] =
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im
[36]:
ITensor ord=3 (dim=2|id=986|"i") (dim=3|id=426|"j") (dim=4|id=797|"k")
NDTensors.Dense{Complex{Float64},Array{Complex{Float64},1}}
縮約
テンソルの縮約も簡単でした。
A = ITensor(i,j)
B = ITensor(k,j)
@show A*B
A * B = ITensor ord=2
Dim 1: (dim=2|id=986|"i")
Dim 2: (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
2×4
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
[38]:
ITensor ord=2 (dim=2|id=986|"i") (dim=4|id=797|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
腕を見るとjで縮約されているのがわかります。
もつれ回路
もつれ回路は元の量子ビットに重ね合わせHとCXをかけると実現できます。
状態ベクトルを作ります。
i = Index(2,"i")
j = Index(2,"j")
こちらは、量子ビット一つ目
q0 = ITensor(i)
q0[1] = 1
q1 = ITensor(j)
q1[1] = 1
確認すると、
@show q1
q1 = ITensor ord=1
Dim 1: (dim=2|id=481|"j")
NDTensors.Dense{Float64,Array{Float64,1}}
2-element
1.0
0.0
[163]:
ITensor ord=1 (dim=2|id=481|"j")
NDTensors.Dense{Float64,Array{Float64,1}}
きちんとできていることが確認できました。
次にアダマールゲートを作ります。
k = Index(2,"k")
h = ITensor(i,k)
h[1] = 1/sqrt(2)
h[2] = 1/sqrt(2)
h[3] = 1/sqrt(2)
h[4] = -1/sqrt(2)
値を設定します。そして、確認。
@show h
h = ITensor ord=2
Dim 1: (dim=2|id=225|"i")
Dim 2: (dim=2|id=563|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
2×2
0.7071067811865475 0.7071067811865475
0.7071067811865475 -0.7071067811865475
[171]:
ITensor ord=2 (dim=2|id=225|"i") (dim=2|id=563|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
行列ができました。
まず重ね合わせ
@show q0*h
できました。
q0 * h = ITensor ord=1
Dim 1: (dim=2|id=563|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
2-element
0.7071067811865475
0.7071067811865475
[172]:
ITensor ord=1 (dim=2|id=563|"k")
NDTensors.Dense{Float64,Array{Float64,1}}
次にもつれ回路
まず最初にCXゲートを作ります。腕を準備
l = Index(2,"l")
m = Index(2,"m")
設定します。今回は4*4ではなく、2*2*2*2で準備しました。
cx = ITensor(k,j,l,m)
cx[1] = 1
cx[7] = 1
cx[12] = 1
cx[14] = 1
@show cx
できました。
cx = ITensor ord=4
Dim 1: (dim=2|id=563|"k")
Dim 2: (dim=2|id=481|"j")
Dim 3: (dim=2|id=553|"l")
Dim 4: (dim=2|id=22|"m")
NDTensors.Dense{Float64,Array{Float64,1}}
2×2×2×2
[:, :, 1, 1] =
1.0 0.0
0.0 0.0
[:, :, 2, 1] =
0.0 1.0
0.0 0.0
[:, :, 1, 2] =
0.0 0.0
0.0 1.0
[:, :, 2, 2] =
0.0 0.0
1.0 0.0
[180]:
ITensor ord=4 (dim=2|id=563|"k") (dim=2|id=481|"j") (dim=2|id=553|"l") (dim=2|id=22|"m")
NDTensors.Dense{Float64,Array{Float64,1}}
縮約してみます。
@show q1*q0*h*cx
q1 * q0 * h * cx = ITensor ord=2
Dim 1: (dim=2|id=553|"l")
Dim 2: (dim=2|id=22|"m")
NDTensors.Dense{Float64,Array{Float64,1}}
2×2
0.7071067811865475 0.0
0.0 0.7071067811865475
[181]:
ITensor ord=2 (dim=2|id=553|"l") (dim=2|id=22|"m")
NDTensors.Dense{Float64,Array{Float64,1}}
できました!00と11でもつれています。無事Juliaでも量子計算できました!どんどん使っていきましょう!