ITとかCockatielとか

技術のこととか。飼鳥(オカメインコ)のこととか。気になったこととか。基本的には備忘録。

Qiskitで量子テレポーテーション!

※Qiitaから引っ越しです。

はじめに

IBMのQiskitを使った量子テレポーテーションの実験をしてみたいと思います。
理論的な説明は難しいので、今回は実際に回路を作ってシミュレータで動かすことを目標にします。
「理解するより、まず先にやってみよう」ということですね。
それでは、始めていきましょう。

Qiskitとは

  • IBM社の量子コンピュータである「IBM Q」を実際に動かすことができるPythonOSSです。
  • シミュレータ機能も含まれているため、量子プログラミングを実践できます。
  • IBM Q Experience上で、誰でもすぐに使えます。

Qiskit Community 紹介

環境

  • Q Experience JupyterNotebook

量子テレポーテーションとは

手元にある量子状態がはるか彼方に一瞬で転送されるという現象です。

アインシュタイン相対性理論においては、光より速いものは存在しないとされています。
しかし、量子テレポーテーションでは光の速度を超えて相互作用を伝達することができるという嘘みたいなことが起こるのです。

量子テレポーテーションで世界が変わる?

手元の量子状態をはるか彼方で再現できることから、何かしらの輸送問題が解決できそうに思います。
しかし、実際は非常に小さな世界のできごとになるため、物質輸送よりも情報通信への応用が期待されます。

でも応用が進んだら本当のテレポーテーションも夢じゃない・・・かも?

量子テレポーテーションの量子実験

説明はそこそにして実験開始です。

Qiskitの準備

Q Experience を利用する場合は準備不要です。 ローカル実行する場合はpipでインストールできます。

pip install qiskit

量子回路を作ってシミュレータで動かしてみる

まずはライブラリ準備から。

# ライブラリのインポート
from qiskit import QuantumRegister, ClassicalRegister, BasicAer

ベースとなる回路を作ります。

# 古典レジスタ(回路図の下3本)を準備
cr0 = ClassicalRegister(1)
cr1 = ClassicalRegister(1)
cr2 = ClassicalRegister(1)

# ベース回路を作る(量子レジスタ3本+古典レジスタ3本)
circ = QuantumCircuit(QuantumRegister(3), cr0, cr1, cr2)

# 表示確認
circ.draw(output='mpl')

f:id:sik_bug:20200812103758p:plain

できました。
回路の役割は以下のとおりです。
量子レジスタ3本目、古典レジスタ3本目がはるか彼方の転送先にあるという想定です。

f:id:sik_bug:20200812103813p:plain

続いて回路にゲートを配置していきます。
作り方は簡単で、回路上にゲートをポチポチと置いていくだけです。

# 測定までの回路を作る
circ.h(0)
circ.h(1)
circ.cx(1,2)
circ.cx(0,1)
circ.h(0)

# 表示確認
circ.draw(output='mpl')

f:id:sik_bug:20200812103826p:plain

とても簡単ですね。
では残りの回路を作っていきます。

barrierで区切りを入れてから、またゲートをポチポチと置いていきます。
古典レジスタ(1本目と2本目)の値によって、量子レジスタ(3本目)のゲート操作が発生するため、c_ifが入ってきますが、要領は同じです。

# 残りの回路を作る
circ.barrier(range(3))
circ.measure(0, 0)
circ.measure(1, 1)
circ.z(2).c_if(cr0, 1)
circ.x(2).c_if(cr1, 1)
circ.measure(2, 2)

# 表示確認
circ.draw(output='mpl')

f:id:sik_bug:20200812103840p:plain

とても簡単にできました、回路はこれで完成です。
量子テレポーテーションというと難しそうですが、回路表現ではたったこれだけです。

では、シミュレータで動かしてみましょう。

# シミュレータで実行する
backend = BasicAer.get_backend('qasm_simulator')
# デフォルトで1024回実行
job = execute(circ, backend) 
result = job.result()

これで実行完了です。
実行結果を見てみます。

# 実行結果を表示、8パターンで合計1024回になる
result.get_counts(circ)

出力結果は以下の通り。

    {'0 0 0': 100,
     '1 1 0': 127,
     '1 0 1': 147,
     '1 0 0': 140,
     '0 0 1': 131,
     '0 1 0': 128,
     '0 1 1': 131,
     '1 1 1': 120}

見方は以下のとおりです。

f:id:sik_bug:20200812103856p:plain

実際にテレポーテーションさせるときは、量子レジスタ3本目は測定せず、そのままの状態で使います。

測定をしなければ、転送元の量子レジスタ1本目と同じ状態が量子レジスタ3本目に再現(テレポーテーション)されます。
測定をすると「重ね合わせ」状態が壊れてしまうのですが、今回は実験なので測定して本当にテレポーテーションしたのかを確認しているわけです。

あれ、ちょっと待って

できあがった回路をもう一度よく見てみましょう。

f:id:sik_bug:20200812103907p:plain

転送元である古典レジスタ1本目、2本目(量子レジスタ1本目、2本目の測定結果に該当)をもとに、転送先の量子レジスタ(3本目)のゲート操作(Z、X)をしていることが分かります。

実は、量子テレポーテーションの実現には「転送元の測定結果を転送先にお知らせする」ということが必要なんです。 どうやって伝えるのかって・・・? LINEかな。

ともあれ、これをしないと「転送先の量子ビットは転送元とちょっとだけ違う状態になっていることがある」ということなんです。

量子テレポーテーションに落とし穴あり!!
(結局、古典通信が必要なんじゃない!というお話でした)

おわりに

今回は解説そこそこに書いてみました。
量子コンピュータは最初の概念理解が難しいので、「まず触ってみる」というのもありだと思います。
触って学んで、理解を深めていきましょう。(と自分に言い聞かせてます、理論難しいので)

参考