The new Qiskit Textbook beta is now available. Try it out now

## 1. Exploring the CNOT-Gate

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

しかし、2番目の量子ビットも重ね合わせの状態にするとどうなるでしょうか？

from qiskit import QuantumCircuit, Aer, assemble
from math import pi
import numpy as np
from qiskit.visualization import plot_bloch_multivector, plot_histogram, array_to_latex

qc = QuantumCircuit(2)
qc.h(0)
qc.h(1)
qc.cx(0,1)
qc.draw()


$$|{+}{+}\rangle = \tfrac{1}{2}(|00\rangle + |01\rangle + |10\rangle + |11\rangle)$$

CNOTは$|01\rangle$と$|11\rangle$の振幅をスワップするため、結果に変わりが無いことが分かります：

qc = QuantumCircuit(2)
qc.h(0)
qc.h(1)
qc.cx(0,1)
display(qc.draw())  # display is a command for Jupyter notebooks
# similar to print, but for rich content

# 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()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
plot_bloch_multivector(final_state)

$$\text{Statevector} = \begin{bmatrix} \tfrac{1}{2} & \tfrac{1}{2} & \tfrac{1}{2} & \tfrac{1}{2} \\ \end{bmatrix}$$

qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
qc.h(1)
qc.draw()


この状態はこちらです：

$$|{-}{+}\rangle = \tfrac{1}{2}(|00\rangle + |01\rangle - |10\rangle - |11\rangle)$$
qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
qc.h(1)
display(qc.draw())
# See the result
qc1 = qc.copy()
qc1.save_statevector()
final_state = svsim.run(qc1).result().get_statevector()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
plot_bloch_multivector(final_state)

$$\text{Statevector} = \begin{bmatrix} \tfrac{1}{2} & \tfrac{1}{2} & -\tfrac{1}{2} & -\tfrac{1}{2} \\ \end{bmatrix}$$

CNOTをこの状態に作用させる場合、$|01\rangle$ と $|11\rangle$ の振幅がスワップされて、次の状態になります：

\begin{aligned} \text{CNOT}|{-}{+}\rangle & = \tfrac{1}{2}(|00\rangle - |01\rangle - |10\rangle + |11\rangle) \\ \text{CNOT}|{-}{+}\rangle & = |{-}{-}\rangle \end{aligned}

これは興味深いものです。なぜなら、標的量子ビットの状態を変更せずに、制御量子ビットの状態に影響を与えるからです。

qc.cx(0,1)
display(qc.draw())

qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
plot_bloch_multivector(final_state)

$$\text{Statevector} = \begin{bmatrix} \tfrac{1}{2} & -\tfrac{1}{2} & -\tfrac{1}{2} & \tfrac{1}{2} \\ \end{bmatrix}$$

Hゲートが$|{+}\rangle \rightarrow |0\rangle$ と $|{-}\rangle \rightarrow |1\rangle$ の変換をすることを覚えていたら、CNOTをHゲートでラップすると、向きが反対のCNOTと同じ作用になることが分かると思います。

これは、Qiskitのユニタリーシミュレーターを使って確認できます：

qc = QuantumCircuit(2)
qc.h(0)
qc.h(1)
qc.cx(0,1)
qc.h(0)
qc.h(1)
display(qc.draw())
# display is an IPython tool, remove if it causes an error

qc.save_unitary()
usim = Aer.get_backend('aer_simulator')
qobj = assemble(qc)
unitary = usim.run(qobj).result().get_unitary()
array_to_latex(unitary, prefix="\\text{Circuit = }\n")

$\displaystyle \text{Circuit = } \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ \end{bmatrix} $$qc = QuantumCircuit(2) qc.cx(1,0) display(qc.draw()) qc.save_unitary() qobj = assemble(qc) unitary = usim.run(qobj).result().get_unitary() array_to_latex(unitary, prefix="\\text{Circuit = }\n")  \displaystyle \text{Circuit = } \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ \end{bmatrix}$$$

この等価性は位相キックバックの一例であり、説明は次のセクションに続きます。。。

## 2. 位相キックバック

### 2.1 CNOT回路の等価性の説明

これはキックバック（または位相キックバック）の一例であり、ほとんどすべての量子アルゴリズムで使用されているほど、とても重要です。キックバックは、ゲートによって量子ビットに追加された固有値が、制御操作によって別の量子ビットに「キックバック」されることです。例えば、$|{-}\rangle$ の量子ビットにXゲートを実行すると、位相 $-1$が得られます：

$$X|{-}\rangle = -|{-}\rangle$$

\begin{aligned} \text{CNOT}|{-}0\rangle & = |{-}\rangle \otimes |0\rangle \\ & = |{-}0\rangle \\ \quad & \\ \text{CNOT}|{-}1\rangle & = X|{-}\rangle \otimes |1\rangle \\ & = -|{-}\rangle \otimes |1\rangle \\ & = -|{-}1\rangle \\ \end{aligned}

\begin{aligned} \text{CNOT}|{-}{+}\rangle & = \tfrac{1}{\sqrt{2}}(\text{CNOT}|{-}0\rangle + \text{CNOT}|{-}1\rangle) \\ & = \tfrac{1}{\sqrt{2}}(|{-}0\rangle + X|{-}1\rangle) \\ & = \tfrac{1}{\sqrt{2}}(|{-}0\rangle -|{-}1\rangle) \\ \end{aligned}

これは、2つの分離可能な量子ビット状態として書き込むことができます：

\begin{aligned} \text{CNOT}|{-}{+}\rangle & = |{-}\rangle \otimes \tfrac{1}{\sqrt{2}}(|{0}\rangle - |1\rangle )\\ & = |{-}{-}\rangle \\ \end{aligned}

HゲートでCNOTをラップすると、量子ビットが計算基底から$(|+\rangle, |-\rangle)$ 基底に変換され、この効果がわかります。一部のハードウェアは2つの特定の量子ビット間の一方向のCNOTしか許されないため、この等価性はハードウェアレベルで非常に有益です。この等価性を使ってこのハードウェアの問題を克服し、双方向のCNOTを実現できるようになります。

### 2.2 Tゲートでのキックバック

qc = QuantumCircuit(2)
qc.cp(pi/4, 0, 1)
qc.draw()


Tゲートは、以下の行列です：

$$\text{T} = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\pi/4}\\ \end{bmatrix}$$

そして、制御Tゲートは以下の行列です：

$$\text{Controlled-T} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & e^{i\pi/4}\\ \end{bmatrix}$$

これはQiskitのユニタリーシミュレーターで確認できます：

qc = QuantumCircuit(2)
qc.cp(pi/4, 0, 1)
display(qc.draw())
# See Results:
qc.save_unitary()
qobj = assemble(qc)
unitary = usim.run(qobj).result().get_unitary()
array_to_latex(unitary, prefix="\\text{Controlled-T} = \n")

\displaystyle \text{Controlled-T} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & \tfrac{1}{\sqrt{2}}(1 + i) \\ \end{bmatrix} $$より一般的には、次の規則を使用して、制御Uオペレーションの行列を見つけることができます：$$ \begin{aligned} \text{U} & = \begin{bmatrix} u_{00} & u_{01} \\ u_{10} & u_{11}\\ \end{bmatrix} \\ \quad & \\ \text{Controlled-U} & = \begin{bmatrix} I & 0 \\ 0 & U\\ \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & u_{00} & u_{01} \\ 0 & 0 & u_{10} & u_{11}\\ \end{bmatrix} \end{aligned} $$または、Qiskitの量子ビット配列では：$$ \text{Controlled-U} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & u_{00} & 0 & u_{01} \\ 0 & 0 & 1 & 0 \\ 0 & u_{10} & 0 & u_{11}\\ \end{bmatrix} $$状態 |1\rangle の量子ビットにTゲートを適用すると、この量子ビットに e^{i\pi/4} の位相が追加されます：$$ T|1\rangle = e^{i\pi/4}|1\rangle $$これはグローバル位相であり、観測することはできませんが、|{+}\rangle状態の別の量子ビットを使用してこの操作を制御すると、位相はグローバルではなく相対になり、制御ビットの相対位相が変化します：$$ \begin{aligned} |1{+}\rangle & = |1\rangle \otimes \tfrac{1}{\sqrt{2}}(|0\rangle + |1\rangle) \\ & = \tfrac{1}{\sqrt{2}}(|10\rangle + |11\rangle) \\ & \\ \text{Controlled-T}|1{+}\rangle & = \tfrac{1}{\sqrt{2}}(|10\rangle + e^{i\pi/4}|11\rangle) \\ & \\ & = |1\rangle \otimes \tfrac{1}{\sqrt{2}}(|0\rangle + e^{i\pi/4}|1\rangle) \end{aligned}\$

これは、標的量子ビットを変化させずに、制御量子ビットをブロッホ球のZ軸回りに回転させる作用があります。これをQiskitで見てみましょう：

qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
display(qc.draw())
# See Results:
qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
plot_bloch_multivector(final_state)

qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)