回答編集履歴

2

edit

2018/03/08 19:59

投稿

mkgrei
mkgrei

スコア8560

test CHANGED
@@ -64,6 +64,10 @@
64
64
 
65
65
 
66
66
 
67
+ ---
68
+
69
+
70
+
67
71
  pythonでnumpyを使って書くと以下になります。
68
72
 
69
73
  (拡散行列は更新されてはいけないのですね。修正しました。)
@@ -82,7 +86,7 @@
82
86
 
83
87
 
84
88
 
85
- n = 2**4
89
+ n = 2**3
86
90
 
87
91
  itr = 8
88
92
 
@@ -139,3 +143,181 @@
139
143
  print(np.argmax(psi*psi))
140
144
 
141
145
  ```
146
+
147
+
148
+
149
+ ---
150
+
151
+
152
+
153
+ sympyで自分で頑張る版。
154
+
155
+ 実際はHadamardGateを使って初期状態を準備しますが、シンボリックで割り算をしてしまって大変なことになるので、無理やり一度実数で割っています。
156
+
157
+ IdentityGateなので使わなくてもいいのに、無駄に使って計算時間が少し増えています。
158
+
159
+ ```python
160
+
161
+ import itertools
162
+
163
+ from sympy.physics.quantum.qubit import Qubit, measure_all
164
+
165
+ from sympy.physics.quantum.dagger import Dagger
166
+
167
+ from sympy.physics.quantum.qapply import qapply
168
+
169
+ from sympy.physics.quantum.gate import HadamardGate, IdentityGate
170
+
171
+ from math import sqrt
172
+
173
+ import matplotlib.pyplot as plt
174
+
175
+ import functools
176
+
177
+ import operator
178
+
179
+
180
+
181
+ def prod(iterable):
182
+
183
+ return functools.reduce(operator.mul, iterable, 1)
184
+
185
+
186
+
187
+ n = 3
188
+
189
+ itr = 8
190
+
191
+
192
+
193
+ f_ = [0]*n
194
+
195
+ f_[1] = 1
196
+
197
+ fa = Qubit(*f_)
198
+
199
+
200
+
201
+ basis = []
202
+
203
+ for psi_ in itertools.product([0,1], repeat=n):
204
+
205
+ basis.append(Qubit(*psi_))
206
+
207
+ psi0 = sum(basis)/sqrt(2**n)
208
+
209
+ psi = sum(basis)/sqrt(2**n)
210
+
211
+
212
+
213
+ Hs = prod([HadamardGate(i) for i in range(n)])
214
+
215
+ Is = prod([IdentityGate(i) for i in range(n)])
216
+
217
+
218
+
219
+ '''
220
+
221
+ p_ = [0]*n
222
+
223
+ p = Qubit(*p_)
224
+
225
+ psi0 = qapply(Hs*p).doit()
226
+
227
+ psi = qapply(Hs*p)
228
+
229
+ '''
230
+
231
+
232
+
233
+ Uf = lambda q: qapply(Is*q - 2*fa*Dagger(fa)*q)
234
+
235
+ Us = lambda q: qapply(2*psi0*Dagger(psi0)*q - Is*q)
236
+
237
+
238
+
239
+ for i in range(itr):
240
+
241
+ psi = Us(Uf(psi))
242
+
243
+ y = [v[1] for v in measure_all(psi)]
244
+
245
+ x = [''.join(map(str, v[0].qubit_values)) for v in measure_all(psi)]
246
+
247
+ plt.plot(x, y, marker='.', label=i)
248
+
249
+ print(y)
250
+
251
+
252
+
253
+ plt.grid()
254
+
255
+ plt.yscale('log')
256
+
257
+ plt.legend()
258
+
259
+ plt.show()
260
+
261
+ ```
262
+
263
+
264
+
265
+ ---
266
+
267
+
268
+
269
+ grover見つけちゃったから答え合わせ版。
270
+
271
+ 操作回数によって逆に振幅が下がるのが気持ち悪いのですが、ライブラリの実装と同じ結果になるので、ビット数が少なくて、操作回数が少ないことが原因だと思い込むことにします。
272
+
273
+ ```python
274
+
275
+ from sympy.physics.quantum.qapply import qapply
276
+
277
+ from sympy.physics.quantum.qubit import IntQubit, Qubit, measure_all
278
+
279
+ from sympy.physics.quantum.grover import OracleGate
280
+
281
+ from sympy.physics.quantum.grover import superposition_basis
282
+
283
+ from sympy.physics.quantum.grover import grover_iteration, apply_grover
284
+
285
+ import matplotlib.pyplot as plt
286
+
287
+
288
+
289
+ numqubits = 3
290
+
291
+ f = lambda qubits: qubits == IntQubit(4)
292
+
293
+ v = OracleGate(numqubits, f)
294
+
295
+ q = superposition_basis(numqubits)
296
+
297
+ for i in range(8):
298
+
299
+ q = qapply(grover_iteration(q, v))
300
+
301
+ ans = qapply(apply_grover(f, numqubits, iterations=i+1))
302
+
303
+ y = [v[1] for v in measure_all(q)]
304
+
305
+ x = [''.join(map(str, v[0].qubit_values)) for v in measure_all(q)]
306
+
307
+ plt.plot(x, y, label=i)
308
+
309
+ print(q)
310
+
311
+ print(ans)
312
+
313
+
314
+
315
+ plt.legend()
316
+
317
+ plt.grid()
318
+
319
+ plt.yscale('log')
320
+
321
+ plt.show()
322
+
323
+ ```

1

edit

2018/03/08 19:59

投稿

mkgrei
mkgrei

スコア8560

test CHANGED
@@ -66,6 +66,8 @@
66
66
 
67
67
  pythonでnumpyを使って書くと以下になります。
68
68
 
69
+ (拡散行列は更新されてはいけないのですね。修正しました。)
70
+
69
71
 
70
72
 
71
73
  ```python
@@ -80,13 +82,17 @@
80
82
 
81
83
 
82
84
 
83
- n = 100
85
+ n = 2**4
84
86
 
85
87
  itr = 8
86
88
 
87
89
  f1 = np.zeros(n)
88
90
 
89
- f1[np.random.randint(n)] = 1
91
+ r = np.random.randint(n)
92
+
93
+ print(r)
94
+
95
+ f1[r] = 1
90
96
 
91
97
 
92
98
 
@@ -106,7 +112,7 @@
106
112
 
107
113
  def Us(v):
108
114
 
109
- new = 2 * psi * np.dot(psi, v) - np.matmul(np.eye(n), v)
115
+ new = 2*np.matmul(np.ones((n,n))/n, v) - np.matmul(np.eye(n), v)
110
116
 
111
117
  return new / np.linalg.norm(new)
112
118
 
@@ -116,9 +122,15 @@
116
122
 
117
123
  psi = Us(Uf(psi))
118
124
 
119
- plt.plot(psi*psi)
125
+ plt.plot(psi*psi, label=i)
120
126
 
121
127
 
128
+
129
+ plt.yscale('log')
130
+
131
+ plt.grid()
132
+
133
+ plt.legend()
122
134
 
123
135
  plt.show()
124
136