找回密码
 欢迎注册
查看: 11004|回复: 2

[求助] 有谁能看懂这段梅森数的lucas-lehmer判别法的代码?

[复制链接]
发表于 2019-3-4 12:10:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
  1. LucasLehmer[n_] :=
  2. Module[{Mp, s, k}, Mp = 2^n - 1; s = 4;
  3.   Do[s = Mod[s^2 - 2, Mp], {k, 1, n - 2}];
  4.   If[s == 0, Return[True], Return[False]]]

  5. LucasLehmer2[p_] :=
  6. Module[{Mp, s, k}, Mp = 2^p - 1; s = 4;
  7.   Do[s = s^2 - 2; If[s < 0, s += Mp];
  8.    s = BitAnd[s, Mp] + BitShiftRight[s, p];
  9.    If[s >= Mp, s -= Mp], {k, 1, p - 2}];
  10.   If[s == 0, Return[True], Return[False]]]
复制代码


https://baike.baidu.com/item/%E5 ... /3757240?fr=aladdin
卢卡斯-莱默检验法 ,用来判别梅森数是不是素数的算法

s = Mod[s^2 - 2, Mp]
这行代码被替换成了下面的
s = s^2 - 2;
If[s < 0, s += Mp];
s = BitAnd[s, Mp] + BitShiftRight[s, p];
If[s >= Mp, s -= Mp]
这代码替换了一下,速度快了
执行
Timing[LucasLehmer2[86243]]
运行结果
{10.9825, True}
执行
Timing[LucasLehmer[86243]]
运行结果
{49.4367, True}
仅仅换了一下代码,运行效率有五倍之差!!!!!!!!!!
效率低的代码是我写的,效率高的代码是别人写的!
我最近研究mathematica软件与prime95的时候,对比发现判别梅森数方面,mathematica比prime95慢了很多!
我还怀疑prime95,真的是越来越发现自己很无知!
这段取模的置换的代码,是不是只对梅森数有效?



毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-3-4 12:15:54 | 显示全部楼层
  1. LucasLehmer[n_] := Module[{Mp, s, k}, Mp = 2^n - 1; s = 4;
  2.   Do[s = Mod[s^2 - 2, Mp]; Print[s], {k, 1, n - 2}];
  3.   If[s == 0, Return[True], Return[False]]]

  4. LucasLehmer2[p_] := Module[{Mp, s, k}, Mp = 2^p - 1; s = 4;
  5.   Do[s = s^2 - 2; If[s < 0, s += Mp];
  6.    s = BitAnd[s, Mp] + BitShiftRight[s, p];
  7.    If[s >= Mp, s -= Mp]; Print[s], {k, 1, p - 2}];
  8.   If[s == 0, Return[True], Return[False]]]
复制代码

我当然也怀疑代码的正确性,就把代码的中间结果也打印出来,每个函数都增加了
  1. Print[s]
复制代码
这句,
结果用LucasLehmer[11]与LucasLehmer2[11]比较中间结果,发现结果完全一样!

问题来了,是不是这种算法只有对梅森数有效果?这段代码的原理又是什么?
真把我打蒙了!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-3-4 13:47:08 | 显示全部楼层
本帖最后由 .·.·. 于 2019-3-4 14:16 编辑
mathematica 发表于 2019-3-4 12:15
我当然也怀疑代码的正确性,就把代码的中间结果也打印出来,每个函数都增加了这句,
结果用LucasLehmer[ ...


取模运算比位运算慢是很显然的事情
你写的是一般的取模运算
人家的代码把特定的取模运算(模Mp)简化成了位运算
所以人家的算法快
这是很正常的事情

原理差不多是
a=2^p*(a-(a mod 2^p))/2^p+(a mod 2^p)
两边mod2^p-1
a mod 2^p-1=(a-(a mod 2^p))/2^p+(a mod 2^p)
/2^p被bitshift替代,mod 2^p被bitand(#,2^p-1)&替代
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-25 13:37 , Processed in 0.048710 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表