中性原子・冷却原子マシンが注目されています(?)ね。中性原子マシンの挙動をうまくシミュレーションしたり、計算を作ったりするためのライブラリが公開されています!
Bloqade.jl
言語はJuliaで書かれています。ドキュメントがありますので、みていきましょう!
https://queracomputing.github.io/Bloqade.jl/dev/
この記事よりも約一年前の記事ですが、紹介記事を書いてました。さっくりおさらいしましょう。
米QuEra社の冷却原子マシンの概要について、その1
https://blueqat.com/yuichiro_minato2/cee2ebdc-0878-4da7-ae4f-e9b0c2003f7d
引用:https://arxiv.org/abs/2012.12281
そうそうこんな感じでした。光ピンセットで原子をトラップして、動的光ピンセットで移動、その後レーザーで時間発展でした。
米QuEra社の冷却原子マシンの概要について、その2。実装装置やハードウェアアルゴリズムについて。
https://blueqat.com/yuichiro_minato2/24d6f7e3-c790-475d-a7fa-e9ff1595b480
結構いろいろあり、原子の並べ替えのアルゴリズムや、ビームの当て方までいろいろマニアックなことが書いてありました。
リュードベリ原子による量子シミュレータの計算方法概観
https://blueqat.com/yuichiro_minato2/04cf37d1-e634-436c-95e1-ce7f3ce8c159
原理としては、横磁場、局所磁場、リュードベリ状態の相互作用でした。時間ごとにパラメータを変化させられますが、距離はリュードベリ半径で決まる固定値となっていました。
そして、時間発展も今回の中性原子に用意されたハミルトニアンによって決まるものでした。いろんなパラメータの操作や時間発展、最終的な並び方のパターンの作り方などがありました。
なんとなく面白そうなので、さっそくbloqadeをみてみましょう。
中性原子量子コンピュータのアナログモード、デジタルモード
量子コンピュータは01を操作するデジタルコンピュータですので、中性原子は通常の二つの基底状態を使った01計算と、相互作用はリュードベリ状態を使ってもつれを作るようです。こちらは中性原子マシンでも「デジタルモード」と表現されています。また、今回のbloqadeはそのデジタルモードではなく、基底状態|g>とリュードベリ状態|r>を利用して計算する「アナログモード」となっています。
アナログモードではシュレディンガー方程式に準ずる量子状態の時間発展シミュレーションを、リュードベリハミルトニアンに準じた形で実行できるということです。詳しい説明は以前の記事から見てくださいませ。
計算を実行するための手順は、
・原子の位置決め
・ハミルトニアンのパラメータの波形決め
・ハミルトニアン作る
・初期状態を設定
・エミュレーション
・測定
となっています。通常の量子回路の設計というよりはシミュレーションを特定の数式に基づいて設計していくという感じになります。
早速プログラミングの方法を見てみます。まずはJuliaのツールを読み込みます。
julia> using Bloqade
今回の例は一次元で原子間の距離を決めるようです。
julia> nsites = 10;
julia> atoms = generate_sites(ChainLattice(), nsites, scale = 5.74)
10-element AtomList{1, Float64}:
(0.0,)
(5.74,)
(11.48,)
(17.22,)
(22.96,)
(28.700000000000003,)
(34.44,)
(40.18,)
(45.92,)
(51.660000000000004,)
面白いですね。一次元で原子が10個、5.74マイクロメートルごとに並びました。
次に与えられたパラメータを決めることでハミルトニアンを生成できます。
これを見る限りは最初の項が相互作用。リュードベリ半径が見えます。次の項が横磁場、そして局所磁場でしょうか。
julia> h = rydberg_h(atoms; Ω = 4 * 2π, Δ = 0)
nqubits: 10
+
├─ [+] ∑ 2π ⋅ 8.627e5.0/|r_i-r_j|^6 n_i n_j
├─ [+] 2π ⋅ 2.0 ⋅ ∑ σ^x_i
└─ [-] 2π ⋅ 0.0 ⋅ ∑ n_i
そして初期状態を作りますが、
julia> reg = zero_state(10)
ArrayReg{2, ComplexF64, Array...}
active qubits: 10/10
nlevel: 2
ここでは、0状態からスタートとのことです。これは基底状態のことを指すようです。
次は早速時間発展のようです。初期状態regに1.6マイクロ秒ハミルトニアンの時間発展を計算します。
julia> prob = SchrodingerProblem(reg, 1.6, h)
SchrodingerProblem:
register info:
type: ArrayReg{2, ComplexF64, Matrix{ComplexF64}}
storage size: 8 bytes
time span (μs): (0.0, 1.6)
equation:
storage size: 183.836 KiB
expression:
nqubits: 10
+
├─ [+] ∑ 2π ⋅ 8.627e5.0/|r_i-r_j|^6 n_i n_j
├─ [+] 2π ⋅ 2.0 ⋅ ∑ σ^x_i
└─ [-] 2π ⋅ 0.0 ⋅ ∑ n_i
options:
save_everystep: false
save_start: false
save_on: false
dense: false
julia> integrator = init(prob, Vern8());
julia> emulate!(prob);
最終的にはDensityというのを出していますが、これがなんなのかすぐにはわかりませんでした、、、誰か教えて下さい。別の機会に学びます。
julia> rydberg_populations = map(1:nsites) do i
rydberg_density(prob.reg, i)
end
10-element Vector{Float64}:
0.42192188992855195
0.17593452666204634
0.2841395261750055
0.20000113642535258
0.30570488901568105
0.30570488901567827
0.20000113642535058
0.28413952617500376
0.17593452666205112
0.4219218899285506
結構高精度で複雑な問題をJuliaで実行するというライブラリのように見えますが、ハミルトニアンはアナログモードではかなり限定されていて、パラメータの設定の仕方などこれからも学ぶべきことが多そうな気がしてきました。
今回はざっくりとみてみましたがこれだけではまだどこまで計算できるのか不明ないので詳しく少しずつ掘り下げていきたいと思います。また、見た感じ組合せ最適化対応してる感じでしたのでやっぱりQAOAやQAのような計算にしばらくはなるのかなと感じました。簡単ですが以上です。