【发布时间】:2016-07-13 06:03:50
【问题描述】:
我几天来一直在尝试实现Baillie-PSW primality test,但遇到了一些问题。特别是在尝试使用Lucas probable prime test 时。 我的问题不是关于百乐,而是关于如何以某个数字为模生成正确的卢卡斯序列
对于前两个伪素数,我的代码给出了正确的结果,例如323 和377。但是对于下一个 psudoprime,标准实现和加倍版本都失败了。
尝试对V_1 进行模运算完全破坏了Luckas 序列生成器的加倍版本。
关于如何在 Python 中正确实现 Lucas 可能素数测试的任何提示或建议?
from fractions import gcd
from math import log
def luckas_sequence_standard(num, D=0):
if D == 0:
D = smallest_D(num)
P = 1
Q = (1-D)/4
V0 = 2
V1 = P
U0 = 0
U1 = 1
for _ in range(num):
U2 = (P*U1 - Q*U0) % num
U1, U0 = U2, U1
V2 = (P*V1 - Q*V0) % num
V1, V0 = V2, V1
return U2%num, V2%num
def luckas_sequence_doubling(num, D=0):
if D == 0:
D = smallest_D(num)
P = 1
Q = (1 - D)/4
V0 = P
U0 = 1
temp_num = num + 1
double = []
while temp_num > 1:
if temp_num % 2 == 0:
double.append(True)
temp_num //= 2
else:
double.append(False)
temp_num += -1
k = 1
double.reverse()
for is_double in double:
if is_double:
U1 = (U0*V0) % num
V1 = V0**2 - 2*Q**k
U0 = U1
V0 = V1
k *= 2
elif not is_double:
U1 = ((P*U0 + V0)/2) % num
V1 = (D*U0 + P*V0)/2
U0 = U1
V0 = V1
k += 1
return U1%num, V1%num
def jacobi(a, m):
if a in [0, 1]:
return a
elif gcd(a, m) != 1:
return 0
elif a == 2:
if m % 8 in [3, 5]:
return -1
elif m % 8 in [1, 7]:
return 1
if a % 2 == 0:
return jacobi(2,m)*jacobi(a/2, m)
elif a >= m or a < 0:
return jacobi(a % m, m)
elif a % 4 == 3 and m % 4 == 3:
return -jacobi(m, a)
return jacobi(m, a)
def smallest_D(num):
D = 5
k = 1
while k > 0 and jacobi(k*D, num) != -1:
D += 2
k *= -1
return k*D
if __name__ == '__main__':
print luckas_sequence_standard(323)
print luckas_sequence_doubling(323)
print
print luckas_sequence_standard(377)
print luckas_sequence_doubling(377)
print
print luckas_sequence_standard(1159)
print luckas_sequence_doubling(1159)
【问题讨论】:
-
来自您链接的文章:如果这些分子中的任何一个是奇数,我们可以通过将其增加 n 来使其成为偶数,因为所有这些计算都是以 n 为模进行的。 i> 你试过吗?
-
谢谢!现在
luckas_sequence_doubling返回与luckas_sequence_standard相同的值,但它们仍然显示不正确的值。例如说1159不是伪素数。我应该更新我的问题以修复错误吗? -
当然应该:)