home *** CD-ROM | disk | FTP | other *** search
/ Math Solutions 1995 October / Math_Solutions_CD-ROM_Walnut_Creek_October_1995.iso / pc / mac / discrete / lib / integer.g < prev    next >
Encoding:
Text File  |  1993-05-05  |  44.7 KB  |  1,255 lines

  1. #############################################################################
  2. ##
  3. #A  integer.g                   GAP library                  Martin Schoenert
  4. #A                                                           & Alice Niemeyer
  5. #A                                                            & Werner Nickel
  6. #A                                                              & Alex Wegner
  7. ##
  8. #A  @(#)$Id: integer.g,v 3.24 1993/02/15 09:21:28 fceller Rel $
  9. ##
  10. #Y  Copyright 1990-1992,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
  11. ##
  12. ##  This file contains  those  functions  that  mainly  deal  with  integers.
  13. ##
  14. #H  $Log: integer.g,v $
  15. #H  Revision 3.24  1993/02/15  09:21:28  fceller
  16. #H  fixed 'Integers.units' and 'IntegerOps.IsIrreducible'
  17. #H
  18. #H  Revision 3.23  1993/02/10  21:20:25  martin
  19. #H  fixed the error message of 'ChineseRemainder'
  20. #H
  21. #H  Revision 3.22  1992/12/16  19:47:27  martin
  22. #H  replaced quoted record names with escaped ones
  23. #H
  24. #H  Revision 3.21  1992/09/10  10:39:33  martin
  25. #H  fixed the problem in 'IsPrimeInt'
  26. #H
  27. #H  Revision 3.20  1992/06/04  07:41:10  fceller
  28. #H  added some primes occuring in q^n-1
  29. #H
  30. #H  Revision 3.19  1992/03/19  18:16:39  martin
  31. #H  added 'IntegersOps.Field'
  32. #H
  33. #H  Revision 3.18  1992/02/06  11:47:31  martin
  34. #H  removed 'InverseMod' and added 'QuotientMod'
  35. #H
  36. #H  Revision 3.17  1991/12/27  15:06:20  martin
  37. #H  moved 'IsPrimeInt', 'FactorsInt', etc. to 'integer.g'
  38. #H
  39. #H  Revision 3.16  1991/12/27  15:01:19  martin
  40. #H  moved 'Rationals' to 'rational.g'
  41. #H
  42. #H  Revision 3.15  1991/12/04  10:57:26  martin
  43. #H  added 'isCyclotomicField' to 'Rationals'
  44. #H
  45. #H  Revision 3.14  1991/10/24  11:58:52  martin
  46. #H  added 'LcmInt' again
  47. #H
  48. #H  Revision 3.13  1991/10/24  11:33:29  martin
  49. #H  changed package for new domain concept with inheritance
  50. #H
  51. #H  Revision 3.12  1991/08/08  16:00:00  martin
  52. #H  added functions for rationals
  53. #H
  54. #H  Revision 3.11  1991/08/08  15:30:00  martin
  55. #H  changed the integer package for domains
  56. #H
  57. #H  Revision 3.10  1991/06/28  14:00:00  martin
  58. #H  moved 'Maximum' and 'Minimum' to the list package
  59. #H
  60. #H  Revision 3.9  1991/06/28  13:00:00  martin
  61. #H  removed 'Random'
  62. #H
  63. #H  Revision 3.8  1991/06/02  13:00:00  martin
  64. #H  improved 'Gcdex'
  65. #H
  66. #H  Revision 3.7  1991/06/02  12:00:00  martin
  67. #H  removed 'GcdInt' since there is an internal function of that name
  68. #H
  69. #H  Revision 3.6  1991/06/01  17:00:00  martin
  70. #H  changed 'IsPrime' to 'IsPrimeInt', 'Factors' to 'FactorsInt', ...
  71. #H
  72. #H  Revision 3.5  1991/06/01  16:00:00  martin
  73. #H  changed 'Gcd' to 'GcdInt', 'Lcm' to 'LcmInt', ...
  74. #H
  75. #H  Revision 3.4  1991/06/01  12:00:00  martin
  76. #H  changed 'Quo' to 'QuoInt'
  77. #H
  78. #H  Revision 3.3  1991/01/07  12:00:00  martin
  79. #H  changed 'Sign' to refuse permutations
  80. #H
  81. #H  Revision 3.2  1990/11/26  12:00:00  martin
  82. #H  renamed 'Combination' to 'ChineseRem'
  83. #H
  84. #H  Revision 3.1  1990/11/16  12:00:00  martin
  85. #H  moved functions from integer to combinatorics package
  86. #H
  87. #H  Revision 3.0  1990/01/01  12:00:00  martin
  88. #H  initial revision under RCS
  89. #H
  90. ##
  91.  
  92.  
  93. #############################################################################
  94. ##
  95. #V  Integers  . . . . . . . . . . . . . . . . . . . . .  ring of the integers
  96. #V  IntegersOps . . . . . . . . . . . . . . . . operation record for integers
  97. ##
  98. IntegersOps := Copy( RingOps );
  99.  
  100. Integers := rec(
  101.     isDomain                    := true,
  102.     isRing                      := true,
  103.  
  104.     generators                  := [ 1 ],
  105.     zero                        := 0,
  106.     one                         := 1,
  107.     name                        := "Integers",
  108.  
  109.     size                        := "infinity",
  110.     isFinite                    := false,
  111.     isCommutativeRing           := true,
  112.     isIntegralRing              := true,
  113.     isUniqueFactorizationRing   := true,
  114.     isEuclideanRing             := true,
  115.     units                       := [ -1, 1 ],
  116.  
  117.     operations                  := IntegersOps
  118. );
  119.  
  120.  
  121. #############################################################################
  122. ##
  123. #F  IntegersOps.Ring(<elms>)  . . . . . . . . ring generated by some integers
  124. ##
  125. IntegersOps.Ring := function ( elms )
  126.     return Integers;
  127. end;
  128.  
  129.  
  130. #############################################################################
  131. ##
  132. #F  IntegersOps.DefaultRing(<elms>) . . . . . . default ring of some integers
  133. ##
  134. IntegersOps.DefaultRing := function ( elms )
  135.     return Integers;
  136. end;
  137.  
  138.  
  139. #############################################################################
  140. ##
  141. #F  IntegersOps.Field(<elms>) . . . . . . .  field generated by some integers
  142. ##
  143. IntegersOps.Field := function ( elms )
  144.     return Rationals;
  145. end;
  146.  
  147.  
  148. #############################################################################
  149. ##
  150. #F  IntegersOps.DefaultField(<elms>) . . . . . default field of some integers
  151. ##
  152. IntegersOps.DefaultField := function ( elms )
  153.     return Rationals;
  154. end;
  155.  
  156.  
  157. #############################################################################
  158. ##
  159. #F  IntegersOps.\in(<n>,<Integers>)  . . . . . . mebership test for integers
  160. ##
  161. IntegersOps.\in := function ( n, Integers )
  162.     return IsInt( n );
  163. end;
  164.  
  165.  
  166. #############################################################################
  167. ##
  168. #F  IntegersOps.Random(<Integers>)  . . . . . . . . . . . . .  random integer
  169. ##
  170. NrBitsInt := function ( n )
  171.     local   nr, nr64;
  172.     nr64:=[0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
  173.            1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6];
  174.     nr := 0;
  175.     while 0 < n  do
  176.         nr := nr + nr64[ n mod 64 + 1 ];
  177.         n := QuoInt( n, 64 );
  178.     od;
  179.     return nr;
  180. end;
  181.  
  182. IntegersOps.Random := function ( Integers )
  183.     return NrBitsInt( RandomList( [0..2^20-1] ) ) - 10;
  184. end;
  185.  
  186.  
  187. #############################################################################
  188. ##
  189. #F  IntegersOps.Quotient(<Integers>,<n>,<m>)  . . .  quotient of two integers
  190. ##
  191. IntegersOps.Quotient := function ( Integers, n, m )
  192.     local   q;
  193.     q := QuoInt( n, m );
  194.     if n <> q * m  then
  195.         q := false;
  196.     fi;
  197.     return q;
  198. end;
  199.  
  200.  
  201. #############################################################################
  202. ##
  203. #F  IntegersOps.StandardAssociate(<Integers>,<n>) . . . . . .  absolute value
  204. ##
  205. IntegersOps.StandardAssociate := function ( Integers, n )
  206.     if n < 0  then
  207.         return -n;
  208.     else
  209.         return n;
  210.     fi;
  211. end;
  212.  
  213.  
  214. #############################################################################
  215. ##
  216. #F  IntegersOps.IsPrime(<Integers>,<n>) .  test whether an integer is a prime
  217. ##
  218. IntegersOps.IsPrime := function ( Integers, n )
  219.     return IsPrimeInt( n );
  220. end;
  221.  
  222.  
  223. #############################################################################
  224. ##
  225. #F  IntegersOps.IsIrreducible(<Integers>,<n>)
  226. ##
  227. IntegersOps.IsIrreducible := IntegersOps.IsPrime;
  228.  
  229.  
  230. #############################################################################
  231. ##
  232. #V  Primes[]  . . . . . . . . . . . . . . . . . . . . . . . .  list of primes
  233. ##
  234. ##  'Primes' is a set, i.e., sorted list, of the 168 primes less than 1000.
  235. ##
  236. ##  This is used in 'IsPrimeInt' and 'FactorsInt' to cast  out  small  primes
  237. ##  quickly.
  238. ##
  239. Primes := [   2,  3,  5,  7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
  240.      59, 61, 67, 71, 73, 79, 83, 89, 97,101,103,107,109,113,127,131,137,139,
  241.     149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,
  242.     241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,
  243.     353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,
  244.     461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,
  245.     587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,
  246.     691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,
  247.     823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,
  248.     947,953,967,971,977,983,991,997 ];
  249. IsSet( Primes );
  250.  
  251.  
  252. #############################################################################
  253. ##
  254. #V  Primes2[] . . . . . . . . . . . . . . . . . . . . . additional prime list
  255. ##
  256. ##  'Primes2' contains those primes found by  'IsPrimeInt'  that  are  not in
  257. ##  'Primes'.  'Primes2' is kept sorted, but may contain holes.
  258. ##
  259. ##  'IsPrimeInt' and  'FactorsInt'  use this list to   cast out already found
  260. ##  primes quickly.  If 'IsPrimeInt' is called only  for random integers this
  261. ##  list  would  be quite useless.   However, users  do not  behave randomly.
  262. ##  Instead, it is not uncommon to factor the  same integer twice.  Likewise,
  263. ##  once we have  tested  that $2^{31}-1$  is prime,  factoring $2^{62}-1$ is
  264. ##  very cheap, because the former divides the latter.
  265. ##
  266. ##  This list is initialized to contain all the prime factors of the integers
  267. ##  $2^n-1$ with $n < 201$,  $3^n-1$ with $n < 101$,  $5^n-1$ with $n < 101$,
  268. ##  $7^n-1$ with $n < 91$, $11^n-1$ with $n < 79$, and $13^n-1$ with $n < 37$
  269. ##  that are larger than $10^7$.
  270. ##
  271. Primes2 := [
  272. 10047871, 10567201, 10746341, 12112549, 12128131, 12207031, 12323587,
  273. 12553493, 12865927, 13097927, 13264529, 13473433, 13821503, 13960201,
  274. 14092193, 14597959, 15216601, 15790321, 16018507, 18837001, 20381027,
  275. 20394401, 20515111, 20515909, 21207101, 21523361, 22253377, 22366891,
  276. 22996651, 23850061, 25781083, 26295457, 28325071, 28878847, 29010221,
  277. 29247661, 29423041, 29866451, 32234893, 32508061, 36855109, 41540861,
  278. 42521761, 43249589, 44975113, 47392381, 47763361, 48544121, 48912491,
  279. 49105547, 49892851, 51457561, 55527473, 56409643, 56737873, 59302051,
  280. 59361349, 59583967, 60816001, 62020897, 65628751, 69566521, 75068993,
  281. 76066181, 85280581, 93507247, 96656723, 97685839,
  282. 106431697, 107367629, 109688713, 110211473, 112901153, 119782433, 127540261,
  283. 134818753, 134927809, 136151713, 147300841, 160465489, 164511353, 177237331,
  284. 183794551, 184481113, 190295821, 190771747, 193707721, 195019441, 202029703,
  285. 206244761, 212601841, 212885833, 228511817, 231769777, 234750601, 272010961,
  286. 283763713, 297315901, 305175781, 308761441, 319020217, 359390389, 407865361,
  287. 420778751, 424256201, 432853009, 457315063, 466344409, 510810301, 515717329,
  288. 527093491, 529510939, 536903681, 540701761, 550413361, 603926681, 616318177,
  289. 632133361, 715827883, 724487149, 745988807, 815702161, 834019001, 852133201,
  290. 857643277, 879399649,
  291. 1001523179, 1036745531, 1065264019, 1106131489, 1169382127, 1390636259,
  292. 1503418321, 1527007411, 1636258751, 1644512641, 1743831169, 1824179209,
  293. 1824726041, 1826934301, 1866013003, 1990415149, 2127431041, 2147483647,
  294. 2238236249, 2316281689, 2413941289, 2481791513, 2550183799, 2576743207,
  295. 2664097031, 2767631689, 2903110321, 2931542417, 3158528101, 3173389601,
  296. 3357897971, 4011586307, 4058036683, 4278255361, 4375578271, 4562284561,
  297. 4649919401, 4698932281, 4795973261, 4885168129, 5960555749, 6809710909,
  298. 7068569257, 7151459701, 7484047069, 7685542369, 7830118297, 7866608083,
  299. 8209475377, 8831418697, 9598959833,
  300. 10879733611, 11898664849, 12447002677, 13455809771, 13564461457, 13841169553,
  301. 13971969971, 14425532687, 15085812853, 15768033143, 15888756269, 16148168401,
  302. 17154094481, 17189128703, 19707683773, 22434744889, 23140471537, 23535794707,
  303. 24127552321, 25480398173, 25829691707, 25994736109, 27669118297, 27989941729,
  304. 28086211607, 30327152671, 32952799801, 33057806959, 35532364099, 39940132241,
  305. 43872038849, 45076044553, 47072139617, 50150933101, 54410972897, 56625998353,
  306. 60726444167, 61070817601, 62983048367, 70845409351, 76831835389, 77158673929,
  307. 77192844961, 78009515593, 83960385389, 86950696619, 88959882481, 99810171997,
  308. 115868130379, 125096112091, 127522693159, 128011456717, 128653413121,
  309. 131105292137, 152587500001, 158822951431, 159248456569, 164504919713,
  310. 165768537521, 168749965921, 229890275929, 241931001601, 269089806001,
  311. 282429005041, 332207361361, 374857981681, 386478495679, 392038110671,
  312. 402011881627, 441019876741, 447600088289, 487824887233, 531968664833,
  313. 555915824341, 593554036769, 598761682261, 641625222857, 654652168021,
  314. 761838257287, 810221830361, 840139875599, 918585913061,
  315. 1030330938209, 1047623475541, 1113491139767, 1133836730401, 1273880539247,
  316. 1534179947851, 1628744948329, 1654058017289, 1759217765581, 1856458657451,
  317. 2098303812601, 2454335007529, 2481357870461, 2549755542947, 2663568851051,
  318. 2879347902817, 2932031007403, 3138426605161, 3203431780337, 3421169496361,
  319. 3740221981231, 4363953127297, 4432676798593, 4446437759531, 4534166740403,
  320. 4981857697937, 5625767248687, 6090817323763, 6493405343627, 6713103182899,
  321. 6740339310641, 7432339208719, 8090594434231, 8157179360521, 8737481256739,
  322. 8868050880709, 9361973132609, 9468940004449, 9857737155463,
  323. 10052678938039, 10979607179423, 13952598148481, 15798461357509,
  324. 18158209813151, 22125996444329, 22542470482159, 22735632934561,
  325. 23161037562937, 23792163643711, 24517014940753, 24587411156281,
  326. 28059810762433, 29078814248401, 31280679788951, 31479823396757,
  327. 33232924804801, 42272797713043, 44479210368001, 45920153384867,
  328. 49971617830801, 57583418699431, 62911130477521, 67280421310721,
  329. 70601370627701, 71316922984999, 83181652304609, 89620825374601,
  330. 110133112994711, 140737471578113, 145295143558111, 150224123975857,
  331. 204064664440913, 205367807127911, 242099935645987, 270547105429567,
  332. 303567967057423, 332584516519201, 434502978835771, 475384700124973,
  333. 520518327319589, 560088668384411, 608459012088799, 637265428480297,
  334. 643170158708221, 707179356161321, 926510094425921, 990643452963163,
  335. 1034150930241911, 1066818132868207, 1120648576818041, 1357105535093947,
  336. 1416258521793067, 1587855697992791, 1611479891519807, 1628413557556843,
  337. 1958423494433591, 2134387368610417, 2646507710984041, 2649263870814793,
  338. 2752135920929651, 2864226125209369, 4889988840047743, 5420506947192709,
  339. 6957533874046531, 9460375336977361, 9472026608675509,
  340. 12557612956332313, 13722816749522711, 14436295738510501, 18584774046020617,
  341. 18624275418445601, 20986207825565581, 21180247636732981, 22666879066355177,
  342. 27145365052629449, 46329453543600481, 50544702849929377, 59509429687890001,
  343. 60081451169922001, 70084436712553223, 76394148218203559, 77001139434480073,
  344. 79787519018560501, 96076791871613611,
  345. 133088039373662309, 144542918285300809, 145171177264407947,
  346. 153560376376050799, 166003607842448777, 177722253954175633,
  347. 196915704073465747, 316825425410373433, 341117531003194129,
  348. 380808546861411923, 489769993189671059, 538953023961943033,
  349. 581283643249112959, 617886851384381281, 625552508473588471,
  350. 645654335737185721, 646675035253258729, 658812288653553079,
  351. 768614336404564651, 862970652262943171, 909456847814334401,
  352. 1100876018364883721, 1195857367853217109, 1245576402371959291,
  353. 1795918038741070627, 2192537062271178641, 2305843009213693951,
  354. 2312581841562813841, 2461243576713869557, 2615418118891695851,
  355. 2691614274040036601, 3011347479614249131, 3358335487319458201,
  356. 3421093417510114543, 3602372010909260861, 3747607031112307667,
  357. 3999088279399464409, 4710883168879506001, 5079304643216687969,
  358. 5559917315850179173, 5782172113400990737, 6106505825833677713,
  359. 6115909044841454629, 9213624084535989031, 9520972806333758431,
  360. 10527743181888260981, 14808607715315782481, 18446744069414584321,
  361. 26831423036065352611, 32032215596496435569, 34563155350221618511,
  362. 36230454570129675721, 58523123221688392679, 82064241848634269407,
  363. 86656268566282183151, 87274497124602996457,
  364. 157571957584602258799, 162715052426691233701, 172827552198815888791,
  365. 195489390796456327201, 240031591394168814433, 344120456368919234899,
  366. 358475907408445923469, 846041103974872866961,
  367. 2519545342349331183143, 3658524738455131951223, 3976656429941438590393,
  368. 5439042183600204290159, 8198241112969626815581,
  369. 11600321878916922053491, 12812432238302009985937, 17551032119981679046729,
  370. 18489605314740987765913, 27665283091695977275201, 42437717969530394595211,
  371. 57912614113275649087721, 61654440233248340616559, 63681511996418550459487,
  372. 105293313660391861035901, 155285743288572277679887, 201487636602438195784363,
  373. 231669654363683130095909, 235169662395069356312233, 402488219476647465854701,
  374. 535347624791488552837151, 604088623657497125653141, 870035986098720987332873,
  375. 950996059627210897943351,
  376. 1412900479108654932024439, 1431185706701868962383741,
  377. 2047572230657338751575051, 2048568835297380486760231,
  378. 2741672362528725535068727, 3042645634792541312037847,
  379. 3745603812007166116831643, 4362139336229068656094783,
  380. 4805345109492315767981401, 5042939439565996049162197,
  381. 7289088383388253664437433, 8235109336690846723986161,
  382. 9680647790568589086355559, 9768997162071483134919121,
  383. 9842332430037465033595921,
  384. 11053036065049294753459639, 11735415506748076408140121,
  385. 13842607235828485645766393, 17499733663152976533452519,
  386. 26273701844015319144827917, 75582488424179347083438319,
  387. 88040095945103834627376781,
  388. 100641220283951395639601683, 140194179307171898833699259,
  389. 207617485544258392970753527, 291280009243618888211558641,
  390. 303309617049998388989376043, 354639323684545612988577649,
  391. 618970019642690137449562111, 913242407367610843676812931,
  392. 7222605228105536202757606969, 7248808599285760001152755641,
  393. 8170509011431363408568150369, 8206973609150536446402438593,
  394. 9080418348371887359375390001,
  395. 14732265321145317331353282383, 15403468930064931175264655869,
  396. 15572244900182528777225808449, 18806327041824690595747113889,
  397. 21283620033217629539178799361, 37201708625305146303973352041,
  398. 42534656091583268045915654719, 48845962828028421155731228333,
  399. 123876132205208335762278423601, 134304196845099262572814573351,
  400. 172974812463239310024750410929, 217648180992721729506406538251,
  401. 227376585863531112677002031251,
  402. 1786393878363164227858270210279, 2598696228942460402343442913969,
  403. 2643999917660728787808396988849, 3340762283952395329506327023033,
  404. 5465713352000770660547109750601,
  405. 28870194250662203210437116612769, 70722308812401674174993533367023,
  406. 78958087694609321439660131899631, 88262612316754526107621113329689,
  407. 162259276829213363391578010288127, 163537220852725398851434325720959,
  408. 177635683940025046467781066894531,
  409. 2679895157783862814690027494144991, 3754733257489862401973357979128773,
  410. 5283012903770196631383821046101707, 5457586804596062091175455674392801,
  411. 10052011757370829033540932021825161, 11419697846380955982026777206637491,
  412. 38904276017035188056372051839841219,
  413. 1914662449813727660680530326064591907, 7923871097285295625344647665764672671,
  414. 9519524151770349914726200576714027279,
  415. 10350794431055162386718619237468234569,
  416. 170141183460469231731687303715884105727,
  417. 1056836588644853738704557482552056406147,
  418. 6918082374901313855125397665325977135579,
  419. 235335702141939072378977155172505285655211,
  420. 360426336941693434048414944508078750920763,
  421. 1032670816743843860998850056278950666491537,
  422. 1461808298382111034194027645506019619578037,
  423. 79638304766856507377778616296087448490695649,
  424. 169002145064468556765676975247413756542145739,
  425. 8166146875847876762859119015147004762656450569,
  426. 18607929421228039083223253529869111644362732899,
  427. 33083146850190391025301565142735000331370209599,
  428. 138497973518827432485604572537024087153816681041,
  429. 673267426712748387612994804392183645147042355211,
  430. 1489459109360039866456940197095433721664951999121,
  431. 4884164093883941177660049098586324302977543600799,
  432. 466345922275629775763320748688970211803553256223529,
  433. 26828803997912886929710867041891989490486893845712448833,
  434. 153159805660301568024613754993807288151489686913246436306439,
  435. 1051153199500053598403188407217590190707671147285551702341089650185945215953
  436. ];
  437. IsSet( Primes2 );
  438.  
  439.  
  440. #############################################################################
  441. ##
  442. #F  IsPrimeInt( <n> ) . . . . . . . . . . . . . . . . . . .  test for a prime
  443. ##
  444. ##  'IsPrimeInt' returns 'true' if the  integer <n>  is  a prime  and 'false'
  445. ##  otherwise.  By convention 'IsPrimeInt( 0 ) = IsPrimeInt( 1 ) = false' and
  446. ##  we define 'IsPrimeInt( -<n> ) = IsPrimeInt( <n> )'.
  447. ##
  448. ##  'IsPrimeInt' does trial divisions by the primes less  than 1000 to detect
  449. ##  composites with a factor less than 1000 and  primes  less  than  1000000.
  450. ##
  451. ##  'IsPrimeInt' then checks that $n$ is a strong pseudoprime to the  base 2.
  452. ##  This uses Fermats theorem which says $2^{n-1}=1$ mod $n$ for a prime $n$.
  453. ##  If $2^{n-1}\<>1$ mod $n$, $n$ is composite, 'IsPrimeInt' returns 'false'.
  454. ##  There are composite numbers for which $2^{n-1}=1$,  but they are  seldom.
  455. ##
  456. ##  Then 'IsPrimeInt' checks that $n$ is a Lucas pseudoprime for $p$, choosen
  457. ##  so that the discriminant $d=p^2/4-1$ is an  quadratic nonresidue mod $n$.
  458. ##  I.e., 'IsPrimeInt' takes the root $a = p/2+\sqrt{d}$ of $x^2 - px + 1$ in
  459. ##  the  ring $Z_n[\sqrt{d}] and computes the  traces of $a^n$ and $a^{n+1}$.
  460. ##  If $n$ is a prime, this  ring is the field of  order $n^2$ and raising to
  461. ##  the $n$th power is conjugation, so $trace(a^n)=p$ and $trace(a^{n+1})=2$.
  462. ##  However, these identities hold only for extremly few composite numbers.
  463. ##
  464. ##  Note that  this  test  for $trace(a^n) = p$  and  $trace(a^{n+1}) = 2$ is
  465. ##  usually formulated using the Lucas sequences  $U_k = (a^k-b^k)/(a-b)$ and
  466. ##  $V_k = (a^k+b^k)=trace(a^k)$, where one tests $U_{n+1} = 0, V_{n+1} = 2$.
  467. ##  However, the trace test is equivalent and requires fewer multiplications.
  468. ##  Thanks to Daniel R. Grayson (dan@symcom.math.uiuc.edu)  for  telling  me.
  469. ##
  470. ##  Better descriptions of the algorithm and related topics can be found  in:
  471. ##  G. Miller, cf. Algorithms and Complexity ed. Traub, AcademPr, 1976, 35-36
  472. ##  C. Pomerance et.al., Pseudoprimes to 25*10^9, MathComp 35 1980, 1003-1026
  473. ##  D. Knuth, Seminumerical Algorithms  (TACP II),  AddiWesl,  1973,  378-380
  474. ##  G. Gonnet, Heuristic Primality Testing, Maple Newsletter 4,  1989,  36-38
  475. ##  R. Baillie, S. Wagstaff, Lucas Pseudoprimes, MathComp 35 1980,  1391-1417
  476. ##
  477. TraceModQF := function ( p, k, n )
  478.     local  trc;
  479.     if k = 1  then
  480.         trc := [ p, 2 ];
  481.     elif k mod 2 = 0  then
  482.         trc := TraceModQF( p, k/2, n );
  483.         trc := [ (trc[1]^2 - 2) mod n, (trc[1]*trc[2] - p) mod n ];
  484.     else
  485.         trc := TraceModQF( p, (k+1)/2, n );
  486.         trc := [ (trc[1]*trc[2] - p) mod n, (trc[2]^2 - 2) mod n ];
  487.     fi;
  488.     return trc;
  489. end;
  490.  
  491. IsPrimeInt := function ( n )
  492.     local  p, e, o, x, i, d;
  493.  
  494.     # make $n$ positive and handle trivial cases
  495.     if n < 0         then n := -n;       fi;
  496.     if n in Primes   then return true;   fi;
  497.     if n in Primes2  then return true;   fi;
  498.     if n <= 1000     then return false;  fi;
  499.  
  500.     # do trial divisions by the primes less than 1000
  501.     # faster than anything fancier because $n$ mod <small int> is very fast
  502.     for p  in Primes  do
  503.         if n mod p = 0  then return false;  fi;
  504.         if n < (p+1)^2  then AddSet(Primes2,n);  return true;   fi;
  505.     od;
  506.  
  507.     # do trial division by the other known primes
  508.     for p  in Primes2  do
  509.         if n mod p = 0  then return false;  fi;
  510.     od;
  511.  
  512.     # find $e$ and $o$ odd such that $n-1 = 2^e * o$
  513.     e := 0;  o := n-1;   while o mod 2 = 0  do e := e+1;  o := o/2;  od;
  514.  
  515.     # look at the seq $2^o, 2^{2 o}, 2^{4 o}, .., 2^{2^e o}=2^{n-1}$
  516.     x := PowerModInt( 2, o, n );
  517.     i := 0;
  518.     while i < e  and x <> 1  and x <> n-1  do
  519.         x := x * x mod n;
  520.         i := i + 1;
  521.     od;
  522.  
  523.     # if it is not of the form $.., -1, 1, 1, ..$ then $n$ is composite
  524.     if not (x = n-1 or (i = 0 and x = 1))  then
  525.         return false;
  526.     fi;
  527.  
  528.     # there are no strong pseudo-primes to base 2 smaller than 2047
  529.     if n < 2047  then
  530.         AddSet( Primes2, n );
  531.         return true;
  532.     fi;
  533.  
  534.     # make sure that $n$ is not a perfect power (especially not a square)
  535.     if SmallestRootInt(n) < n  then
  536.         return false;
  537.     fi;
  538.  
  539.     # find a quadratic nonresidue $d = p^2/4-1$ mod $n$
  540.     p := 2;  while Jacobi( p^2-4, n ) <> -1  do p := p+1;  od;
  541.  
  542.     # for a prime $n$ the trace of $(p/2+\sqrt{d})^n$ must be $p$
  543.     # and the trace of $(p/2+\sqrt{d})^{n+1}$ must be 2
  544.     if TraceModQF( p, n+1, n ) = [ 2, p ]  then
  545.         AddSet( Primes2, n );
  546.         return true;
  547.     fi;
  548.  
  549.     # $n$ is not a prime
  550.     return false;
  551. end;
  552.  
  553.  
  554. #############################################################################
  555. ##
  556. #F  IsPrimePowerInt( <n> )  . . . . . . . . . . . test for a power of a prime
  557. ##
  558. ##  'IsPrimePowerInt' returns 'true' if the integer <n>  is a prime power and
  559. ##  'false' otherwise.
  560. ##
  561. IsPrimePowerInt := function ( n )
  562.     return IsPrimeInt( SmallestRootInt( n ) );
  563. end;
  564.  
  565.  
  566. #############################################################################
  567. ##
  568. #F  NextPrimeInt( <n> ) . . . . . . . . . . . . . . . . . . next larger prime
  569. ##
  570. ##  'NextPrimeInt' returns the smallest prime  which is strictly larger  than
  571. ##  the integer <n>.
  572. ##
  573. NextPrimeInt := function ( n )
  574.     if   -3 = n             then n := -2;
  575.     elif -3 < n  and n < 2  then n :=  2;
  576.     elif n mod 2 = 0        then n := n+1;
  577.     else                         n := n+2;
  578.     fi;
  579.     while not IsPrimeInt(n)  do
  580.         if n mod 6 = 1  then n := n+4;
  581.         else                 n := n+2;
  582.         fi;
  583.     od;
  584.     return n;
  585. end;
  586.  
  587.  
  588. #############################################################################
  589. ##
  590. #F  PrevPrimeInt( <n> ) . . . . . . . . . . . . . . .  previous smaller prime
  591. ##
  592. ##  'PrevPrimeInt' returns the largest prime  which is strictly smaller  than
  593. ##  the integer <n>.
  594. ##
  595. PrevPrimeInt := function ( n )
  596.     if    3 = n             then n :=  2;
  597.     elif -2 < n  and n < 3  then n := -2;
  598.     elif n mod 2 = 0        then n := n-1;
  599.     else                         n := n-2;
  600.     fi;
  601.     while not IsPrimeInt(n)  do
  602.         if n mod 6 = 5  then n := n-4;
  603.         else                 n := n-2;
  604.         fi;
  605.     od;
  606.     return n;
  607. end;
  608.  
  609.  
  610. #############################################################################
  611. ##
  612. #F  IntegersOps.Factors(<Integers>,<n>) . . . . . factorization of an integer
  613. ##
  614. IntegersOps.Factors := function ( Integers, n )
  615.     return FactorsInt( n );
  616. end;
  617.  
  618.  
  619. #############################################################################
  620. ##
  621. #F  FactorsInt( <n> ) . . . . . . . . . . . . . . prime factors of an integer
  622. #F  FactorsRho(<n>,<inc>,<cluster>,<limit>) . . .  Pollards rho factorization
  623. ##
  624. ##  'FactorsInt' returns a list of prime factors of the integer <n>.
  625. ##
  626. ##  'FactorsInt' does trial divisions by the primes less than 1000 to  detect
  627. ##  all composites with a factor less than 1000 and primes less than 1000000.
  628. ##  After that it calls 'FactorsRho(<n>,1,16,8192)' to do the hard work.
  629. ##
  630. ##  'FactorsInt' and 'FactorsRho' return the same  value  for  all  integers.
  631. ##  Usually 'FactorsInt' factors integers with prime factors $\<1000$ faster.
  632. ##  However for integers with no factor $\<1000$ 'FactorsRho' will be faster.
  633. ##
  634. ##  'FactorsRho' uses Pollards $\rho$ method to factor the integer $n = p q$.
  635. ##  For a small simple example lets assume we want to factor $667 = 23 * 29$.
  636. ##  'FactorsRho' first calls 'IsPrimeInt' to avoid trying to factor a prime.
  637. ##
  638. ##  Then it uses the sequence defined by  $x_0=1, x_{i+1}=(x_i^2+1)$ mod $n$.
  639. ##  In our example this is $1, 2, 5, 26, 10, 101, 197, 124, 36, 630, .. $.
  640. ##
  641. ##  Modulo $p$ it takes on at most $p-1$ different values, thus it eventually
  642. ##  becomes recurrent, usually this happens after roughly $2 \sqrt{p}$ steps.
  643. ##  In our example modulo 23 we get $1, 2, 5, 3, 10, 9, 13, 9, 13, 9, .. $.
  644. ##
  645. ##  Thus there exist pairs $i, j$ such that $x_i = x_j$ mod $p$,  i.e.,  such
  646. ##  that $p$ divides $Gcd( n, x_j-x_i )$.  With a bit of luck no other factor
  647. ##  of $n$ divides $x_j - x_i$ so we find $p$ if we know such a pair.  In our
  648. ##  example $5, 7$ is the first pair, $x_7-x_5=23$, and $Gcd(667,23) = 23$.
  649. ##
  650. ##  Now it is too expensive to check all pairs, but there also must be  pairs
  651. ##  of the form $2^i-1, j$ with $3*2^{i-1} <= j < 4*2^{i-1}$.  In our example
  652. ##  $7, 13$ is the first such pair, $x_13-x_7=506$, and $Gcd(667,506) = 23$.
  653. ##
  654. ##  Thus by taking the gcds of $n$ and $x_j-x_i$ for such pairs, we will find
  655. ##  the factor $p$ after approximately $2 \sqrt{p} \<= 2 \sqrt^4{n}$ steps.
  656. ##
  657. ##  If $Gcd( n, x_j - x_i )$  is not a prime 'FactorsRho'  will  call  itself
  658. ##  recursivly with a different value for <inc>, i.e., it  will try to factor
  659. ##  the gcd using a different sequence $x_{i+1} = (x_i^2 + inc)$ mod $n$.
  660. ##
  661. ##  Since the gcd computations are by far the most time consuming part of the
  662. ##  algorithm  one can save time by  clustering differences and computing the
  663. ##  gcd  only every <cluster>  iteration.  This slightly increases the chance
  664. ##  that a gcd is composite, but reduces the runtime by a large amount.
  665. ##
  666. ##  Finally 'FactorsRho' accepts an argument <limit>  which is the number  of
  667. ##  iterations  performed by 'FactorsRho' before giving up. The default value
  668. ##  is  8192  which corresponds to a few minutes  while guaranteing that  all
  669. ##  prime factors less than $10^6$ and most less than $10^9$ are found.
  670. ##
  671. ##  Better descriptions of the algorithm and related topics can be found  in:
  672. ##  J. Pollard, A Monte Carlo Method for Factorization, BIT 15, 1975, 331-334
  673. ##  R. Brent, An Improved Monte Carlo Method for Fact., BIT 20, 1980, 176-184
  674. ##  D. Knuth, Seminumerical Algorithms  (TACP II),  AddiWesl,  1973,  369-371
  675. ##
  676. FactorsRho := function ( n, inc, cluster, limit )
  677.     local   sign, factors, x, y, z, i, g, k;
  678.  
  679.     # make $n$ positive and handle trivial cases
  680.     sign := 1;
  681.     if n < 0  then sign := -sign;  n := -n;  fi;
  682.     if n < 4  then return [ sign * n ];  fi;
  683.     factors := [];
  684.     while n mod 2 = 0  do Add( factors, 2 );  n := n / 2;  od;
  685.     while n mod 3 = 0  do Add( factors, 3 );  n := n / 3;  od;
  686.     if IsPrimeInt(n)  then Add( factors, n );  n := 1;  fi;
  687.  
  688.     # initialize $x_0$
  689.     x := 1;  z := 1;  i := 0;
  690.  
  691.     # loop until we have factored $n$ completely or run out of patience
  692.     while 1 < n  and 2^i <= limit  do
  693.  
  694.         # $y = x_{2^i-1}$
  695.         y := x;  i := i + 1;
  696.  
  697.         # $x_{2^i}, .., x_{3*2^{i-1}-1}$ need not be compared to $x_{2^i-1}$
  698.         for k  in [1..2^(i-1)]  do
  699.             x := (x^2 + inc) mod n;
  700.         od;
  701.  
  702.         # compare $x_{3*2^{i-1}}, .., x_{4*2^{i-1}-1}$ with $x_{2^i-1}$
  703.         for k  in [1..2^(i-1)]  do
  704.             x := (x^2 + inc) mod n;
  705.             z := z * (x - y) mod n;
  706.  
  707.             # from time to time compute the gcd
  708.             if k mod cluster = 0  then
  709.                 g := GcdInt( n, z );
  710.  
  711.                 # if it is > 1 we have found a factor which need not be prime
  712.                 if g > 1  then
  713.                     factors := Concatenation( factors,
  714.                               FactorsRho(g,inc+1,QuoInt(cluster+1,2),limit));
  715.                     n := n / g;
  716.                     if IsPrimeInt(n)  then Add( factors, n );  n := 1;  fi;
  717.                 fi;
  718.  
  719.             fi;
  720.  
  721.         od;
  722.  
  723.     od;
  724.  
  725.     # sort the list of factors and return it
  726.     if 1 < n  then Error("could not factor",n);  fi;
  727.     Sort( factors );
  728.     factors[1] := sign * factors[1];
  729.     return factors;
  730. end;
  731.  
  732. FactorsInt := function ( n )
  733.     local  sign, factors, p;
  734.  
  735.     # make $n$ positive and handle trivial cases
  736.     sign := 1;
  737.     if n < 0  then sign := -sign;  n := -n;  fi;
  738.     if n < 4  then return [ sign * n ];  fi;
  739.     factors := [];
  740.  
  741.     # do trial divisions by the primes less than 1000
  742.     # faster than anything fancier because $n$ mod <small int> is very fast
  743.     for p  in Primes  do
  744.         while n mod p = 0  do Add( factors, p );  n := n / p;  od;
  745.         if n < (p+1)^2 and 1 < n  then Add(factors,n);  n := 1;  fi;
  746.         if n = 1  then factors[1] := sign*factors[1];  return factors;  fi;
  747.     od;
  748.  
  749.     # do trial divisions by known factors
  750.     for p  in Primes2  do
  751.         while n mod p = 0  do Add( factors, p );  n := n / p;  od;
  752.         if n = 1  then factors[1] := sign*factors[1];  return factors;  fi;
  753.     od;
  754.  
  755.     # handle perfect powers
  756.     p := SmallestRootInt( n );
  757.     if p < n  then
  758.         while 1 < n  do
  759.             Append( factors, FactorsInt(p) );
  760.             n := n / p;
  761.         od;
  762.         Sort( factors );
  763.         factors[1] := sign * factors[1];
  764.         return factors;
  765.     fi;
  766.  
  767.     # let 'FactorsRho' do the work
  768.     factors := Concatenation( factors, FactorsRho( n, 1, 16, 8192 ) );
  769.     Sort( factors );
  770.     factors[1] := sign * factors[1];
  771.     return factors;
  772. end;
  773.  
  774.  
  775. #############################################################################
  776. ##
  777. #F  DivisorsInt( <n> )  . . . . . . . . . . . . . . .  divisors of an integer
  778. ##
  779. ##  'DivisorsInt' returns a list of all divisors  of  the  integer  <n>.  The
  780. ##  list is sorted, so that it starts with 1 and  ends  with <n>.  We  define
  781. ##  that 'Divisors( -<n> ) = Divisors( <n> )'.
  782. ##
  783. DivisorsSmall := [,[1],[1,2],[1,3],[1,2,4],[1,5],[1,2,3,6],[1,7]];
  784. DivisorsInt := function ( n )
  785.     local  divisors, factors, divs;
  786.  
  787.     # make <n> it nonnegative, handle trivial cases, and get prime factors
  788.     if n < 0  then n := -n;  fi;
  789.     if n = 0  then Error("DivisorsInt: <n> must not be 0");  fi;
  790.     if n < 8  then return DivisorsSmall[n+1];  fi;
  791.     factors := FactorsInt( n );
  792.  
  793.     # recursive function to compute the divisors
  794.     divs := function ( i, m )
  795.         if Length(factors) < i     then return [ m ];
  796.         elif m mod factors[i] = 0  then return divs(i+1,m*factors[i]);
  797.         else return Concatenation( divs(i+1,m), divs(i+1,m*factors[i]) );
  798.         fi;
  799.     end;
  800.  
  801.     divisors := divs( 1, 1 );
  802.     Sort( divisors );
  803.     return divisors;
  804. end;
  805.  
  806.  
  807. #############################################################################
  808. ##
  809. #F  Sigma( <n> )  . . . . . . . . . . . . . . . sum of divisors of an integer
  810. ##
  811. ##  'Sigma' returns the sum of the positive divisors of the integer <n>.
  812. ##
  813. ##  'Sigma' is a multiplicative arithmetic function, i.e., if $n$ and $m$ are
  814. ##  relative prime we have $\sigma(n m) = \sigma(n) \sigma(m)$.
  815. ##
  816. Sigma := function ( n )
  817.     local  sigma, p, q, k;
  818.  
  819.     # make <n> it nonnegative, handle trivial cases
  820.     if n < 0  then n := -n;  fi;
  821.     if n = 0  then Error("Sigma: <n> must not be 0");  fi;
  822.     if n < 8  then return Sum(DivisorsSmall[n+1]);  fi;
  823.  
  824.     # loop over all prime $p$ factors of $n$
  825.     sigma := 1;
  826.     for p  in Set(FactorsInt(n))  do
  827.  
  828.         # compute $p^e$ and $k = 1+p+p^2+..p^e$
  829.         q := p;  k := 1 + p;
  830.         while n mod (q * p) = 0  do q := q * p;  k := k + q;  od;
  831.  
  832.         # combine with the value found so far
  833.         sigma := sigma * k;
  834.     od;
  835.  
  836.     return sigma;
  837. end;
  838.  
  839.  
  840. #############################################################################
  841. ##
  842. #F  Tau( <n> )  . . . . . . . . . . . . . .  number of divisors of an integer
  843. ##
  844. ##  'Tau' returns the number of the positive divisors of the integer <n>.
  845. ##
  846. ##  'Tau' is a multiplicative arithmetic function, i.e., if $n$ and  $m$  are
  847. ##  relative prime we have $\tau(n m) = \tau(n) \tau(m)$.
  848. ##
  849. Tau := function ( n )
  850.     local  tau, p, q, k;
  851.  
  852.     # make <n> it nonnegative, handle trivial cases
  853.     if n < 0  then n := -n;  fi;
  854.     if n = 0  then Error("Tau: <n> must not be 0");  fi;
  855.     if n < 8  then return Length(DivisorsSmall[n+1]);  fi;
  856.  
  857.     # loop over all prime factors $p$ of $n$
  858.     tau := 1;
  859.     for p  in Set(FactorsInt(n))  do
  860.  
  861.         # compute $p^e$ and $k = e+1$
  862.         q := p;  k := 2;
  863.         while n mod (q * p) = 0  do q := q * p;  k := k + 1;  od;
  864.  
  865.         # combine with the value found so far
  866.         tau := tau * k;
  867.     od;
  868.  
  869.     return tau;
  870. end;
  871.  
  872.  
  873. #############################################################################
  874. ##
  875. #F  MoebiusMu( <n> )  . . . . . . . . . . . . . .  Moebius inversion function
  876. ##
  877. ##  'MoebiusMu'  computes the value  of  Moebius  inversion function for  the
  878. ##  integer <n>.   This  is 0 for  integers  which are not squarefree,  i.e.,
  879. ##  which are divided by a square $r^2$.  Otherwise it is 1 if <n> has a even
  880. ##  number and -1 if <n> has an odd number of prime factors.
  881. ##
  882. MoebiusMu := function ( n )
  883.     local  factors;
  884.  
  885.     if n < 0  then n := -n;  fi;
  886.     if n = 0  then Error("MoebiusMu: <n> must be nonzero");  fi;
  887.     if n = 1  then return 1;  fi;
  888.  
  889.     factors := FactorsInt( n );
  890.     if factors <> Set( factors )  then return 0;  fi;
  891.     return (-1) ^ Length(factors);
  892. end;
  893.  
  894.  
  895. #############################################################################
  896. ##
  897. #F  IntegersOps.EuclideanDegree(<Integers>,<n>) . . . . . . . . absolut value
  898. ##
  899. IntegersOps.EuclideanDegree := function ( Integers, n )
  900.     if n < 0  then
  901.         return -n;
  902.     else
  903.         return n;
  904.     fi;
  905. end;
  906.  
  907.  
  908. #############################################################################
  909. ##
  910. #F  IntegersOps.Mod(<Integers>,<n>,<m>) . . . . . . remainder of two integers
  911. ##
  912. IntegersOps.Mod := function ( Integers, n, m )
  913.     return n mod m;
  914. end;
  915.  
  916.  
  917. #############################################################################
  918. ##
  919. #F  IntegersOps.QuotientMod(<Integers>,<r>,<s>,<m>)  quotient of two integers
  920. #F                                                             modulo another
  921. ##
  922. IntegersOps.QuotientMod := function ( Integers, r, s, m )
  923.     if r mod GcdInt( s, m ) = 0  then
  924.         return r/s mod m;
  925.     else
  926.         return false;
  927.     fi;
  928. end;
  929.  
  930.  
  931. #############################################################################
  932. ##
  933. #F  IntegersOps.PowerMod(<Integers>,<r>,<e>,<m>)  . . power of an integer mod
  934. #F                                                                    another
  935. #F  PowerModInt(<r>,<e>,<m>)  . . . . . . power of one integer modulo another
  936. ##
  937. PowerModInt := function ( r, e, m )
  938.     local   pow, f;
  939.  
  940.     # reduce r initially
  941.     r := r mod m;
  942.  
  943.     # handle special case
  944.     if e = 0  then
  945.         return 1;
  946.     fi;
  947.  
  948.     # if e is negative then invert n modulo m with Euclids algorithm
  949.     if e < 0  then
  950.         r := 1/r mod m;
  951.         e := -e;
  952.     fi;
  953.  
  954.     # now use the repeated squaring method (right-to-left)
  955.     pow := 1;
  956.     f := 2 ^ (LogInt( e, 2 ) + 1);
  957.     while 1 < f  do
  958.         pow := (pow * pow) mod m;
  959.         f := QuoInt( f, 2 );
  960.         if f <= e  then
  961.             pow := (pow * r) mod m;
  962.             e := e - f;
  963.         fi;
  964.     od;
  965.  
  966.     # return the power
  967.     return pow;
  968. end;
  969.  
  970. IntegersOps.PowerMod := function ( Integers, r, e, m )
  971.     return PowerModInt( r, e, m );
  972. end;
  973.  
  974.  
  975. #############################################################################
  976. ##
  977. #F  IntegersOps.Gcd(<Integers>,<n>,<m>) . . . . . . . . . gcd of two integers
  978. #F  GcdInt(<n>,<m>) . . . . . . . . . . . . . . . . . . . gcd of two integers
  979. ##
  980. IntegersOps.Gcd := function ( Integers, n, m )
  981.     return GcdInt( n, m );
  982. end;
  983.  
  984.  
  985. #############################################################################
  986. ##
  987. #F  IntegersOps.Lcm(<Integers>,<n>,<m>) . . least common multiple of integers
  988. #F  LcmInt( <m>, <n> )  . . . . . . . . . . least common multiple of integers
  989. ##
  990. IntegersOps.Lcm := function ( Integers, n, m )
  991.     return LcmInt( n, m );
  992. end;
  993.  
  994. LcmInt := function ( n, m )
  995.     if m = 0  and n = 0  then
  996.         return 0;
  997.     else
  998.         return AbsInt( m / GcdInt( m, n ) * n );
  999.     fi;
  1000. end;
  1001.  
  1002.  
  1003. #############################################################################
  1004. ##
  1005. #F  Gcdex( <m>, <n> ) . . . . . . . . . . greatest common divisor of integers
  1006. ##
  1007. Gcdex := function ( m, n )
  1008.     local   f, g, h, fm, gm, hm, q;
  1009.     if 0 <= m  then f:=m; fm:=1; else f:=-m; fm:=-1; fi;
  1010.     if 0 <= n  then g:=n; gm:=0; else g:=-n; gm:=0;  fi;
  1011.     while g <> 0  do
  1012.         q := QuoInt( f, g );
  1013.         h := g;          hm := gm;
  1014.         g := f - q * g;  gm := fm - q * gm;
  1015.         f := h;          fm := hm;
  1016.     od;
  1017.     if n = 0  then
  1018.         return rec( gcd := f, coeff1 := fm, coeff2 := 0,
  1019.                               coeff3 := gm, coeff4 := 1 );
  1020.     else
  1021.         return rec( gcd := f, coeff1 := fm, coeff2 := (f - fm * m) / n,
  1022.                               coeff3 := gm, coeff4 := (0 - gm * m) / n );
  1023.     fi;
  1024. end;
  1025.  
  1026.  
  1027. #############################################################################
  1028. ##
  1029. #F  Int( <obj> )  . . . . . . . . . . . . . . . . . . . convert to an integer
  1030. ##
  1031. Int := function ( obj )
  1032.     if IsInt( obj )  then
  1033.         return obj;
  1034.     elif IsRat( obj )  then
  1035.         return QuoInt( Numerator( obj ), Denominator( obj ) );
  1036.     elif IsFFE( obj )  then
  1037.         return IntFFE( obj );
  1038.     else
  1039.         Error("<obj> must be rational or a finite field element");
  1040.     fi;
  1041. end;
  1042.  
  1043.  
  1044. #############################################################################
  1045. ##
  1046. #F  AbsInt( <n> ) . . . . . . . . . . . . . . .  absolute value of an integer
  1047. ##
  1048. AbsInt := function ( n )
  1049.     if 0 <= n  then return  n;
  1050.     else            return -n;
  1051.     fi;
  1052. end;
  1053.  
  1054.  
  1055. #############################################################################
  1056. ##
  1057. #F  SignInt( <n> )  . . . . . . . . . . . . . . . . . . .  sign of an integer
  1058. ##
  1059. SignInt := function ( n )
  1060.     if   0 =  n  then
  1061.         return 0;
  1062.     elif 0 <= n  then
  1063.         return 1;
  1064.     else
  1065.         return -1;
  1066.     fi;
  1067. end;
  1068.  
  1069.  
  1070. #############################################################################
  1071. ##
  1072. #F  ChineseRem( <moduli>, <residues> )  . . . . . . . . . . chinese remainder
  1073. ##
  1074. ChineseRem := function ( moduli, residues )
  1075.     local   i, c, l, g;
  1076.  
  1077.     # combine the residues modulo the moduli
  1078.     i := 1;
  1079.     c := residues[1];
  1080.     l := moduli[1];
  1081.     while i < Length(moduli)  do
  1082.         i := i + 1;
  1083.         g := Gcdex( l, moduli[i] );
  1084.         if g.gcd <> 1  and (residues[i]-c) mod g.gcd <> 0  then
  1085.             Error("the residues must be equal modulo ",g.gcd);
  1086.         fi;
  1087.         c := l * (((residues[i]-c) / g.gcd * g.coeff1) mod moduli[i]) + c;
  1088.         l := moduli[i] / g.gcd * l;
  1089.     od;
  1090.  
  1091.     # reduce c into the range [0..l-1]
  1092.     c := c mod l;
  1093.     return c;
  1094. end;
  1095.  
  1096.  
  1097. #############################################################################
  1098. ##
  1099. #F  LogInt( <n>, <base> ) . . . . . . . . . . . . . . logarithm of an integer
  1100. ##
  1101. LogInt := function ( n, base )
  1102.     local   log;
  1103.  
  1104.     # check arguments
  1105.     if n    <= 0  then Error("<n> must be positive");  fi;
  1106.     if base <= 1  then Error("<base> must be greater than 1");  fi;
  1107.  
  1108.     # 'log(b)' returns $log_b(n)$ and divides 'n' by 'b^log(b)'
  1109.     log := function ( b )
  1110.         local   i;
  1111.         if b > n  then return 0;  fi;
  1112.         i := log( b^2 );
  1113.         if b > n  then return 2 * i;
  1114.         else  n := QuoInt( n, b );  return 2 * i + 1;  fi;
  1115.     end;
  1116.  
  1117.     return log( base );
  1118. end;
  1119.  
  1120.  
  1121. #############################################################################
  1122. ##
  1123. #F  RootInt( <n>, <k> ) . . . . . . . . . . . . . . . . .  root of an integer
  1124. ##
  1125. RootInt := function ( arg )
  1126.     local   n, k, r, s, t;
  1127.  
  1128.     # get the arguments
  1129.     if   Length(arg) = 1  then n := arg[1];  k := 2;
  1130.     elif Length(arg) = 2  then n := arg[1];  k := arg[2];
  1131.     else Error("usage: 'Root( <n> )' or 'Root( <n>, <k> )'");
  1132.     fi;
  1133.  
  1134.     # check the arguments and handle trivial cases
  1135.     if  k <= 0                  then Error("<k> must be positive");
  1136.     elif k = 1                  then return n;
  1137.     elif n < 0 and k mod 2 = 0  then Error("<n> must be positive");
  1138.     elif n < 0 and k mod 2 = 1  then return -RootInt( -n, k );
  1139.     elif n = 0                  then return 0;
  1140.     elif n <= k                 then return 1;
  1141.     fi;
  1142.  
  1143.     # r is the first approximation, s the second, we need: root <= s < r
  1144.     r := n;  s := 2^( QuoInt( LogInt(n,2), k ) + 1 ) - 1;
  1145.  
  1146.     # do Newton iterations until the approximations stop decreasing
  1147.     while s < r  do
  1148.         r := s;  t := r^(k-1);  s := QuoInt( n + (k-1)*r*t, k*t );
  1149.     od;
  1150.  
  1151.     # and thats the integer part of the root
  1152.     return r;
  1153. end;
  1154.  
  1155.  
  1156. #############################################################################
  1157. ##
  1158. #F  SmallestRootInt( <n> )  . . . . . . . . . . . smallest root of an integer
  1159. ##
  1160. SmallestRootInt := function ( n )
  1161.     local   k, r, s, p, l, q;
  1162.  
  1163.     # check the argument
  1164.     if   n > 0  then k := 2;  s :=  1;
  1165.     elif n < 0  then k := 3;  s := -1;  n := -n;
  1166.     else return 0;
  1167.     fi;
  1168.  
  1169.     # exclude small divisors, and thereby large exponents
  1170.     if n mod 2 = 0  then
  1171.         p := 2;
  1172.     else
  1173.         p := 3;  while p < 100  and n mod p <> 0  do p := p+2;  od;
  1174.     fi;
  1175.     l := LogInt( n, p );
  1176.  
  1177.     # loop over the possible prime divisors of exponents
  1178.     # use Euler's criterion to cast out impossible ones
  1179.     while k <= l  do
  1180.         q := 2*k+1;  while not IsPrimeInt(q)  do q := q+2*k;  od;
  1181.         if PowerModInt( n, (q-1)/k, q ) <= 1  then
  1182.             r := RootInt( n, k );
  1183.             if r ^ k = n  then
  1184.                 n := r;
  1185.                 l := QuoInt( l, k );
  1186.             else
  1187.                 k := NextPrimeInt( k );
  1188.             fi;
  1189.         else
  1190.             k := NextPrimeInt( k );
  1191.         fi;
  1192.     od;
  1193.  
  1194.     return s * n;
  1195. end;
  1196.  
  1197.  
  1198. #############################################################################
  1199. ##
  1200. #F  IntegersOps.AsGroup(<Integers>) . . . . . . . . . .  view the integers as
  1201. #F                                                       multiplicative group
  1202. ##
  1203. IntegersOps.AsGroup := function ( Integers )
  1204.     Error("sorry, Z is not finitely generated as multiplicative group");
  1205. end;
  1206.  
  1207.  
  1208. #############################################################################
  1209. ##
  1210. #F  IntegersOps.AsAdditiveGroup(<Integers>) . . . . . .  view the integers as
  1211. #F                                                             additive group
  1212. ##
  1213. #N  14-Oct-91 martin this should be
  1214. #N  IntegersAsAddtiveGroupOps := Copy( AdditveGroupOps );
  1215. ##
  1216. IntegersAsAdditiveGroupOps := Copy( DomainOps );
  1217. IntegersAsAdditiveGroupOps.\in   := IntegersOps.\in;
  1218. IntegersAsAdditiveGroupOps.Random := IntegersOps.Random;
  1219.  
  1220. IntegersOps.AsAdditiveGroup := function ( Integers )
  1221.  
  1222.     return rec(
  1223.  
  1224.         isDomain                := true,
  1225.         isAdditiveGroup         := true,
  1226.  
  1227.         generators              := [ 1 ],
  1228.         zero                    := 0,
  1229.  
  1230.         isFinite                := false,
  1231.         size                    := "infinity",
  1232.         isCyclic                := true,
  1233.  
  1234.         operations              := IntegersAsAdditiveGroupOps
  1235.     );
  1236.  
  1237. end;
  1238.  
  1239.  
  1240. #############################################################################
  1241. ##
  1242. #E  Emacs . . . . . . . . . . . . . . . . . . . . . . . local emacs variables
  1243. ##
  1244. ##  Local Variables:
  1245. ##  mode:               outline
  1246. ##  outline-regexp:     "#F\\|#V\\|#E"
  1247. ##  fill-column:        73
  1248. ##  fill-prefix:        "##  "
  1249. ##  eval:               (hide-body)
  1250. ##  End:
  1251. ##
  1252.  
  1253.  
  1254.  
  1255.