-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshor.py
63 lines (42 loc) · 1.16 KB
/
shor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import QuantumComputation as qc
import ContinuedFractions as cf
from QuantumComputation import ket
from math import sqrt, e, pi
# Shor's algorithm
N = 15
M = 256
a = 2
# Generate superposition
psi = sum( ket(c,0) for c in range(0,M) ).normalize()
def f(c):
return pow(a,c,N)
def _Uf(t):
(c,r) = t
return ket(c,(r+f(c)) % N)
Uf = qc.QOperator(_Uf)
res = Uf * psi
per = res.measure([1]).discard([1])
# QFT
omega = e**(2*pi*1j/M)
def Fourier(t):
(a,) = t
return sum( ((1/sqrt(M)) *omega**(a*b))*ket(b) for b in range(0,M) )
QFT = qc.QOperator(Fourier)
c = QFT * per
# Extract an approximation
def extract():
(ck,) = c.sample()
for (k,r) in cf.convergents(ck,M):
if r < N and abs(ck/M - k/r) <= 1/(2*N*N) and f(r)==f(0):
print("Found period r = %i" % r)
if r % 2 == 0:
p = pow(a,r//2,N)
q1, q2 = cf.gcd(p-1,N), cf.gcd(p+1, N)
print("Possible factors: %i, %i" % (q1,q2))
return True
print("Algorithm unsuccessful, trying again")
return False
for i in range(10):
success = extract()
if success:
break