Browse Source

Working Strong Lucas test

Petra Lamborn 5 years ago
parent
commit
60c91ea940
1 changed files with 64 additions and 3 deletions
  1. 64
    3
      lucas.py

+ 64
- 3
lucas.py View File

@@ -1,6 +1,7 @@
1 1
 # Finding lucas pseudoprimes
2 2
 from math import sqrt, gcd, floor, log
3 3
 from time import process_time
4
+from psimp import trd, hund_div
4 5
 
5 6
 def isqrt(n):
6 7
     """ Find the integer square root of n via newton's method, code via
@@ -179,15 +180,75 @@ def LucasPrime(n):
179 180
     lnum = LucasFast(n + 1, 1, q, n)
180 181
     return lnum[0] == 0
181 182
 
183
+def StrongLucasPrime(n):
184
+    """Strong version of the Lucas probable prime test
185
+    """
186
+    if n < 2:
187
+        return False
188
+    if n == 2:
189
+        return True
190
+    if n % 2 == 0:
191
+        return False
192
+    d = FirstD(n)
193
+    if d == 0:
194
+        return False
195
+    s, od = trd(n + 1)
196
+    p = 1
197
+    q = (1 - d) // 4
198
+    uc, vc = Lucas(0, p, q)
199
+    dk = floor(log(od, 2))
200
+    tp = 2**dk
201
+    krunn = od
202
+    ks = 0
203
+    for i in range(dk + 1):
204
+        un = (uc * vc)
205
+        vn = (pow(vc, 2, n) - 2 * pow(q, ks, n))
206
+        uc = un % n
207
+        vc = vn % n
208
+        ks = ks * 2
209
+        if krunn >= tp:
210
+            krunn = krunn - tp
211
+            ks = ks + 1
212
+            un = p * uc + vc
213
+            if un % 2 != 0:
214
+                un = un + n
215
+            vn = (p * p - 4 * q) * uc + p * vc
216
+            if vn % 2 != 0:
217
+                vn = vn + n
218
+            uc = (un // 2) % n
219
+            vc = (vn // 2) % n
220
+        tp = tp // 2
221
+    if uc == 0:
222
+        return True
223
+    if vc == 0:
224
+        return True
225
+    for r in range(1, s):
226
+        un = (uc * vc)
227
+        vn = (pow(vc, 2, n) - 2 * pow(q, ks, n))
228
+        uc = un % n
229
+        vc = vn % n
230
+        if vc == 0:
231
+            return True
232
+        ks = ks * 2
233
+    return False
234
+
235
+
236
+
237
+#print(StrongLucasPrime(7))
182 238
 
183 239
 np = 0
184 240
 
185
-for i in range(1000):
186
-    lp = LucasPrime(i)
241
+for i in range(10000):
242
+    lp = StrongLucasPrime(i)
187 243
     if lp:
188 244
         np = np + 1
189
-    print("{}:\t{}".format(i, lp))
245
+        print("{}:\t{};\t{}".format(i, lp, np))
190 246
 
191 247
 print(np)
192 248
 
249
+print(StrongLucasPrime(5459))
250
+print(hund_div(5459))
251
+print(StrongLucasPrime(5777))
252
+print(hund_div(5777))
253
+
193 254