Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/translations/ja/ch-gates/multiple-qubits-entangled-states.ipynb
3855 views
Kernel: Python 3

複数量子ビットともつれ状態

単一の量子ビットは興味深いものではありますが、これらは個別では計算的に優位性をもたらすものではありません。ここでは複数の量子ビットに関する表現方法と、これらの量子ビットがどのように相互作用することができるかについて見ていきます。これまでに、2次元ベクトルを使用して1つの量子ビットに関する状態を表現することができることを学びました。今回は複数量子ビットの状態についてどのように表現することができるかについて見ていくことにします。

目次

  1. 複数量子ビット状態の表現 1.1 練習問題

  2. 複数量子ビット状態ベクトル上の単一量子ビットゲート 2.1 練習問題

  3. 複数量子ビットゲート 3.1 CNOTゲート 3.2 もつれ状態 3.3 もつれ状態の可視化 3.4 練習問題

1. 複数量子ビット状態の表現

単一の量子ビットは2つの状態を持つことができ、その状態は2つの複素振幅を持つことを見てきました。同様に、2量子ビットは4つの状態を持ちます。

00 01 10 11

さらに、2量子ビットの状態を説明するには4つの複素振幅が必要です。これらの振幅を以下のように4次元ベクトルで表します。

a=a0000+a0101+a1010+a1111=[a00 a01 a10 a11]|a\rangle = a_{00}|00\rangle + a_{01}|01\rangle + a_{10}|10\rangle + a_{11}|11\rangle = \begin{bmatrix} a_{00} \ a_{01} \ a_{10} \ a_{11} \end{bmatrix}

観測に関するルールについても単一量子ビットの時と同様に機能します。

p(00)=00a2=a002p(|00\rangle) = |\langle 00 | a \rangle |^2 = |a_{00}|^2

また、規格化条件などについても同様です。

a002+a012+a102+a112=1|a_{00}|^2 + |a_{01}|^2 + |a_{10}|^2 + |a_{11}|^2 = 1

2つの分離した量子ビットがある場合、クロネッカー積を使用してそれらの集合状態を表現できます。

a=[a0 a1],b=[b0 b1]|a\rangle = \begin{bmatrix} a_0 \ a_1 \end{bmatrix}, \quad |b\rangle = \begin{bmatrix} b_0 \ b_1 \end{bmatrix}ba=ba=[b0×[a0 a1] b1×[a0 a1]]=[b0a0 b0a1 b1a0 b1a1]|ba\rangle = |b\rangle \otimes |a\rangle = \begin{bmatrix} b_0 \times \begin{bmatrix} a_0 \ a_1 \end{bmatrix} \ b_1 \times \begin{bmatrix} a_0 \ a_1 \end{bmatrix} \end{bmatrix} = \begin{bmatrix} b_0 a_0 \ b_0 a_1 \ b_1 a_0 \ b_1 a_1 \end{bmatrix}

また、同じルールに従って、クロネッカー積を使用して、任意の数の量子ビットの集合状態を記述することができます。以下は3量子ビットの例です。

cba=[c0b0a0 c0b0a1 c0b1a0 c0b1a1 c1b0a0 c1b0a1 c1b1a0 c1b1a1 ]|cba\rangle = \begin{bmatrix} c_0 b_0 a_0 \ c_0 b_0 a_1 \ c_0 b_1 a_0 \ c_0 b_1 a_1 \ c_1 b_0 a_0 \ c_1 b_0 a_1 \ c_1 b_1 a_0 \ c_1 b_1 a_1 \ \end{bmatrix}

nn個の量子ビットがある場合、2n2^n個の複素振幅について記録する必要があります。これらのベクトルは量子ビットの数と共に指数関数的に大きくなります。これが多数の量子ビットを用いた量子コンピューターの演算をシミュレートすることが大変困難である理由です。現代のラップトップは約20量子ビットのシミュレートは簡単にできますが、100量子ビットになると最も大きいスーパーコンピューターでも手に負えません。

回路の例を見てみましょう。

from qiskit import QuantumCircuit, Aer, assemble import numpy as np from qiskit.visualization import plot_histogram, plot_bloch_multivector
qc = QuantumCircuit(3) # Apply H-gate to each qubit: for qubit in range(3): qc.h(qubit) # See the circuit: qc.draw()
Image in a Jupyter notebook

各量子ビットは+|+\rangleの状態をとっており、ベクトルは以下のとおりとなります。

+++=18[1 1 1 1 1 1 1 1 ]|{+++}\rangle = \frac{1}{\sqrt{8}}\begin{bmatrix} 1 \ 1 \ 1 \ 1 \ 1 \ 1 \ 1 \ 1 \ \end{bmatrix}
# Let's see the result svsim = Aer.get_backend('aer_simulator') qc.save_statevector() qobj = assemble(qc) final_state = svsim.run(qobj).result().get_statevector() # In Jupyter Notebooks we can display this nicely using Latex. # If not using Jupyter Notebooks you may need to remove the # array_to_latex function and use print(final_state) instead. from qiskit.visualization import array_to_latex array_to_latex(final_state, prefix="\\text{Statevector} = ")
Statevector=[1818181818181818]\text{Statevector} = \begin{bmatrix} \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} & \tfrac{1}{\sqrt{8}} \\ \end{bmatrix}

期待した結果が得られたことが確認できます。

1.1 練習問題:

  1. 量子ビットのクロネッカー積を書き下してください。
    a) 01|0\rangle|1\rangle
    b) 0+|0\rangle|+\rangle
    c) +1|+\rangle|1\rangle
    d) +|-\rangle|+\rangle

  2. 状態を2つの別々の量子ビットとして記述せよ。 ψ=1200+i201|\psi\rangle = \tfrac{1}{\sqrt{2}}|00\rangle + \tfrac{i}{\sqrt{2}}|01\rangle

2. 複数量子ビット状態ベクトル上の単一量子ビットゲート

Xゲートは以下の行列で表現されます。

X=[0amp;1 1amp;0]X = \begin{bmatrix} 0 & 1 \ 1 & 0 \end{bmatrix}

さらに、Xゲートは0|0\rangleの状態に以下のように作用します。

X0=[0amp;1 1amp;0][1 0]=[0 1]X|0\rangle = \begin{bmatrix} 0 & 1 \ 1 & 0 \end{bmatrix}\begin{bmatrix} 1 \ 0 \end{bmatrix} = \begin{bmatrix} 0 \ 1\end{bmatrix}

ただし、Xゲートが複数量子ビットベクトルの量子ビットにどのように作用するかは明確ではない場合があります。幸い、ルールは非常に単純です。クロネッカー積を使用して複数量子ビット状態ベクトルを計算したのと同じように、テンソル積を使用してこれらの状態ベクトルに作用する行列を計算します。たとえば、次の回路では次のようになります。

qc = QuantumCircuit(2) qc.h(0) qc.x(1) qc.draw()
Image in a Jupyter notebook

クロネッカー積を使用して、同時操作(HとX)を表すことができます。

Xq1Hq0=(XH)q1q0X|q_1\rangle \otimes H|q_0\rangle = (X\otimes H)|q_1 q_0\rangle

演算は以下の通りとなり、

XH=[0amp;1 1amp;0]12[1amp;1 1amp;1]X\otimes H = \begin{bmatrix} 0 & 1 \ 1 & 0 \end{bmatrix} \otimes \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \ 1 & -1 \end{bmatrix}=12[0×[1amp;1 1amp;1]amp;1×[1amp;1 1amp;1] 1×[1amp;1 1amp;1]amp;0×[1amp;1 1amp;1]]= \frac{1}{\sqrt{2}} \begin{bmatrix} 0 \times \begin{bmatrix} 1 & 1 \ 1 & -1 \end{bmatrix} & 1 \times \begin{bmatrix} 1 & 1 \ 1 & -1 \end{bmatrix} \ 1 \times \begin{bmatrix} 1 & 1 \ 1 & -1 \end{bmatrix} & 0 \times \begin{bmatrix} 1 & 1 \ 1 & -1 \end{bmatrix} \end{bmatrix}=12[0amp;0amp;1amp;1 0amp;0amp;1amp;1 1amp;1amp;0amp;0 1amp;1amp;0amp;0 ]= \frac{1}{\sqrt{2}} \begin{bmatrix} 0 & 0 & 1 & 1 \ 0 & 0 & 1 & -1 \ 1 & 1 & 0 & 0 \ 1 & -1 & 0 & 0 \ \end{bmatrix}

4次元状態ベクトルq1q0|q_1 q_0\rangleに適用することができます。表記がかなり煩雑になるため、以下のとおり簡略化した表記法がよく用いられます。

XH=[0amp;H Hamp;0 ]X\otimes H = \begin{bmatrix} 0 & H \ H & 0\ \end{bmatrix}

手計算の代わりに、Qiskitのaer_simulatorを使用して計算することができます。 Aerシミュレーターは、回路内のすべてのゲートを乗算して、量子回路全体を実行する単一のユニタリー行列をコンパイルします。

usim = Aer.get_backend('aer_simulator') qc.save_unitary() qobj = assemble(qc) unitary = usim.run(qobj).result().get_unitary()

結果を見てみます:

# In Jupyter Notebooks we can display this nicely using Latex. # If not using Jupyter Notebooks you may need to remove the # array_to_latex function and use print(unitary) instead. from qiskit.visualization import array_to_latex array_to_latex(unitary, prefix="\\text{Circuit = }\n")
$$\text{Circuit = } [001212001212121200121200]\begin{bmatrix} 0 & 0 & \tfrac{1}{\sqrt{2}} & \tfrac{1}{\sqrt{2}} \\ 0 & 0 & \tfrac{1}{\sqrt{2}} & -\tfrac{1}{\sqrt{2}} \\ \tfrac{1}{\sqrt{2}} & \tfrac{1}{\sqrt{2}} & 0 & 0 \\ \tfrac{1}{\sqrt{2}} & -\tfrac{1}{\sqrt{2}} & 0 & 0 \\ \end{bmatrix}$$

一度に1つの量子ビットのみにゲートを適用する場合(以下の回路など)、単位行列を使用したクロネッカー積を使用してこれを表現します。例えば、

XIX \otimes I
qc = QuantumCircuit(2) qc.x(1) qc.draw()
Image in a Jupyter notebook
# Simulate the unitary usim = Aer.get_backend('aer_simulator') qc.save_unitary() qobj = assemble(qc) unitary = usim.run(qobj).result().get_unitary() # Display the results: array_to_latex(unitary, prefix="\\text{Circuit = } ")
Circuit = [0010000110000100]\text{Circuit = } \begin{bmatrix} 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ \end{bmatrix}

Qiskitがクロネッカー積を計算したことがわかります:X otimesI= beginbmatrix0I I0  endbmatrix= beginbmatrix0010 0001 1000 0100  endbmatrix X \ otimes I = \ begin {bmatrix} 0&I \ I&0 \ \ end {bmatrix} = \ begin {bmatrix} 0&0&1&0 \ 0 &0&0&1 \ 1&0&0&0 \ 0&1&0&0 \ \ end {bmatrix}

2.1 練習問題:

  1. ゲートのシーケンスによって生成された単一量子ビットユニタリー行列(UU)を計算してください: U=XZHU=XZH。 QiskitのAerシミュレーターを使用して結果を確認してください。

  2. 上記の回路のゲートを変更してみてください。クロネッカー積を計算し、Aerシミュレーターを使用して答えを確認してください。

**注:**量子ビットの順序は書籍やソフトウェア、ウェブサイトによって異なります。これは、同じ回路に対するクロネッカー積が全く異なって見える可能性があることを意味します。他の情報源にあたるときはこのことを念頭に置いてください。

3. 複数量子ビットゲート

複数量子ビットの状態について表現方法を知ることができたため、複数量子ビットがそれぞれどのように相互作用するかについて学ぶ準備ができました。重要な2量子ビットゲートはCNOTゲートです。

3.1 CNOTゲート

このゲートは計算の原子の章に出てきました。このゲートは条件付きゲートであり、1つ目の量子ビット(制御)が1|1\rangleの場合に2つ目の量子ビット(ターゲット)にXゲートを適用する、というものです。このゲートはq0を制御、q1をターゲットとして以下のような回路として描画できます。

qc = QuantumCircuit(2) # Apply CNOT qc.cx(0,1) # See the circuit: qc.draw()
Image in a Jupyter notebook

量子ビットが0|0\rangle1|1\rangleの重ね合わせでない場合、このゲートはとても単純で直感的にわかりやすいです。古典の真理値表を使用できます。

Input (t,c)Output (t,c)
0000
0111
1010
1101

4次元状態ベクトルに従うと、どちらの量子ビットがコントロールでどちらがターゲットかにより、以下の2つの行列のいずれかになります。

CNOT=[1amp;0amp;0amp;0 0amp;0amp;0amp;1 0amp;0amp;1amp;0 0amp;1amp;0amp;0 ],CNOT=[1amp;0amp;0amp;0 0amp;1amp;0amp;0 0amp;0amp;0amp;1 0amp;0amp;1amp;0 ]\text{CNOT} = \begin{bmatrix} 1 & 0 & 0 & 0 \ 0 & 0 & 0 & 1 \ 0 & 0 & 1 & 0 \ 0 & 1 & 0 & 0 \ \end{bmatrix}, \quad \text{CNOT} = \begin{bmatrix} 1 & 0 & 0 & 0 \ 0 & 1 & 0 & 0 \ 0 & 0 & 0 & 1 \ 0 & 0 & 1 & 0 \ \end{bmatrix}

どの量子ビットが制御ビットで、どれがターゲットビットかによります。書籍やシミュレーター、論文ごとに量子ビットの順序も異なります。今回の場合、左側の行列は上記の回路のCNOTに対応します。この行列は、状態ベクトルの 01|01\rangle11|11\rangleの振幅を交換します。

a=[a00 a01 a10 a11],CNOTa=[a00 a11 a10 a01]   |a\rangle = \begin{bmatrix} a_{00} \ a_{01} \ a_{10} \ a_{11} \end{bmatrix}, \quad \text{CNOT}|a\rangle = \begin{bmatrix} a_{00} \ a_{11} \ a_{10} \ a_{01} \end{bmatrix} \begin{matrix} \ \leftarrow \ \ \leftarrow \end{matrix}

これまで古典的な状態に対する作用について見てきましたが、今度は重ね合わせ状態の量子ビットに対しての作用を見ていきましょう。1量子ビットを+|+\rangleの状態にします。

qc = QuantumCircuit(2) # Apply H-gate to the first: qc.h(0) qc.draw()
Image in a Jupyter notebook
# Let's see the result: svsim = Aer.get_backend('aer_simulator') qc.save_statevector() qobj = assemble(qc) final_state = svsim.run(qobj).result().get_statevector() # Print the statevector neatly: array_to_latex(final_state, prefix="\\text{Statevector = }")
Statevector = [121200]\text{Statevector = } \begin{bmatrix} \tfrac{1}{\sqrt{2}} & \tfrac{1}{\sqrt{2}} & 0 & 0 \\ \end{bmatrix}

これは期待通りに0+=0+|0\rangle \otimes |{+}\rangle = |0{+}\rangleの状態を作ります。

0+=12(00+01)|0{+}\rangle = \tfrac{1}{\sqrt{2}}(|00\rangle + |01\rangle)

CNOTゲートを適用するとどうなるか見てみましょう。

qc = QuantumCircuit(2) # Apply H-gate to the first: qc.h(0) # Apply a CNOT: qc.cx(0,1) qc.draw()
Image in a Jupyter notebook
# Let's get the result: qc.save_statevector() qobj = assemble(qc) result = svsim.run(qobj).result() # Print the statevector neatly: final_state = result.get_statevector() array_to_latex(final_state, prefix="\\text{Statevector = }")
Statevector = [120012]\text{Statevector = } \begin{bmatrix} \tfrac{1}{\sqrt{2}} & 0 & 0 & \tfrac{1}{\sqrt{2}} \\ \end{bmatrix}

以下の状態が得られます。

CNOT0+=12(00+11)\text{CNOT}|0{+}\rangle = \tfrac{1}{\sqrt{2}}(|00\rangle + |11\rangle)

これはもつれ状態になっており、大変興味深いです。もつれ状態については次節に進みましょう。

3.2 もつれ状態

前節では以下の状態を作ることができることを見ました。:

12(00+11)\tfrac{1}{\sqrt{2}}(|00\rangle + |11\rangle)

これはベル状態として知られています。この状態は、50%の確率で00|00\rangleの状態が観測され、50%の確率で11|11\rangleの状態が観測されます。最も興味深いことに、01|01\rangleまたは10|10\rangleが観測される確率は0% です。このことは、Qiskitで確認することができます。

plot_histogram(result.get_counts())
Image in a Jupyter notebook

この結合された状態は、2つの別々の量子ビット状態として記述することはできません。このことには興味深い示唆があります。量子ビットが重ね合わせ状態にあるにも関わらず、1つの量子ビットを観測するともう1つの量子ビットの状態が得られると同時に重ね合わせ状態がなくなります。例として、一番上の量子ビットを観測して1|1\rangleの状態が得られたとすると、2つの量子ビットの状態は以下のように変化します。

12(00+11)measure11\tfrac{1}{\sqrt{2}}(|00\rangle + |11\rangle) \quad \xrightarrow[]{\text{measure}} \quad |11\rangle

2つの量子ビットを数光年の距離に離したとしても、1つの量子ビットに関する観測はもう1つの量子ビットに対して影響を及ぼしているようにみえます。この不気味な遠隔作用 は20世紀初期に非常に多くの物理学者を悩ませました。

測定結果はランダムであり、一方の量子ビットの観測結果は、もう一方の量子ビットの操作の影響を受けないことに注意することが重要です。 このため、共量子もつれ状態を使用して通信をする方法はありません。 これは、通信不可能定理[1]として知られています。

3.3 もつれ状態の可視化

この状態は2つの別々の量子ビット状態として書けないことがわかりましたが、このことは、別々のブロッホ球に状態をプロットしようとすると、情報が失われることも意味します。

plot_bloch_multivector(final_state)
Image in a Jupyter notebook

前の章でブロッホ球をどのように定義したかを考えると、Qiskitがこのようなもつれた量子ビットを持つブロッホベクトルをどのように計算するかが明確でない場合があります。単一量子ビットの場合、軸に沿ったブロッホベクトルの位置は、その基底での測定の期待値にうまく対応します。これをブロッホベクトルのプロットルールとすると、上記の結論に到達します。これは、特定の測定が保証されている単一量子ビットの測定基底がないことを示しています。これは、常に単一量子ビット基底を選択できる単一量子ビット状態とは対照的です。このように個々の量子ビットを見ると、量子ビット間の相関の重要な効果を見逃しています。異なるもつれた状態を区別することはできません。たとえば、次の2つの状態があります。

12(01+10)and12(00+11)\tfrac{1}{\sqrt{2}}(|01\rangle + |10\rangle) \quad \text{and} \quad \tfrac{1}{\sqrt{2}}(|00\rangle + |11\rangle)

は、測定結果が異なる全く異なる状態であるにもかかわらず、この別々のブロッホ球の上ではどちらも同じに見えます。

この状態ベクトルを他にどのように可視化すればよいのでしょうか?この状態ベクトルは単純に4つの振幅(複素数)の集まりであり、これを画像にうつす方法は無限にあります。そのような可視化の1つが「Q-sphere」で、ここでは各振幅を球の表面上のブロブで表現しています。ブロブの大きさは振幅の大きさに比例し、色は振幅の位相に比例します。00|00\rangle11|11\rangleの振幅は等しく、他の振幅はすべて0です。

from qiskit.visualization import plot_state_qsphere plot_state_qsphere(final_state)
Image in a Jupyter notebook

ここでは、量子ビットの間の相関を明確に見ることができます。Q-sphereの形は重要ではなく、単にブロブを並べるのにいい方法であるにすぎません。状態の0の個数はZ軸上の状態の位置に比例するので、ここでは00|00\rangleの振幅は球の上の極にあり、11|11\rangleの振幅は球の下の極にあることが分かります。

3.4 練習問題:

  1. 以下のベル状態を作り出す量子回路を作成せよ。 12(01+10)\tfrac{1}{\sqrt{2}}(|01\rangle + |10\rangle). 状態ベクトルシミュレーターを使用して結果を検証せよ。

  2. 設問1にて作成した回路は状態00|00\rangle12(01+10)\tfrac{1}{\sqrt{2}}(|01\rangle + |10\rangle)に変換するものです。この回路のユニタリー行列をQiskitシミュレーターを使用して計算してください。このユニタリー行列が正しい変換を行えることを検証してください。

  3. 状態ベクトルを視覚的に表現する他の方法について考えてください。各振幅の大きさと位相を読み取ることができる、興味深い視覚化をデザインが可能でしょうか?

4. 参考文献

[1] Asher Peres, Daniel R. Terno, Quantum Information and Relativity Theory, 2004, https://arxiv.org/abs/quant-ph/0212023

import qiskit.tools.jupyter %qiskit_version_table