Changeset 0b937c in git
- Timestamp:
- Jan 31, 2003, 10:09:46 AM (21 years ago)
- Branches:
- (u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
- Children:
- 6a874ee99f6ab05d5981f0dc589bc510d18d6f6c
- Parents:
- cd22d1a27db3332385586c32609b3ccce07f4c94
- Location:
- Singular
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/modulop.cc
rcd22d1a r0b937c 2 2 * Computer Algebra System SINGULAR * 3 3 ****************************************/ 4 /* $Id: modulop.cc,v 1.2 6 2001-08-27 14:47:12Singular Exp $ */4 /* $Id: modulop.cc,v 1.27 2003-01-31 09:09:46 Singular Exp $ */ 5 5 /* 6 6 * ABSTRACT: numbers modulo p (<=32003) … … 24 24 int npMapPrime; 25 25 26 #ifdef HAVE_DIV_MOD 27 CARDINAL *npInvTable=NULL; 28 #endif 29 30 #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD) 26 31 CARDINAL *npExpTable=NULL; 27 32 CARDINAL *npLogTable=NULL; 33 #endif 28 34 29 35 … … 34 40 } 35 41 36 unsigned long npMultMod(unsigned long a, unsigned long b)37 {38 unsigned long c = a*b;39 c = c % npPrimeM;40 assume(c == (unsigned long) npMultM((number) a, (number) b));41 return c;42 }42 //unsigned long npMultMod(unsigned long a, unsigned long b) 43 //{ 44 // unsigned long c = a*b; 45 // c = c % npPrimeM; 46 // assume(c == (unsigned long) npMultM((number) a, (number) b)); 47 // return c; 48 //} 43 49 44 50 number npMult (number a,number b) … … 47 53 return (number)0; 48 54 else 49 {50 55 return npMultM(a,b); 51 }52 56 } 53 57 … … 96 100 } 97 101 102 #ifdef HAVE_DIV_MOD 103 #if 1 //ifdef HAVE_NTL // in ntl.a 104 extern void XGCD(long& d, long& s, long& t, long a, long b); 105 #else 106 void XGCD(long& d, long& s, long& t, long a, long b) 107 { 108 long u, v, u0, v0, u1, v1, u2, v2, q, r; 109 110 long aneg = 0, bneg = 0; 111 112 if (a < 0) { 113 a = -a; 114 aneg = 1; 115 } 116 117 if (b < 0) { 118 b = -b; 119 bneg = 1; 120 } 121 122 u1=1; v1=0; 123 u2=0; v2=1; 124 u = a; v = b; 125 126 while (v != 0) { 127 q = u / v; 128 r = u % v; 129 u = v; 130 v = r; 131 u0 = u2; 132 v0 = v2; 133 u2 = u1 - q*u2; 134 v2 = v1- q*v2; 135 u1 = u0; 136 v1 = v0; 137 } 138 139 if (aneg) 140 u1 = -u1; 141 142 if (bneg) 143 v1 = -v1; 144 145 d = u; 146 s = u1; 147 t = v1; 148 } 149 #endif 150 151 long InvMod(long a) 152 { 153 long d, s, t; 154 155 XGCD(d, s, t, a, npPrimeM); 156 assume (d == 1); 157 if (s < 0) 158 return s + npPrimeM; 159 else 160 return s; 161 } 162 #endif 163 164 inline number npInversM (number c) 165 { 166 #ifndef HAVE_DIV_MOD 167 return (number)npExpTable[npPminus1M - npLogTable[(int)c]]; 168 #else 169 CARDINAL inv=npInvTable[(int)c]; 170 if (inv==0) 171 { 172 inv=InvMod((long)c); 173 npInvTable[(int)c]=inv; 174 } 175 return (number)inv; 176 #endif 177 } 178 98 179 number npDiv (number a,number b) 99 180 { 100 181 if ((int)a==0) 101 182 return (number)0; 183 #ifndef HAVE_DIV_MOD 102 184 else if ((int)b==0) 103 185 { … … 112 194 return (number)npExpTable[s]; 113 195 } 114 } 115 196 #else 197 number inv=npInversM(b); 198 return npMultM(a,inv); 199 #endif 200 } 116 201 number npInvers (number c) 117 202 { … … 121 206 return (number)0; 122 207 } 123 return (number)npExpTable[npPminus1M - npLogTable[(int)c]];208 return npInversM(c); 124 209 } 125 210 … … 195 280 s = npEati(s, &n); 196 281 } 197 *a = npDiv((number)z,(number)n); 282 if (n == 1) 283 *a = (number)z; 284 else 285 #ifdef NV_OPS 286 if (npPrimeM>NV_MAX_PRIME) 287 *a = nvDiv((number)z,(number)n); 288 else 289 #endif 290 *a = npDiv((number)z,(number)n); 198 291 return s; 199 292 } … … 216 309 217 310 // if (c==npPrimeM) return; 218 // if (npPrimeM > 1)219 // {220 // omFreeSize( (ADDRESS)npExpTable,npPrimeM*sizeof(CARDINAL) );221 // omFreeSize( (ADDRESS)npLogTable,npPrimeM*sizeof(CARDINAL) );222 // }223 311 if ((c>1) || (c<(-1))) 224 312 { … … 226 314 else npPrimeM = -c; 227 315 npPminus1M = npPrimeM - 1; 228 // npExpTable= (CARDINAL *)omAlloc( npPrimeM*sizeof(CARDINAL) ); 229 // npLogTable= (CARDINAL *)omAlloc( npPrimeM*sizeof(CARDINAL) ); 230 // omMarkAsStaticAddr(npExpTable); 231 // omMarkAsStaticAddr(npLogTable); 232 // memcpy(npExpTable,r->cf->npExpTable,npPrimeM*sizeof(CARDINAL)); 233 // memcpy(npLogTable,r->cf->npLogTable,npPrimeM*sizeof(CARDINAL)); 316 #ifdef HAVE_DIV_MOD 317 npInvTable=r->cf->npInvTable; 318 #endif 319 #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD) 234 320 npExpTable=r->cf->npExpTable; 235 321 npLogTable=r->cf->npLogTable; 236 322 npGen = npExpTable[1]; 323 #endif 237 324 } 238 325 else 239 326 { 240 327 npPrimeM=0; 328 #ifdef HAVE_DIV_MOD 329 npInvTable=NULL; 330 #endif 331 #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD) 241 332 npExpTable=NULL; 242 333 npLogTable=NULL; 334 #endif 243 335 } 244 336 } … … 253 345 else r->cf->npPrimeM = -c; 254 346 r->cf->npPminus1M = r->cf->npPrimeM - 1; 255 r->cf->npExpTable= (CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) ); 256 r->cf->npLogTable= (CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) ); 257 r->cf->npExpTable[0] = 1; 258 r->cf->npLogTable[0] = 0; 259 if (r->cf->npPrimeM > 2) 347 #ifdef NV_OPS 348 if (r->cf->npPrimeM <=NV_MAX_PRIME) 349 #endif 260 350 { 261 w = 1; 262 loop 351 #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD) 352 r->cf->npExpTable=(CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) ); 353 r->cf->npLogTable=(CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) ); 354 r->cf->npExpTable[0] = 1; 355 r->cf->npLogTable[0] = 0; 356 if (r->cf->npPrimeM > 2) 263 357 { 264 r->cf->npLogTable[1] = 0; 265 w++; 266 i = 0; 358 w = 1; 267 359 loop 268 360 { 269 i++; 270 r->cf->npExpTable[i] = (int)(((long)w * (long)r->cf->npExpTable[i-1]) 361 r->cf->npLogTable[1] = 0; 362 w++; 363 i = 0; 364 loop 365 { 366 i++; 367 r->cf->npExpTable[i] =(int)(((long)w * (long)r->cf->npExpTable[i-1]) 271 368 % r->cf->npPrimeM); 272 r->cf->npLogTable[r->cf->npExpTable[i]] = i; 273 if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1)) 369 r->cf->npLogTable[r->cf->npExpTable[i]] = i; 370 if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1)) 371 break; 372 } 373 if (i == r->cf->npPrimeM - 1) 274 374 break; 275 375 } 276 if (i == r->cf->npPrimeM - 1)277 break;278 376 } 279 } 280 else 281 { 282 r->cf->npExpTable[1] = 1; 283 r->cf->npLogTable[1] = 0; 377 else 378 { 379 r->cf->npExpTable[1] = 1; 380 r->cf->npLogTable[1] = 0; 381 } 382 #endif 383 #ifdef HAVE_DIV_MOD 384 r->cf->npInvTable=(CARDINAL*)omAlloc0( r->cf->npPrimeM*sizeof(CARDINAL) ); 385 #endif 284 386 } 285 387 } … … 348 450 #if defined(LDEBUG) 349 451 res->debug=123456; 452 #endif 453 #ifndef NL_OLDCOPY 454 res->ref=1; 350 455 #endif 351 456 dest = &(res->z); … … 412 517 return NULL; /* default */ 413 518 } 519 520 // ----------------------------------------------------------- 521 // operation for very large primes (32003< p < 2^31-1) 522 // ---------------------------------------------------------- 523 #ifdef NV_OPS 524 525 number nvMult (number a,number b) 526 { 527 if (((int)a == 0) || ((int)b == 0)) 528 return (number)0; 529 else 530 return nvMultM(a,b); 531 } 532 533 long nvInvMod(long a) 534 { 535 long s, t; 536 537 long u, v, u0, v0, u1, v1, u2, v2, q, r; 538 539 u1=1; v1=0; 540 u2=0; v2=1; 541 u = a; v = npPrimeM; 542 543 while (v != 0) { 544 q = u / v; 545 r = u % v; 546 u = v; 547 v = r; 548 u0 = u2; 549 v0 = v2; 550 u2 = u1 - q*u2; 551 v2 = v1- q*v2; 552 u1 = u0; 553 v1 = v0; 554 } 555 556 s = u1; 557 //t = v1; 558 if (s < 0) 559 return s + npPrimeM; 560 else 561 return s; 562 } 563 564 inline number nvInversM (number c) 565 { 566 long inv=InvMod((long)c); 567 return (number)inv; 568 } 569 570 number nvDiv (number a,number b) 571 { 572 if ((int)a==0) 573 return (number)0; 574 else if ((int)b==0) 575 { 576 WerrorS("div by 0"); 577 return (number)0; 578 } 579 else 580 { 581 number inv=nvInversM(b); 582 return nvMultM(a,inv); 583 } 584 } 585 number nvInvers (number c) 586 { 587 if ((int)c==0) 588 { 589 WerrorS("1/0"); 590 return (number)0; 591 } 592 return nvInversM(c); 593 } 594 #endif -
Singular/modulop.h
rcd22d1a r0b937c 4 4 * Computer Algebra System SINGULAR * 5 5 ****************************************/ 6 /* $Id: modulop.h,v 1.1 6 2001-10-09 16:36:09Singular Exp $ */6 /* $Id: modulop.h,v 1.17 2003-01-31 09:09:46 Singular Exp $ */ 7 7 /* 8 8 * ABSTRACT: numbers modulo p (<=32003) … … 10 10 #include "structs.h" 11 11 12 // defines are in struct.h 12 13 // define if a*b is with mod instead of tables 13 #define HAVE_MULT_MOD 14 //#define HAVE_MULT_MOD 15 // define if a/b is with mod instead of tables 16 //#define HAVE_DIV_MOD 17 // define if an if should be used 18 //#define HAVE_GENERIC_ADD 19 20 // enable large primes (32003 < p < 2^31-) 21 #define NV_OPS 22 #define NV_MAX_PRIME 32003 14 23 15 24 extern int npPrimeM; … … 46 55 /*-------specials for spolys, do NOT use otherwise--------------------------*/ 47 56 /* for npMultM, npSubM, npNegM, npEqualM : */ 57 #ifdef HAVE_DIV_MOD 58 extern CARDINAL *npInvTable; 59 #else 60 #ifndef HAVE_MULT_MOD 48 61 extern int npPminus1M; 49 62 extern CARDINAL *npExpTable; 50 63 extern CARDINAL *npLogTable; 64 #endif 65 #endif 51 66 67 #if 0 68 inline number npMultM(number a, number b) 69 // return (a*b)%n 70 { 71 double ab; 72 long q, res; 73 74 ab = ((double) ((int)a)) * ((double) ((int)b)); 75 q = (long) (ab/((double) npPrimeM)); // q could be off by (+/-) 1 76 res = (long) (ab - ((double) q)*((double) npPrimeM)); 77 res += (res >> 31) & npPrimeM; 78 res -= npPrimeM; 79 res += (res >> 31) & npPrimeM; 80 return (number)res; 81 } 82 #endif 52 83 #ifdef HAVE_MULT_MOD 53 inline number npMultM(number a, number b)84 static inline number npMultM(number a, number b) 54 85 { 55 return (number) 86 return (number) 56 87 ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) npPrimeM)); 57 88 } 58 89 #else 59 inline number npMultM(number a, number b)90 static inline number npMultM(number a, number b) 60 91 { 61 92 int x = npLogTable[(int)a]+npLogTable[(int)b]; … … 84 115 } 85 116 #endif 86 87 inline number npAddM(number a, number b)117 #ifdef HAVE_GENERIC_ADD 118 static inline number npAddM(number a, number b) 88 119 { 89 120 int r = (int)a + (int)b; 90 121 return (number)(r >= npPrimeM ? r - npPrimeM : r); 91 122 } 123 static inline number npSubM(number a, number b) 124 { 125 return (number)((int)a<(int)b ? 126 npPrimeM-(int)b+(int)a : (int)a-(int)b); 127 } 128 #else 129 static inline number npAddM(number a, number b) 130 { 131 int res = (int)a + (int)b; 132 res -= npPrimeM; 133 res += (res >> 31) & npPrimeM; 134 return (number)res; 135 } 136 static inline number npSubM(number a, number b) 137 { 138 int res = (int)a - (int)b; 139 res += (res >> 31) & npPrimeM; 140 return (number)res; 141 } 142 #endif 92 143 93 inline BOOLEAN npIsZeroM (number a)144 static inline BOOLEAN npIsZeroM (number a) 94 145 { 95 146 return 0 == (int)a; … … 103 154 */ 104 155 105 #define npSubM(a,b) (number)((int)a<(int)b ?\106 npPrimeM-(int)b+(int)a : (int)a-(int)b)107 108 156 #define npNegM(A) (number)(npPrimeM-(int)(A)) 109 157 #define npEqualM(A,B) ((int)A==(int)B) 110 #define npIsZeroM(a) (0 == (int)a) 158 159 160 #ifdef NV_OPS 161 static inline number nvMultM(number a, number b) 162 { 163 return (number) 164 ((((unsigned long long) a)*((unsigned long long) b)) % ((unsigned long long) npPrimeM)); 165 } 166 number nvMult (number a, number b); 167 number nvDiv (number a, number b); 168 number nvInvers (number c); 111 169 #endif 112 170 171 #endif
Note: See TracChangeset
for help on using the changeset viewer.