LoginSignup
8
3

More than 5 years have passed since last update.

Python QulacsでToffoliゲートを作成してみた

Posted at

はじめに

量子プログラムを書いてみようと思います。
京都大学・QunaSys社のオープンソースライブラリのQulacsを使って、練習と勉強がてらToffoliゲートをPythonで実装してみました。
Qulacsについては
PythonフレームワークのQulacsで量子コンピュータに触れてみる
にも記事があるので、参考にしてください。

Toffoliゲート

量子回路上で$|x,y,z\rangle\mapsto |x,y,x\wedge y \oplus z\rangle~(x,y,z=0,1)$を実現します。
したがって$z=0$とすれば、3番目の量子ビットの状態を観測することにより、1,2番目の量子状態のANDが得られるので、それを見てみます。
実装ですが、適当にググって出てきた
Realization of the quantum Toffoli gate
のp.5にToffoliを実現する回路図がありますが、面倒くさいので今回はToffoliゲートを表すユニタリー変換を実装します。
表現行列は以下になります:

\begin{pmatrix}
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 & 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 
\end{pmatrix}

コード

Qulacs公式リファレンス見ながら書いてみます。
まず、必要なモジュールをインポートします。

from qulacs import QuantumState
from qulacs import QuantumCircuit
from qulacs import Observable
from qulacs.gate import DenseMatrix

Toffoliゲートは3量子ビットの回路なので、その設定と入力状態を設定します。
この例では$|110\rangle$を入力します。
したがって、出力は量子ビット3を観測するので、$|1\rangle$となるはずです。

# 量子ビット数3(0,1,2の3つ)
n = 3
state = QuantumState(n)
# 入力状態は|110>
state.set_computational_basis(0b110)

回路にToffoliゲートを追加。

toffoli = [
    [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, 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]
]
gate = DenseMatrix([0, 1, 2], toffoli)
circuit.add_gate(gate)

量子状態を更新します。

circuit.update_quantum_state(state)

観測のため、オブザーバブルを設定します。
$Z$方向の上下を観測するので、Pauli $Z$で観測します。
ここちょっと謎なんですが、リファレンス読む限り、下記'Z 0'と書いている部分は'Z 2'だと思うのですが、ゲートなし3量子回路で書いてみて確認したら'Z 0'じゃないと想定した動作をしませんでした。これだけ数える順番逆なのかな?

# オブザーバブルの設定
# 量子ビット数3
# n = 3
observable = Observable(n)
# 量子ビット2の上下を観測
# 何故か'Z 2'ではなく'Z 0'
observable.add_operator(1.0, 'Z 0')

最後に結果を表示します。

# 量子ビット2の上下を観測
value = observable.get_expectation_value(state)
# 結果表示
value = (1.0 - value) / 2.0
# 状態ベクトル表記で出力するように細工
print('|' + str(int(value)) + '>')

結果

ちゃんと$|1\rangle$が返ってきました。
他の入力$|x,y,0\rangle$でも$|x\wedge y\rangle$が返ってきました。

まとめ

今回はToffoliゲートをPython Qulacsを使って量子プログラムを実装してみて、ちゃんとANDを返す量子回路を書くことができました。
最後に全体コードです。

# インポート
from qulacs import QuantumState
from qulacs import QuantumCircuit
from qulacs import Observable
from qulacs.gate import DenseMatrix

# 量子状態の設定
# 量子ビット数3(0,1,2の3つ)
n = 3
state = QuantumState(n)
state.set_computational_basis(0b110)

# 入力状態を表示
print('initial state: ' + str(state.get_vector()))

# 回路にToffoliゲート追加
circuit = QuantumCircuit(n)
toffoli = [
    [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, 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]
]
gate = DenseMatrix([0, 1, 2], toffoli)
circuit.add_gate(gate)
circuit.update_quantum_state(state)

# オブザーバブルの設定
# 量子ビット数3
observable = Observable(n)
# 量子ビット2の上下を観測
# 何故か'Z 2'ではなく'Z 0'
observable.add_operator(1.0, 'Z 0')

# 量子ビット2の上下を観測
value = observable.get_expectation_value(state)
# 結果表示
value = (1.0 - value) / 2.0
print('|' + str(int(value)) + '>')
8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3