Nobisuke
Dekisugi
RAG
Privacy policy
2021/10/14 23:51
量子ビットを使った計算と違って光量子計算では量子モードを使いますよね。今回は量子テレポーテーション回路をやってみました。 別の記事では1量子モードゲートのみを使ったのですが、前回飛ばした2モードのゲートを使ってみたいと思います。
ビームスプリッタという素子で2つのモードにある光を混ぜ合わせます。 ビームスプリッタとは入ってきた光の%を反射し、%を透過する()素子で、一定量の光を透過する鏡のようなものです。
という説明があります。
Copy !pip install -U -q photonqat
Copy import photonqat as pq import numpy as np import matplotlib.pyplot as plt
今回はフォックシミュレータでモード数2、カットオフを20に設定しています。 ここでようやく見えてきましたが、モード0とモード1にそれぞれ光子を一つずつ準備して、 それをビームスプリッタゲートにいれてますね。
引数は0,1となっていて2モードを使って、三つ目の引数がパラメータでしょうか。今回は -np.pi/4 を入れると50%のビームスプリッタになるようです。
Copy F = pq.Fock(2, cutoff = 20) F.n_photon(0, 1) F.n_photon(1, 1) F.BS(0, 1, -np.pi/4) # 50:50 ビームスプリッタ F.run() res = F.photonSampling(0, ite = 50) # mode 0 のphoton数を50回サンプリング print(res) print("HOM干渉計:2つのSingle photon Modeをビームスプリッタに入力すると出力モードの光子数は必ず1方のモードが2, もう1方が0になる")
[2 2 0 0 2 0 2 2 0 0 2 2 0 0 0 2 2 0 0 0 0 0 2 2 2 0 0 2 2 2 2 2 0 2 0 0 2
0 0 0 2 2 2 0 2 2 2 2 2 2]
HOM干渉計:2つのSingle photon Modeをビームスプリッタに入力すると出力モードの光子数は必ず1方のモードが2, もう1方が0になる
フォトンサンプリングで50回同じ操作を行って、0番目の量子モードのほうを測定しているという感じでしょうか。 今回は2つのモードに単体の光子を入力をすると、出力は片方が0片方が2と偏りが出るようで、それが確認できています。 Wigner関数でも確認してみました。
Copy F.Wigner(0)
<Figure size 432x288 with 1 Axes>
(array([-5.00000000e+00, -4.90000000e+00, -4.80000000e+00, -4.70000000e+00,
-4.60000000e+00, -4.50000000e+00, -4.40000000e+00, -4.30000000e+00,
-4.20000000e+00, -4.10000000e+00, -4.00000000e+00, -3.90000000e+00,
-3.80000000e+00, -3.70000000e+00, -3.60000000e+00, -3.50000000e+00,
-3.40000000e+00, -3.30000000e+00, -3.20000000e+00, -3.10000000e+00,
-3.00000000e+00, -2.90000000e+00, -2.80000000e+00, -2.70000000e+00,
-2.60000000e+00, -2.50000000e+00, -2.40000000e+00, -2.30000000e+00,
-2.20000000e+00, -2.10000000e+00, -2.00000000e+00, -1.90000000e+00,
-1.80000000e+00, -1.70000000e+00, -1.60000000e+00, -1.50000000e+00,
-1.40000000e+00, -1.30000000e+00, -1.20000000e+00, -1.10000000e+00,
-1.00000000e+00, -9.00000000e-01, -8.00000000e-01, -7.00000000e-01,
-6.00000000e-01, -5.00000000e-01, -4.00000000e-01, -3.00000000e-01,
-2.00000000e-01, -1.00000000e-01, -1.77635684e-14, 1.00000000e-01,
2.00000000e-01, 3.00000000e-01, 4.00000000e-01, 5.00000000e-01,
6.00000000e-01, 7.00000000e-01, 8.00000000e-01, 9.00000000e-01,
1.00000000e+00, 1.10000000e+00, 1.20000000e+00, 1.30000000e+00,
1.40000000e+00, 1.50000000e+00, 1.60000000e+00, 1.70000000e+00,
1.80000000e+00, 1.90000000e+00, 2.00000000e+00, 2.10000000e+00,
2.20000000e+00, 2.30000000e+00, 2.40000000e+00, 2.50000000e+00,
2.60000000e+00, 2.70000000e+00, 2.80000000e+00, 2.90000000e+00,
3.00000000e+00, 3.10000000e+00, 3.20000000e+00, 3.30000000e+00,
3.40000000e+00, 3.50000000e+00, 3.60000000e+00, 3.70000000e+00,
3.80000000e+00, 3.90000000e+00, 4.00000000e+00, 4.10000000e+00,
4.20000000e+00, 4.30000000e+00, 4.40000000e+00, 4.50000000e+00,
4.60000000e+00, 4.70000000e+00, 4.80000000e+00, 4.90000000e+00]),
array([-5.00000000e+00, -4.90000000e+00, -4.80000000e+00, -4.70000000e+00,
-4.60000000e+00, -4.50000000e+00, -4.40000000e+00, -4.30000000e+00,
-4.20000000e+00, -4.10000000e+00, -4.00000000e+00, -3.90000000e+00,
-3.80000000e+00, -3.70000000e+00, -3.60000000e+00, -3.50000000e+00,
-3.40000000e+00, -3.30000000e+00, -3.20000000e+00, -3.10000000e+00,
-3.00000000e+00, -2.90000000e+00, -2.80000000e+00, -2.70000000e+00,
-2.60000000e+00, -2.50000000e+00, -2.40000000e+00, -2.30000000e+00,
-2.20000000e+00, -2.10000000e+00, -2.00000000e+00, -1.90000000e+00,
-1.80000000e+00, -1.70000000e+00, -1.60000000e+00, -1.50000000e+00,
-1.40000000e+00, -1.30000000e+00, -1.20000000e+00, -1.10000000e+00,
-1.00000000e+00, -9.00000000e-01, -8.00000000e-01, -7.00000000e-01,
-6.00000000e-01, -5.00000000e-01, -4.00000000e-01, -3.00000000e-01,
-2.00000000e-01, -1.00000000e-01, -1.77635684e-14, 1.00000000e-01,
2.00000000e-01, 3.00000000e-01, 4.00000000e-01, 5.00000000e-01,
6.00000000e-01, 7.00000000e-01, 8.00000000e-01, 9.00000000e-01,
1.00000000e+00, 1.10000000e+00, 1.20000000e+00, 1.30000000e+00,
1.40000000e+00, 1.50000000e+00, 1.60000000e+00, 1.70000000e+00,
1.80000000e+00, 1.90000000e+00, 2.00000000e+00, 2.10000000e+00,
2.20000000e+00, 2.30000000e+00, 2.40000000e+00, 2.50000000e+00,
2.60000000e+00, 2.70000000e+00, 2.80000000e+00, 2.90000000e+00,
3.00000000e+00, 3.10000000e+00, 3.20000000e+00, 3.30000000e+00,
3.40000000e+00, 3.50000000e+00, 3.60000000e+00, 3.70000000e+00,
3.80000000e+00, 3.90000000e+00, 4.00000000e+00, 4.10000000e+00,
4.20000000e+00, 4.30000000e+00, 4.40000000e+00, 4.50000000e+00,
4.60000000e+00, 4.70000000e+00, 4.80000000e+00, 4.90000000e+00]),
array([[1.47407029e-19, 3.80838619e-19, 9.64445837e-19, ...,
2.39406750e-18, 9.64445837e-19, 3.80838619e-19],
[3.80838619e-19, 9.83092439e-19, 2.48744807e-18, ...,
6.16918218e-18, 2.48744807e-18, 9.83092439e-19],
[9.64445837e-19, 2.48744807e-18, 6.28822707e-18, ...,
1.55814551e-17, 6.28822707e-18, 2.48744807e-18],
...,
[2.39406750e-18, 6.16918218e-18, 1.55814551e-17, ...,
3.85731577e-17, 1.55814551e-17, 6.16918218e-18],
[9.64445837e-19, 2.48744807e-18, 6.28822707e-18, ...,
1.55814551e-17, 6.28822707e-18, 2.48744807e-18],
[3.80838619e-19, 9.83092439e-19, 2.48744807e-18, ...,
6.16918218e-18, 2.48744807e-18, 9.83092439e-19]]))
この調子で引き続きBSゲートを使う量子テレポーテーションのチュートリアルを見てみました。
まずはお決まりのシミュレータを準備します。チュートリアルの通りガウシアンシミュレータを準備します。
Copy G = pq.Gaussian(3)
そして、次は量子状態の準備です。こちらは量子ビット型のシミュレータと同じですね。テレポートしたい量子状態を準備します。今回はDゲートなので変位ゲートを使って0モードを変位させています。
Copy G.D(0, 1 + 0.5j) # state to teleport
<photonqat.Gaussian.Gaussian at 0x7f89d1f01700>
次に量子ゲートマシンではアダマールゲートが来ますが、量子モードマシンではスクイージングゲートが来るようです。パラメータrを決めてモード1とモード2に適用。
Copy r = 2 G.S(1, -r) G.S(2, r)
<photonqat.Gaussian.Gaussian at 0x7f89d1f01700>
そして、量子ビットならCXゲートの登場ですが、ここでBSゲートを適用50:50に設定するようです。
Copy G.BS(1, 2, np.pi/4) # 50:50 beam splitter G.BS(0, 1, np.pi/4) # 50:50 beam splitter
<photonqat.Gaussian.Gaussian at 0x7f89d1f01700>
そして測定ですね。今回はX測定とP測定というのを使うようです。 そして、量子テレポーテーションの場合には、測定結果を使って操作をしますね。モード2に適用します。 何をやってるかわかりませんが、チュートリアルの通りに実行します。
Copy G.MeasX(0) G.MeasP(1) G.X(2, G.Creg(0, "x", scale = np.sqrt(2))) G.Z(2, G.Creg(1, "p", scale = np.sqrt(2))) G.run()
<photonqat.Gaussian.Gaussian at 0x7f89d1f01700>
どうやらこれで完了のようです。Wigner関数を使ってプロットしてみます。
Copy G.Wigner(2) # plot print('measured x =', G.Creg(0, "x").read()) print('measured p =', G.Creg(1, "p").read()) print('teleported mu =', G.mean(2)) # mu of qumode 0
<Figure size 432x288 with 1 Axes>
measured x = 0.7099008889433029
measured p = 5.174593377132181
teleported mu = [1.39945544 0.94491589]
どうでしょうか。なんかチュートリアルと同じになった気はします。 ただ、xとかpの値とmuの関係とか関数表示のプロットとかの意味があまりよくわかりません。 開発者に聞いて説明を待ちたいと思います。
量子テレポーテーションをやってみると、量子ゲートマシンとの関係性がありそうなことがわかりました。光マシンは通信にも相性が良さそうなので、量子ゲートでの量子テレポーテーションは使いどころが難しかったですが、光マシンでやると未来が見えます。ツールが開発途中ですが、素人からしたらどこが分からないかが一目瞭然なので、グラフの読み方やゲートの活用方法などを持って詳しく探っていきたいと思います。
ちなみにblueqatの量子ビットタイプのマシンの量子テレポーテーションと回路を比べてみます。 測定部分はcx/czで簡略化して書いてしまっています。
量子モードでのSゲートが、量子ビットでのHゲートに対応。 量子モードでのBSゲートが、量子ビットでのCXゲートに対応。
その他は似た感じですね。できることは同じみたいなので比べながら学んでみてもいいかもしれません。
Copy from blueqat import Circuit #量子テレポーテーション回路 a = Circuit().h[1].cx[1,2].cx[0,1].h[0].cx[1,2].cz[0,2].m[:] a.run(shots=100)
Counter({'110': 27, '100': 29, '000': 23, '010': 21})
今回は以上です!
© 2024, blueqat Inc. All rights reserved