- 注册时间
- 2021-11-19
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 8645
- 在线时间
- 小时
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?欢迎注册
×
- Clear["Global`*"];(*Clear all variables*)
- (*StrongLucas素数判定算法*)
- StrongLucas[n0_]:=Module[
- (*指定局部变量*)
- {n=n0,m,s,P,Q,d,JS,mi2,UU,VV,UUtemp,VVtemp,kk,k,QQ,VVV,QQQ,VV2Q},
- If[Mod[n,2]==0&&n>2,Return[False]];(*排除偶数*)
- If[IntegerQ[Sqrt[n]],Return[False]];(*如果是完全平方数,返回False*)
- (*写成n+1=2^s*m的形式,其中m是奇数*)
- m=n+1;s=0;While[Mod[m,2]==0,m=m/2;s=s+1];
- (*根据P=2,Q=-2,-3,-4,-5,以及雅克比符号等于-1来找到Q,如果d与n有约数,则返回false,且d不应该是n的倍数*)
- (*此处如果n很小,而d较大且是n的倍数,这时可能存在n是质数,而雅克比符号等于零的情况,这种情况需要特殊处理一下*)
- P=2;Q=-2;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]];
- While[JS!=-1,Q=Q-1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]]];
- mi2=IntegerDigits[m,2];(*把m写成二进制的方式*)
- UU=1;VV=P;QQ=Q;(*分别是lucas序列的U(1)与V(1)与Q(1)的值*)
- Do[
- UU=Mod[UU*VV,n];
- VV=Mod[VV^2-2*QQ,n];
- QQ=Mod[QQ^2,n];
- If[mi2[[kk]]==1,
- UUtemp=(P*UU+VV);
- VVtemp=(d*UU+P*VV);
- (*UUtemp,VVtemp都可能是奇数,如果是奇数,则加上一个n,这样就是偶数了,
- 下面才能除以2得到整数,至于为什么要这么做,我也不是太清楚为什么,
- 可能是由于n是奇数,模的时候,减去偶数个n奇偶性不变,而减去奇数个n奇偶性变了.
- 20220824补充:除以2,其实是乘以2模n的逆,而2模n的逆=(n+1)/2,这里n肯定是奇数
- 当UUtemp=2k(偶数的时候),2k*(n+1)/2=k*(n+1)=k(mod n),相当于直接除以2,
- 当UUtemp=2k+1(奇数的时候),(2k+1)*(n+1)/2=2k*(n+1)/2+(n+1)/2=k+(n+1)/2=(2k+1+n)/2(mod n),相当于加上n后再除以2,
- VVtemp同理
- *)
- If[OddQ[UUtemp],UUtemp=UUtemp+n];
- If[OddQ[VVtemp],VVtemp=VVtemp+n];
- UU=Mod[UUtemp/2,n];
- VV=Mod[VVtemp/2,n];
- QQ=Mod[QQ*Q,n]
- ],
- {kk,2,Length@mi2}];(*此处必须从2开始,程序没有错误!*)
- (*计算UU、VV、QQ的值,用来素数判定*)
- (*Print["第1处:"];*)
- (*Print[{n,m,s,P,Q,d,UU,VV,QQ}];调试的时候用*)
- k=0;
- While[k<s-1&&VV!=0,k=k+1;VV=Mod[VV^2-2*QQ,n];QQ=Mod[QQ^2,n]];(*计算VV[m*2^k]的值*)
- VVV=VV;(*保存下来此处的VV,为将来判定VV是否等于零做准备*)
- While[k<s-1,k=k+1;VV=Mod[VV^2-2*QQ,n];QQ=Mod[QQ^2,n]];(*计算QQ^((n+1)/2)的值,此处VV的值必须也计算,否则后面VV值计算错误*)
- QQQ=Mod[QQ-JacobiSymbol[Q,n]*Q,n];(*判定Q^((n+1)/2)-JacobiSymbol[Q,n]*Q是否等于零,此处雅克比符号分子是Q!*)
- While[k<s, k=k+1;VV=Mod[VV^2-2*QQ,n];QQ=Mod[QQ^2,n]];(*计算VV[n+1]的值*)
- VV2Q=Mod[VV-2*Q,n];(*保存这个值*)
- If[(UU==0||VVV==0)&&(QQQ==0)&&(VV2Q==0),
- Return[True],
- Return[False]]
- ]
复制代码 |
|