Changeset e90dfd6 in git
- Timestamp:
- Sep 6, 2010, 12:08:33 PM (13 years ago)
- Branches:
- (u'spielwiese', '8d54773d6c9e2f1d2593a28bc68b7eeab54ed529')
- Children:
- e903733fa2ff9e4f7582f1faabf6cc2a6baea275
- Parents:
- 5d594a96114bdb26100c2b8e2ae329a7529f0e45
- git-author:
- Frank Seelisch <seelisch@mathematik.uni-kl.de>2010-09-06 12:08:33+02:00
- git-committer:
- Mohamed Barakat <mohamed.barakat@rwth-aachen.de>2011-11-09 11:55:29+01:00
- Location:
- coeffs
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
coeffs/coeffs.h
-
Property
mode
changed from
100644
to100755
r5d594a9 re90dfd6 190 190 191 191 #ifdef HAVE_RINGS 192 int_number ringflaga; /* Z/(ringflag^ringflagb)=Z/nrnModul*/ 193 unsigned long ringflagb; 194 unsigned long nr2mModul; /* Z/nr2mModul */ 195 int_number nrnModul; 192 /* The following members are for representing the ring Z/n, 193 where n is not a prime. We distinguish three cases: 194 1.) n has at least two distinct prime factors. Then 195 modBase stores n, modExponent stores 1, modNumber 196 stores n, and mod2mMask is not used; 197 2.) n = p^k for some odd prime p and k > 1. Then 198 modBase stores p, modExponent stores k, modNumber 199 stores n, and mod2mMask is not used; 200 3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in 201 an unsigned long. Then modBase stores 2, modExponent 202 stores k, modNumber is not used, and mod2mMask stores 203 2^k - 1, i.e., the bit mask '111..1' of length k. 204 4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in 205 an unsigned long. Then modBase stores 2, modExponent 206 stores k, modNumber stores n, and mod2mMask is not 207 used; 208 Cases 1.), 2.), and 4.) are covered by the implementation 209 in the files rmodulon.h and rmodulon.cc, whereas case 3.) 210 is implemented in the files rmodulo2m.h and rmodulo2m.cc. */ 211 int_number modBase; 212 unsigned long modExponent; 213 int_number modNumber; 214 unsigned long mod2mMask; 196 215 #endif 197 216 int ch; /* characteristic, rInit */ -
Property
mode
changed from
-
coeffs/rmodulo2m.cc
-
Property
mode
changed from
100644
to100755
r5d594a9 re90dfd6 24 24 #include <string.h> 25 25 26 int nr2mExp;27 28 26 extern omBin gmp_nrz_bin; /* init in rintegers*/ 29 27 … … 34 32 nr2mInitExp((int)(long)(p), r); 35 33 36 r->cfInit = nr2mInit;37 r->cfCopy = ndCopy;38 r->cfInt = nr2mInt;34 r->cfInit = nr2mInit; 35 r->cfCopy = ndCopy; 36 r->cfInt = nr2mInt; 39 37 r->cfAdd = nr2mAdd; 40 38 r->cfSub = nr2mSub; … … 54 52 r->cfIsMOne = nr2mIsMOne; 55 53 r->cfGreaterZero = nr2mGreaterZero; 56 r->cfWrite = nr2mWrite;54 r->cfWrite = nr2mWrite; 57 55 r->cfRead = nr2mRead; 58 56 r->cfPower = nr2mPower; 59 r->cfSetMap = nr2mSetMap;57 r->cfSetMap = nr2mSetMap; 60 58 r->cfNormalize = ndNormalize; 61 59 r->cfLcm = nr2mLcm; … … 75 73 * Multiply two numbers 76 74 */ 77 number nr2mMult 75 number nr2mMult(number a, number b, const coeffs r) 78 76 { 79 77 if (((NATNUMBER)a == 0) || ((NATNUMBER)b == 0)) 80 78 return (number)0; 81 79 else 82 return nr2mMultM(a, b,r);83 } 84 85 /* 86 * Give the smallest non unitk, such that a * x = k = b * y has a solution80 return nr2mMultM(a, b, r); 81 } 82 83 /* 84 * Give the smallest k, such that a * x = k = b * y has a solution 87 85 */ 88 number nr2mLcm 86 number nr2mLcm(number a, number b, const coeffs r) 89 87 { 90 88 NATNUMBER res = 0; 91 if ((NATNUMBER) 92 if ((NATNUMBER) 93 while ((NATNUMBER) 94 { 95 a = (number) ((NATNUMBER)a / 2);96 if ((NATNUMBER) b % 2 == 0) b = (number) ((NATNUMBER)b / 2);89 if ((NATNUMBER)a == 0) a = (number) 1; 90 if ((NATNUMBER)b == 0) b = (number) 1; 91 while ((NATNUMBER)a % 2 == 0) 92 { 93 a = (number)((NATNUMBER)a / 2); 94 if ((NATNUMBER)b % 2 == 0) b = (number)((NATNUMBER)b / 2); 97 95 res++; 98 96 } 99 while ((NATNUMBER) 100 { 101 b = (number) ((NATNUMBER)b / 2);97 while ((NATNUMBER)b % 2 == 0) 98 { 99 b = (number)((NATNUMBER)b / 2); 102 100 res++; 103 101 } 104 return (number) 105 } 106 107 /* 108 * Give the largest non unitk, such that a = x * k, b = y * k has102 return (number)(1L << res); // (2**res) 103 } 104 105 /* 106 * Give the largest k, such that a = x * k, b = y * k has 109 107 * a solution. 110 108 */ 111 number nr2mGcd 109 number nr2mGcd(number a, number b, const coeffs r) 112 110 { 113 111 NATNUMBER res = 0; 114 if ((NATNUMBER) a == 0 && (NATNUMBER) b == 0) return (number)1;115 while ((NATNUMBER) a % 2 == 0 && (NATNUMBER)b % 2 == 0)116 { 117 a = (number) ((NATNUMBER)a / 2);118 b = (number) ((NATNUMBER)b / 2);112 if ((NATNUMBER)a == 0 && (NATNUMBER)b == 0) return (number)1; 113 while ((NATNUMBER)a % 2 == 0 && (NATNUMBER)b % 2 == 0) 114 { 115 a = (number)((NATNUMBER)a / 2); 116 b = (number)((NATNUMBER)b / 2); 119 117 res++; 120 118 } 121 // if ((NATNUMBER) 119 // if ((NATNUMBER)b % 2 == 0) 122 120 // { 123 // return (number) ((1L << res));// * (NATNUMBER) a); // (2**res)*a a ist Einheit121 // return (number)((1L << res)); // * (NATNUMBER) a); // (2**res)*a a is a unit 124 122 // } 125 123 // else 126 124 // { 127 return (number) ((1L << res));// * (NATNUMBER) b); // (2**res)*b b ist Einheit125 return (number)((1L << res)); // * (NATNUMBER) b); // (2**res)*b b is a unit 128 126 // } 129 127 } 130 128 131 129 /* 132 * Give the largest non unitk, such that a = x * k, b = y * k has130 * Give the largest k, such that a = x * k, b = y * k has 133 131 * a solution. 134 132 */ 135 number nr2mExtGcd 133 number nr2mExtGcd(number a, number b, number *s, number *t, const coeffs r) 136 134 { 137 135 NATNUMBER res = 0; 138 if ((NATNUMBER) a == 0 && (NATNUMBER) b == 0) return (number)1;139 while ((NATNUMBER) a % 2 == 0 && (NATNUMBER)b % 2 == 0)140 { 141 a = (number) ((NATNUMBER)a / 2);142 b = (number) ((NATNUMBER)b / 2);136 if ((NATNUMBER)a == 0 && (NATNUMBER)b == 0) return (number)1; 137 while ((NATNUMBER)a % 2 == 0 && (NATNUMBER)b % 2 == 0) 138 { 139 a = (number)((NATNUMBER)a / 2); 140 b = (number)((NATNUMBER)b / 2); 143 141 res++; 144 142 } 145 if ((NATNUMBER) 143 if ((NATNUMBER)b % 2 == 0) 146 144 { 147 145 *t = NULL; 148 146 *s = nr2mInvers(a,r); 149 return (number) ((1L << res));// * (NATNUMBER) a); // (2**res)*a a ist Einheit147 return (number)((1L << res)); // * (NATNUMBER) a); // (2**res)*a a is a unit 150 148 } 151 149 else … … 153 151 *s = NULL; 154 152 *t = nr2mInvers(b,r); 155 return (number) ((1L << res));// * (NATNUMBER) b); // (2**res)*b b ist Einheit156 } 157 } 158 159 void nr2mPower 160 { 161 if (i ==0)153 return (number)((1L << res)); // * (NATNUMBER) b); // (2**res)*b b is a unit 154 } 155 } 156 157 void nr2mPower(number a, int i, number * result, const coeffs r) 158 { 159 if (i == 0) 162 160 { 163 161 *(NATNUMBER *)result = 1; 164 162 } 165 else if (i ==1)163 else if (i == 1) 166 164 { 167 165 *result = a; … … 169 167 else 170 168 { 171 nr2mPower(a, i-1,result,r);172 *result = nr2mMultM(a, *result,r);169 nr2mPower(a, i-1, result, r); 170 *result = nr2mMultM(a, *result, r); 173 171 } 174 172 } … … 177 175 * create a number from int 178 176 */ 179 number nr2mInit 177 number nr2mInit(int i, const coeffs r) 180 178 { 181 179 if (i == 0) return (number)(NATNUMBER)i; … … 183 181 long ii = i; 184 182 NATNUMBER j = (NATNUMBER)1; 185 if (ii < 0) { j = r-> nr2mModul; ii = -ii; }183 if (ii < 0) { j = r->mod2mMask; ii = -ii; } 186 184 NATNUMBER k = (NATNUMBER)ii; 187 k = k & r-> nr2mModul;188 /* now we have: from= j * k mod 2^m */189 return (number)nr2mMult((number)j, (number)k, r);185 k = k & r->mod2mMask; 186 /* now we have: i = j * k mod 2^m */ 187 return (number)nr2mMult((number)j, (number)k, r); 190 188 } 191 189 … … 198 196 int nr2mInt(number &n, const coeffs r) 199 197 { 200 NATNUMBER nn = (unsigned long)(NATNUMBER)n & r-> nr2mModul;201 unsigned long l = r-> nr2mModul>> 1; l++; /* now: l = 2^(m-1) */198 NATNUMBER nn = (unsigned long)(NATNUMBER)n & r->mod2mMask; 199 unsigned long l = r->mod2mMask >> 1; l++; /* now: l = 2^(m-1) */ 202 200 if ((NATNUMBER)nn > l) 203 return (int)((NATNUMBER)nn - r-> nr2mModul- 1);201 return (int)((NATNUMBER)nn - r->mod2mMask - 1); 204 202 else 205 203 return (int)((NATNUMBER)nn); 206 204 } 207 205 208 number nr2mAdd (number a, number b, const coeffs r) 209 { 210 return nr2mAddM(a,b,r); 211 } 212 213 number nr2mSub (number a, number b, const coeffs r) 214 { 215 return nr2mSubM(a,b,r); 216 } 217 218 BOOLEAN nr2mIsUnit (number a, const coeffs r) 219 { 220 return ((NATNUMBER) a % 2 == 1); 221 } 222 223 number nr2mGetUnit (number k, const coeffs r) 224 { 225 if (k == NULL) 226 return (number) 1; 227 NATNUMBER tmp = (NATNUMBER) k; 228 while (tmp % 2 == 0) 229 tmp = tmp / 2; 230 return (number) tmp; 231 } 232 233 BOOLEAN nr2mIsZero (number a, const coeffs r) 206 number nr2mAdd(number a, number b, const coeffs r) 207 { 208 return nr2mAddM(a, b, r); 209 } 210 211 number nr2mSub(number a, number b, const coeffs r) 212 { 213 return nr2mSubM(a, b, r); 214 } 215 216 BOOLEAN nr2mIsUnit(number a, const coeffs r) 217 { 218 return ((NATNUMBER)a % 2 == 1); 219 } 220 221 number nr2mGetUnit(number k, const coeffs r) 222 { 223 if (k == NULL) return (number)1; 224 NATNUMBER erg = (NATNUMBER)k; 225 while (erg % 2 == 0) erg = erg / 2; 226 return (number)erg; 227 } 228 229 BOOLEAN nr2mIsZero(number a, const coeffs r) 234 230 { 235 231 return 0 == (NATNUMBER)a; 236 232 } 237 233 238 BOOLEAN nr2mIsOne 234 BOOLEAN nr2mIsOne(number a, const coeffs r) 239 235 { 240 236 return 1 == (NATNUMBER)a; 241 237 } 242 238 243 BOOLEAN nr2mIsMOne (number a, const coeffs r) 244 { 245 return (r->nr2mModul == (NATNUMBER)a) 246 && (r->nr2mModul != 2); 247 } 248 249 BOOLEAN nr2mEqual (number a, number b, const coeffs r) 250 { 251 return a==b; 252 } 253 254 BOOLEAN nr2mGreater (number a, number b, const coeffs r) 239 BOOLEAN nr2mIsMOne(number a, const coeffs r) 240 { 241 return (r->mod2mMask == (NATNUMBER)a); 242 } 243 244 BOOLEAN nr2mEqual(number a, number b, const coeffs r) 245 { 246 return a == b; 247 } 248 249 BOOLEAN nr2mGreater(number a, number b, const coeffs r) 255 250 { 256 251 return nr2mDivBy(a, b,r); … … 265 260 if (a == NULL) 266 261 { 267 NATNUMBER c = r-> nr2mModul+ 1;262 NATNUMBER c = r->mod2mMask + 1; 268 263 if (c != 0) /* i.e., if no overflow */ 269 264 return (c % (NATNUMBER)b) == 0; … … 291 286 int nr2mDivComp(number as, number bs, const coeffs r) 292 287 { 293 NATNUMBER a = (NATNUMBER) 294 NATNUMBER b = (NATNUMBER) 288 NATNUMBER a = (NATNUMBER)as; 289 NATNUMBER b = (NATNUMBER)bs; 295 290 assume(a != 0 && b != 0); 296 291 while (a % 2 == 0 && b % 2 == 0) … … 317 312 318 313 /* TRUE iff 0 < k <= 2^m / 2 */ 319 BOOLEAN nr2mGreaterZero 314 BOOLEAN nr2mGreaterZero(number k, const coeffs r) 320 315 { 321 316 if ((NATNUMBER)k == 0) return FALSE; 322 if ((NATNUMBER)k > ((r-> nr2mModul>> 1) + 1)) return FALSE;317 if ((NATNUMBER)k > ((r->mod2mMask >> 1) + 1)) return FALSE; 323 318 return TRUE; 324 319 } … … 328 323 and 't' such that a * s + 2^m * t = gcd(a, 2^m) = 1; 329 324 this code will always find a positive 's' */ 330 void specialXGCD(unsigned long& s, unsigned long a, const coeffs R)325 void specialXGCD(unsigned long& s, unsigned long a, const coeffs r) 331 326 { 332 327 int_number u = (int_number)omAlloc(sizeof(mpz_t)); … … 339 334 mpz_init(u2); 340 335 int_number v = (int_number)omAlloc(sizeof(mpz_t)); 341 mpz_init_set_ui(v, R->nr2mModul);336 mpz_init_set_ui(v, r->mod2mMask); 342 337 mpz_add_ui(v, v, 1); /* now: v = 2^m */ 343 338 int_number v0 = (int_number)omAlloc(sizeof(mpz_t)); … … 349 344 int_number q = (int_number)omAlloc(sizeof(mpz_t)); 350 345 mpz_init(q); 351 int_number r = (int_number)omAlloc(sizeof(mpz_t));352 mpz_init(r );346 int_number rr = (int_number)omAlloc(sizeof(mpz_t)); 347 mpz_init(rr); 353 348 354 349 while (mpz_cmp_ui(v, 0) != 0) /* i.e., while v != 0 */ 355 350 { 356 351 mpz_div(q, u, v); 357 mpz_mod(r , u, v);352 mpz_mod(rr, u, v); 358 353 mpz_set(u, v); 359 mpz_set(v, r );354 mpz_set(v, rr); 360 355 mpz_set(u0, u2); 361 356 mpz_set(v0, v2); … … 369 364 { 370 365 /* we add 2^m = (2^m - 1) + 1 to u1: */ 371 mpz_add_ui(u1, u1, R->nr2mModul);366 mpz_add_ui(u1, u1, r->mod2mMask); 372 367 mpz_add_ui(u1, u1, 1); 373 368 } … … 383 378 mpz_clear(v2); omFree((ADDRESS)v2); 384 379 mpz_clear(q); omFree((ADDRESS)q); 385 mpz_clear(r ); omFree((ADDRESS)r);380 mpz_clear(rr); omFree((ADDRESS)rr); 386 381 } 387 382 … … 395 390 //#endif 396 391 397 inline number nr2mInversM 392 inline number nr2mInversM(number c, const coeffs r) 398 393 { 399 394 assume((NATNUMBER)c % 2 != 0); … … 401 396 NATNUMBER inv; 402 397 inv = InvMod((NATNUMBER)c,r); 403 return (number) inv; 404 } 405 406 number nr2mDiv (number a, number b, const coeffs r) 407 { 408 if ((NATNUMBER)a==0) 409 return (number)0; 410 else if ((NATNUMBER)b%2==0) 398 return (number)inv; 399 } 400 401 number nr2mDiv(number a, number b, const coeffs r) 402 { 403 if ((NATNUMBER)a == 0) return (number)0; 404 else if ((NATNUMBER)b % 2 == 0) 411 405 { 412 406 if ((NATNUMBER)b != 0) 413 407 { 414 while (( NATNUMBER) b%2 == 0 && (NATNUMBER) a%2 == 0)408 while (((NATNUMBER)b % 2 == 0) && ((NATNUMBER)a % 2 == 0)) 415 409 { 416 a = (number) ((NATNUMBER)a / 2);417 b = (number) ((NATNUMBER)b / 2);410 a = (number)((NATNUMBER)a / 2); 411 b = (number)((NATNUMBER)b / 2); 418 412 } 419 413 } 420 if ((NATNUMBER) b%2 == 0)414 if ((NATNUMBER)b % 2 == 0) 421 415 { 422 416 WerrorS("Division not possible, even by cancelling zero divisors."); … … 425 419 } 426 420 } 427 return (number) 428 } 429 430 number nr2mMod (number a, number b, const coeffs R)421 return (number)nr2mMult(a, nr2mInversM(b,r),r); 422 } 423 424 number nr2mMod(number a, number b, const coeffs r) 431 425 { 432 426 /* 433 We need to return the number r which is uniquely determined by the427 We need to return the number rr which is uniquely determined by the 434 428 following two properties: 435 (1) 0 <= r < |b| (with respect to '<' and '<=' performed in Z x Z)436 (2) There exists some k in the integers Z such that a = k * b + r .429 (1) 0 <= rr < |b| (with respect to '<' and '<=' performed in Z x Z) 430 (2) There exists some k in the integers Z such that a = k * b + rr. 437 431 Consider g := gcd(2^m, |b|). Note that then |b|/g is a unit in Z/2^m. 438 432 Now, there are three cases: 439 433 (a) g = 1 440 434 Then |b| is a unit in Z/2^m, i.e. |b| (and also b) divides a. 441 Thus r = 0.435 Thus rr = 0. 442 436 (b) g <> 1 and g divides a 443 Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again r = 0.437 Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again rr = 0. 444 438 (c) g <> 1 and g does not divide a 445 439 Let's denote the division with remainder of a by g as follows: 446 440 a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b| 447 fulfills (1) and (2), i.e. r := t is the correct result. Hence448 in this third case, r is the remainder of division of a by g in Z.441 fulfills (1) and (2), i.e. rr := t is the correct result. Hence 442 in this third case, rr is the remainder of division of a by g in Z. 449 443 This algorithm is the same as for the case Z/n, except that we may 450 444 compute the gcd of |b| and 2^m "by hand": We just extract the highest … … 455 449 NATNUMBER b_div = (NATNUMBER)b; 456 450 if (b_div < 0) b_div = -b_div; // b_div now represents |b| 457 NATNUMBER r = 0;458 while ((g < R->nr2mModul) && (b_div > 0) && (b_div % 2 == 0))451 NATNUMBER rr = 0; 452 while ((g < r->mod2mMask ) && (b_div > 0) && (b_div % 2 == 0)) 459 453 { 460 454 b_div = b_div >> 1; … … 462 456 } // g is now the gcd of 2^m and |b| 463 457 464 if (g != 1) r = (NATNUMBER)a % g;465 return (number)r ;466 } 467 468 number nr2mIntDiv 458 if (g != 1) rr = (NATNUMBER)a % g; 459 return (number)rr; 460 } 461 462 number nr2mIntDiv(number a, number b, const coeffs r) 469 463 { 470 464 if ((NATNUMBER)a == 0) … … 474 468 if ((NATNUMBER)b == 1) 475 469 return (number)0; 476 NATNUMBER c = r-> nr2mModul+ 1;470 NATNUMBER c = r->mod2mMask + 1; 477 471 if (c != 0) /* i.e., if no overflow */ 478 472 return (number)(c / (NATNUMBER)b); … … 481 475 /* overflow: c = 2^32 resp. 2^64, depending on platform */ 482 476 int_number cc = (int_number)omAlloc(sizeof(mpz_t)); 483 mpz_init_set_ui(cc, r-> nr2mModul); mpz_add_ui(cc, cc, 1);477 mpz_init_set_ui(cc, r->mod2mMask); mpz_add_ui(cc, cc, 1); 484 478 mpz_div_ui(cc, cc, (unsigned long)(NATNUMBER)b); 485 479 unsigned long s = mpz_get_ui(cc); … … 496 490 } 497 491 498 number nr2mInvers(number c, const coeffs r)499 { 500 if ((NATNUMBER)c %2==0)492 number nr2mInvers(number c, const coeffs r) 493 { 494 if ((NATNUMBER)c % 2 == 0) 501 495 { 502 496 WerrorS("division by zero divisor"); 503 497 return (number)0; 504 498 } 505 return nr2mInversM(c, r);506 } 507 508 number nr2mNeg 509 { 510 if ((NATNUMBER)c ==0) return c;511 return nr2mNegM(c, r);499 return nr2mInversM(c, r); 500 } 501 502 number nr2mNeg(number c, const coeffs r) 503 { 504 if ((NATNUMBER)c == 0) return c; 505 return nr2mNegM(c, r); 512 506 } 513 507 514 508 number nr2mMapMachineInt(number from, const coeffs src, const coeffs dst) 515 509 { 516 NATNUMBER i = ((NATNUMBER) from) % dst->nr2mModul;517 return (number) 510 NATNUMBER i = ((NATNUMBER)from) % dst->mod2mMask ; 511 return (number)i; 518 512 } 519 513 … … 521 515 { 522 516 NATNUMBER j = (NATNUMBER)1; 523 long ii = (long) 524 if (ii < 0) { j = dst-> nr2mModul; ii = -ii; }517 long ii = (long)from; 518 if (ii < 0) { j = dst->mod2mMask; ii = -ii; } 525 519 NATNUMBER i = (NATNUMBER)ii; 526 i = i & dst-> nr2mModul;520 i = i & dst->mod2mMask; 527 521 /* now we have: from = j * i mod 2^m */ 528 522 return (number)nr2mMult((number)i, (number)j, dst); … … 531 525 number nr2mMapQ(number from, const coeffs src, const coeffs dst) 532 526 { 533 int_number erg = (int_number) 527 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 534 528 mpz_init(erg); 535 int_number k = (int_number) 536 mpz_init_set_ui(k, dst-> nr2mModul);529 int_number k = (int_number)omAlloc(sizeof(mpz_t)); 530 mpz_init_set_ui(k, dst->mod2mMask); 537 531 538 532 nlGMP(from, (number)erg, dst); … … 543 537 mpz_clear(k); omFree((ADDRESS)k); 544 538 545 return (number) 539 return (number)res; 546 540 } 547 541 548 542 number nr2mMapGMP(number from, const coeffs src, const coeffs dst) 549 543 { 550 int_number erg = (int_number) 544 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 551 545 mpz_init(erg); 552 int_number k = (int_number) 553 mpz_init_set_ui(k, dst-> nr2mModul);546 int_number k = (int_number)omAlloc(sizeof(mpz_t)); 547 mpz_init_set_ui(k, dst->mod2mMask); 554 548 555 549 mpz_and(erg, (int_number)from, k); … … 559 553 mpz_clear(k); omFree((ADDRESS)k); 560 554 561 return (number) 555 return (number)res; 562 556 } 563 557 … … 565 559 { 566 560 if (nCoeff_is_Ring_2toM(src) 567 && (src-> ringflagb == dst->ringflagb))561 && (src->mod2mMask == dst->mod2mMask)) 568 562 { 569 563 return ndCopyMap; … … 587 581 return nr2mMapQ; 588 582 } 589 if (nCoeff_is_Zp(src) 590 && (src->ch == 2) 591 && (dst->ringflagb == 1)) 583 if (nCoeff_is_Zp(src) && (src->ch == 2)) 592 584 { 593 585 return nr2mMapZp; … … 596 588 { 597 589 // Computing the n of Z/n 598 int_number modul = (int_number) omAllocBin(gmp_nrz_bin); 599 mpz_init(modul); 600 mpz_set(modul, src->ringflaga); 601 mpz_pow_ui(modul, modul, src->ringflagb); 602 if (mpz_divisible_2exp_p(modul, dst->ringflagb)) 603 { 604 mpz_clear(modul); 605 omFree((void *) modul); 590 int_number modul = (int_number)omAllocBin(gmp_nrz_bin); 591 mpz_init_set(modul, src->modNumber); 592 int_number twoToTheK = (int_number)omAllocBin(gmp_nrz_bin); 593 mpz_init_set_ui(twoToTheK, src->mod2mMask); 594 mpz_add_ui(twoToTheK, twoToTheK, 1); 595 if (mpz_divisible_p(modul, twoToTheK)) 596 { 597 mpz_clear(modul); omFree((void *)modul); 598 mpz_clear(twoToTheK); omFree((void *)twoToTheK); 606 599 return nr2mMapGMP; 607 600 } 608 mpz_clear(modul); 609 omFree((void *) modul);601 mpz_clear(modul); omFree((void *) modul); 602 mpz_clear(twoToTheK); omFree((void *)twoToTheK); 610 603 } 611 604 return NULL; // default … … 613 606 614 607 /* 615 * set the exponent (allocate and init tables) (TODO)608 * set the exponent 616 609 */ 617 610 … … 620 613 if (m > 1) 621 614 { 622 nr2mExp = m; 623 /* we want nr2mModul to be the bit pattern '11..1' consisting 624 of m one's: */ 625 r->nr2mModul = 1; 626 for (int i = 1; i < m; i++) r->nr2mModul = (r->nr2mModul * 2) + 1; 627 } 628 else 629 { 630 nr2mExp = 2; 631 r->nr2mModul = 3; /* i.e., '11' in binary representation */ 615 /* we want mod2mMask to be the bit pattern 616 '111..1' consisting of m one's: */ 617 r->mod2mMask = 1; 618 for (int i = 1; i < m; i++) r->mod2mMask = (r->mod2mMask << 1) + 1; 619 } 620 else 621 { 622 /* code unexpectedly called with m = 1; we go on with m = 2: */ 623 r->mod2mMask = 3; /* i.e., '11' in binary representation */ 632 624 } 633 625 } … … 636 628 { 637 629 nr2mSetExp(m, r); 638 if (m < 2) WarnS("nr2mInitExp failed: we go on with Z/2^2"); 630 if (m < 2) 631 WarnS("nr2mInitExp unexpectedly called with m = 1 (we go on with Z/2^2"); 639 632 } 640 633 … … 643 636 { 644 637 if ((NATNUMBER)a < 0) return FALSE; 645 if (((NATNUMBER)a & r-> nr2mModul) != (NATNUMBER)a) return FALSE;638 if (((NATNUMBER)a & r->mod2mMask) != (NATNUMBER)a) return FALSE; 646 639 return TRUE; 647 640 } … … 664 657 (*i) *= 10; 665 658 (*i) += *s++ - '0'; 666 if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) & r-> nr2mModul;659 if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) & r->mod2mMask; 667 660 } 668 661 while (((*s) >= '0') && ((*s) <= '9')); 669 (*i) = (*i) & r-> nr2mModul;662 (*i) = (*i) & r->mod2mMask; 670 663 } 671 664 else (*i) = 1; -
Property
mode
changed from
-
coeffs/rmodulo2m.h
-
Property
mode
changed from
100644
to100755
r5d594a9 re90dfd6 6 6 /* $Id$ */ 7 7 /* 8 * ABSTRACT: numbers modulo 2^m 8 * ABSTRACT: numbers modulo 2^m such that 2^m - 1 9 * fits in an unsigned long 9 10 */ 10 11 #ifdef HAVE_RINGS … … 16 17 #endif 17 18 18 19 19 BOOLEAN nr2mInitChar (coeffs r, void*); 20 21 extern int nr2mExp;22 extern NATNUMBER nr2mModul; /* for storing 2^m - 1, i.e., the23 bit pattern '11..1' of length m */24 20 25 21 number nr2mCopy (number a, const coeffs r); … … 62 58 { 63 59 return (number) 64 ((((NATNUMBER) a) * ((NATNUMBER) b)) & ((NATNUMBER) r->nr2mModul));60 ((((NATNUMBER) a) * ((NATNUMBER) b)) & ((NATNUMBER)r->mod2mMask)); 65 61 } 66 62 … … 68 64 { 69 65 return (number) 70 ((((NATNUMBER) a) + ((NATNUMBER) b)) & ((NATNUMBER) r->nr2mModul));66 ((((NATNUMBER) a) + ((NATNUMBER) b)) & ((NATNUMBER)r->mod2mMask)); 71 67 } 72 68 73 69 static inline number nr2mSubM(number a, number b, const coeffs r) 74 70 { 75 return (number)((NATNUMBER)a<(NATNUMBER)b ? 76 r->nr2mModul-(NATNUMBER)b+(NATNUMBER)a + 1: (NATNUMBER)a-(NATNUMBER)b); 71 return (number)((NATNUMBER)a < (NATNUMBER)b ? 72 r->mod2mMask - (NATNUMBER)b + (NATNUMBER)a + 1: 73 (NATNUMBER)a - (NATNUMBER)b); 77 74 } 78 75 79 #define nr2mNegM(A,r) (number)( r->nr2mModul-(NATNUMBER)(A) + 1)76 #define nr2mNegM(A,r) (number)((r->mod2mMask - (NATNUMBER)(A) + 1) & r->mod2mMask) 80 77 #define nr2mEqualM(A,B) ((A)==(B)) 81 78 -
Property
mode
changed from
-
coeffs/rmodulon.cc
-
Property
mode
changed from
100644
to100755
r5d594a9 re90dfd6 26 26 extern omBin gmp_nrz_bin; 27 27 28 int_number nrnMinusOne = NULL;29 unsigned long nrnExponent = 0;30 31 28 /* for initializing function pointers */ 32 29 BOOLEAN nrnInitChar (coeffs r, void* p) … … 34 31 35 32 nrnInitExp((int)(long)(p), r); 36 37 r->cfInit= nrnInit;38 r->cfDelete= nrnDelete;39 r->cfCopy= nrnCopy;40 41 r->cfInt= nrnInt;42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 r->cfWrite= nrnWrite;60 61 62 r->cfSetMap= nrnSetMap;63 64 65 66 67 68 69 33 34 r->cfInit = nrnInit; 35 r->cfDelete = nrnDelete; 36 r->cfCopy = nrnCopy; 37 r->cfSize = nrnSize; 38 r->cfInt = nrnInt; 39 r->cfAdd = nrnAdd; 40 r->cfSub = nrnSub; 41 r->cfMult = nrnMult; 42 r->cfDiv = nrnDiv; 43 r->cfIntDiv = nrnIntDiv; 44 r->cfIntMod = nrnMod; 45 r->cfExactDiv = nrnDiv; 46 r->cfNeg = nrnNeg; 47 r->cfInvers = nrnInvers; 48 r->cfDivBy = nrnDivBy; 49 r->cfDivComp = nrnDivComp; 50 r->cfGreater = nrnGreater; 51 r->cfEqual = nrnEqual; 52 r->cfIsZero = nrnIsZero; 53 r->cfIsOne = nrnIsOne; 54 r->cfIsMOne = nrnIsMOne; 55 r->cfGreaterZero = nrnGreaterZero; 56 r->cfWrite = nrnWrite; 57 r->cfRead = nrnRead; 58 r->cfPower = nrnPower; 59 r->cfSetMap = nrnSetMap; 60 r->cfNormalize = ndNormalize; 61 r->cfLcm = nrnLcm; 62 r->cfGcd = nrnGcd; 63 r->cfIsUnit = nrnIsUnit; 64 r->cfGetUnit = nrnGetUnit; 65 r->cfExtGcd = nrnExtGcd; 66 r->cfName = ndName; 70 67 #ifdef LDEBUG 71 68 r->cfDBTest = nrnDBTest; 72 69 #endif 73 70 return FALSE; … … 77 74 * create a number from int 78 75 */ 79 number nrnInit 76 number nrnInit(int i, const coeffs r) 80 77 { 81 78 int_number erg = (int_number) omAllocBin(gmp_nrz_bin); 82 79 mpz_init_set_si(erg, i); 83 mpz_mod(erg, erg, r-> nrnModul);80 mpz_mod(erg, erg, r->modNumber); 84 81 return (number) erg; 85 82 } … … 111 108 int nrnInt(number &n, const coeffs r) 112 109 { 113 return (int) mpz_get_si((int_number) n);110 return (int)mpz_get_si((int_number) n); 114 111 } 115 112 … … 117 114 * Multiply two numbers 118 115 */ 119 number nrnMult 120 { 121 int_number erg = (int_number) 122 mpz_init(erg); 123 mpz_mul(erg, (int_number) 124 mpz_mod(erg, erg, r-> nrnModul);116 number nrnMult(number a, number b, const coeffs r) 117 { 118 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 119 mpz_init(erg); 120 mpz_mul(erg, (int_number)a, (int_number) b); 121 mpz_mod(erg, erg, r->modNumber); 125 122 return (number) erg; 126 123 } 127 124 128 void nrnPower 129 { 130 int_number erg = (int_number) 131 mpz_init(erg); 132 mpz_powm_ui(erg, (int_number) a, i, r->nrnModul);125 void nrnPower(number a, int i, number * result, const coeffs r) 126 { 127 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 128 mpz_init(erg); 129 mpz_powm_ui(erg, (int_number)a, i, r->modNumber); 133 130 *result = (number) erg; 134 131 } 135 132 136 number nrnAdd 137 { 138 int_number erg = (int_number) 139 mpz_init(erg); 140 mpz_add(erg, (int_number) 141 mpz_mod(erg, erg, r-> nrnModul);133 number nrnAdd(number a, number b, const coeffs r) 134 { 135 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 136 mpz_init(erg); 137 mpz_add(erg, (int_number)a, (int_number) b); 138 mpz_mod(erg, erg, r->modNumber); 142 139 return (number) erg; 143 140 } 144 141 145 number nrnSub 146 { 147 int_number erg = (int_number) 148 mpz_init(erg); 149 mpz_sub(erg, (int_number) 150 mpz_mod(erg, erg, r-> nrnModul);142 number nrnSub(number a, number b, const coeffs r) 143 { 144 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 145 mpz_init(erg); 146 mpz_sub(erg, (int_number)a, (int_number) b); 147 mpz_mod(erg, erg, r->modNumber); 151 148 return (number) erg; 152 149 } 153 150 154 number nrnNeg 155 { 156 // nNeg inplace !!! 157 mpz_sub((int_number) c, r->nrnModul, (int_number)c);151 number nrnNeg(number c, const coeffs r) 152 { 153 // Attention: This method operates in-place. 154 mpz_sub((int_number)c, r->modNumber, (int_number)c); 158 155 return c; 159 156 } 160 157 161 number nrnInvers(number c, const coeffs r)162 { 163 int_number erg = (int_number) 164 mpz_init(erg); 165 mpz_invert(erg, (int_number) c, r->nrnModul);158 number nrnInvers(number c, const coeffs r) 159 { 160 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 161 mpz_init(erg); 162 mpz_invert(erg, (int_number)c, r->modNumber); 166 163 return (number) erg; 167 164 } 168 165 169 166 /* 170 * Give the smallest non unitk, such that a * x = k = b * y has a solution171 * TODO: lcm(gcd,gcd) be sser alsgcd(lcm) ?172 */ 173 number nrnLcm 167 * Give the smallest k, such that a * x = k = b * y has a solution 168 * TODO: lcm(gcd,gcd) better than gcd(lcm) ? 169 */ 170 number nrnLcm(number a, number b, const coeffs r) 174 171 { 175 172 number erg = nrnGcd(NULL, a, r); 176 173 number tmp = nrnGcd(NULL, b, r); 177 mpz_lcm((int_number) erg, (int_number) erg, (int_number)tmp);174 mpz_lcm((int_number)erg, (int_number)erg, (int_number)tmp); 178 175 nrnDelete(&tmp, NULL); 179 return (number) 180 } 181 182 /* 183 * Give the largest non unitk, such that a = x * k, b = y * k has176 return (number)erg; 177 } 178 179 /* 180 * Give the largest k, such that a = x * k, b = y * k has 184 181 * a solution. 185 182 */ 186 number nrnGcd 183 number nrnGcd(number a, number b, const coeffs r) 187 184 { 188 185 if ((a == NULL) && (b == NULL)) return nrnInit(0,r); 186 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 187 mpz_init_set(erg, r->modNumber); 188 if (a != NULL) mpz_gcd(erg, erg, (int_number)a); 189 if (b != NULL) mpz_gcd(erg, erg, (int_number)b); 190 return (number)erg; 191 } 192 193 /* Not needed any more, but may have room for improvement 194 number nrnGcd3(number a,number b, number c,ring r) 195 { 189 196 int_number erg = (int_number) omAllocBin(gmp_nrz_bin); 190 mpz_init_set(erg, r->nrnModul); 191 if (a != NULL) mpz_gcd(erg, erg, (int_number) a); 192 if (b != NULL) mpz_gcd(erg, erg, (int_number) b); 193 return (number) erg; 194 } 195 196 /* Not needed any more, but may have room for improvement 197 number nrnGcd3 (number a,number b, number c,ring r) 198 { 199 int_number erg = (int_number) omAllocBin(gmp_nrz_bin); 200 mpz_init(erg); 201 if (a == NULL) a = (number) r->nrnModul; 202 if (b == NULL) b = (number) r->nrnModul; 203 if (c == NULL) c = (number) r->nrnModul; 204 mpz_gcd(erg, (int_number) a, (int_number) b); 205 mpz_gcd(erg, erg, (int_number) c); 206 mpz_gcd(erg, erg, r->nrnModul); 207 return (number) erg; 197 mpz_init(erg); 198 if (a == NULL) a = (number)r->modNumber; 199 if (b == NULL) b = (number)r->modNumber; 200 if (c == NULL) c = (number)r->modNumber; 201 mpz_gcd(erg, (int_number)a, (int_number)b); 202 mpz_gcd(erg, erg, (int_number)c); 203 mpz_gcd(erg, erg, r->modNumber); 204 return (number)erg; 208 205 } 209 206 */ 210 207 211 208 /* 212 * Give the largest non unitk, such that a = x * k, b = y * k has209 * Give the largest k, such that a = x * k, b = y * k has 213 210 * a solution and r, s, s.t. k = s*a + t*b 214 211 */ 215 number nrnExtGcd(number a, number b, number *s, number *t, const coeffs r)216 { 217 int_number erg = (int_number) 218 int_number bs = (int_number)omAllocBin(gmp_nrz_bin);219 int_number bt = (int_number)omAllocBin(gmp_nrz_bin);212 number nrnExtGcd(number a, number b, number *s, number *t, const coeffs r) 213 { 214 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 215 int_number bs = (int_number)omAllocBin(gmp_nrz_bin); 216 int_number bt = (int_number)omAllocBin(gmp_nrz_bin); 220 217 mpz_init(erg); 221 218 mpz_init(bs); 222 219 mpz_init(bt); 223 mpz_gcdext(erg, bs, bt, (int_number) a, (int_number)b);224 mpz_mod(bs, bs, r-> nrnModul);225 mpz_mod(bt, bt, r-> nrnModul);226 *s = (number) 227 *t = (number) 228 return (number) 229 } 230 231 BOOLEAN nrnIsZero 220 mpz_gcdext(erg, bs, bt, (int_number)a, (int_number)b); 221 mpz_mod(bs, bs, r->modNumber); 222 mpz_mod(bt, bt, r->modNumber); 223 *s = (number)bs; 224 *t = (number)bt; 225 return (number)erg; 226 } 227 228 BOOLEAN nrnIsZero(number a, const coeffs r) 232 229 { 233 230 #ifdef LDEBUG 234 231 if (a == NULL) return FALSE; 235 232 #endif 236 return 0 == mpz_cmpabs_ui((int_number) 237 } 238 239 BOOLEAN nrnIsOne 233 return 0 == mpz_cmpabs_ui((int_number)a, 0); 234 } 235 236 BOOLEAN nrnIsOne(number a, const coeffs r) 240 237 { 241 238 #ifdef LDEBUG 242 239 if (a == NULL) return FALSE; 243 240 #endif 244 return 0 == mpz_cmp_si((int_number) 245 } 246 247 BOOLEAN nrnIsMOne 241 return 0 == mpz_cmp_si((int_number)a, 1); 242 } 243 244 BOOLEAN nrnIsMOne(number a, const coeffs r) 248 245 { 249 246 #ifdef LDEBUG 250 247 if (a == NULL) return FALSE; 251 248 #endif 252 return 0 == mpz_cmp((int_number) a, nrnMinusOne); 253 } 254 255 BOOLEAN nrnEqual (number a, number b, const coeffs r) 256 { 257 return 0 == mpz_cmp((int_number) a, (int_number) b); 258 } 259 260 BOOLEAN nrnGreater (number a, number b, const coeffs r) 261 { 262 return 0 < mpz_cmp((int_number) a, (int_number) b); 263 } 264 265 BOOLEAN nrnGreaterZero (number k, const coeffs r) 266 { 267 return 0 < mpz_cmp_si((int_number) k, 0); 268 } 269 270 BOOLEAN nrnIsUnit (number a, const coeffs r) 271 { 272 number tmp = nrnGcd(a, (number) r->nrnModul, r); 273 bool res = nrnIsOne(tmp,r); 249 mpz_t t; mpz_init_set(t, (int_number)a); 250 mpz_add_ui(t, t, 1); 251 bool erg = (0 == mpz_cmp(t, r->modNumber)); 252 mpz_clear(t); 253 return erg; 254 } 255 256 BOOLEAN nrnEqual(number a, number b, const coeffs r) 257 { 258 return 0 == mpz_cmp((int_number)a, (int_number)b); 259 } 260 261 BOOLEAN nrnGreater(number a, number b, const coeffs r) 262 { 263 return 0 < mpz_cmp((int_number)a, (int_number)b); 264 } 265 266 BOOLEAN nrnGreaterZero(number k, const coeffs r) 267 { 268 return 0 < mpz_cmp_si((int_number)k, 0); 269 } 270 271 BOOLEAN nrnIsUnit(number a, const coeffs r) 272 { 273 number tmp = nrnGcd(a, (number)r->modNumber, r); 274 bool res = nrnIsOne(tmp, r); 274 275 nrnDelete(&tmp, NULL); 275 276 return res; 276 277 } 277 278 278 number nrnGetUnit(number k, const coeffs r)279 { 280 if (mpz_divisible_p(r-> nrnModul, (int_number)k)) return nrnInit(1,r);281 282 int_number unit = (int_number) 283 mpz_tdiv_q(unit, (int_number) 284 int_number gcd = (int_number) nrnGcd((number)unit, 0, r);285 if (!nrnIsOne((number) 279 number nrnGetUnit(number k, const coeffs r) 280 { 281 if (mpz_divisible_p(r->modNumber, (int_number)k)) return nrnInit(1,r); 282 283 int_number unit = (int_number)nrnGcd(k, 0, r); 284 mpz_tdiv_q(unit, (int_number)k, unit); 285 int_number gcd = (int_number)nrnGcd((number)unit, 0, r); 286 if (!nrnIsOne((number)gcd,r)) 286 287 { 287 288 int_number ctmp; … … 298 299 // tmp := tmp * unit 299 300 mpz_mul(tmp, tmp, unit); 300 mpz_mod(tmp, tmp, r-> nrnModul);301 mpz_mod(tmp, tmp, r->modNumber); 301 302 // gcd_new := gcd(tmp, 0) 302 mpz_gcd(gcd_new, tmp, r-> nrnModul);303 mpz_gcd(gcd_new, tmp, r->modNumber); 303 304 } 304 // unit := unit + nrnModul/ gcd_new305 mpz_tdiv_q(tmp, r-> nrnModul, gcd_new);305 // unit := unit + modNumber / gcd_new 306 mpz_tdiv_q(tmp, r->modNumber, gcd_new); 306 307 mpz_add(unit, unit, tmp); 307 mpz_mod(unit, unit, r-> nrnModul);308 mpz_mod(unit, unit, r->modNumber); 308 309 nrnDelete((number*) &gcd_new, NULL); 309 310 nrnDelete((number*) &tmp, NULL); 310 311 } 311 312 nrnDelete((number*) &gcd, NULL); 312 return (number) 313 } 314 315 BOOLEAN nrnDivBy 313 return (number)unit; 314 } 315 316 BOOLEAN nrnDivBy(number a, number b, const coeffs r) 316 317 { 317 318 if (a == NULL) 318 return mpz_divisible_p(r-> nrnModul, (int_number)b);319 return mpz_divisible_p(r->modNumber, (int_number)b); 319 320 else 320 321 { /* b divides a iff b/gcd(a, b) is a unit in the given ring: */ … … 332 333 if (mpz_divisible_p((int_number) a, (int_number) b)) return -1; 333 334 if (mpz_divisible_p((int_number) b, (int_number) a)) return 1; 334 return 2;335 } 336 337 number nrnDiv 338 { 339 if (a == NULL) a = (number) r->nrnModul;340 int_number erg = (int_number) 341 mpz_init(erg); 342 if (mpz_divisible_p((int_number) a, (int_number)b))343 { 344 mpz_divexact(erg, (int_number) a, (int_number)b);345 return (number) 335 return 0; 336 } 337 338 number nrnDiv(number a, number b, const coeffs r) 339 { 340 if (a == NULL) a = (number)r->modNumber; 341 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 342 mpz_init(erg); 343 if (mpz_divisible_p((int_number)a, (int_number)b)) 344 { 345 mpz_divexact(erg, (int_number)a, (int_number)b); 346 return (number)erg; 346 347 } 347 348 else 348 349 { 349 int_number gcd = (int_number) 350 mpz_divexact(erg, (int_number) 351 if (!nrnIsUnit((number) erg,r))350 int_number gcd = (int_number)nrnGcd(a, b, r); 351 mpz_divexact(erg, (int_number)b, gcd); 352 if (!nrnIsUnit((number)erg, r)) 352 353 { 353 354 WerrorS("Division not possible, even by cancelling zero divisors."); … … 355 356 mpz_tdiv_q(erg, (int_number) a, (int_number) b); 356 357 nrnDelete((number*) &gcd, NULL); 357 return (number) 358 return (number)erg; 358 359 } 359 360 // a / gcd(a,b) * [b / gcd (a,b)]^(-1) 360 int_number tmp = (int_number) 361 mpz_divexact(erg, (int_number) 361 int_number tmp = (int_number)nrnInvers((number) erg,r); 362 mpz_divexact(erg, (int_number)a, gcd); 362 363 mpz_mul(erg, erg, tmp); 363 364 nrnDelete((number*) &gcd, NULL); 364 365 nrnDelete((number*) &tmp, NULL); 365 mpz_mod(erg, erg, r-> nrnModul);366 return (number) 367 } 368 } 369 370 number nrnMod (number a, number b, const coeffs R)366 mpz_mod(erg, erg, r->modNumber); 367 return (number)erg; 368 } 369 } 370 371 number nrnMod(number a, number b, const coeffs r) 371 372 { 372 373 /* 373 We need to return the number r which is uniquely determined by the374 We need to return the number rr which is uniquely determined by the 374 375 following two properties: 375 (1) 0 <= r < |b| (with respect to '<' and '<=' performed in Z x Z)376 (2) There exists some k in the integers Z such that a = k * b + r .376 (1) 0 <= rr < |b| (with respect to '<' and '<=' performed in Z x Z) 377 (2) There exists some k in the integers Z such that a = k * b + rr. 377 378 Consider g := gcd(n, |b|). Note that then |b|/g is a unit in Z/n. 378 379 Now, there are three cases: 379 380 (a) g = 1 380 381 Then |b| is a unit in Z/n, i.e. |b| (and also b) divides a. 381 Thus r = 0.382 Thus rr = 0. 382 383 (b) g <> 1 and g divides a 383 Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again r = 0.384 Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again rr = 0. 384 385 (c) g <> 1 and g does not divide a 385 386 Then denote the division with remainder of a by g as this: 386 387 a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b| 387 fulfills (1) and (2), i.e. r := t is the correct result. Hence388 in this third case, r is the remainder of division of a by g in Z.388 fulfills (1) and (2), i.e. rr := t is the correct result. Hence 389 in this third case, rr is the remainder of division of a by g in Z. 389 390 Remark: according to mpz_mod: a,b are always non-negative 390 391 */ 391 int_number g = (int_number) 392 int_number r = (int_number)omAllocBin(gmp_nrz_bin);392 int_number g = (int_number)omAllocBin(gmp_nrz_bin); 393 int_number rr = (int_number)omAllocBin(gmp_nrz_bin); 393 394 mpz_init(g); 394 mpz_init_set_si(r ,(long)0);395 mpz_gcd(g, (int_number) R->nrnModul, (int_number)b); // g is now as above396 if (mpz_cmp_si(g, (long)1) != 0) mpz_mod(r , (int_number)a, g); // the case g <> 1395 mpz_init_set_si(rr, 0); 396 mpz_gcd(g, (int_number)r->modNumber, (int_number)b); // g is now as above 397 if (mpz_cmp_si(g, (long)1) != 0) mpz_mod(rr, (int_number)a, g); // the case g <> 1 397 398 mpz_clear(g); 398 399 omFreeBin(g, gmp_nrz_bin); 399 return (number)r ;400 } 401 402 number nrnIntDiv 403 { 404 int_number erg = (int_number) 405 mpz_init(erg); 406 if (a == NULL) a = (number) r->nrnModul;407 mpz_tdiv_q(erg, (int_number) a, (int_number)b);408 return (number) 400 return (number)rr; 401 } 402 403 number nrnIntDiv(number a, number b, const coeffs r) 404 { 405 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 406 mpz_init(erg); 407 if (a == NULL) a = (number)r->modNumber; 408 mpz_tdiv_q(erg, (int_number)a, (int_number)b); 409 return (number)erg; 409 410 } 410 411 … … 422 423 number nrnMap2toM(number from, const coeffs src, const coeffs dst) 423 424 { 424 int_number erg = (int_number) 425 mpz_init(erg); 426 mpz_mul_ui(erg, nrnMapCoef, (NATNUMBER) 427 mpz_mod(erg, erg, dst-> nrnModul);428 return (number) 425 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 426 mpz_init(erg); 427 mpz_mul_ui(erg, nrnMapCoef, (NATNUMBER)from); 428 mpz_mod(erg, erg, dst->modNumber); 429 return (number)erg; 429 430 } 430 431 431 432 number nrnMapZp(number from, const coeffs src, const coeffs dst) 432 433 { 433 int_number erg = (int_number) 434 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 434 435 mpz_init(erg); 435 436 // TODO: use npInt(...) 436 mpz_mul_si(erg, nrnMapCoef, (NATNUMBER) 437 mpz_mod(erg, erg, dst-> nrnModul);438 return (number) 437 mpz_mul_si(erg, nrnMapCoef, (NATNUMBER)from); 438 mpz_mod(erg, erg, dst->modNumber); 439 return (number)erg; 439 440 } 440 441 441 442 number nrnMapGMP(number from, const coeffs src, const coeffs dst) 442 443 { 443 int_number erg = (int_number) 444 mpz_init(erg); 445 mpz_mod(erg, (int_number) from, dst->nrnModul);446 return (number) 444 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 445 mpz_init(erg); 446 mpz_mod(erg, (int_number)from, dst->modNumber); 447 return (number)erg; 447 448 } 448 449 449 450 number nrnMapQ(number from, const coeffs src, const coeffs dst) 450 451 { 451 int_number erg = (int_number) 452 mpz_init(erg); 453 nlGMP(from, (number) 454 mpz_mod(erg, erg, src-> nrnModul);455 return (number) 452 int_number erg = (int_number)omAllocBin(gmp_nrz_bin); 453 mpz_init(erg); 454 nlGMP(from, (number)erg, src); 455 mpz_mod(erg, erg, src->modNumber); 456 return (number)erg; 456 457 } 457 458 … … 471 472 { 472 473 if ( (src->ringtype > 0) 473 && (mpz_cmp(src-> ringflaga, dst->ringflaga) == 0)474 && (src-> ringflagb == dst->ringflagb)) return nrnCopy;474 && (mpz_cmp(src->modBase, dst->modBase) == 0) 475 && (src->modExponent == dst->modExponent)) return nrnMapGMP; 475 476 else 476 477 { … … 484 485 { 485 486 mpz_init(nrnMapModul); 486 mpz_set(nrnMapModul, src->ringflaga); 487 mpz_pow_ui(nrnMapModul, nrnMapModul, src->ringflagb); 487 mpz_set(nrnMapModul, src->modNumber); 488 488 } 489 489 // nrnMapCoef = 1 in dst if dst is a subring of src … … 494 494 mpz_init(nrnMapCoef); 495 495 } 496 if (mpz_divisible_p(nrnMapModul, dst-> nrnModul))496 if (mpz_divisible_p(nrnMapModul, dst->modNumber)) 497 497 { 498 498 mpz_set_si(nrnMapCoef, 1); … … 501 501 if (nrnDivBy(NULL, (number) nrnMapModul,dst)) 502 502 { 503 mpz_divexact(nrnMapCoef, dst-> nrnModul, nrnMapModul);504 int_number tmp = dst-> nrnModul;505 dst-> nrnModul= nrnMapModul;503 mpz_divexact(nrnMapCoef, dst->modNumber, nrnMapModul); 504 int_number tmp = dst->modNumber; 505 dst->modNumber = nrnMapModul; 506 506 if (!nrnIsUnit((number) nrnMapCoef,dst)) 507 507 { 508 dst-> nrnModul= tmp;508 dst->modNumber = tmp; 509 509 nrnDelete((number*) &nrnMapModul, dst); 510 510 return NULL; 511 511 } 512 512 int_number inv = (int_number) nrnInvers((number) nrnMapCoef,dst); 513 dst-> nrnModul= tmp;513 dst->modNumber = tmp; 514 514 mpz_mul(nrnMapCoef, nrnMapCoef, inv); 515 mpz_mod(nrnMapCoef, nrnMapCoef, dst-> nrnModul);515 mpz_mod(nrnMapCoef, nrnMapCoef, dst->modNumber); 516 516 nrnDelete((number*) &inv, dst); 517 517 } … … 539 539 void nrnSetExp(int m, coeffs r) 540 540 { 541 if ((r->nrnModul != NULL) && (mpz_cmp(r->nrnModul, r->ringflaga) == 0) && (nrnExponent == r->ringflagb)) return;542 543 nrnExponent = r->ringflagb;544 if (r->nrnModul == NULL) 545 {546 r->nrnModul = (int_number)omAllocBin(gmp_nrz_bin);547 mpz_init(r->nrnModul);548 nrnMinusOne = (int_number) omAllocBin(gmp_nrz_bin);549 mpz_init(nrnMinusOne);550 }551 // BUG: r->ringflaga is undefined!552 mpz_set(r-> nrnModul, r->ringflaga);553 mpz_pow_ui(r->nrnModul, r->nrnModul, nrnExponent);554 mpz_sub_ui(nrnMinusOne, r->nrnModul, 1); 555 } 556 541 /* clean up former stuff */ 542 if (r->modBase != NULL) mpz_clear(r->modBase); 543 if (r->modNumber != NULL) mpz_clear(r->modNumber); 544 545 /* this is Z/m = Z/(m^1), hence set modBase = m, modExponent = 1: */ 546 r->modBase = (int_number)omAllocBin(gmp_nrz_bin); 547 mpz_init(r->modBase); 548 mpz_set_ui(r->modBase, (unsigned long)m); 549 r->modExponent = 1; 550 r->modNumber = (int_number)omAllocBin(gmp_nrz_bin); 551 mpz_init(r->modNumber); 552 mpz_set(r->modNumber, r->modBase); 553 /* mpz_pow_ui(r->modNumber, r->modNumber, r->modExponent); */ 554 } 555 556 /* We expect this ring to be Z/m for some m > 2 which is not a prime. */ 557 557 void nrnInitExp(int m, coeffs r) 558 558 { 559 if (m <= 2) WarnS("nrnInitExp failed (m in Z/m too small)"); 559 560 nrnSetExp(m, r); 560 561 if (mpz_cmp_ui(r->nrnModul, 2) <= 0) // ???562 {563 WarnS("nrnInitExp failed");564 }565 566 r->ch = m; // ???567 561 } 568 562 … … 571 565 { 572 566 if (a==NULL) return TRUE; 573 if ( (mpz_cmp_si((int_number) a, 0) < 0) || (mpz_cmp((int_number) a, r-> nrnModul) > 0) )567 if ( (mpz_cmp_si((int_number) a, 0) < 0) || (mpz_cmp((int_number) a, r->modNumber) > 0) ) 574 568 { 575 569 return FALSE; … … 612 606 s = nlCPEatLongC((char *)s, z); 613 607 } 614 mpz_mod(z, z, r-> nrnModul);608 mpz_mod(z, z, r->modNumber); 615 609 *a = (number) z; 616 610 return s; -
Property
mode
changed from
Note: See TracChangeset
for help on using the changeset viewer.