💣

[量子現象] 量子爆弾検査と量子ゼノン効果

2023/04/02に公開

この記事でやること

量子力学の世界では人間の直感に反した現象が様々起きます。この記事では量子力学の世界での観測が引き起こす二つの面白い現象:

  • 物体を直接観測せずに、観測する
  • 観測を繰り返すだけで系の時間発展を止める

を扱います。
まず初めに、前者を示すために量子爆弾検査について紹介し、その後量子爆弾検査の背景にある量子ゼノン効果と後者について紹介します。また、量子プログラミング言語Qiskitでエミュレートすることでその理解を深めます。

この記事は"Building Quantum Bomb Testers (And Other Thought Experiments) with Quantum Computers","The Quantum Zeno Effect: From Motionless Arrows to Entangled Freezers",および Wikipedia:量子ゼノン効果
を主に参考にしています。

量子爆弾検査

問題設定

量子爆弾検査の問題設定はとてもシンプルです。

ここに爆弾が沢山あるとします。この爆弾には光検出器がついていて、光子が一つでもあたると、爆発してしまいます。ただし、爆弾の中にはニセモノも混じっていて、ニセモノについている光検出器は光子を素通りさせます。
さて、たくさんある爆弾をホンモノのとニセモノに仕分けするにはどうしたらよいでしょうか。もちろん、危ないので爆弾を爆発させてホンモノかどうか確認してはいけません。


図1

とりあえずの解答

MZ干渉計

最初の解答はこの問題設定を考えたElitzurとVaidmanによって1993年に示されました。下図のようなMach–Zehnder干渉計(MZ干渉計)の間に爆弾を置くことで、光子を爆弾にあてずに爆弾を見つけることができます。下側のパスを\ket{0},上側のパスを\ket{1}と名付けましょう。


図2

MZ干渉計ではビームスプリッター (BS)の表面で反射される光は、反射時に位相が反転(\piずれる)します。1光子だけMZ干渉計に入れると検出器D0に至るパスの確率振幅同士が打ち消しあって、\ket{0}から入れた光子は\ket{1}方向にのみ光が出てきます。


図3

後の説明をわかりやすくするために量子回路でも表しておきましょう。上記を量子回路で表すと


図4
となります。ただし、Rゲートは

R (\theta,\phi)= \begin{bmatrix} \cos \frac{\theta}{2} & -i e^{-i\phi} \sin \frac {\theta}{2}\\ -i e^{i\phi} \sin \frac{\theta}{2} & \cos \frac{\theta}{2} \end{bmatrix}, \qquad R\left(\theta = \frac{\pi}{2}, \phi = -\frac{\pi}{2} \right) = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 1\\ -1 & 1 \end{bmatrix}

です。

さて、図5に爆弾がホンモノだった場合とニセモノだった場合それぞれについてすべての場合を書き示しました。爆弾がホンモノの場合、爆発から光子が来たことがわかるので、爆弾を検出器とみなすせます。対してニセモノだった場合、素通りしてしまうのでMZ干渉計中では観測行為は行われないと考えられます。よって、

  • ホンモノの場合
    • 50% で爆発
    • 25%でD0が検出
    • 25%でD1が検出
  • ニセモノだった場合
    • 100%でD1が検出

であり、ここから、D0が検出すれば爆弾がホンモノであることが言えます。

図5

このように、爆弾を爆発させずに爆弾の存在を確認することが可能です。このような測定をInteraction-free measurementと言ったりします。

ただし、上記の光学系ではその効率は25%と低く、実験したら爆弾が爆発する可能性はありますし、D1が検出した場合ホンモノかどうかわからないので、検査としての実用性は低いでしょう。

爆弾がホンモノであった場合の実験を量子回路で表しましょう。これは2 qubitとCNOTゲートを使うことで実現できます。


図6
爆弾が爆発することは新しく加えたBomb qubitの測定で1が得られることと対応するとします。この量子回路を計算してみると測定前の状態は

\ket{q_1q_0}=\ket{00}\xrightarrow{R} \frac{\ket{00}-\ket{01}}{\sqrt{2}} \xrightarrow{CNOT} \frac{\ket{00}-\ket{11}}{\sqrt{2}} \xrightarrow{R} \underset{(3)}{\underline{\frac{\ket{00}}{2}}} - \underset{(2)}{\underline{\frac{\ket{01}}{2}}} - \underset{(1)}{\underline{\frac{\ket{10}+\ket{11}}{2}}}

となり、第1項からこの量子回路が効率25%の爆弾検査を表していることがわかります。

効率100%への改良案

では、確実に爆弾があることを示すにはどうしたらよいでしょうか。その答えは意外と簡単で

  • MZ干渉計を多数並べる(N個とします)
  • 透過率が\sin^2 \pi/2N,反射率が\cos^2 \pi/2NのBSを用いる

ことで効率100%の爆弾検査が可能になります。例えばN=4の場合、下図のようになります。


図7
こうすることで

  • D0が検出したときは爆弾がホンモノ
  • D1が検出したときは爆弾はニセモノ

という風な判断が可能になります。等価回路を考え、爆弾がニセモノの場合とホンモノの場合の動作を考えましょう。
ニセモノ場合

図8

R\left(\frac{\pi}{N},-\frac{\pi}{2}\right)^N \ket{0} = \begin{bmatrix} \cos \frac{\pi}{2N} & \sin \frac{\pi}{2N}\\ -\sin \frac{\pi}{2N} & \cos \frac{\pi}{2N} \end{bmatrix} ^N = \begin{bmatrix} \cos \frac{\pi}{2} & \sin \frac{\pi}{2}\\ -\sin \frac{\pi}{2} & \cos \frac{\pi}{2} \end{bmatrix} \ket{0} =-\ket{1}

となり、必ずD1が検出することがわかります。二つ目のイコールではRゲートが回転行列に一致していることを利用しました。

ホンモノの場合

図9
一つのMZ干渉計で量子状態は

\ket{q_1q_0}=\ket{00} \xrightarrow{R} \cos \frac{\pi}{2N}\ket{00}-\sin\frac{\pi}{2N}\ket{01} \xrightarrow{CNOT} \cos \frac{\pi}{2N}\ket{00}-\sin\frac{\pi}{2N}\ket{11}

と変わるので、q_1を測定して爆発しない(つまり0が得られる)確率は、\cos^2 (\pi/2N)となります。これをN個つなぐので、最終的に爆発しない確率は

P = \left(\cos^2 \frac{\pi}{2N} \right)^N = \left(1- \frac{1}{2}\left(\frac{\pi}{2N}\right)^2 + O(N^{-4}) \right)^{2N} = 1 - \frac{\pi^2}{4N}+O(N^{-2}) \rightarrow 1 \quad(N\rightarrow \infty)

です。つまりホンモノの場合、検出器D0が必ず検出し、かつ爆弾は爆発しないとわかります。

Qiskitを使った実証

こんな都合がよいことが本当に起きるのか、Qiskitを使って検証してみましょう。ここでは連鎖数Nを増やしていったときに検査効率がどれだけ改善するのかを見ていきます。
爆弾がホンモノの場合のシミュレーション結果を下記に示します。


図10
確かに連鎖数Nを増やすほど爆発せずにD0が検出する確率が高くなっていくことがわかります。N=63で検出効率96%程度です。対して、D1が検出したり爆弾が爆発する確率は下がっていきます。
このように、検出効率を90%以上まで上げることが可能です。

プログラムはappendixに載せておきます。

なぜこんなことが起きるのか?:量子ゼノン効果

では、なぜこんな高効率の相互作用無しの測定が可能なのでしょうか。そのポイントは二つあります。

  • 毎回測定を行う。毎回観測を行うことで、\ket{q_0=0}に状態を射影、つまり系の状態をリセットしている。
  • BSの反射率が\cos \theta = 1 - \frac{\theta ^2}{1} + ..., \theta<<1である。反射率は測定確率につながっており、N乗したときに0項目の1だけ残る。

特に前者は量子ゼノン効果として知られています。最後にそれを紹介しましょう。
適当な量子状態が時間に依存しないあるハミルトニアン\hat{H}に従い、時間発展する場合を考えます。時刻0である量子状態が\ket{\phi_0}:=\ket{\phi(t=0)}とかけるとき、この量子の時刻tでの状態\ket{\phi(t)}\ket{\phi(t)}= e^{-i\hat{H}t/\hbar}\ket{\phi_0}と書けます。これはシュレディンガー方程式の形式解として知られています。

さて、時間がtまで経過しても、なお系が\ket{\phi_0}に留まっている確率P(t)を計算してみましょう。時刻tに達するまで一度も観測を行わなければ、その確率は

P(t) = |\braket{\phi_0|\psi(t)}|^2 = \braket{\phi_0|e^{i\hat{H}t/\hbar}|\phi_0} \braket{\phi_0|e^{-i\hat{H}t/\hbar}|\phi_0}

となります。では時刻tに達するまでに、N(>>1)回系を測定したらどうでしょうか。測定の時間間隔を\tau=t/Nとします。この時のP(t)は:

\begin{align} P(t) &= P(\tau)^N =\left[\braket{\phi_0|e^{i\hat{H}\tau/\hbar}|\phi_0} \braket{\phi_0|e^{-i\hat{H}\tau/\hbar}|\phi_0}\right]^N\\ &\sim \left[\braket{\phi_0|\left(1+i\frac{\hat{H}\tau}{\hbar} - \frac{1}{2} \frac{\hat{H}^2 \tau^2}{\hbar^2} \right)|\phi_0} \braket{\phi_0|\left(1-i\frac{\hat{H} \tau}{\hbar} - \frac{1}{2} \frac{\hat{H}^2 \tau^2}{\hbar^2} \right)|\phi_0}\right]^N\\ &\sim \left[1- \left(\frac{\Delta\hat{H} \tau}{\hbar}\right)^2 \right]^N =\left[1- \left(\frac{\Delta\hat{H} t}{\hbar N}\right)^2 \right]^N \\ &\rightarrow 1 \quad (N\rightarrow \infty) \end{align}

ただし、

\Delta \hat{H} := \sqrt{\braket{\phi_0|\hat{H}^2|\phi_0}-\braket{\phi_0|\hat{H}|\phi_0}^2}

と定義しました。

確率が1に近づくことから明らかなように、時間発展する系を頻繁に観測したことで時間発展が止まってしまいました。この効果を量子ゼノン効果(quantum zeno effect)と言います。「飛んでいる矢は止まっている」なんておかしなことが身の回りで起きないのは古典系の世界では自明ですが、量子力学で考えるとそれに近い現象が起きてしまうのは不思議ですね。高効率の量子爆弾検査ではこの効果を使い、ちまちま観測することで系の時間発展(=ゲートによるユニタリ時間発展)を妨げていたと考えることが来ます。

まとめ

この記事では爆弾検査問題を通じて、測定に関する不思議な性質を二つ見てきました。またそれが実際に起きることをQiskiで確かめました。

今回紹介した量子ゼノン効果を応用することで、コンピューターを動かさずに計算結果を推測すること(counterfactual quantum computing)が可能であることを示せるそうです。勉強していずれ別の記事はこれらについても紹介したいと思います。

Appendix:program

#import qiskit tools
import qiskit
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, transpile, Aer, IBMQ
from qiskit.tools.visualization import circuit_drawer
from qiskit.tools.monitor import job_monitor, backend_monitor, backend_overview
from qiskit.providers.aer import noise
from qiskit.quantum_info import Statevector
#import python stuff
import matplotlib.pyplot as plt
import numpy as np
import time

# Set quantum computer
IBMQ.load_account()
provider = IBMQ.get_provider('ibm-q')
quito = provider.get_backend('ibmq_qasm_simulator')

# 量子回路の定義
def make_zeno_circuit(N):
    zeno_circuits = []
    
    for n in N:
        circuit = QuantumCircuit(2,2)
        circuit.r(np.pi/(n+1),-np.pi/2,0)
        circuit.cx(0,1)
        circuit.measure(1,1)
        circuit.reset(1)
        
        for i in range(n):
            circuit.r(np.pi/(n+1),-np.pi/2,0)
            if i != n-1:
                circuit.cx(0,1)
                circuit.measure(1,1)
                circuit.reset(1)
        circuit.measure(0,0)
        zeno_circuits.append(circuit)
    return zeno_circuits

loop = 64
N_vec = np.arange(1,loop)

my_zeno_circuits = make_zeno_circuit(N_vec)
my_zeno_circuits[2].draw()

# 測定開始
tic = time.time()
transpiled_circuits = transpile(my_zeno_circuits, quito)
job = quito.run(transpiled_circuits, shots = 8192)
job_monitor(job)
result = job.result()
toc = time.time()
print(toc-tic)

#グラフ化のための測定データの処理
zeno_hist = []
un0_hist = []
un1_hist = []
exp0_hist = [] 
exp1_hist = []

for i in range(0,63):
    zeno_hist = result.get_counts(i)
    un0_hist.append(zeno_hist.get('00'))
    un1_hist.append(zeno_hist.get('01'))
    exp0_hist.append(zeno_hist.get('10'))
    exp1_hist.append(zeno_hist.get('11'))
    
un0_array = np.array(un0_hist)
np.putmask(un0_array,un0_array==None,0)

un1_array = np.array(un1_hist)
np.putmask(un1_array,un1_array==None,0)

exp0_array = np.array(exp0_hist)
np.putmask(exp0_array,exp0_array==None,0)

exp1_array = np.array(exp1_hist)
np.putmask(exp1_array,exp1_array==None,0)

exp_array = (exp0_array + exp1_array)/(un0_array + un1_array+exp0_array + exp1_array)
un0_array = (un0_array)/(un0_array + un1_array+exp0_array + exp1_array)
un1_array = (un1_array)/(un0_array + un1_array+exp0_array + exp1_array)

print(un0_array)
print(un1_array)
print(exp_array)

#グラフ化
plt.figure(figsize=(12,8))
plt.rcParams.update({'font.size': 22})
plt.plot(N_vec,un0_array,'o-',label = 'unexploded and D0 detected')
plt.plot(N_vec,un1_array,'o-',label = 'unexploded and D1 detected')
plt.plot(N_vec,exp_array,'o-',label = 'explosion')

plt.grid(which='major',axis='both')
plt.rcParams.update({'font.size': 16})
plt.legend(loc='lower center', bbox_to_anchor=(0.5, -0.3))
plt.ylim(0, 1)
plt.xlabel('N')
plt.ylabel('Probability')

Reference

爆弾を見ないで発見する方法 (萱沼 洋輔)
http://www.p.s.osakafu-u.ac.jp/~kayanuma/QIFM.pdf

Discussion