Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: More Adam vs Hydra Hype

Author: Dann Corbit

Date: 01:52:21 05/27/05

Go up one level in this thread


   10   '
   20   '         "APRT-CLE" is the extended version of "APRT-CL"
   30   '      Cohen-Lenstra version of Adleman-Pomerance-Rumely Test
   40   '                  programmed by Koichiro Akiyama
   50   '                             1988 2 12
   60   '
   70   '            modified for UBASIC version 7 by Yuji KIDA
   80   '                       1989 1 31 & 1989 3 30
   90   '                      amended by Frank O'Hara
  100   '                             1990 1 28
  110   '       extended to 844 digits using extra memories by Yuji KIDA
  120   '                             1991 9 30
  130   '  extended to 844 digits WITHOUT using extra memories by Frank O'Hara
  140   '                             1991 12 13
  150   '                     rearranged by Yuji KIDA
  160   '                             1992 1 24
  170   '
  180   word -200
  190   NPmax%=6:PWmax%=32:PWmax1%=PWmax%-1:Prms32767%=3512
  200   NQmax%=136:Qmax%=30241
  210   LEVELmax%=11
  220   dim Indx%(Qmax%),F%(Qmax%)
  230   dim P%(NPmax%),Qmem%(NQmax%),Q%(NQmax%),G%(NQmax%),Inv%(PWmax1%)
  240   dim NP%(LEVELmax%),NQ%(LEVELmax%),T(LEVELmax%)
  250   dim JS(PWmax1%),JW(PWmax1%),JX(PWmax1%)
  260   dim J0(PWmax1%),J1(PWmax1%),J2(PWmax1%)
  270   dim J(1,PWmax1%)
  280   '
  290   input "Test number  N=";N
  300   if N<2 then end
  310   clr time
  320   '
  330   gosub *GetAllPrimes
  340   gosub *GetPrimes2Test
  350   if LEVELnow%=-1 then
  360     :print:print "This number is too large.":end
  370   '
  380   print:print "Preparatory test"
  390   W=prmdiv(N)
  400   if W=N then *YesPrime
  410   if W<>0 then *FindFactor
  420   print "    Pass !";
  430   '
  440   '     Main test
  450   '
  460   *MainStart
  470   for I%=1 to NP%
  480     P%=P%(I%)
  490     clr SW%,TestedQs%
  500     print:print:print "Main test  for P=";P%
  510     if P%>2 then
  520       :if modpow(N,P%-1,P%^2)<>1 then SW%=1
  530     for J%=TestedQs%+1 to TestingQs%
  540       Q=Q%(J%):G%=G%(J%)
  550       K%=fnPowerIndex(P%,Q-1)
  560       if K%=0 then 760
  570       print "   for Q=";Q;
  580       PK%=P%^K%:PL%=(P%-1)*P%^(K%-1):PM%=P%^(K%-1)
  590       gosub *GetIndexTable
  600       gosub *GetFxTable
  610       '
  620       gosub *PrepareJacobis
  630       gosub *CalcJacobiPQVs:'     J(v,p,q)
  640       gosub *CalcJPQ0uJPQV:'      J(0,p,q)^u*J(v,p,q)
  650       H%=fnMatchingRoot:'          J = zeta^H%
  660       if H%=-1 then cancel for,for:goto *NotPrime
  670       '
  680       if SW%=1 then 760
  690       if H%@P%=0 then 760
  700       if P%<>2 then SW%=1:goto 760
  710       if K%<>1 then 740
  720       if N@4=1 then SW%=1:goto 760
  730       goto 760
  740       if modpow(Q,(N-1)\2,N)<>N-1 then cancel for,for:goto *NotPrime
  750       SW%=1
  760     next J%
  770     if SW%=0 then TestedQs%=TestingQs%:goto *TestMoreQs
  780   next I%
  790   goto *Final
  800   '
  810   *TestMoreQs
  820     if TestingQs%<NQ%(LEVELnow%) then
  830       :print "retry";
  840       :inc TestingQs%:Q=Q%(TestingQs%)
  850       :U=T:repeat S*=Q:U=U\Q until res
  860       :goto 530
  870     cancel for
  880   if LEVELnow%=LEVELmax% then *CannotTell
  890   print "retry from the beginning";
  900   inc LEVELnow%:T=T(LEVELnow%):NP%=NP%(LEVELnow%)
  910   S=2
  920   for J%=1 to NQ%(LEVELnow%)
  930     Q=Q%(J%)
  940     U=T:repeat S*=Q:U=U\Q until res
  950     if S^2>N then TestingQs%=J%:cancel for:goto *MainStart
  960   next
  970   print "Program error !":stop:end
  980   '
  990   *Final
 1000   W=fnFinalTest
 1010   if and{1<W,W<N} then *FindFactor
 1020   '
 1030   *YesPrime
 1040   print "    Pass !"
 1050   print:print N;"is prime."
 1060   goto *End
 1070   '
 1080   *NotPrime
 1090   print:print "    Fail !"
 1100   print:print N;"is not prime."
 1110   goto *End
 1120   '
 1130   *FindFactor
 1140   print "    Fail !"
 1150   print:print N;"is a multiple of";W;"."
 1160   goto *End
 1170   '
 1180   *CannotTell
 1190   print "    Fail !"
 1200   print:print "I'm sorry !"
 1210   print "    I can't tell whether this number is prime or not."
 1220   print:print "test number=";N
 1230   print:print "Please try another test."
 1240   goto *End
 1250   '
 1260   *End
 1270   print time
 1280   end
 1290   '
 1300   *GetAllPrimes
 1310     for I%=1 to NPmax%:P%(I%)=prm(I%):next
 1320     NQall%=1:Qmem%(1)=2
 1330     T=2^5*3^3*5^2*7*11*13
 1340       gosub *GetallQs(T)
 1350     TestingQs%=1:Q%(1)=2:G%(1)=1
 1360     T(1)=2^2*3:NP%(1)=2
 1370       gosub *GetQsGs(T(1)):NQ%(1)=TestingQs%
 1380     T(2)=2^2*3*5:NP%(2)=3
 1390       gosub *GetQsGs(T(2)):NQ%(2)=TestingQs%
 1400     T(3)=2^2*3^2*5:NP%(3)=3
 1410       gosub *GetQsGs(T(3)):NQ%(3)=TestingQs%
 1420     T(4)=2^2*3^2*5*7:NP%(4)=4
 1430       gosub *GetQsGs(T(4)):NQ%(4)=TestingQs%
 1440     T(5)=2^3*3^2*5*7:NP%(5)=4
 1450       gosub *GetQsGs(T(5)):NQ%(5)=TestingQs%
 1460     T(6)=2^4*3^2*5*7:NP%(6)=4
 1470       gosub *GetQsGs(T(6)):NQ%(6)=TestingQs%
 1480     T(7)=2^4*3^3*5*7:NP%(7)=4
 1490       gosub *GetQsGs(T(7)):NQ%(7)=TestingQs%
 1500     T(8)=2^4*3^3*5*7*11:NP%(8)=5
 1510       gosub *GetQsGs(T(8)):NQ%(8)=TestingQs%
 1520     T(9)=2^4*3^3*5^2*7*11:NP%(9)=5
 1530       gosub *GetQsGS(T(9)):NQ%(9)=TestingQs%
 1540     T(10)=2^5*3^3*5^2*7*11:NP%(10)=5
 1550       gosub *GetQsGs(T(10)):NQ%(10)=TestingQs%
 1560     T(11)=2^5*3^3*5^2*7*11*13:NP%(11)=6:'11=LEVELmax%
 1570       gosub *GetQsGs(T(11)):NQ%(11)=TestingQs%
 1580   return
 1590   '
 1600   *GetPrimes2Test
 1610     for I%=1 to LEVELmax%
 1620       S=2
 1630       for J%=1 to NQ%(I%)
 1640         Q=Q%(J%)
 1650         U=T(I%):repeat S*=Q:U=U\Q until res
 1660         if S^2>N then
 1670           :LEVELnow%=I%:TestingQs%=J%
 1680           :T=T(LEVELnow%):NP%=NP%(LEVELnow%)
 1690           :cancel for,for:goto 1730
 1700       next
 1710     next
 1720     LEVELnow%=-1:'     too big
 1730   return
 1740   '
 1750   *PrepareJacobis
 1760     block J0(0..PK%-1)=0
 1770     block J1(0..PK%-1)=0
 1780      if P%>2 then
 1790       :gosub *JacobiSum(1,1)
 1800       :return
 1810     if K%=1 then return
 1820     '
 1830     gosub *JacobiSum(1,1)
 1840     block JW(0..PK%-1)=0
 1850     if K%=2 then return
 1860     '
 1870     block JW(0..PM%-1)=block J0(0..PM%-1)
 1880     gosub *JacobiSum(2,1)
 1890     block JS(0..PM%-1)=block J0(0..PM%-1)
 1900     gosub *JS_JW:gosub *NormalizeJS
 1910     block J1(0..PM%-1)=block JS(0..PM%-1)
 1920     gosub *JacobiSum(3*2^(K%-3),2^(K%-3))
 1930     block JW(0..PK%-1)=0
 1940     block JS(0..PM%-1)=block J0(0..PM%-1)
 1950     gosub *JS_2:gosub *NormalizeJS
 1960     block J2(0..PM%-1)=block JS(0..PM%-1)
 1970   return
 1980   '
 1990   '     J(p,q,v)              ( J(v,i) )
 2000   '
 2010   *CalcJacobiPQVs
 2020     local I%
 2030     block J(0..1,1..PK%-1)=0
 2040     block J(0..1,0)=1
 2050     VK%=N@PK%
 2060     gosub *GetInverseTable
 2070     if P%=2 then 2290
 2080     for IV%=0 to 1
 2090       for X%=1 to PK%-1
 2100         block JS(0..PK%-1)=block J0(0..PK%-1)
 2110         if X%@P%=0 then 2260
 2120         if IV%=0 then E=X%:goto 2150
 2130         E=(VK%*X%)\PK%
 2140         if E=0 then 2260
 2150         gosub *JS_E
 2160         block JW(0..PK%-1)=0
 2170         InvX%=Inv%(X%)
 2180         for I%=0 to PK%-1
 2190           S%=(I%*InvX%)@PK%
 2200           JW(S%)+=JS(I%)
 2210         next
 2220         gosub *NormalizeJW
 2230         block JS(0..PK%-1)=block J(IV%,0..PK%-1)
 2240         gosub *JS_JW
 2250         block J(IV%,0..PK%-1)=block JS(0..PK%-1)
 2260       next
 2270     next
 2280     return
 2290     if K%=1 then J(0,0)=Q:J(1,0)=1:return
 2300     if K%>2 then 2500
 2310   '
 2320   '     J(2,q,v) k=2             ( J(v,i) )
 2330   '
 2340     if VK%=1 then J(1,0)=1
 2350     for I%=0 to 1
 2360       JS(I%)=J0(I%)
 2370     next
 2380     gosub *JS_2
 2390     if VK%<>3 then 2430
 2400     for I%=0 to 1
 2410       J(1,I%)=JS(I%)
 2420     next
 2430     for I%=0 to 1
 2440       J(0,I%)=JS(I%)*Q
 2450     next
 2460     return
 2470   '
 2480   '     J(2,q,v) k>2             ( J(v,i) )
 2490   '
 2500     for IV%=0 to 1
 2510       for X%=1 to PK%-1 step 2
 2520         block JS(0..PM%)=block J1(0..PM%)
 2530         if or{X%@8=5,X%@8=7} then 2690
 2540         if IV%=0 then E=X%
 2550         :else E=(VK%*X%)\PK%
 2560            :if E=0 then 2690
 2570         gosub *JS_E
 2580         block JW(0..PK%-1)=0
 2590         InvX%=Inv%(X%)
 2600         for I%=0 to PK%-1
 2610           S%=(I%*InvX%)@PK%
 2620           JW(S%)+=JS(I%)
 2630         next
 2640         gosub *NormalizeJW
 2650         block JS(0..PK%-1)=block J(IV%,0..PK%-1)
 2660         gosub *NormalizeJS
 2670         gosub *JS_JW
 2680         block J(IV%,0..PK%-1)=block JS(0..PK%-1)
 2690       next X%
 2700       if or{IV%=0,VK%@8=1,VK%@8=3} then 2770
 2710       block JW(0..PK%-1)=0
 2720       block JS(0..PK%-1)=0
 2730       block JW(0..PM%-1)=block J2(0..PM%-1)
 2740       block JS(0..PM%-1)=block J(IV%,0..PM%-1)
 2750       gosub *JS_JW
 2760       block J(IV%,0..PM%-1)=block JS(0..PM%-1)
 2770     next IV%
 2780   return
 2790   '
 2800   '     J(0,p,q)^u*J(v,p,q)
 2810   '
 2820   *CalcJPQ0uJPQV
 2830     local I%,J%
 2840     block JS(0..PK%-1)=0
 2850     U=N\PK%
 2860     block JS(0..PL%-1)=block J(0,0..PL%-1)
 2870     E=U:gosub *JS_E
 2880     block JW(0..PK%-1)=0
 2890     for I%=0 to PL%-1
 2900       for J%=0 to PL%-1
 2910         S%=(I%+J%)@PK%
 2920         JW(S%)=(JW(S%)+JS(I%)*J(1,J%))@N
 2930       next
 2940     next
 2950     gosub *NormalizeJW
 2960     for I%=0 to PL%-1
 2970       JW(I%)@=N
 2980     next
 2990   return
 3000   '
 3010   fnMatchingRoot
 3020     local I%,J%,H%=-1
 3030     W=0
 3040     for I%=0 to PL%-1
 3050       W+=JW(I%)
 3060     next
 3070     if W=1 then
 3080       :for I%=0 to PL%-1
 3090          :if JW(I%)=1 then H%=I%:cancel for:goto 3230:endif
 3100       :next
 3110     '
 3120     if W<>(N-1)*(P%-1) then H%=-1:goto 3230
 3130     for I%=0 to PM%-1
 3140       if JW(I%)=N-1 then cancel for:goto 3180
 3150     next
 3160     H%=-1:goto 3230
 3170     '
 3180     for J%=1 to P%-2
 3190       S%=I%+J%*PM%
 3200       if JW(S%)<>N-1 then H%=-1:cancel for:goto 3230
 3210     next
 3220     H%=I%+PL%:'        =i%+(P%-1)*P%^(K%-1)
 3230   return(H%)
 3240   '
 3250   fnFinalTest
 3260     local I%,J%,T1%,T2%,R
 3270     R=1
 3280     T1%=T\10000:T2%=T@10000
 3290     for I%=1 to T1%
 3300       for J%=1 to 10000
 3310         R=R*N@S
 3320         if R=1 then cancel for,for:goto 3420
 3330         if and{N@R=0,R<N} then cancel for,for:goto 3420
 3340       next
 3350     next
 3360     for I%=1 to T2%
 3370       R=R*N@S
 3380       if R=1 then cancel for:goto 3420
 3390       if and{N@R=0,R<N} then cancel for:goto 3420
 3400     next
 3410     R=1
 3420   return(R)
 3430   '
 3440   '     table of index            x=G%^Indx%(x)@Q
 3450   '
 3460   *GetIndexTable
 3470     local I%
 3480     W%=1
 3490     for I%=1 to Q-1
 3500       W%=W%*G%@Q
 3510       Indx%(W%)=I%
 3520     next
 3530   return
 3540   '
 3550   '     table of F(x)             G%^F%(x)=1-G%^x
 3560   '
 3570   *GetFxTable
 3580     local I%
 3590     W%=1
 3600     for I%=1 to Q-2
 3610       W%=W%*G%@Q
 3620       F%(I%)=Indx%((1-W%)@Q)
 3630     next
 3640   return
 3650   '
 3660   '     Jacobi sum
 3670   '
 3680   *JacobiSum(A%,B%)
 3690     local I%,J%,K%
 3700     block J0(0..PL%-1)=0
 3710     for I%=1 to Q-2
 3720       J%=(A%*I%+B%*F%(I%))@PK%
 3730       if J%<PL% then inc J0(J%)
 3740       :else for K%=1 to P%-1:dec J0(J%-K%*PM%):next
 3750     next
 3760   return
 3770   '
 3780   '     table of inverses mod P^k         Inv%(x)*x@PK% = 1
 3790   '
 3800   *GetInverseTable
 3810     local I%
 3820     for I%=1 to PK%-1
 3830       if I%@P% then Inv%(I%)=modinv(I%,PK%) else Inv%(I%)=0
 3840     next
 3850   return
 3860   '
 3870   '     JS=JS^E
 3880   '
 3890   *JS_E
 3900     local I%
 3910     if E=1 then 3970
 3920     block JW(0..PL%-1)=block JS(0..PL%-1)
 3930     for I%=len(E)-2 to 0 step -1
 3940       gosub *JS_2
 3950       if bit(I%,E) then gosub *JS_JW
 3960     next
 3970   return
 3980   '
 3990   '     JS=JS*JW
 4000   '
 4010   *JS_JW
 4020     local I%,J%,K%
 4030     for I%=0 to PL%-1
 4040       for J%=0 to PL%-1
 4050         K%=(I%+J%)@PK%
 4060         JX(K%)=(JX(K%)+JS(I%)*JW(J%))@N
 4070       next
 4080     next
 4090     block JS(0..PK%-1)=block JX(0..PK%-1)
 4100     block JX(0..PK%-1)=0
 4110     gosub *NormalizeJS
 4120   return
 4130   '
 4140   '     JS=JS^2
 4150   '
 4160   *JS_2
 4170     local I%,J%,K%
 4180     for I%=0 to PL%-1
 4190       K%=2*I%@PK%
 4200       JX(K%)=(JX(K%)+JS(I%)^2)@N
 4210     next
 4220     for I%=0 to PL%-1
 4230       for J%=I%+1 to PL%-1
 4240         K%=(I%+J%)@PK%
 4250         JX(K%)=(JX(K%)+2*JS(I%)*JS(J%))@N
 4260       next
 4270     next
 4280     block JS(0..PK%-1)=block JX(0..PK%-1)
 4290     block JX(0..PK%-1)=0
 4300     gosub *NormalizeJS
 4310   return
 4320   '
 4330   '     normalize coefficient of JS
 4340   '
 4350   *NormalizeJS
 4360     local I%,J%
 4370     for I%=PL% to PK%-1
 4380       if JS(I%) then JW=JS(I%)
 4390         :for J%=1 to P%-1
 4400           :JS(I%-J%*PM%)-=JW
 4410         :next
 4420         :clr JS(I%)
 4430     next
 4440   return
 4450   '
 4460   '     normalize coefficient of JW
 4470   '
 4480   *NormalizeJW
 4490     local I%,J%
 4500     for I%=PL% to PK%-1
 4510       if JW(I%) then JW=JW(I%)
 4520         :for J%=1 to P%-1
 4530            :JW(I%-J%*PM%)-=JW
 4540         :next
 4550         :clr JW(I%)
 4560     next
 4570   return
 4580   '
 4590   'GENSHI version 1.4
 4600   fnGenshi(P)
 4610     local Gen=1,N=P-1,Nw,Div,SW%
 4620     repeat
 4630       inc Gen:Nw=N:SW%=1
 4640       repeat
 4650         Div=prmdiv(Nw)
 4660         repeat:Nw=Nw\Div:until res:Nw=Nw*Div+res
 4670         if modpow(Gen,N\Div,P)=1 then SW%=0:Nw=1
 4680       until Nw=1
 4690     until SW%
 4700   return(Gen)
 4710   '
 4720   *GetAllQs(T)
 4730     local I%,Q
 4740     for I%=2 to Prms32767%
 4750       Q=prm(I%)
 4760       if T@(Q-1)=0 then
 4770         :inc NQall%:Qmem%(NQall%)=Q
 4780     next
 4790   return
 4800   '
 4810   *GetQsGs(T)
 4820     local I%,Q
 4830     for I%=2 to NQall%
 4840       Q=Qmem%(I%)
 4850       if and{Q<>0,T@(Q-1)=0} then
 4860         :inc TestingQs%
 4870         :Q%(TestingQs%)=Q:G%(TestingQs%)=fnGenshi(Q):Qmem%(I%)=0
 4880     next
 4890   return
 4900   '
 4910   fnPowerIndex(P%,X)
 4920     local K%=-1
 4930       repeat inc K%:X=X\P% until res
 4940   return(K%)



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.