めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

量子計算(量子回路)の考え方を理解するために最低限必要な量子力学の知識を(それなりに納得感のある形で)うまいこと導入する方法について考えてみた(その5)

何の話かというと

enakai00.hatenablog.com

の続編です。前回、2量子ビットの状態は、

 {\mid 00\rangle}:確率 1 で (z_0,\,z_1) = (+1,\,+1) が得られる状態
 {\mid 01\rangle}:確率 1 で (z_0,\,z_1) = (+1,\,-1) が得られる状態
 {\mid 10\rangle}:確率 1 で (z_0,\,z_1) = (-1,\,+1) が得られる状態
 {\mid 11\rangle}:確率 1 で (z_0,\,z_1) = (-1,\,-1) が得られる状態

  {\mid 00\rangle} = \begin{pmatrix}1 \\  0 \\ 0 \\ 0\end{pmatrix},\ {\mid 01\rangle} = \begin{pmatrix}0 \\  1 \\ 0 \\ 0\end{pmatrix},\ {\mid 10\rangle} = \begin{pmatrix}0 \\  0 \\ 1 \\ 0\end{pmatrix},\ {\mid 11\rangle} = \begin{pmatrix}0 \\  0 \\ 0 \\ 1\end{pmatrix}

を基底ベクトルとする4次元の複素ベクトルで表されることを説明しました。一般の状態は、下記のように表されます。

 {\mid\psi\rangle} = c_{00} {\mid 00\rangle} + c_{10} {\mid 01\rangle} + c_{01} {\mid 10\rangle} +c_{11} {\mid 11\rangle}

また、量子ビットに対する操作は、4\times 4 のユニタリ行列で表されることも説明して、ちょっと興味深い例として、次の Controlled-NOT 演算の行列を紹介しました。

  U = \begin{pmatrix}
1 & 0 & 0 & 0 \\
0 & 1 & 0 & 0 \\
0 & 0 & 0 & 1 \\
0& 0 & 1 & 0 
\end{pmatrix}

この後は、実際の量子計算機で用いられる具体的な演算操作(ゲート)を学んでいけばよいのですが、個々の演算操作を行列の代わりにブラケット記号で表記するという方法があります。実際に回路の計算をする際は、ブラケット記号の方が便利なことも多いので、ここでは、ブラケット記号による演算の手続きを説明しておきます。

ブラケット記号による演算

以前に説明しましたが、ケット記号は、次のように縦ベクトルを表す記号です。

 {\mid\psi\rangle} = \begin{pmatrix}c_{00} \\ c_{01} \\ c_{10} \\ c_{11} \end{pmatrix}

一方、これを転置して複素共役をとったものは、ブラ記号で表されます。

 {\langle\psi\mid} = \begin{pmatrix}c^*_{00} & c^*_{01} & c^*_{10} & c^*_{11}\end{pmatrix}

すると、2つのベクトル

 {\mid\psi_1\rangle} = \begin{pmatrix}c_{00} \\ c_{01} \\ c_{10} \\ c_{11} \end{pmatrix}
,\ {\mid\psi_2\rangle} = \begin{pmatrix}d_{00} \\ d_{01} \\ d_{10} \\ d_{11} \end{pmatrix}

の内積は、次のようにブラ記号とケット記号を組み合わせて表記することができます。

 {\langle\psi_1\mid\psi_2\rangle} = \begin{pmatrix}c^*_{00} & c^*_{01} & c^*_{10} & c^*_{11}\end{pmatrix}\begin{pmatrix}d_{00} \\ d_{01} \\ d_{10} \\ d_{11} \end{pmatrix} = c^*_{00}d_{00} +c^*_{01}d_{01} +c^*_{10}d_{10} +c^*_{11}d_{11}

なお、複素ベクトルの内積は、上記のように一方の成分について複素共役を取る約束になっています。

ここまでは、単なる記法の話なのですが、ここで、一度、1量子ビットの場合に話を戻して、

 {\mid 0\rangle} = \begin{pmatrix} 1 \\ 0 \end{pmatrix},\ {\mid 1\rangle} = \begin{pmatrix} 0 \\ 1 \end{pmatrix}

と置いた上で、次の演算子を考えます。

 U = {\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid} --- (1)

これは一体何者?と思うかもしれませんが、素直にこのままの形で、一般の状態

 {\mid\psi\rangle} = c_0{\mid 0\rangle}+c_1{\mid 1\rangle}

に左から掛けてみましょう。

 U{\mid\psi\rangle} = \left({\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid}\right){\mid\psi\rangle}
 
    ={\mid 1\rangle}{\langle 0\mid\psi\rangle} + {\mid 0\rangle}{\langle 1\mid\psi\rangle}

ここで、{\mid 0\rangle}{\mid 1\rangle} が正規直交系であることから、内積  {\langle 0\mid\psi\rangle} および  {\langle 1\mid\psi\rangle} は、次のように計算されます。

  {\langle 0\mid\psi\rangle} = c_0{\langle 0\mid 0\rangle} + c_1{\langle 0\mid 1\rangle} = c_0

  {\langle 1\mid\psi\rangle} = c_0{\langle 1\mid 0\rangle} + c_1{\langle 1\mid 1\rangle} = c_1

この結果を代入すると、次が得られます。

 U{\mid\psi\rangle} = c_0{\mid 1\rangle} + c_1{\mid 0\rangle}

この結果を見ると、これは、スピンの上下を反転するフリップ演算になっていることがわかります。つまり、(1) の演算子は、パウリ行列 \sigma_x と同じ効果を持っており、計算上は、\sigma_x と同一視することができるのです。

少し違う例として、

 \Pi_0 = {\mid 0 \rangle}{\langle 0\mid}

という演算子はどうでしょうか? これは、一般の状態に演算すると次の結果が得られます。

 \Pi_0{\mid\psi\rangle} = {\mid 0 \rangle}{\langle 0\mid}(c_0{\mid 0\rangle}+c_1{\mid 1\rangle}) = c_0{\mid 0\rangle}

つまり、これは、{\mid 0 \rangle} 成分だけを取り出す射影演算子になっており、行列で表すならば、次のようになります。

 \Pi_0 = \begin{pmatrix} 1 & 0 \\ 0 & 0\end{pmatrix}

※ これはユニタリ行列ではないため、実際のスピンに対してこのような変化を起こすことはできません。演算後の状態は、全確率が1という束縛条件を満たさない点に注意してください。

また、「何もしない」恒等演算、行列で言うと単位行列にあたる演算子は、次になります。

  1 = {\mid 0 \rangle}{\langle 0\mid} + {\mid 1 \rangle}{\langle 1\mid}

これが実際に何もしないことは、これまどと同じ直接計算でもわかりますし、あるいは、次のように行列に置き換えて確認することもできます。

  {\mid 0 \rangle}{\langle 0\mid} + {\mid 1 \rangle}{\langle 1\mid} = \begin{pmatrix} 1 & 0 \\ 0 & 0\end{pmatrix} + \begin{pmatrix} 0 & 0 \\ 0 & 1\end{pmatrix} =  \begin{pmatrix} 1 & 0 \\ 0 & 1\end{pmatrix}

このようにして、1量子ビットの状態ベクトルに対する線形演算、すなわち、任意の 2\times 2 行列は、すべて、ケット記号とブラ記号の組み合わせに置き換えることができます。ブラケット記号を用いることで、その演算による状態変換の内容が少し見やすくなることがわかるでしょう。複数の演算を続けて行う処理、すなわち、2つの行列を連続して掛けるという計算もまた、ブラケット記号に置き換えて実行することが可能です。例として、フリップ演算の後に射影演算子をほどこしたものは、次のようになります。

 \Pi_0 \sigma_x = {\mid 0 \rangle}{\langle 0\mid}({\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid})
= {\mid 0 \rangle}{\langle 0\mid 1\rangle}{\langle 0\mid} + {\mid 0 \rangle}{\langle 0\mid 0\rangle}{\langle 1\mid} = {\mid 0 \rangle}{\langle 1\mid}

ブラとケットがくっついてブラケットになると、その部分が内積の値に置き換わるという、一般的なルールが読み取れると思います。

テンソル積による2量子ビットへの拡張

1量子ビットの場合と同様に、2量子ビットの場合においてもブラケット記号で任意の線形演算を表すことが可能です。1量子ビットの場合を素直に拡張するならば、

  {\mid 00\rangle},\ {\mid 01\rangle},\ {\mid 10\rangle},\ {\mid 11\rangle}

という4種類の記号を組み合わせることになります。たとえば、Controlled-NOT 演算子 C_X は、次のように表すことができるでしょう。

 C_X = {\mid 00\rangle}{\langle 00\mid} +  {\mid 01\rangle}{\langle 01\mid} +  {\mid 11\rangle}{\langle 10\mid} +  {\mid 10\rangle}{\langle 11\mid}

あるいは、両方の量子ビットを同時にフリップする演算子 U は、次になります。

 U = {\mid 11\rangle}{\langle 00\mid} +  {\mid 10\rangle}{\langle 01\mid} +  {\mid 01\rangle}{\langle 10\mid} +  {\mid 00\rangle}{\langle 11\mid} --- (2)

これはこれで正しい記法なのですが、ちょっとだけ記法を変えて、前述の4種類の基底ベクトルを次のように表記することがあります。\otimes は「テンソル積」と呼ばれる記号です(別名、ヘソマーク)。

  {\mid 0\rangle}\otimes{\mid 0\rangle}, {\mid 0\rangle}\otimes{\mid 1\rangle}, {\mid 1\rangle}\otimes{\mid 0\rangle}, {\mid 1\rangle}\otimes{\mid 1\rangle}

この記法を用いると、1つ目の量子ビットに対する演算と2つ目の量子ビットに対する演算を分離して記述することができます。たとえば、 U_1\otimes U_2 という演算子は、U_1 を1つ目の量子ビットに演算して、U_2 を2つ目の量子ビットに演算する、という操作になります。具体例をあげると、1量子ビットに対する演算子

 \sigma_x = {\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid}

は、量子ビットをフリップする効果がありました。この時、

 \sigma_x \otimes \sigma_x= ({\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid})\otimes({\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid})

という演算子は、2量子ビットの状態について、それぞれの量子ビットをフリップするという処理になります。一般の状態

 {\mid\psi\rangle} = c_{00}{\mid 0\rangle}\otimes{\mid 0\rangle}+c_{01}{\mid 0\rangle}\otimes{\mid 1\rangle}+c_{10}{\mid 1\rangle}\otimes{\mid 0\rangle}+c_{11}{\mid 1\rangle}\otimes{\mid 1\rangle}

に対して演算すると、次のように計算が進みます。

 (\sigma_x \otimes \sigma_x){\mid\psi\rangle} =(\sigma_x \otimes \sigma_x)(c_{00}{\mid 0\rangle}\otimes{\mid 0\rangle}+c_{01}{\mid 0\rangle}\otimes{\mid 1\rangle}+c_{10}{\mid 1\rangle}\otimes{\mid 0\rangle}+c_{11}{\mid 1\rangle}\otimes{\mid 1\rangle})
   =c_{00}{\sigma_x\mid 0\rangle}\otimes\sigma_x{\mid 0\rangle}+c_{01}\sigma_x{\mid 0\rangle}\otimes\sigma_x{\mid 1\rangle}+c_{10}\sigma_x{\mid 1\rangle}\otimes\sigma_x{\mid 0\rangle}+c_{11}\sigma_x{\mid 1\rangle}\otimes\sigma_x{\mid 1\rangle}
   =c_{00}{\mid 1\rangle}\otimes{\mid 1\rangle}+c_{01}{\mid 1\rangle}\otimes{\mid 0\rangle}+c_{10}{\mid 0\rangle}\otimes{\mid 1\rangle}+c_{11}{\mid 0\rangle}\otimes{\mid 0\rangle}

最後の計算結果からテンソル積記号を取り除くと、(2) の演算と同じ結果になることが自明にわかりますが、実は、\sigma_x\otimes\sigma_x という演算子の段階でテンソル積を展開することも可能です。具体的には、次のような計算となります。

 \sigma_x \otimes \sigma_x = ({\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid})\otimes({\mid 1\rangle}{\langle 0\mid} + {\mid 0\rangle}{\langle 1\mid})
   = ({\mid 1\rangle}{\langle 0\mid})\otimes({\mid 1\rangle}{\langle 0\mid})+ ({\mid 1\rangle}{\langle 0\mid})\otimes({\mid 0\rangle}{\langle 1\mid})+ ({\mid 0\rangle}{\langle 1\mid})\otimes({\mid 1\rangle}{\langle 0\mid})+ ({\mid 0\rangle}{\langle 1\mid})\otimes({\mid 0\rangle}{\langle 1\mid})
   = ({\mid 1\rangle}\otimes{\mid 1\rangle})({\langle 0\mid}\otimes{\langle 0\mid})+
({\mid 1\rangle}\otimes{\mid 0\rangle})({\langle 0\mid}\otimes{\langle 1\mid})+
({\mid 0\rangle}\otimes{\mid 1\rangle})({\langle 1\mid}\otimes{\langle 0\mid})+
({\mid 0\rangle}\otimes{\mid 0\rangle})({\langle 1\mid}\otimes{\langle 1\mid})

なんだか目がちらちらしますが、この最後の行からテンソル積記号を取り除けば、(2) と同じものになっていることがわかります。

このように、テンソル積を用いると、自分の意図した操作を的確に演算子で表すことが可能になります。テンソル積をすべて展開すれば、4\times 4 行列で記述しなおす事も可能ですが、上記のようにブラケット形式のままで、「演算の意味」を考えながら計算を進める方が都合のよいこともあります。(一方、行列形式にすれば、何も考えずに機械的な操作だけで進められるというメリットもあるのですが。。。。とは言え、3量子ビット以上になると、行列のサイズが巨大になるので、行列による表記は現実的ではなくなります。)

それではここで練習問題です。

Controlled-NOT をブラケット形式で、テンソル積を用いて表すとどうなるでしょうか?

そしていきなりですが、答えはこちらです。

  C_X = {\mid 0 \rangle}{\langle 0\mid}\otimes 1 + {\mid 1\rangle}{\langle 1\mid}\otimes \sigma_x

ここで、

  1 =  {\mid 0 \rangle}{\langle 0\mid}+ {\mid 1 \rangle}{\langle 1\mid}

は、何もしない恒等演算子で、

  \sigma_x = {\mid 0\rangle}{\langle 0\mid}+ {\mid 0 \rangle}{\langle 1\mid}

は、スピンをフリップする演算子です。

これにより、1つ目の量子ビットが {\mid 0\rangle}{\mid 1\rangle} によって、2つ目の量子ビットに対する演算子がうまく選択されていることがおわかりいただけるでしょうか。

次回予告

なんだかこれで、量子力学に関連する基礎はおさえられた気がします。(もっと深くやるなら POVM やらも説明したくなることろですが。。。そこはもはや量子力学というよりは、量子計算の範疇ですね。)

次回は最後のまとめとして、量子回路の読み方を説明したいと思います。