光量子コンピュータを使いたいですが、ベースとなる理論があまりに今の量子ゲートや量子アニーリングと違うので二の足を踏んでいる人が多いようです。ということで、やってみましょう!
今回使ったのはbolearisです。こちらはカナダのベンチャー企業Xanaduが出しているマシンで、光連続量と呼ばれる手法を使っています。詳しい解説や計算手法はblueqat.comで連続量で検索してみてください。
今回のチュートリアルはこの辺りを使います。
最初にBorealisに行く前に、まずは光連続量の簡単な使い方を確認します。
ツールはstrawberryfieldsを使います。
import strawberryfields as sf
from strawberryfields.ops import *
import numpy as np
from numpy import pi, sqrt
# set the random seed
np.random.seed(42)
まずは量子ビットに対応する量子モードを準備します。
prog = sf.Program(3)
そうしたらさっそく回路を記述します。以前別のブログでも確認しましたが使えるゲートの種類が異なります。
from braket.aws import AwsDevice
device = AwsDevice('arn:aws:braket:us-east-1::device/qpu/xanadu/Borealis')
print(device.properties.action['braket.ir.blackbird.program'].supportedOperations)
['s', 'r0', 'r1', 'r2', 'bs0', 'bs1', 'bs2', 'loop0_phase', 'loop1_phase', 'loop2_phase']
上記のゲートの種類を使ってStrawberryFields形式で書いていきます。
これはチュートリアルからとってきましたが、量子テレポーテーションでしょうか。
alpha = 1+0.5j
r = np.abs(alpha)
phi = np.angle(alpha)
with prog.context as q:
# prepare initial states
Coherent(r, phi) | q[0]
Squeezed(-2) | q[1]
Squeezed(2) | q[2]
# apply gates
BS = BSgate(pi/4, pi)
BS | (q[1], q[2])
BS | (q[0], q[1])
# Perform homodyne measurements
MeasureX | q[0]
MeasureP | q[1]
# Displacement gates conditioned on
# the measurements
Xgate(sqrt(2) * q[0].par) | q[2]
Zgate(-sqrt(2) * q[1].par) | q[2]
早速計算しますが、シミュレーションをします。Fock既定のシミュレータで5次元のカットオフで実行します。
シミュレータは複数ありFockシミュレータやGaussianシミュレータなどあります。
eng = sf.Engine('fock', backend_options={"cutoff_dim": 5})
シミュレータが指定できましたので実行します。
result = eng.run(prog, shots=1, modes=None, compile_options={})
print(result.samples)
[[1.74371744 0.67170672]]
計算結果が出ました。Fockシミュレータは比較的内部の計算は重たいのでシミュレータとして軽量のものを使う場合には注意が必要です。
次にさっそくBorealisを使ってみましょう。こちらは光のパルスがループ内を時系列で並んで、時間差で計算をするタイプになっていて、今回はGBSという光量子超越を達成したアルゴリズムについてみてみます。
import strawberryfields as sf
import numpy as np
from braket.strawberryfields_plugin import BraketEngine
eng = BraketEngine("arn:aws:braket:us-east-1::device/qpu/xanadu/Borealis")
device = eng.device
時間ごとの管理は大変なのでヘルパー関数を使うようです。
from strawberryfields.tdm import borealis_gbs, get_mode_indices
gate_args_list = borealis_gbs(device, modes=216, squeezing="high")
delays = [1, 6, 36]
n, N = get_mode_indices(delays)
2022-10-14 01:53:44,917 - WARNING - 133/259 arguments of phase gate 1 have been shifted by pi in order to be compatible with the phase modulators.
2022-10-14 01:53:44,921 - WARNING - 145/259 arguments of phase gate 2 have been shifted by pi in order to be compatible with the phase modulators.
先ほど確認した光連続量量子ゲートで回路を記述します。
from strawberryfields.ops import Sgate, Rgate, BSgate, MeasureFock
prog = sf.TDMProgram(N)
with prog.context(*gate_args_list) as (p, q):
Sgate(p[0]) | q[n[0]]
for i in range(len(delays)):
Rgate(p[2 * i + 1]) | q[n[i]]
BSgate(p[2 * i + 2], np.pi / 2) | (q[n[i + 1]], q[n[i]])
MeasureFock() | q[0]
いざ実行です!
shots = 10_000
results = eng.run(prog, shots=shots, crop=True)
print(results.samples)