Selaa lähdekoodia

working fast lucas algo

Note: non-fast lucas stack overflows, will re-implement
Petra Lamborn 5 vuotta sitten
vanhempi
commit
bffeafc193
1 muutettua tiedostoa jossa 38 lisäystä ja 5 poistoa
  1. 38
    5
      lucas.py

+ 38
- 5
lucas.py Näytä tiedosto

1
 # Finding lucas pseudoprimes
1
 # Finding lucas pseudoprimes
2
-from math import sqrt, gcd
2
+from math import sqrt, gcd, floor, log
3
 
3
 
4
 def isqrt(n):
4
 def isqrt(n):
5
     """ Find the integer square root of n via newton's method, code via
5
     """ Find the integer square root of n via newton's method, code via
88
     if n < 1 or n % 2 == 0:
88
     if n < 1 or n % 2 == 0:
89
         raise ValueError("n must be a positive odd number")
89
         raise ValueError("n must be a positive odd number")
90
     for D in Dsequence():
90
     for D in Dsequence():
91
-        if Jacobi(D/n) == -1:
91
+        if Jacobi(D, n) == -1:
92
             return D
92
             return D
93
     # Shouldn't fire
93
     # Shouldn't fire
94
     return 0
94
     return 0
124
         raise ValueError("k must be a non-negative integer")
124
         raise ValueError("k must be a non-negative integer")
125
     if n < 1:
125
     if n < 1:
126
         raise ValueError("n must be a postive integer")
126
         raise ValueError("n must be a postive integer")
127
-    uc, vc = Lucas(1, p, q)
127
+    if n % 2 == 0:
128
+        raise ValueError("n must be odd")
129
+    uc, vc = Lucas(0, p, q)
128
     dk = floor(log(k, 2))
130
     dk = floor(log(k, 2))
129
     tp = 2**dk
131
     tp = 2**dk
130
-    for i in range(dk):
131
-
132
+    krunn = k
133
+    ks = 0
134
+    for i in range(dk + 1):
135
+        un = (uc * vc)
136
+        vn = (pow(vc, 2, n) - 2 * pow(q, ks, n))
137
+        uc = un % n
138
+        vc = vn % n
139
+        ks = ks * 2
140
+        if krunn >= tp:
141
+            krunn = krunn - tp
142
+            ks = ks + 1
143
+            un = p * uc + vc
144
+            if un % 2 != 0:
145
+                un = un + n
146
+            vn = (p * p - 4 * q) * uc + p * vc
147
+            if vn % 2 != 0:
148
+                vn = vn + n
149
+            uc = (un // 2) % n
150
+            vc = (vn // 2) % n
151
+        tp = tp // 2
152
+    return(uc, vc)
153
+
154
+
155
+for i in range(1, 20000, 2):
156
+    if hasIntSQRT(i):
157
+        continue
158
+    d = FirstD(i)
159
+    q = (1 - d) // 4
160
+    fu, fv = LucasFast(i + 1, 1, q, i)
161
+    su, sv = Lucas(i + 1, 1, q)
162
+    su = su % i
163
+    sv = sv % i
164
+    print("{}: {}, {}; {}".format(i, fu == su, fv == sv, Lucas(i + 1, 1, q)))
132
 
165
 
133
 
166
 
134
 
167