Python
sympy
量子コンピュータ
量子ゲート

sympy でグローバーアルゴリズム(量子ゲート計算)

グローバーアルゴリズムとは、|0>,|1>,|2>,....|N> の線形重ね合わせから、任意の状態 |a> の確率振幅を増幅して、できるだけ 1に近づけるアルゴリズムである。

sympy でお手軽グローバー

sympy ではライブラリ化されているので使うのはめっちゃ簡単。3-qubitの系で、|7>を取り出したいな。|7> = |111> の観測確率は、その他の状態の 121 倍に増幅されている。

>>> from sympy.physics.quantum.qubit import IntQubit, measure_all
>>> from sympy.physics.quantum.qapply import qapply
>>> from sympy.physics.quantum.grover import apply_grover

>>> isKet7 = lambda state: state == IntQubit(7)
>>> measure_all(qapply(apply_grover(isKet7, 3)))
[(|000>, 1/128), (|001>, 1/128), (|010>, 1/128), (|011>, 1/128), (|100>, 1/128), (|101>, 1/128), (|110>, 1/128), (|111>, 121/128)]

sympy でもう少し踏み込んでグローバー

以上で終わりなのだが、これだけだとあまりにもつまらないので、もう少し手作り感をだそう。|7> = |111> に対応するオラクルは、OracleGateが対応する。行列表示をすれば一目瞭然に |7> だけがフェーズシフトされる様子がわかる。

>>> from sympy.physics.quantum.grover import OracleGate
>>> from sympy.physics.quantum.represent import represent

>>> ora = OracleGate(3, isKet7)
>>> represent(ora)
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, 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]])

オラクルの後は、Inversion about mean という操作をする。これは sympy では WGate と呼ばれている。よってグローバーオペレータGを定義できる。G を 1回、2回かけた際にどのように確率振幅がどのようになるかを見よう。

mygrover.py
from sympy.physics.quantum.qapply import qapply
from sympy.physics.quantum.dagger import Dagger
from sympy.physics.quantum.grover import apply_grover, OracleGate, WGate, superposition_basis
from sympy.physics.quantum.qubit import Qubit, IntQubit, measure_all
from sympy.physics.quantum.gate import I, X, Z, H, CNOT, CGate

G = WGate(3) * OracleGate(3, lambda state: state == IntQubit(7))
print(measure_all(qapply(G*superposition_basis(3))))
print(measure_all(qapply(G*G*superposition_basis(3))))

結果は以下の通り、2回 Gをかけた結果が、前述のapply_grover の結果と一致している。

[(|000>, 1/32), (|001>, 1/32), (|010>, 1/32), (|011>, 1/32), (|100>, 1/32), (|101>, 1/32), (|110>, 1/32), (|111>, 25/32)]
[(|000>, 1/128), (|001>, 1/128), (|010>, 1/128), (|011>, 1/128), (|100>, 1/128), (|101>, 1/128), (|110>, 1/128), (|111>, 121/128)]

sympy で完全手作りグローバー

さて、私たちは具体的にこのオラクルの具体的な実現方式を知っている(CGate((0,1,2),X(3)) 末尾の参考文献参照)。それと比べてみよう。インプットとして 3-qubit, オラクルビットとして 1bit の計 4-qubit の系が必要。

mygrover.py
from sympy.physics.quantum.qapply import qapply
from sympy.physics.quantum.dagger import Dagger
from sympy.physics.quantum.grover import apply_grover, OracleGate
from sympy.physics.quantum.qubit import Qubit, IntQubit
from sympy.physics.quantum.gate import I, X, Z, H, CNOT, CGate

myora = CGate((0,1,2),X(3))

for state in range(8):
    inputState = qapply(H(3) * IntQubit(8+state))
    applied = qapply(myora * inputState)
    print (qapply(Dagger(inputState) * applied))

出力。確かに、 |7> の時だけフェーズシフトされていることがわかる。よってこのように構成した量子ゲートは上述のオラクルと対応付けることができる。つまり、我々の構成した 4-qubit の量子ゲートは、以降の全ての処理では、オラクルキュービットを無視するので、3-qubit の前述のオラクルで代替可能である。以降 3-qubit系で議論を進める。

1
1
1
1
1
1
1
-1

Wゲートに関してもその具体的な構成方法がわかっているので、グローバーオペレータを定義できる。

from sympy.physics.quantum.qapply import qapply
from sympy.physics.quantum.dagger import Dagger
from sympy.physics.quantum.grover import OracleGate, superposition_basis
from sympy.physics.quantum.qubit import Qubit, IntQubit, measure_all
from sympy.physics.quantum.gate import I, X, Z, H, CNOT, CGate

ora = OracleGate(3, lambda state: state == IntQubit(7))
W = X(0) * X(1) * X(2) * CGate((0,1),Z(2)) * X(0) * X(1) * X(2)
myG = H(0) * H(1) * H(2) * W * H(0) * H(1) * H(2) * ora

state1 = qapply(myG*superposition_basis(3))
print(measure_all(state1))
state2 = qapply(myG*state1)
print(measure_all(state2))

結果は以下のようになる。ばっちりOK。

[(|000>, 1/32), (|001>, 1/32), (|010>, 1/32), (|011>, 1/32), (|100>, 1/32), (|101>, 1/32), (|110>, 1/32), (|111>, 25/32)]
[(|000>, 1/128), (|001>, 1/128), (|010>, 1/128), (|011>, 1/128), (|100>, 1/128), (|101>, 1/128), (|110>, 1/128), (|111>, 121/128)]

だれか sympy で次元の圧縮のやり方を知っている人がいればおしえてほすい

参考: https://www.appi.keio.ac.jp/Itoh_group/abe/pdf/qc4.pdf