找回密码
 欢迎注册
查看: 22781|回复: 3

[原创] Baillie_PSW素性判定的mathematica代码

[复制链接]
发表于 2019-2-27 14:37:40 | 显示全部楼层 |阅读模式

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

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

×
mathematica本身有了大整数加减乘除取模,所以在mathematica之上要简单很多,很久以前就有实现这个算法的心愿,今年终于完成了

  1. Clear["Global`*"];(*Clear all variables*)
  2. Lucas[n0_]:=Module[
  3.     (*指定局部变量*)
  4.     {n=n0,m,s,P,Q,d,JS,mi2,UU,VV,uutemp,vvtemp,Utemp,Vtemp,kk},
  5.     If[Mod[n,2]==0&&n>2,Return[False]];(*排除偶数*)
  6.     If[IntegerQ[Sqrt[n]],Return[False]];(*如果是完全平方数,返回False*)
  7.     (*写成n+1=2^s*m的形式*)
  8.     m=n+1;
  9.     (*s=0;While[Mod[m,2]==0,m=m/2;s=s+1];*)
  10.     (*根据P=3 4 5 6 7 Q=1,以及雅克比符号等于-1来找到P,如果d与n有约数,则返回false,且d不应该是n的倍数*)
  11.     (*此处如果n很小,而d较大且是n的倍数,这时可能存在n是质数,而雅克比符号等于零的情况,这种情况需要特殊处理一下*)
  12.     P=3;Q=1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]];
  13.     While[JS==1,P=P+1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]]];
  14.     mi2=IntegerDigits[m,2];(*把m写成二进制的方式*)
  15.     UU=1;VV=P;(*分别是lucas序列的U(1)与V(1)的值*)
  16.     Do[
  17.         Utemp=Mod[UU*VV,n];
  18.         Vtemp=Mod[VV^2-2,n];(*此处Q=1*)
  19.         If[mi2[[kk]]==1,
  20.             uutemp=(P*Utemp+Vtemp);
  21.             vvtemp=(d*Utemp+P*Vtemp);
  22.             (*uutemp,vvtemp都可能是奇数,如果是奇数,则加上一个n,这样就是偶数了,
  23.             下面才能除以2得到整数,至于为什么要这么做,我也不是太清楚为什么,
  24.             可能是由于n是奇数,模的时候,减去偶数个n奇偶性不变,而减去奇数个n奇偶性变了*)
  25.             If[OddQ[uutemp],uutemp=uutemp+n];
  26.             If[OddQ[vvtemp],vvtemp=vvtemp+n];
  27.             UU=Mod[uutemp/2,n];
  28.             VV=Mod[vvtemp/2,n],
  29.             UU=Utemp;
  30.             VV=Vtemp
  31.         ],
  32.         {kk,2,Length@mi2}];(*此处必须从2开始,程序没有错误!*)
  33.     If[UU==0&&Mod[VV,n]==2,Return[True],Return[False]]
  34. ]

  35. (*miller rabin测试,n0是被测试的整数,a0是选择的基*)
  36. MillerRabin[n0_,a0_]:=Module[{n=n0,a=a0,s,m,t1,k},
  37.     s=0;m=n-1;While[Mod[m,2]==0,m=m/2;s=s+1];
  38.     t1=PowerMod[a,m,n];
  39.     If[t1==1,Return[True]];
  40.     k=0;While[k<s-1&&t1!=n-1,k=k+1;t1=Mod[t1^2,n]];
  41.     If[t1==n-1,Return[True],Return[False]]
  42. ]
复制代码


一些细节问题都写在代码注释里了

https://bbs.emath.ac.cn/forum.ph ... 757&fromuid=865
https://bbs.emath.ac.cn/forum.ph ... 734&fromuid=865

共享给感兴趣的人,也当做玩mathematica软件的一个练习吧!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2020-3-2 10:47:12 | 显示全部楼层
  1. Clear["Global`*"];(*Clear all variables*)
  2. Lucas[n0_]:=Module[
  3.     (*指定局部变量*)
  4.     {n=n0,m,s,P,Q,d,JS,mi2,UU,VV,UUtemp,VVtemp,kk},
  5.     If[Mod[n,2]==0&&n>2,Return[False]];(*排除偶数*)
  6.     If[IntegerQ[Sqrt[n]],Return[False]];(*如果是完全平方数,返回False*)
  7.     (*写成n+1=2^s*m的形式*)
  8.     m=n+1;
  9.     (*s=0;While[Mod[m,2]==0,m=m/2;s=s+1];*)
  10.     (*根据P=3 4 5 6 7 Q=1,以及雅克比符号等于-1来找到P,如果d与n有约数,则返回false,且d不应该是n的倍数*)
  11.     (*此处如果n很小,而d较大且是n的倍数,这时可能存在n是质数,而雅克比符号等于零的情况,这种情况需要特殊处理一下*)
  12.     P=3;Q=1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]];
  13.     While[JS==1,P=P+1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]]];
  14.     mi2=IntegerDigits[m,2];(*把m写成二进制的方式*)
  15.     UU=1;VV=P;(*分别是lucas序列的U(1)与V(1)的值*)
  16.     Do[
  17.         UU=Mod[UU*VV,n];
  18.         VV=Mod[VV^2-2,n];(*此处Q=1*)
  19.         If[mi2[[kk]]==1,
  20.             UUtemp=(P*UU+VV);
  21.             VVtemp=(d*UU+P*VV);
  22.             (*UUtemp,VVtemp都可能是奇数,如果是奇数,则加上一个n,这样就是偶数了,
  23.             下面才能除以2得到整数,至于为什么要这么做,我也不是太清楚为什么,
  24.             可能是由于n是奇数,模的时候,减去偶数个n奇偶性不变,而减去奇数个n奇偶性变了*)
  25.             If[OddQ[UUtemp],UUtemp=UUtemp+n];
  26.             If[OddQ[VVtemp],VVtemp=VVtemp+n];
  27.             UU=Mod[UUtemp/2,n];
  28.             VV=Mod[VVtemp/2,n]
  29.         ],
  30.         {kk,2,Length@mi2}];(*此处必须从2开始,程序没有错误!*)
  31.     If[UU==0&&Mod[VV,n]==2,Return[True],Return[False]]
  32. ]

  33. (*miller rabin测试,n0是被测试的整数,a0是选择的基*)
  34. MillerRabin[n0_,a0_]:=Module[{n=n0,a=a0,s,m,t1,k},
  35.     s=0;m=n-1;While[Mod[m,2]==0,m=m/2;s=s+1];
  36.     t1=PowerMod[a,m,n];
  37.     If[t1==1,Return[True]];
  38.     k=0;While[k<s-1&&t1!=n-1,k=k+1;t1=Mod[t1^2,n]];
  39.     If[t1==n-1,Return[True],Return[False]]
  40. ]

复制代码


进一步把代码简化了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2020-3-2 12:49:32 | 显示全部楼层
本帖最后由 mathematica 于 2020-3-2 12:57 编辑

这个文章的说明了为什么要把lucas伪素数与强伪素数相结合!

QQ截图20200302125708.png
QQ截图20200302125316.png
QQ截图20200302124637.png

点评

因数分解的形状不一样  发表于 2020-3-2 12:59
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-24 19:19 , Processed in 0.025994 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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