回答編集履歴
2
edit
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**
|
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
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 =
|
85
|
+
n = 2**4
|
84
86
|
|
85
87
|
itr = 8
|
86
88
|
|
87
89
|
f1 = np.zeros(n)
|
88
90
|
|
89
|
-
|
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
|
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
|
|