forked from Michaelvll/myQShor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shor.py
101 lines (87 loc) · 3.45 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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import gcd
import fastPow
import miller_robin
import fraction
import power
import random
from multiprocessing.pool import ThreadPool
import qsharp
# Initializing
import sys
sys.path.append('../myShorLib/bin/Release/netstandard2.0')
import clr
clr.AddReference("Microsoft.Quantum.Canon")
clr.AddReference('myShorLib')
from myShorLib import PhaseEstimation
class myShor():
def __init__(self, precision, thread_num):
self.Precision = precision
self.Thread_Num = thread_num
def order_finding(self, x, n):
qsim = qsharp.QuantumSimulator()
def phase_estimation(x, n):
tmp = int(qsim.run(PhaseEstimation, x, n,
self.Precision).result().clr_object)
theta = float(tmp) / (2**self.Precision)
return theta
for _ in range(2):
theta = phase_estimation(x, n)
if theta == 0:
print("========\nOrder Finding for: x={}, N={}\nGet theta: {}\nNo r estimated\n".format(
x, n, theta))
continue
r = fraction.denominator(theta, n)
print("========\nOrder Finding for: x={}, N={}\nGet theta: {}\nEstimate r: {}\n".format(
x, n, theta, r))
for i in r:
m = fastPow.fastPow(x, i, n)
if m == 1:
return i
return -1
def shor(self, n):
if miller_robin.miller_robin(n):
return (1, n)
else:
tmp = power.power(n)
if tmp != -1:
return (tmp, n // tmp)
else:
if (n % 2 == 0):
return (2, n // 2)
while True:
# Parrel computing for some random x
xlist = random.sample(range(3, n - 1), self.Thread_Num)
g = [gcd.gcd(x, n) for x in xlist]
for idx, g in enumerate(g):
if (g != 1):
# ======= For debug ===========
# while gcd.gcd(xlist[idx], n) != 1:
# newx = random.randint(3, n - 1)
# xlist[idx] = newx
# ======= In Real Quantum Computer =========
return (g, n // g)
print("======== Order Finding Started ========")
threadPool = ThreadPool(processes=self.Thread_Num)
results = []
for x in xlist:
results.append(threadPool.apply_async(
self.order_finding, args=(x, n)))
threadPool.close()
threadPool.join()
results = [r.get() for r in results]
for r in results:
if r == -1:
continue
if (r % 2 == 0):
s = fastPow.fastPow(x, r // 2, n)
if (s != 1 and s != n-1):
g1 = gcd.gcd(s+1, n)
g2 = gcd.gcd(s-1, n)
if (g1 != 1):
return (g1, n // g1)
elif (g2 != 1):
return (g2, n // g2)
if __name__ == "__main__":
n = int(input())
alg = myShor(6, 3)
print("The factor of {} is {}".format(n, alg.shor(n)))