この記事について
量子コンピュータの勉強をするにあたり、多くの方がつまづくであろう(少なくとも私はつまづきました)「その量子、右から見るか?左から見るか?」という話を整理していこうと思います。
といきなり言われてもさっぱりだと思いますので、一旦概要を述べます。
量子ビットは古典ビットの表記方法と異なり、ブラケット表記を使用します。
$ |01\rangle$ ← こんな感じの表記です。
これは以下の二通りの解釈の仕方があります。
(添え字は0から始まると仮定します。)
- 0量子ビット目が0、1量子ビット目が1
- 0量子ビット目が1、1量子ビット目が0
という二通りです。
これらの解釈の仕方を整理せずに勉強を進めていくと後々、頭が混乱していくので今回はそれを整理していきます。
特に量子特有の行列計算をする際に制御ゲートというものがあり、
- 0量子ビット目を制御ビットとする
- 1量子ビット目を制御ビットとする
というように2量子系のどちらかを制御ビットと特定する必要があるので、
量子ビットの読み方をしっかりと整理していこうと思います。
今回はIBM QiskitとAmazonBraketを活用して量子ビットの読み方を整理していきますが、
制御ビットと制御ゲートの考え方、制御ゲートチートシートという記事も書いているので是非参考にしてみてください。
また、量子コンピュータ関係の他の記事は、下記で紹介しています。
2量子ビットの表記方法
まずは2量子ビットの表記方法を整理します。
2つの演算子$A$と$B$を用意した時、それぞれが片方ずつの量子ビットに作用すると考えるとテンソル積を用いて以下のように示されます。
A\otimes B = \begin{pmatrix}
A_{00} \begin{pmatrix}
B_{00} & B_{01} \\
B_{10} & B_{11}
\end{pmatrix} & A_{01} \begin{pmatrix}
B_{00} & B_{01} \\
B_{10} & B_{11}
\end{pmatrix} \\
A_{10} \begin{pmatrix}
B_{00} & B_{01} \\
B_{10} & B_{11}
\end{pmatrix} & A_{11} \begin{pmatrix}
B_{00} & B_{01} \\
B_{10} & B_{11}
\end{pmatrix}
\end{pmatrix}.
ここで$A_{ij}, B_{kl}$はそれぞれの行列成分を示します。
|0 \rangle = \begin{pmatrix}
1 \\
0
\end{pmatrix},
|1 \rangle = \begin{pmatrix}
0 \\
1
\end{pmatrix}.
1量子ビット系の表記方法が上記のように表されることに注意すると、
2量子ビットは以下のようにテンソル積を用いて表すことができます。
\begin{split}\begin{equation}\begin{split}
\left|{00}\right\rangle &= \begin{pmatrix}
1 \begin{pmatrix}
1 \\
0
\end{pmatrix} \\
0 \begin{pmatrix}
1 \\
0
\end{pmatrix}
\end{pmatrix} = \begin{pmatrix} 1 \\ 0 \\ 0 \\0 \end{pmatrix}~~~\left|{01}\right\rangle = \begin{pmatrix}
1 \begin{pmatrix}
0 \\
1
\end{pmatrix} \\
0 \begin{pmatrix}
0 \\
1
\end{pmatrix}
\end{pmatrix} = \begin{pmatrix}0 \\ 1 \\ 0 \\ 0 \end{pmatrix}\end{split}
\end{equation}\end{split}
\begin{split}\begin{equation}\begin{split}\left|{10}\right\rangle = \begin{pmatrix}
0\begin{pmatrix}
1 \\
0
\end{pmatrix} \\
1\begin{pmatrix}
1 \\
0
\end{pmatrix}
\end{pmatrix} = \begin{pmatrix} 0 \\ 0 \\ 1 \\ 0 \end{pmatrix}
\left|{11}\right\rangle = \begin{pmatrix}
0 \begin{pmatrix}
0 \\
1
\end{pmatrix} \\
1\begin{pmatrix}
0 \\
1
\end{pmatrix}
\end{pmatrix} = \begin{pmatrix} 0 \\ 0 \\ 0 \\1 \end{pmatrix}\end{split}
\end{equation}.\end{split}
なのでベクトルのそれぞれの成分が以下のように対応していることがわかると思います。
\begin{pmatrix} |{00}\rangle \\ |{01}\rangle \\ |{10}\rangle \\ |{11}\rangle \end{pmatrix}
表記の順番
上記のように複数量子ビットの表記をしたときに
- 一番左端を最初の量子ビット、つまり0ビット目とし、一番右端のもの最後の量子ビットとする読み方
- 一番右端を最初の量子ビット、つまり0ビット目とし、一番左端のもの最後の量子ビットとする読み方
があることがわかるかと思います。
どちらが正しいのかと言いますと、結論から言うとどちらも正しいです。
物理コミュニティでは一番左を最初の量子ビットとし、右を最後の量子ビットとするそうです。
一方で、Qiskitでは物理コミュニティとは異なった表記方法をとります。
これは、古典コンピュータ上のビット列表現と同様にしているという意図があるようで最上位ビット(Most Significant Bit - MSB)を左にとり、最下位ビット(Least Significant Bit - LSB) を右に取ります。(こちらを参考にしてみてください。)
注意してほしいのは、いまのところこれらは量子コンピュータの界隈で統一的になっているわけではないということです。
例えば、AmazonBraketの場合、表記は真逆で最上位ビット(Most Significant Bit - MSB)を右にとり、最下位ビット(Least Significant Bit - LSB)を左に取ります。
具体例
少しわかりにくいので実際にコーディングしてみた結果を示します。
3量子ビットの初期状態を $|000 \rangle$とし、量子ビットの0ビット目、1ビット目に恒等変換$I$、第2ビット目に$X$ゲートを適用します。
$X$ゲートはビット反転なので、
- Qiskitでは第2ビット目、つまり、最上位ビットの左端の量子ビットが$1$に反転され、 $|100 \rangle$となり、
- AmazonBraketでは、同様に第2ビット目の最上位ビットである右端の量子ビットが反転し、$|001 \rangle$となるはずです。
では、まずはQiskitでコーディングしていきましょう。
from qiskit import *
from qiskit.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor
circuit = QuantumCircuit(3, 3)
# 第0ビットと第1ビットに恒等変換
circuit.i(0)
circuit.i(1)
# 第2ビットにXゲート
circuit.x(2)
# 観測
meas = QuantumCircuit(3, 3)
meas.measure([0,1,2], [0,1,2])
# execute the quantum circuit
backend = BasicAer.get_backend('qasm_simulator') # the device to run on
circ = circuit + meas
result = execute(circ, backend, shots=1000).result()
counts = result.get_counts(circ)
#結果を出力
print(counts)
AmazonBraketでは以下の通りになります。
# general imports
import matplotlib.pyplot as plt
%matplotlib inline
# AWS imports: Import Braket SDK modules
from braket.circuits import Circuit
from braket.devices import LocalSimulator
# 第0ビットと第1ビットに恒等変換、第2ビットにXゲート
circuit = Circuit().i(0).i(1).x(2)
device = LocalSimulator()
# run circuit
result = device.run(circuit, shots=1000).result()
# get measurement shots
counts = result.measurement_counts
# 結果を出力
print(counts)
それぞれ同じことを意味するコーディングをしていますが、
結果を見てみると以下の通りになります。
Qiskit | AmazonBraket |
---|---|
{'100': 1000} | {'001': 1000} |
上記を見ると真反対、つまり、
- Qiskitの最上位ビット(Most Significant Bit - MSB)は左
- AmazonBraketの最上位ビット(Most Significant Bit - MSB)は右
ということがわかったかと思います。
(ちなみにQiskitは量子ビットと古典ビットの対応は自分で変えることができるのであくまで標準的な考え方という位置づけになるかと思います。)
制御ゲートとの対応
別記事にまとめていますが、2量子系の制御ゲートでは制御量子ビットを0量子ビット目か1量子ビット目に定め、制御量子ビットが$1$だった時にもう片方のユニタリ変換を行うという操作を行います。
具体的に言うと、
- Qiskitの最上位ビット(Most Significant Bit - MSB)は左
の場合、
- 0量子ビット目を制御ビットにすると以下の$\bf{\color{red}{赤色}}$で示した要素が制御ビットとして作用します。
- 1量子ビット目を制御ビットにすると以下の$\bf{\color{blue}{青色}}$で示した要素が制御ビットとして作用します。
\begin{pmatrix} |{00}\rangle \\ |{0\color{red}1}\rangle \\ |{10}\rangle \\ |{1\color{red}1}\rangle \end{pmatrix},
\begin{pmatrix} |{00}\rangle \\ |{01}\rangle \\ |{\color{blue}10}\rangle \\ |{\color{blue}11}\rangle \end{pmatrix}.
一方で、
- AmazonBraketの最上位ビット(Most Significant Bit - MSB)は右
の場合、
- 0量子ビット目を制御ビットにすると以下の$\bf{\color{blue}{青色}}$で示した要素が制御ビットとして作用します。
- 1量子ビット目を制御ビットにすると以下の$\bf{\color{red}{赤色}}$で示した要素が制御ビットとして作用します。
\begin{pmatrix} |{00}\rangle \\ |{01}\rangle \\ |{\color{blue}10}\rangle \\ |{\color{blue}11}\rangle \end{pmatrix},
\begin{pmatrix} |{00}\rangle \\ |{0\color{red}1}\rangle \\ |{10}\rangle \\ |{1\color{red}1}\rangle \end{pmatrix}.
上記を見てみると、2量子系の世界ではQiskitとAmazonBraketは対になる関係なので
制御ゲートを考える際もQiskitかAmazonBraketのどちらか一つに関して制御ビットを0量子ビット目にするか、1量子ビット目にするかだけを考えるだけで
QiskitもしくはAmazonBraketのもう片方の制御ゲートも示すことができます。
そのため、制御ビットと制御ゲートの考え方の記事ではQiskitの0量子ビット目が制御ビットの場合と1量子ビット目が制御ビットの場合で制御ゲートがどう変わるのかを見ていこうかと思います。
(ちなみに話がややこしくなるので触れませんが、3量子系以上では量子ビットをどちらから見るか。そして制御ビットをどちらにするかはとても重要になるので2量子系を扱うときから注意した方が良いです。)
まとめ
今回の記事では、「その量子、右から見るか?左から見るか?」という観点で記事を書かせていただきました。
結果としてはどちらでも良さそうですし、分野によってもツールによっても解釈の仕方が違うことがわかりました。
ただし、計算をする際は多少注目するビットが変わってくるので注意が必要ということもわかったかと思います。
また別記事で本記事を活用した制御ビットと制御ゲートの考え方という旨の記事を出しているのでそちらも見てみてください。