グローバーアルゴリズムをつかった、データベース探索のプログラムを行おうとしています。
問題設定】
左から番号1、2、3...nと名前がついた箱があり、このn個の箱のどれかに、値1があり、それ以外の箱は0を持っています。この1を持つ箱は何番目の箱なのかを探すプログラムをpythonで再現するようにしています。> http://testen.wp.xdomain.jp/2017/06/07/グローバーのアルゴリズム/
量子状態の足し算について困っています。
例として、
|Φ>=Σ|i> (i=1~10)
なる、量子状態Φをどのように計算するのでしょうか?
python
1n=10 2def sigma(function, frm, to): 3 result = 0; 4 for i in range(frm, to+1): 5 result += func(i) 6 print(result) 7#Φの定義 8 phai = sigma(Qubit(i), 1, n)
Qubitは0か1状態でしか、計算できないので、Qubit(i)は間違っているのは自明なのですが、、、
私の考えとして、たとえば、5を2進数で展開すると、bin(5)='0b101'とbが入ってしまい、再びエラーになってしまいます。
それ以前に、Qubitと量子状態の意味を完全に理解していない気もしますが。。
ご鞭撻のほど、よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/08 09:09
2018/03/08 09:43
2018/03/08 09:47
2018/03/08 09:49
回答3件
0
ベストアンサー
ハミルトニアンに対する基底が決まれば、任意の状態はその完全系の線形結合で表現できます。
ですので、基底の数が有限nの場合、任意の状態は一本のn次元のベクトルで表現できます。
また、任意の作用素はnxn次元の行列になります。
そのうち今の選ばれた状態というのが以下のもので、
R
1f1 = rep(0,n) 2f1[sample(1:n,1)]=1
n次元のベクトルを0で初期化して、そのうちどれか一個の要素をランダムで選んで、1にしています。
psi = rep(1,n) / sqrt(n)
は|Φ>=Σ|i> (i=1~10)
ですべての要素が1で初期化して、規格化してノルムを1にしています。
R
1Uf = diag(1,n) - 2 * f1 %*% bra(f1) 2Us = 2 * psi %*% bra(psi) - diag(1,n)
は「グローバー回転の動き」の後の式を、基底で展開して、連立方程式を考えると出てきます。
R
1for(i in 1:itr){ 2 psi = Us %*% Uf %*% psi 3}
この部分でUs,Ufをitr回作用させています。
ψにRを作用させることで、均等な重ね合わせ|ψ⟩から、|f1⟩の確率振幅が強められた状態に移ったことを意味します。
というのを実行しています。
最後に振幅が最大の要素を取り出せば終わりです。
which.max(psi^2)
pythonでnumpyを使って書くと以下になります。
(拡散行列は更新されてはいけないのですね。修正しました。)
python
1import numpy as np 2import matplotlib.pyplot as plt 3 4np.random.seed(1024) 5 6n = 2**3 7itr = 8 8f1 = np.zeros(n) 9r = np.random.randint(n) 10print(r) 11f1[r] = 1 12 13psi = np.ones(n) 14psi /= np.linalg.norm(psi) 15 16def Uf(v): 17 new = np.matmul(np.eye(n), v) - 2 * f1 * np.dot(f1, v) 18 return new / np.linalg.norm(new) 19 20def Us(v): 21 new = 2*np.matmul(np.ones((n,n))/n, v) - np.matmul(np.eye(n), v) 22 return new / np.linalg.norm(new) 23 24for i in range(itr): 25 psi = Us(Uf(psi)) 26 plt.plot(psi*psi, label=i) 27 28plt.yscale('log') 29plt.grid() 30plt.legend() 31plt.show() 32 33print(np.argmax(psi*psi))
sympyで自分で頑張る版。
実際はHadamardGateを使って初期状態を準備しますが、シンボリックで割り算をしてしまって大変なことになるので、無理やり一度実数で割っています。
IdentityGateなので使わなくてもいいのに、無駄に使って計算時間が少し増えています。
python
1import itertools 2from sympy.physics.quantum.qubit import Qubit, measure_all 3from sympy.physics.quantum.dagger import Dagger 4from sympy.physics.quantum.qapply import qapply 5from sympy.physics.quantum.gate import HadamardGate, IdentityGate 6from math import sqrt 7import matplotlib.pyplot as plt 8import functools 9import operator 10 11def prod(iterable): 12 return functools.reduce(operator.mul, iterable, 1) 13 14n = 3 15itr = 8 16 17f_ = [0]*n 18f_[1] = 1 19fa = Qubit(*f_) 20 21basis = [] 22for psi_ in itertools.product([0,1], repeat=n): 23 basis.append(Qubit(*psi_)) 24psi0 = sum(basis)/sqrt(2**n) 25psi = sum(basis)/sqrt(2**n) 26 27Hs = prod([HadamardGate(i) for i in range(n)]) 28Is = prod([IdentityGate(i) for i in range(n)]) 29 30''' 31p_ = [0]*n 32p = Qubit(*p_) 33psi0 = qapply(Hs*p).doit() 34psi = qapply(Hs*p) 35''' 36 37Uf = lambda q: qapply(Is*q - 2*fa*Dagger(fa)*q) 38Us = lambda q: qapply(2*psi0*Dagger(psi0)*q - Is*q) 39 40for i in range(itr): 41 psi = Us(Uf(psi)) 42 y = [v[1] for v in measure_all(psi)] 43 x = [''.join(map(str, v[0].qubit_values)) for v in measure_all(psi)] 44 plt.plot(x, y, marker='.', label=i) 45 print(y) 46 47plt.grid() 48plt.yscale('log') 49plt.legend() 50plt.show()
grover見つけちゃったから答え合わせ版。
操作回数によって逆に振幅が下がるのが気持ち悪いのですが、ライブラリの実装と同じ結果になるので、ビット数が少なくて、操作回数が少ないことが原因だと思い込むことにします。
python
1from sympy.physics.quantum.qapply import qapply 2from sympy.physics.quantum.qubit import IntQubit, Qubit, measure_all 3from sympy.physics.quantum.grover import OracleGate 4from sympy.physics.quantum.grover import superposition_basis 5from sympy.physics.quantum.grover import grover_iteration, apply_grover 6import matplotlib.pyplot as plt 7 8numqubits = 3 9f = lambda qubits: qubits == IntQubit(4) 10v = OracleGate(numqubits, f) 11q = superposition_basis(numqubits) 12for i in range(8): 13 q = qapply(grover_iteration(q, v)) 14 ans = qapply(apply_grover(f, numqubits, iterations=i+1)) 15 y = [v[1] for v in measure_all(q)] 16 x = [''.join(map(str, v[0].qubit_values)) for v in measure_all(q)] 17 plt.plot(x, y, label=i) 18 print(q) 19 print(ans) 20 21plt.legend() 22plt.grid() 23plt.yscale('log') 24plt.show()
投稿2018/03/08 14:39
編集2018/03/08 19:59総合スコア8560
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/08 16:40
2018/03/08 16:57
2018/03/08 17:00
2018/03/09 10:29
0
皆さま、お答えありがとうございます!!
私なりに、チャレンジしてみました。まだ完成ではないのですが、4割~6割ほどの出来だと思います。よろしければ、添削の程をお願い致します。
python
1from sympy.physics.quantum import* 2from sympy.physics.quantum.gate import IdentityGate as I 3from sympy.physics.quantum.qubit import Qubit 4from sympy.physics.quantum.dagger import Dagger 5import math 6import numpy as np 7import random 8from sympy import* 9import sympy 10#準備 11n = 10 12itr = 8 #Grover回転の回数 13f = np.zeros(n) #0が10個の箱を作る 14a = random.randint(0, n-1) #1からnのいずれかの一つを選ぶ 15f[a] = 1 #選んだ箱に1を入れる 16A = '{:04b}'.format(a) #Qubitを使うために、2進数表記 17fa = Qubit(A) #|f1> 18fb = Dagger(fa) 19 20def s(t): 21 p = Qubit('{:04b}'.format(t)) 22 return(1/sympy.sqrt(n))*p 23def w(t): 24 r = Dagger(p) 25 return(1/sympy.sqrt(n))*r 26 27def sigma(function, start, end): 28 result = 0; 29 for i in range(start, end+1): 30 result += function(i) 31 print(result) 32 33Uf = I - 2*fa * fb 34Us = 2*sigma(s,1,n)*sigma(w,1,n) - I 35for i in range(itr): 36 z = Us*Uf*sigma(s,1,n) 37 38#plt.plot(n, z^2) 39#plt.show() 40print(z)
投稿2018/03/08 16:43
総合スコア124
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/08 17:01
2018/03/09 10:18 編集
2018/03/09 10:46
2018/03/09 15:12 編集
2018/03/09 15:34
0
質問の内容も理解できない全くの門外漢ですがQuantum Mechanicsを使うとなんとなくそれっぽい結果が得られました。
結果の意味も分かっていませんが。
参考:SymPy で量子プログラミングを体験してみましょう
Python
1from sympy.physics.quantum.qubit import Qubit 2ret = None 3for i in range(10): # 1(0000)から10(1010) 4 s = '{:04b}'.format(i+1) # '0101'など 5 q = Qubit(s) 6 print(q) 7 if ret is None: 8 ret = q 9 else: 10 ret += q 11print(ret) 12# |0001> + |0010> + |0011> + |0100> + |0101> + |0110> + |0111> + |1000> + |1001> + |1010>
投稿2018/03/08 09:25
総合スコア38266
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/08 09:46
2018/03/08 09:51
2018/03/08 09:51
2018/03/08 09:55
2018/03/08 09:59
2018/03/08 10:05
2018/03/08 10:08
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。