Browse Source

working fast lucas algo

Note: non-fast lucas stack overflows, will re-implement
Petra Lamborn 5 years ago
parent
commit
bffeafc193
1 changed files with 38 additions and 5 deletions
  1. 38
    5
      lucas.py

+ 38
- 5
lucas.py View File

@@ -1,5 +1,5 @@
1 1
 # Finding lucas pseudoprimes
2
-from math import sqrt, gcd
2
+from math import sqrt, gcd, floor, log
3 3
 
4 4
 def isqrt(n):
5 5
     """ Find the integer square root of n via newton's method, code via
@@ -88,7 +88,7 @@ def FirstD(n):
88 88
     if n < 1 or n % 2 == 0:
89 89
         raise ValueError("n must be a positive odd number")
90 90
     for D in Dsequence():
91
-        if Jacobi(D/n) == -1:
91
+        if Jacobi(D, n) == -1:
92 92
             return D
93 93
     # Shouldn't fire
94 94
     return 0
@@ -124,11 +124,44 @@ def LucasFast(k, p, q, n):
124 124
         raise ValueError("k must be a non-negative integer")
125 125
     if n < 1:
126 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 130
     dk = floor(log(k, 2))
129 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