CNOTゲートの行列表現と量子もつれ

量子ゲートの具体的な行列表現を考えるときに、複数量子ビット状態の場合にテンソル積について考え始めると段々こんがらがってきてしまうので、まとめてみました。特に、CNOTゲートのような他量子ビットに作用するゲートの場合に、どのように行列表現を導出すればよいのか分からず、調べてみても意外と分かりやすい記事が見つからなかったので、備忘録も兼ねています。

$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
\def\ketround#1{\mathinner{\left|{\,#1\,}\right)}}
$$

# 多量子ビット状態の表現

$\ket{0}$と$\ket{1}$が1量子ビット状態の基底になっています。なぜなら$\braket{m}{n} = \delta _{m,n}$でありなおかつ

```math
\sum _{m=0,1} \ket{m} \bra{m} = \hat{I}, 
\quad \ket{0} = \left(
\begin{matrix}
1 \\
0
\end{matrix}
\right), 
\quad \ket{1} = \left(
\begin{matrix}
0 \\
1
\end{matrix}
\right)
```
を満たすからです。多量子ビット状態は、上記ベクトルの直積状態で書けます。例えば2量子ビット状態であれば

```math
\ket{\psi} = \sum _{m=0,1} \sum _{n=0,1} \alpha _{m,n} \ket{m} \otimes \ket{n}, 
\quad

\sum _{m=0,1} \sum _{n=0,1} \left| \alpha _{m,n} \right| ^{2} = 1
```
です。具体的にテンソル積を計算してあげると例えば、

```math
\ket{0} \otimes \ket{0} = \left(
\begin{matrix}
1 \otimes \left( \begin{matrix} 1 \\ 0 \end{matrix} \right) \\
0 \otimes \left( \begin{matrix} 1 \\ 0 \end{matrix} \right) 
\end{matrix}
\right) = \left(
\begin{matrix}
1 \\
0 \\
0 \\
0
\end{matrix}
\right)
```
ですね。

# CNOTゲートの行列表現

さて本題なのですが、CNOTゲートはよく以下の4×4行列で表現されています。

```math
CNOT = \left( 
\begin{matrix}
I & O \\
O & X 
\end{matrix}
\right) = \left(
\begin{matrix}
1 & 0 & 0 & 0 \\
0 & 1 & 0 & 0 \\
0 & 0 & 0 & 1 \\
0 & 0 & 1 & 0 \\
\end{matrix}
\right) .  
```

1量子ビット目が制御ビット、2量子ビット目が標的ビットになっている場合ですので、制御ビットと標的ビットが逆であれば行列表現も異なります。

こういった行列表現を眺めていて困るのは、例えば3量子ビットの状態に対する演算を行列で表現しようと思った場合に、CNOTゲートを始めとした2量子以上のビットに作用するゲートをどのように書けばよいのかということです。おそらくこういった計算が得意な方からしてみれば自明すぎて何が疑問なの？というような話だとは思うのですが、私はなかなか理解できずに苦しみました。

2量子ビット状態を考える場合に、作用するゲートが1量子ビットに対する演算（たとえばX, Y, Zゲートやアダマールゲートなど）であれば、深く考えずにテンソル積を計算すれば話は終わります。例えば
1量子ビット目にXゲートを、2量子ビット目にZゲートを作用させる場合、二つの演算を表現する行列は以下のように書けます。インデックスは作用する量子ビットを明示的に表すものです。

```math
X_{1} \otimes Z_{2} = \left(
\begin{matrix}
0 & 1 \\
1 & 0 
\end{matrix}
\right) \otimes  \left(
\begin{matrix}
1 & 0 \\
0 & -1 
\end{matrix}
\right)

= \left(
\begin{matrix}
0 \otimes \left(
\begin{matrix}
1 & 0 \\
0 & -1 
\end{matrix}
\right)  & 1 \otimes \left(
\begin{matrix}
1 & 0 \\
0 & -1 
\end{matrix}
\right)  \\
1 \otimes \left(
\begin{matrix}
1 & 0 \\
0 & -1 
\end{matrix}
\right) & 0 \otimes \left(
\begin{matrix}
1 & 0 \\
0 & -1 
\end{matrix}
\right)  
\end{matrix}
\right) 
= \otimes \left(
\begin{matrix}
0 & 0 & 1 & 0 \\
0 & 0 & 0 & -1 \\
1 & 0 & 0 & 0 \\
0 & -1 & 0 & 0 \\
\end{matrix}
\right) . 
```

ところが、CNOTゲートを始めとした多量子ビットに作用するゲートについて考えようとした場合に、表現に困ります。例えば3量子ビットの量子回路について、1量子ビット目を制御ビット、3量子ビット目を標的ビットにした場合に、どのように行列を書いてあげればよいのでしょうか？結論から言いますと、ベースになるのは1量子ビットに作用する2×2の行列のテンソル積です。しかしここで注意しなければならないのは、CNOTゲートは量子もつれを生み出すゲートであり、それはすなわち1量子ビットに作用するゲートの直積では表現できない、ということです。この点に考えが至らなかった結果、私の場合は悩んでいたようです。

具体的に考えてみます。2量子ビットに話を戻して、1量子ビット目を制御ビット、2量子ビット目を標的ビットとするCNOTゲート $CNOT(1,2)$は、すなわち以下のように分解することができます。

```math
CNOT(1,2) = \left(
\begin{matrix}
I & O \\
O & X 
\end{matrix}
\right) = \left(
\begin{matrix}
I & O \\
O & O 
\end{matrix}
\right) + \left(
\begin{matrix}
O & O \\
O & X 
\end{matrix}
\right)

= \left(
\begin{matrix}
1 & 0 \\
0 & 0 
\end{matrix}
\right) \otimes I + \left(
\begin{matrix}
0 & 0 \\
0 & 1 
\end{matrix}
\right) \otimes X 
= \ket{0}\bra{0} \otimes I + \ket{1}\bra{1} \otimes X. 
```

制御ビットが0であれば何もしない（＝恒等演算子）、1であれば標的ビットにXゲートが作用するという話とも一貫性がありますね。これを適用してあげれば、3量子ビット以上の状態に対しても簡単に行列表現を導出することができます。

## 3量子ビット状態のCNOTゲート

具体的に1量子ビット目を制御ビット、3量子ビット目を標的とします。2量子ビット目には何もしないので、恒等演算子だけが作用することになります。上で書いたテンソル積で表現すれば、

```math
CNOT(1,3) = 
\ket{0} \bra{0} \otimes I \otimes I + \ket{1}\bra{1} \otimes I \otimes X
```

です。あとは素直にテンソル積を計算するだけなので、計算すると以下のようになります。

```math
CNOT(1,3) = 
\left(
\begin{matrix}
1 & 0 \\
0 & 0 
\end{matrix}
\right)
 
\otimes 

\left(
\begin{matrix}
1 & 0 \\
0 & 1
\end{matrix}
\right)

\otimes 

\left(
\begin{matrix}
1 & 0 \\
0 & 1 
\end{matrix}
\right)

+ \left(
\begin{matrix}
0 & 0 \\
0 & 1 
\end{matrix}
\right)

\otimes 

\left(
\begin{matrix}
1 & 0 \\
0 & 1 
\end{matrix}
\right)

\otimes 

\left(
\begin{matrix}
0 & 1 \\
1 & 0 
\end{matrix}
\right)

= \left(
\begin{matrix}
1 & 0 \\
0 & 0 
\end{matrix}
\right)

\otimes 
\left(
\begin{matrix}
1 & 0 & 0 & 0\\
0 & 1 & 0 & 0\\
0 & 0 & 1 & 0\\
0 & 0 & 0 & 1
\end{matrix}
\right)

+ \left(
\begin{matrix}
0 & 0 \\
0 & 1 
\end{matrix}
\right)

\otimes 
\left(
\begin{matrix}
0 & 1 & 0 & 0\\
1 & 0 & 0 & 0\\
0 & 0 & 0 & 1\\
0 & 0 & 1 & 0
\end{matrix}
\right)

= \left(
\begin{matrix}
1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\
0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\
0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 
\end{matrix}
\right). 

```

---

他量子ビットに作用するゲートの行列表現について、特にCNOTの表現についてまとめてみました。CNOTゲートがもつれ状態を作り出すゲートであることと、もつれ状態は直積状態で表現できないことを考慮すれば、1量子ゲートの直積では表現できないことが分かり、そこから直積状態の線形和を取ることが推測されます。

量子ゲートについてはIBM Qの実機や各種シミュレータがあるため、上記のような演算を自分でする必要はないかもしれませんが、どのように計算しているのか知っておくことに損はないかなと考えています。