Annotation of OpenXM_contrib2/asir2000/engine/gmpq.c, Revision 1.1
1.1 ! noro 1: #include "ca.h"
! 2: #include "gmp.h"
! 3: #include "base.h"
! 4: #include "inline.h"
! 5:
! 6: mpz_t ONEMPZ;
! 7: GZ ONEGZ;
! 8:
! 9: void isqrtgz(GZ a,GZ *r);
! 10: void bshiftgz(GZ a,int n,GZ *r);
! 11:
! 12: void *gc_realloc(void *p,size_t osize,size_t nsize)
! 13: {
! 14: return (void *)GC_realloc(p,nsize);
! 15: }
! 16:
! 17: void gc_free(void *p,size_t size)
! 18: {
! 19: GC_free(p);
! 20: }
! 21:
! 22: void init_gmpq()
! 23: {
! 24: mp_set_memory_functions(GC_malloc_atomic,gc_realloc,gc_free);
! 25:
! 26: mpz_init(ONEMPZ); mpz_set_ui(ONEMPZ,1); MPZTOGZ(ONEMPZ,ONEGZ);
! 27: }
! 28:
! 29: GZ utogz(unsigned int u)
! 30: {
! 31: mpz_t z;
! 32: GZ r;
! 33:
! 34: if ( !u ) return 0;
! 35: mpz_init(z); mpz_set_ui(z,u); MPZTOGZ(z,r); return r;
! 36: }
! 37:
! 38: GZ stogz(int s)
! 39: {
! 40: mpz_t z;
! 41: GZ r;
! 42:
! 43: if ( !s ) return 0;
! 44: mpz_init(z); mpz_set_si(z,s); MPZTOGZ(z,r); return r;
! 45: }
! 46:
! 47: GQ mpqtogzq(mpq_t a)
! 48: {
! 49: GZ z;
! 50: GQ q;
! 51:
! 52: if ( INTMPQ(a) ) {
! 53: MPZTOGZ(mpq_numref(a),z); return (GQ)z;
! 54: } else {
! 55: MPQTOGQ(a,q); return q;
! 56: }
! 57: }
! 58:
! 59: GZ ztogz(Q a)
! 60: {
! 61: mpz_t z;
! 62: mpq_t b;
! 63: N nm;
! 64: GZ s;
! 65:
! 66: if ( !a ) return 0;
! 67: nm = NM(a);
! 68: mpz_init(z);
! 69: mpz_import(z,PL(nm),-1,sizeof(BD(nm)[0]),0,0,BD(nm));
! 70: if ( SGN(a)<0 ) mpz_neg(z,z);
! 71: MPZTOGZ(z,s);
! 72: return s;
! 73: }
! 74:
! 75: Q gztoz(GZ a)
! 76: {
! 77: N nm;
! 78: Q q;
! 79: int sgn;
! 80: size_t len;
! 81:
! 82: if ( !a ) return 0;
! 83: len = WORDSIZE_IN_N(BDY((GZ)a)); nm = NALLOC(len);
! 84: mpz_export(BD(nm),&len,-1,sizeof(int),0,0,BDY((GZ)a));
! 85: PL(nm) = len;
! 86: sgn = mpz_sgn(BDY((GZ)a)); NTOQ(nm,sgn,q);
! 87: return q;
! 88: }
! 89:
! 90: int n_bits_gz(GZ a)
! 91: {
! 92: return a ? mpz_sizeinbase(BDY(a),2) : 0;
! 93: }
! 94:
! 95: GQ qtogq(Q a)
! 96: {
! 97: mpz_t z;
! 98: mpq_t b;
! 99: N nm,dn;
! 100: GZ s;
! 101: GQ r;
! 102:
! 103: if ( !a ) return 0;
! 104: if ( INT(a) ) {
! 105: nm = NM(a);
! 106: mpz_init(z);
! 107: mpz_import(z,PL(nm),-1,sizeof(BD(nm)[0]),0,0,BD(nm));
! 108: if ( SGN(a)<0 ) mpz_neg(z,z);
! 109: MPZTOGZ(z,s);
! 110: return (GQ)s;
! 111: } else {
! 112: nm = NM(a); dn = DN(a);
! 113: mpq_init(b);
! 114: mpz_import(mpq_numref(b),PL(nm),-1,sizeof(BD(nm)[0]),0,0,BD(nm));
! 115: mpz_import(mpq_denref(b),PL(dn),-1,sizeof(BD(dn)[0]),0,0,BD(dn));
! 116: if ( SGN(a)<0 ) mpq_neg(b,b);
! 117: MPQTOGQ(b,r);
! 118: return r;
! 119: }
! 120: }
! 121:
! 122: Q gqtoq(GQ a)
! 123: {
! 124: N nm,dn;
! 125: Q q;
! 126: int sgn;
! 127: size_t len;
! 128:
! 129: if ( !a ) return 0;
! 130: if ( NID(a) == N_GZ ) {
! 131: len = WORDSIZE_IN_N(BDY((GZ)a)); nm = NALLOC(len);
! 132: mpz_export(BD(nm),&len,-1,sizeof(int),0,0,BDY((GZ)a));
! 133: PL(nm) = len;
! 134: sgn = mpz_sgn(BDY((GZ)a)); NTOQ(nm,sgn,q);
! 135: } else {
! 136: len = WORDSIZE_IN_N(mpq_numref(BDY(a))); nm = NALLOC(len);
! 137: mpz_export(BD(nm),&len,-1,sizeof(int),0,0,mpq_numref(BDY(a)));
! 138: PL(nm) = len;
! 139: len = WORDSIZE_IN_N(mpq_denref(BDY(a))); dn = NALLOC(len);
! 140: mpz_export(BD(dn),&len,-1,sizeof(int),0,0,mpq_denref(BDY(a)));
! 141: PL(dn) = len;
! 142: sgn = mpz_sgn(mpq_numref(BDY(a))); NDTOQ(nm,dn,sgn,q);
! 143: }
! 144: return q;
! 145: }
! 146:
! 147: P ptogp(P a)
! 148: {
! 149: DCP dc,dcr,dcr0;
! 150: P b;
! 151:
! 152: if ( !a ) return 0;
! 153: if ( NUM(a) ) return (P)qtogq((Q)a);
! 154: for ( dc = DC(a), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 155: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = (P)ptogp(COEF(dc));
! 156: }
! 157: NEXT(dcr) = 0; MKP(VR(a),dcr0,b);
! 158: return b;
! 159: }
! 160:
! 161: P gptop(P a)
! 162: {
! 163: DCP dc,dcr,dcr0;
! 164: P b;
! 165:
! 166: if ( !a ) return 0;
! 167: if ( NUM(a) ) b = (P)gqtoq((GQ)a);
! 168: else {
! 169: for ( dc = DC(a), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 170: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);
! 171: COEF(dcr) = (P)gptop(COEF(dc));
! 172: }
! 173: NEXT(dcr) = 0; MKP(VR(a),dcr0,b);
! 174: }
! 175: return b;
! 176: }
! 177:
! 178: void addgz(GZ n1,GZ n2,GZ *nr)
! 179: {
! 180: mpz_t t;
! 181: int s1,s2;
! 182:
! 183: if ( !n1 ) *nr = n2;
! 184: else if ( !n2 ) *nr = n1;
! 185: else {
! 186: mpz_init(t); mpz_add(t,BDY(n1),BDY(n2)); MPZTOGZ(t,*nr);
! 187: }
! 188: }
! 189:
! 190: void subgz(GZ n1,GZ n2,GZ *nr)
! 191: {
! 192: mpz_t t;
! 193:
! 194: if ( !n1 )
! 195: if ( !n2 )
! 196: *nr = 0;
! 197: else {
! 198: t[0] = BDY(n2)[0]; mpz_neg(t,t); MPZTOGZ(t,*nr);
! 199: }
! 200: else if ( !n2 )
! 201: *nr = n1;
! 202: else if ( n1 == n2 )
! 203: *nr = 0;
! 204: else {
! 205: mpz_init(t); mpz_sub(t,BDY(n1),BDY(n2)); MPZTOGZ(t,*nr);
! 206: }
! 207: }
! 208:
! 209: void mulgz(GZ n1,GZ n2,GZ *nr)
! 210: {
! 211: mpz_t t;
! 212:
! 213: if ( !n1 || !n2 ) *nr = 0;
! 214: else if ( UNIGZ(n1) ) *nr = n2;
! 215: else if ( UNIGZ(n2) ) *nr = n1;
! 216: else if ( MUNIGZ(n1) ) chsgngz(n2,nr);
! 217: else if ( MUNIGZ(n2) ) chsgngz(n1,nr);
! 218: else {
! 219: mpz_init(t); mpz_mul(t,BDY(n1),BDY(n2)); MPZTOGZ(t,*nr);
! 220: }
! 221: }
! 222:
! 223: void divgz(GZ n1,GZ n2,GZ *nq)
! 224: {
! 225: mpz_t t;
! 226: mpq_t a, b, q;
! 227:
! 228: if ( !n2 ) {
! 229: error("division by 0");
! 230: *nq = 0;
! 231: } else if ( !n1 )
! 232: *nq = 0;
! 233: else if ( n1 == n2 ) {
! 234: mpz_init(t); mpz_set_ui(t,1); MPZTOGZ(t,*nq);
! 235: } else {
! 236: MPZTOMPQ(BDY(n1),a); MPZTOMPQ(BDY(n2),b);
! 237: mpq_init(q); mpq_div(q,a,b); *nq = (GZ)mpqtogzq(q);
! 238: }
! 239: }
! 240:
! 241: void divqrgz(GZ n1,GZ n2,GZ *nq,GZ *nr)
! 242: {
! 243: mpz_t t, a, b, q, r;
! 244:
! 245: if ( !n2 ) {
! 246: error("division by 0");
! 247: *nq = 0; *nr = 0;
! 248: } else if ( !n1 ) {
! 249: *nq = 0; *nr = 0;
! 250: } else if ( n1 == n2 ) {
! 251: mpz_init(t); mpz_set_ui(t,1); MPZTOGZ(t,*nq); *nr = 0;
! 252: } else {
! 253: mpz_init(q); mpz_init(r);
! 254: mpz_fdiv_qr(q,r,BDY(n1),BDY(n2));
! 255: if ( !mpz_sgn(q) ) *nq = 0;
! 256: else MPZTOGZ(q,*nq);
! 257: if ( !mpz_sgn(r) ) *nr = 0;
! 258: else MPZTOGZ(r,*nr);
! 259: }
! 260: }
! 261:
! 262: void divsgz(GZ n1,GZ n2,GZ *nq)
! 263: {
! 264: mpz_t t;
! 265: mpq_t a, b, q;
! 266:
! 267: if ( !n2 ) {
! 268: error("division by 0");
! 269: *nq = 0;
! 270: } else if ( !n1 )
! 271: *nq = 0;
! 272: else if ( n1 == n2 ) {
! 273: mpz_init(t); mpz_set_ui(t,1); MPZTOGZ(t,*nq);
! 274: } else {
! 275: mpz_init(t); mpz_divexact(t,BDY(n1),BDY(n2)); MPZTOGZ(t,*nq);
! 276: }
! 277: }
! 278:
! 279: void chsgngz(GZ n,GZ *nr)
! 280: {
! 281: mpz_t t;
! 282:
! 283: if ( !n )
! 284: *nr = 0;
! 285: else {
! 286: t[0] = BDY(n)[0]; mpz_neg(t,t); MPZTOGZ(t,*nr);
! 287: }
! 288: }
! 289:
! 290: void pwrgz(GZ n1,Q n,GZ *nr)
! 291: {
! 292: mpq_t t,q;
! 293: mpz_t z;
! 294: GQ p,r;
! 295:
! 296: if ( !n || UNIGZ(n1) ) *nr = ONEGZ;
! 297: else if ( !n1 ) *nr = 0;
! 298: else if ( !INT(n) ) {
! 299: error("can't calculate fractional power."); *nr = 0;
! 300: } else if ( MUNIGZ(n1) ) *nr = BD(NM(n))[0]%2 ? n1 : ONEGZ;
! 301: else if ( PL(NM(n)) > 1 ) {
! 302: error("exponent too big."); *nr = 0;
! 303: } else if ( NID(n1)==N_GZ && SGN(n)>0 ) {
! 304: mpz_init(z); mpz_pow_ui(z,BDY(n1),QTOS(n)); MPZTOGZ(z,*nr);
! 305: } else {
! 306: MPZTOMPQ(BDY(n1),q); MPQTOGQ(q,r);
! 307: pwrgq(r,n,&p); *nr = (GZ)p;
! 308: }
! 309: }
! 310:
! 311: int cmpgz(GZ q1,GZ q2)
! 312: {
! 313: int sgn;
! 314:
! 315: if ( !q1 )
! 316: if ( !q2 )
! 317: return 0;
! 318: else
! 319: return -mpz_sgn(BDY(q2));
! 320: else if ( !q2 )
! 321: return mpz_sgn(BDY(q1));
! 322: else if ( (sgn = mpz_sgn(BDY(q1))) != mpz_sgn(BDY(q2)) )
! 323: return sgn;
! 324: else {
! 325: sgn = mpz_cmp(BDY(q1),BDY(q2));
! 326: if ( sgn > 0 ) return 1;
! 327: else if ( sgn < 0 ) return -1;
! 328: else return 0;
! 329: }
! 330: }
! 331:
! 332: void gcdgz(GZ n1,GZ n2,GZ *nq)
! 333: {
! 334: mpz_t t;
! 335:
! 336: if ( !n1 ) *nq = n2;
! 337: else if ( !n2 ) *nq = n1;
! 338: else {
! 339: mpz_init(t); mpz_gcd(t,BDY(n1),BDY(n2));
! 340: MPZTOGZ(t,*nq);
! 341: }
! 342: }
! 343:
! 344: void lcmgz(GZ n1,GZ n2,GZ *nq)
! 345: {
! 346: GZ g,t;
! 347:
! 348: if ( !n1 || !n2 ) *nq = 0;
! 349: else {
! 350: gcdgz(n1,n2,&g); divsgz(n1,g,&t);
! 351: mulgz(n2,t,nq);
! 352: }
! 353: }
! 354:
! 355: void gcdvgz(VECT v,GZ *q)
! 356: {
! 357: int n,i;
! 358: GZ *b;
! 359: GZ g,g1;
! 360:
! 361: n = v->len;
! 362: b = (GZ *)v->body;
! 363: g = b[0];
! 364: for ( i = 1; i < n; i++ ) {
! 365: gcdgz(g,b[i],&g1); g = g1;
! 366: }
! 367: *q = g;
! 368: }
! 369:
! 370: void gcdvgz_estimate(VECT v,GZ *q)
! 371: {
! 372: int n,m,i;
! 373: GZ s,t,u;
! 374: GZ *b;
! 375:
! 376: n = v->len;
! 377: b = (GZ *)v->body;
! 378: if ( n == 1 ) {
! 379: if ( mpz_sgn(BDY(b[0]))<0 ) chsgngz(b[0],q);
! 380: else *q = b[0];
! 381: }
! 382: m = n/2;
! 383: for ( i = 0, s = 0; i < m; i++ ) {
! 384: if ( b[i] && mpz_sgn(BDY(b[i]))<0 ) subgz(s,b[i],&u);
! 385: else addgz(s,b[i],&u);
! 386: s = u;
! 387: }
! 388: for ( i = 0, t = 0; i < n; i++ ) {
! 389: if ( b[i] && mpz_sgn(BDY(b[i]))<0 ) subgz(t,b[i],&u);
! 390: else addgz(t,b[i],&u);
! 391: t = u;
! 392: }
! 393: gcdgz(s,t,q);
! 394: }
! 395:
! 396: void addgq(GQ n1,GQ n2,GQ *nr)
! 397: {
! 398: mpq_t q1,q2,t;
! 399:
! 400: if ( !n1 ) *nr = n2;
! 401: else if ( !n2 ) *nr = n1;
! 402: else {
! 403: if ( NID(n1) == N_GZ ) MPZTOMPQ(BDY((GZ)n1),q1);
! 404: else q1[0] = BDY(n1)[0];
! 405: if ( NID(n2) == N_GZ ) MPZTOMPQ(BDY((GZ)n2),q2);
! 406: else q2[0] = BDY(n2)[0];
! 407: mpq_init(t); mpq_add(t,q1,q2); *nr = mpqtogzq(t);
! 408: }
! 409: }
! 410:
! 411: void subgq(GQ n1,GQ n2,GQ *nr)
! 412: {
! 413: mpq_t q1,q2,t;
! 414:
! 415: if ( !n1 )
! 416: if ( !n2 ) *nr = 0;
! 417: else {
! 418: if ( NID(n1) == N_GZ ) chsgngz((GZ)n1,(GZ *)nr);
! 419: else {
! 420: mpq_init(t); mpq_neg(t,BDY(n2)); MPQTOGQ(t,*nr);
! 421: }
! 422: }
! 423: else if ( !n2 ) *nr = n1;
! 424: else if ( n1 == n2 ) *nr = 0;
! 425: else {
! 426: if ( NID(n1) == N_GZ ) MPZTOMPQ(BDY((GZ)n1),q1);
! 427: else q1[0] = BDY(n1)[0];
! 428: if ( NID(n2) == N_GZ ) MPZTOMPQ(BDY((GZ)n2),q2);
! 429: else q2[0] = BDY(n2)[0];
! 430: mpq_init(t); mpq_sub(t,q1,q2); *nr = mpqtogzq(t);
! 431: }
! 432: }
! 433:
! 434: void mulgq(GQ n1,GQ n2,GQ *nr)
! 435: {
! 436: mpq_t t,q1,q2;
! 437:
! 438: if ( !n1 || !n2 ) *nr = 0;
! 439: else {
! 440: if ( NID(n1) == N_GZ ) MPZTOMPQ(BDY((GZ)n1),q1);
! 441: else q1[0] = BDY(n1)[0];
! 442: if ( NID(n2) == N_GZ ) MPZTOMPQ(BDY((GZ)n2),q2);
! 443: else q2[0] = BDY(n2)[0];
! 444: mpq_init(t); mpq_mul(t,q1,q2); *nr = mpqtogzq(t);
! 445: }
! 446: }
! 447:
! 448: void divgq(GQ n1,GQ n2,GQ *nq)
! 449: {
! 450: mpq_t t,q1,q2;
! 451:
! 452: if ( !n2 ) {
! 453: error("division by 0");
! 454: *nq = 0;
! 455: return;
! 456: } else if ( !n1 ) *nq = 0;
! 457: else if ( n1 == n2 ) *nq = (GQ)ONEGZ;
! 458: else {
! 459: if ( NID(n1) == N_GZ ) MPZTOMPQ(BDY((GZ)n1),q1);
! 460: else q1[0] = BDY(n1)[0];
! 461: if ( NID(n2) == N_GZ ) MPZTOMPQ(BDY((GZ)n2),q2);
! 462: else q2[0] = BDY(n2)[0];
! 463: mpq_init(t); mpq_div(t,q1,q2); *nq = mpqtogzq(t);
! 464: }
! 465: }
! 466:
! 467: void chsgngq(GQ n,GQ *nr)
! 468: {
! 469: mpq_t t;
! 470:
! 471: if ( !n ) *nr = 0;
! 472: else if ( NID(n) == N_GZ ) chsgngz((GZ)n,(GZ *)nr);
! 473: else {
! 474: mpq_init(t); mpq_neg(t,BDY(n)); MPQTOGQ(t,*nr);
! 475: }
! 476: }
! 477:
! 478: void pwrgq(GQ n1,Q n,GQ *nr)
! 479: {
! 480: int e;
! 481: mpz_t nm,dn;
! 482: mpq_t t;
! 483:
! 484: if ( !n || UNIGZ((GZ)n1) || UNIGQ(n1) ) *nr = (GQ)ONEGZ;
! 485: else if ( !n1 ) *nr = 0;
! 486: else if ( !INT(n) ) {
! 487: error("can't calculate fractional power."); *nr = 0;
! 488: } else if ( PL(NM(n)) > 1 ) {
! 489: error("exponent too big."); *nr = 0;
! 490: } else {
! 491: e = QTOS(n);
! 492: if ( e < 0 ) {
! 493: e = -e;
! 494: if ( NID(n1)==N_GZ ) {
! 495: nm[0] = ONEMPZ[0];
! 496: dn[0] = BDY((GZ)n1)[0];
! 497: } else {
! 498: nm[0] = mpq_denref(BDY(n1))[0]; dn[0] = mpq_numref(BDY(n1))[0];
! 499: }
! 500: } else {
! 501: if ( NID(n1)==N_GZ ) {
! 502: nm[0] = BDY((GZ)n1)[0]; dn[0] = ONEMPZ[0];
! 503: } else {
! 504: nm[0] = mpq_numref(BDY(n1))[0]; dn[0] = mpq_denref(BDY(n1))[0];
! 505: }
! 506: }
! 507: mpq_init(t);
! 508: mpz_pow_ui(mpq_numref(t),nm,e); mpz_pow_ui(mpq_denref(t),dn,e);
! 509: *nr = mpqtogzq(t);
! 510: }
! 511: }
! 512:
! 513: int cmpgq(GQ n1,GQ n2)
! 514: {
! 515: mpq_t q1,q2;
! 516: int sgn;
! 517:
! 518: if ( !n1 )
! 519: if ( !n2 ) return 0;
! 520: else return (NID(n2)==N_GZ) ? -mpz_sgn(BDY((GZ)n2)) : -mpq_sgn(BDY(n2));
! 521: if ( !n2 ) return (NID(n1)==N_GZ) ? mpz_sgn(BDY((GZ)n1)) : mpq_sgn(BDY(n1));
! 522: else if ( (sgn = mpq_sgn(BDY(n1))) != mpq_sgn(BDY(n2)) ) return sgn;
! 523: else {
! 524: if ( NID(n1) == N_GZ ) MPZTOMPQ(BDY((GZ)n1),q1);
! 525: else q1[0] = BDY(n1)[0];
! 526: if ( NID(n2) == N_GZ ) MPZTOMPQ(BDY((GZ)n2),q2);
! 527: else q2[0] = BDY(n2)[0];
! 528: sgn = mpq_cmp(q1,q2);
! 529: if ( sgn > 0 ) return 1;
! 530: else if ( sgn < 0 ) return -1;
! 531: else return 0;
! 532: }
! 533: }
! 534:
! 535: void mkgwc(int k,int l,GZ *t)
! 536: {
! 537: mpz_t a,b,q,nm,z,u;
! 538: int i,n;
! 539:
! 540: n = MIN(k,l);
! 541: mpz_init_set_ui(z,1);
! 542: mpz_init(u); mpz_set(u,z); MPZTOGZ(u,t[0]);
! 543: mpz_init(a); mpz_init(b); mpz_init(nm);
! 544: for ( i = 1; i <= n; i++ ) {
! 545: mpz_set_ui(a,k-i+1); mpz_set_ui(b,l-i+1); mpz_mul(nm,a,b);
! 546: mpz_mul(z,BDY(t[i-1]),nm); mpz_fdiv_q_ui(z,z,i);
! 547: mpz_init(u); mpz_set(u,z); MPZTOGZ(u,t[i]);
! 548: }
! 549: }
! 550:
! 551: void gz_lgp(P p,GZ *g,GZ *l);
! 552:
! 553: void gz_ptozp(P p,int sgn,GQ *c,P *pr)
! 554: {
! 555: GZ nm,dn;
! 556:
! 557: if ( !p ) {
! 558: *c = 0; *pr = 0;
! 559: } else {
! 560: gz_lgp(p,&nm,&dn);
! 561: divgz(nm,dn,(GZ *)c);
! 562: divsp(CO,p,(P)*c,pr);
! 563: }
! 564: }
! 565:
! 566: void gz_lgp(P p,GZ *g,GZ *l)
! 567: {
! 568: DCP dc;
! 569: GZ g1,g2,l1,l2,l3,l4;
! 570:
! 571: if ( NUM(p) ) {
! 572: if ( NID((GZ)p)==N_GZ ) {
! 573: MPZTOGZ(BDY((GZ)p),*g);
! 574: *l = ONEGZ;
! 575: } else {
! 576: MPZTOGZ(mpq_numref(BDY((GQ)p)),*g);
! 577: MPZTOGZ(mpq_denref(BDY((GQ)p)),*l);
! 578: }
! 579: } else {
! 580: dc = DC(p); gz_lgp(COEF(dc),g,l);
! 581: for ( dc = NEXT(dc); dc; dc = NEXT(dc) ) {
! 582: gz_lgp(COEF(dc),&g1,&l1); gcdgz(*g,g1,&g2); *g = g2;
! 583: gcdgz(*l,l1,&l2); mulgz(*l,l1,&l3); divgz(l3,l2,l);
! 584: }
! 585: }
! 586: }
! 587:
! 588: void gz_qltozl(GQ *w,int n,GZ *dvr)
! 589: {
! 590: GZ nm,dn;
! 591: GZ g,g1,l1,l2,l3;
! 592: GQ c;
! 593: int i;
! 594: struct oVECT v;
! 595:
! 596: for ( i = 0; i < n; i++ )
! 597: if ( w[i] && NID(w[i])==N_GQ )
! 598: break;
! 599: if ( i == n ) {
! 600: v.id = O_VECT; v.len = n; v.body = (pointer *)w;
! 601: gcdvgz(&v,dvr); return;
! 602: }
! 603: for ( i = 0; !w[i]; i++ );
! 604: c = w[i];
! 605: if ( NID(c)==N_GQ ) {
! 606: MPZTOGZ(mpq_numref(BDY(c)),nm); MPZTOGZ(mpq_denref(BDY(c)),dn);
! 607: } else {
! 608: MPZTOGZ(BDY((GZ)c),nm); dn = ONEGZ;
! 609: }
! 610: for ( i++; i < n; i++ ) {
! 611: c = w[i];
! 612: if ( !c ) continue;
! 613: if ( NID(c)==N_GQ ) {
! 614: MPZTOGZ(mpq_numref(BDY(c)),g1); MPZTOGZ(mpq_denref(BDY(c)),l1);
! 615: } else {
! 616: MPZTOGZ(BDY((GZ)c),g1); l1 = ONEGZ;
! 617: }
! 618: gcdgz(nm,g1,&g); nm = g;
! 619: gcdgz(dn,l1,&l2); mulgz(dn,l1,&l3); divgz(l3,l2,&dn);
! 620: }
! 621: divgz(nm,dn,dvr);
! 622: }
! 623:
! 624: int gz_bits(GQ q)
! 625: {
! 626: if ( !q ) return 0;
! 627: else if ( NID(q)==N_Q )
! 628: return n_bits(NM((Q)q))+(INT((Q)q)?0:n_bits(DN((Q)q)));
! 629: else if ( NID(q)==N_GZ ) return mpz_sizeinbase(BDY((GZ)q),2);
! 630: else
! 631: return mpz_sizeinbase(mpq_numref(BDY(q)),2)
! 632: + mpz_sizeinbase(mpq_denref(BDY(q)),2);
! 633: }
! 634:
! 635: int gzp_mag(P p)
! 636: {
! 637: int s;
! 638: DCP dc;
! 639:
! 640: if ( !p ) return 0;
! 641: else if ( OID(p) == O_N ) return gz_bits((GQ)p);
! 642: else {
! 643: for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) s += gzp_mag(COEF(dc));
! 644: return s;
! 645: }
! 646: }
! 647:
! 648: void makesubstgz(VL v,NODE *s)
! 649: {
! 650: NODE r,r0;
! 651: GZ q;
! 652: unsigned int n;
! 653:
! 654: for ( r0 = 0; v; v = NEXT(v) ) {
! 655: NEXTNODE(r0,r); BDY(r) = (pointer)v->v;
! 656: #if defined(_PA_RISC1_1)
! 657: n = mrand48()&BMASK; q = utogz(n);
! 658: #else
! 659: n = random(); q = utogz(n);
! 660: #endif
! 661: NEXTNODE(r0,r); BDY(r) = (pointer)q;
! 662: }
! 663: if ( r0 ) NEXT(r) = 0;
! 664: *s = r0;
! 665: }
! 666:
! 667: unsigned int remgq(GQ a,unsigned int mod)
! 668: {
! 669: unsigned int c,nm,dn;
! 670: mpz_t r;
! 671:
! 672: if ( !a ) return 0;
! 673: else if ( NID(a)==N_GZ ) {
! 674: mpz_init(r);
! 675: c = mpz_fdiv_r_ui(r,BDY((GZ)a),mod);
! 676: } else {
! 677: mpz_init(r);
! 678: nm = mpz_fdiv_r_ui(r,mpq_numref(BDY(a)),mod);
! 679: dn = mpz_fdiv_r_ui(r,mpq_denref(BDY(a)),mod);
! 680: dn = invm(dn,mod);
! 681: DMAR(nm,dn,0,mod,c);
! 682: }
! 683: return c;
! 684: }
! 685:
! 686: extern int DP_Print;
! 687:
! 688: #define GZ_F4_INTRAT_PERIOD 8
! 689:
! 690: int gz_generic_gauss_elim(MAT mat,MAT *nm,GZ *dn,int **rindp,int **cindp)
! 691: {
! 692: int **wmat;
! 693: GZ **bmat,**tmat,*bmi,*tmi;
! 694: GZ q,m1,m2,m3,s,u;
! 695: int *wmi,*colstat,*wcolstat,*rind,*cind;
! 696: int row,col,ind,md,i,j,k,l,t,t1,rank,rank0,inv;
! 697: MAT r,crmat;
! 698: int ret;
! 699:
! 700: bmat = (GZ **)mat->body;
! 701: row = mat->row; col = mat->col;
! 702: wmat = (int **)almat(row,col);
! 703: colstat = (int *)MALLOC_ATOMIC(col*sizeof(int));
! 704: wcolstat = (int *)MALLOC_ATOMIC(col*sizeof(int));
! 705: for ( ind = 0; ; ind++ ) {
! 706: if ( DP_Print ) {
! 707: fprintf(asir_out,"."); fflush(asir_out);
! 708: }
! 709: md = get_lprime(ind);
! 710: for ( i = 0; i < row; i++ )
! 711: for ( j = 0, bmi = bmat[i], wmi = wmat[i]; j < col; j++ )
! 712: wmi[j] = remgq((GQ)bmi[j],md);
! 713: rank = generic_gauss_elim_mod(wmat,row,col,md,wcolstat);
! 714: if ( !ind ) {
! 715: RESET:
! 716: m1 = utogz(md);
! 717: rank0 = rank;
! 718: bcopy(wcolstat,colstat,col*sizeof(int));
! 719: MKMAT(crmat,rank,col-rank);
! 720: MKMAT(r,rank,col-rank); *nm = r;
! 721: tmat = (GZ **)crmat->body;
! 722: for ( i = 0; i < rank; i++ )
! 723: for ( j = k = 0, tmi = tmat[i], wmi = wmat[i]; j < col; j++ )
! 724: if ( !colstat[j] ) tmi[k++] = utogz(wmi[j]);
! 725: } else {
! 726: if ( rank < rank0 ) {
! 727: if ( DP_Print ) {
! 728: fprintf(asir_out,"lower rank matrix; continuing...\n");
! 729: fflush(asir_out);
! 730: }
! 731: continue;
! 732: } else if ( rank > rank0 ) {
! 733: if ( DP_Print ) {
! 734: fprintf(asir_out,"higher rank matrix; resetting...\n");
! 735: fflush(asir_out);
! 736: }
! 737: goto RESET;
! 738: } else {
! 739: for ( j = 0; (j<col) && (colstat[j]==wcolstat[j]); j++ );
! 740: if ( j < col ) {
! 741: if ( DP_Print ) {
! 742: fprintf(asir_out,"inconsitent colstat; resetting...\n");
! 743: fflush(asir_out);
! 744: }
! 745: goto RESET;
! 746: }
! 747: }
! 748:
! 749: inv = invm(remgq((GQ)m1,md),md);
! 750: m2 = utogz(md); mulgz(m1,m2,&m3);
! 751: for ( i = 0; i < rank; i++ )
! 752: for ( j = k = 0, tmi = tmat[i], wmi = wmat[i]; j < col; j++ )
! 753: if ( !colstat[j] ) {
! 754: if ( tmi[k] ) {
! 755: /* f3 = f1+m1*(m1 mod m2)^(-1)*(f2 - f1 mod m2) */
! 756: t = remgq((GQ)tmi[k],md);
! 757: if ( wmi[j] >= t ) t = wmi[j]-t;
! 758: else t = md-(t-wmi[j]);
! 759: DMAR(t,inv,0,md,t1)
! 760: u = utogz(t1); mulgz(m1,u,&s);
! 761: addgz(tmi[k],s,&u); tmi[k] = u;
! 762: } else if ( wmi[j] ) {
! 763: /* f3 = m1*(m1 mod m2)^(-1)*f2 */
! 764: DMAR(wmi[j],inv,0,md,t)
! 765: u = utogz(t); mulgz(m1,u,&s); tmi[k] = s;
! 766: }
! 767: k++;
! 768: }
! 769: m1 = m3;
! 770: if ( ind % GZ_F4_INTRAT_PERIOD )
! 771: ret = 0;
! 772: else
! 773: ret = gz_intmtoratm(crmat,m1,*nm,dn);
! 774: if ( ret ) {
! 775: *rindp = rind = (int *)MALLOC_ATOMIC(rank*sizeof(int));
! 776: *cindp = cind = (int *)MALLOC_ATOMIC((col-rank)*sizeof(int));
! 777: for ( j = k = l = 0; j < col; j++ )
! 778: if ( colstat[j] ) rind[k++] = j;
! 779: else cind[l++] = j;
! 780: if ( gz_gensolve_check(mat,*nm,*dn,rind,cind) )
! 781: return rank;
! 782: }
! 783: }
! 784: }
! 785: }
! 786:
! 787: int gz_generic_gauss_elim2(MAT mat,MAT *nm,GZ *dn,int **rindp,int **cindp)
! 788: {
! 789:
! 790: MAT full;
! 791: GZ **bmat,**b;
! 792: GZ *bmi;
! 793: GZ dn0;
! 794: int row,col,md,i,j,rank,ret;
! 795: int **wmat;
! 796: int *wmi;
! 797: int *colstat,*rowstat;
! 798:
! 799: bmat = (GZ **)mat->body;
! 800: row = mat->row; col = mat->col;
! 801: wmat = (int **)almat(row,col);
! 802: colstat = (int *)MALLOC_ATOMIC(col*sizeof(int));
! 803: rowstat = (int *)MALLOC_ATOMIC(row*sizeof(int));
! 804: /* XXX */
! 805: md = get_lprime(0);
! 806: for ( i = 0; i < row; i++ )
! 807: for ( j = 0, bmi = bmat[i], wmi = wmat[i]; j < col; j++ )
! 808: wmi[j] = remgq((GQ)bmi[j],md);
! 809: rank = generic_gauss_elim_mod2(wmat,row,col,md,colstat,rowstat);
! 810: b = (GZ **)MALLOC(rank*sizeof(GZ));
! 811: for ( i = 0; i < rank; i++ ) b[i] = bmat[rowstat[i]];
! 812: NEWMAT(full); full->row = rank; full->col = col; full->body = (pointer **)b;
! 813: ret = gz_generic_gauss_elim_full(full,nm,dn,rindp,cindp);
! 814: if ( !ret ) {
! 815: rank = gz_generic_gauss_elim(mat,nm,&dn0,rindp,cindp);
! 816: for ( i = 0; i < rank; i++ ) dn[i] = dn0;
! 817: }
! 818: return rank;
! 819: }
! 820:
! 821: int gz_generic_gauss_elim_full(MAT mat,MAT *nm,GZ *dn,int **rindp,int **cindp)
! 822: {
! 823: int **wmat;
! 824: int *stat;
! 825: GZ **bmat,**tmat,*bmi,*tmi,*ri;
! 826: GZ q,m1,m2,m3,s,u;
! 827: int *wmi,*colstat,*wcolstat,*rind,*cind;
! 828: int row,col,ind,md,i,j,k,l,t,t1,rank,rank0,inv,h;
! 829: MAT r,crmat;
! 830: int ret,initialized,done;
! 831:
! 832: initialized = 0;
! 833: bmat = (GZ **)mat->body;
! 834: row = mat->row; col = mat->col;
! 835: wmat = (int **)almat(row,col);
! 836: stat = (int *)MALLOC_ATOMIC(row*sizeof(int));
! 837: for ( i = 0; i < row; i++ ) stat[i] = 0;
! 838: colstat = (int *)MALLOC_ATOMIC(col*sizeof(int));
! 839: wcolstat = (int *)MALLOC_ATOMIC(col*sizeof(int));
! 840: for ( ind = 0; ; ind++ ) {
! 841: if ( DP_Print ) {
! 842: fprintf(asir_out,"."); fflush(asir_out);
! 843: }
! 844: md = get_lprime(ind);
! 845: for ( i = 0; i < row; i++ )
! 846: for ( j = 0, bmi = bmat[i], wmi = wmat[i]; j < col; j++ )
! 847: wmi[j] = remgq((GQ)bmi[j],md);
! 848: rank = generic_gauss_elim_mod(wmat,row,col,md,wcolstat);
! 849: if ( rank < row ) continue;
! 850: if ( !initialized ) {
! 851: m1 = utogz(md);
! 852: bcopy(wcolstat,colstat,col*sizeof(int));
! 853: MKMAT(crmat,row,col-row);
! 854: MKMAT(r,row,col-row); *nm = r;
! 855: tmat = (GZ **)crmat->body;
! 856: for ( i = 0; i < row; i++ )
! 857: for ( j = k = 0, tmi = tmat[i], wmi = wmat[i]; j < col; j++ )
! 858: if ( !colstat[j] ) tmi[k++] = utogz(wmi[j]);
! 859: initialized = 1;
! 860: } else {
! 861: for ( j = 0; (j<col) && (colstat[j]==wcolstat[j]); j++ );
! 862: if ( j < col ) continue;
! 863:
! 864: inv = invm(remgq((GQ)m1,md),md);
! 865: m2 = utogz(md); mulgz(m1,m2,&m3);
! 866: for ( i = 0; i < row; i++ )
! 867: switch ( stat[i] ) {
! 868: case 1:
! 869: /* consistency check */
! 870: ri = (GZ *)BDY(r)[i]; wmi = wmat[i];
! 871: for ( j = 0; j < col; j++ ) if ( colstat[j] ) break;
! 872: h = md-remgq((GQ)dn[i],md);
! 873: for ( j++, k = 0; j < col; j++ )
! 874: if ( !colstat[j] ) {
! 875: t = remgq((GQ)ri[k],md);
! 876: DMAR(wmi[i],h,t,md,t1);
! 877: if ( t1 ) break;
! 878: }
! 879: if ( j == col ) { stat[i]++; break; }
! 880: else {
! 881: /* fall to the case 0 */
! 882: stat[i] = 0;
! 883: }
! 884: case 0:
! 885: tmi = tmat[i]; wmi = wmat[i];
! 886: for ( j = k = 0; j < col; j++ )
! 887: if ( !colstat[j] ) {
! 888: if ( tmi[k] ) {
! 889: /* f3 = f1+m1*(m1 mod m2)^(-1)*(f2 - f1 mod m2) */
! 890: t = remgq((GQ)tmi[k],md);
! 891: if ( wmi[j] >= t ) t = wmi[j]-t;
! 892: else t = md-(t-wmi[j]);
! 893: DMAR(t,inv,0,md,t1)
! 894: u = utogz(t1); mulgz(m1,u,&s);
! 895: addgz(tmi[k],s,&u); tmi[k] = u;
! 896: } else if ( wmi[j] ) {
! 897: /* f3 = m1*(m1 mod m2)^(-1)*f2 */
! 898: DMAR(wmi[j],inv,0,md,t)
! 899: u = utogz(t); mulgz(m1,u,&s); tmi[k] = s;
! 900: }
! 901: k++;
! 902: }
! 903: break;
! 904: case 2: default:
! 905: break;
! 906: }
! 907: m1 = m3;
! 908: if ( ind % 4 )
! 909: ret = 0;
! 910: else
! 911: ret = gz_intmtoratm2(crmat,m1,*nm,dn,stat);
! 912: if ( ret ) {
! 913: *rindp = rind = (int *)MALLOC_ATOMIC(row*sizeof(int));
! 914: *cindp = cind = (int *)MALLOC_ATOMIC((col-row)*sizeof(int));
! 915: for ( j = k = l = 0; j < col; j++ )
! 916: if ( colstat[j] ) rind[k++] = j;
! 917: else cind[l++] = j;
! 918: return gz_gensolve_check2(mat,*nm,dn,rind,cind);
! 919: }
! 920: }
! 921: }
! 922: }
! 923:
! 924: int gz_generic_gauss_elim_direct(MAT mat,MAT *nm,GZ *dn,int **rindp,int **cindp){
! 925: GZ **bmat,*s;
! 926: GZ u,v,w,x,d,t,y;
! 927: int row,col,i,j,k,l,m,rank;
! 928: int *colstat,*colpos,*cind;
! 929: MAT r,in;
! 930:
! 931: row = mat->row; col = mat->col;
! 932: MKMAT(in,row,col);
! 933: for ( i = 0; i < row; i++ )
! 934: for ( j = 0; j < col; j++ ) in->body[i][j] = mat->body[i][j];
! 935: bmat = (GZ **)in->body;
! 936: colstat = (int *)MALLOC_ATOMIC(col*sizeof(int));
! 937: *rindp = colpos = (int *)MALLOC_ATOMIC(row*sizeof(int));
! 938: for ( j = 0, rank = 0, d = ONEGZ; j < col; j++ ) {
! 939: for ( i = rank; i < row && !bmat[i][j]; i++ );
! 940: if ( i == row ) { colstat[j] = 0; continue; }
! 941: else { colstat[j] = 1; colpos[rank] = j; }
! 942: if ( i != rank )
! 943: for ( k = j; k < col; k++ ) {
! 944: t = bmat[i][k]; bmat[i][k] = bmat[rank][k]; bmat[rank][k] = t;
! 945: }
! 946: for ( i = rank+1, v = bmat[rank][j]; i < row; i++ )
! 947: for ( k = j, u = bmat[i][j]; k < col; k++ ) {
! 948: mulgz(bmat[i][k],v,&w); mulgz(bmat[rank][k],u,&x);
! 949: subgz(w,x,&y); divsgz(y,d,&bmat[i][k]);
! 950: }
! 951: d = v; rank++;
! 952: }
! 953: *dn = d;
! 954: s = (GZ *)MALLOC(col*sizeof(GZ));
! 955: for ( i = rank-1; i >= 0; i-- ) {
! 956: for ( k = colpos[i]; k < col; k++ ) mulgz(bmat[i][k],d,&s[k]);
! 957: for ( m = rank-1; m > i; m-- ) {
! 958: for ( k = colpos[m], u = bmat[i][k]; k < col; k++ ) {
! 959: mulgz(bmat[m][k],u,&w); subgz(s[k],w,&x); s[k] = x;
! 960: }
! 961: }
! 962: for ( k = colpos[i], u = bmat[i][k]; k < col; k++ )
! 963: divgz(s[k],u,&bmat[i][k]);
! 964: }
! 965: *cindp = cind = (int *)MALLOC_ATOMIC((col-rank)*sizeof(int));
! 966: MKMAT(r,rank,col-rank); *nm = r;
! 967: for ( j = 0, k = 0; j < col; j++ )
! 968: if ( !colstat[j] ) {
! 969: cind[k] = j;
! 970: for ( i = 0; i < rank; i++ ) r->body[i][k] = bmat[i][j];
! 971: k++;
! 972: }
! 973: return rank;
! 974: }
! 975:
! 976: int gz_intmtoratm(MAT mat,GZ md,MAT nm,GZ *dn)
! 977: {
! 978: GZ t,s,b,dn0,dn1,nm1,q,u,unm,udn,dmy;
! 979: int i,j,k,l,row,col,sgn,ret;
! 980: GZ **rmat,**tmat,*tmi,*nmk;
! 981:
! 982: if ( UNIGZ(md) )
! 983: return 0;
! 984: row = mat->row; col = mat->col;
! 985: bshiftgz(md,1,&t);
! 986: isqrtgz(t,&s);
! 987: bshiftgz(s,64,&b);
! 988: if ( !b ) b = ONEGZ;
! 989: dn0 = ONEGZ;
! 990: tmat = (GZ **)mat->body;
! 991: rmat = (GZ **)nm->body;
! 992: for ( i = 0; i < row; i++ )
! 993: for ( j = 0, tmi = tmat[i]; j < col; j++ )
! 994: if ( tmi[j] ) {
! 995: mulgz(tmi[j],dn0,&s);
! 996: divqrgz(s,md,&dmy,&u);
! 997: ret = gz_inttorat(u,md,b,&sgn,&unm,&udn);
! 998: if ( !ret ) return 0;
! 999: else {
! 1000: if ( sgn < 0 ) chsgngz(unm,&nm1);
! 1001: else nm1 = unm;
! 1002: dn1 = udn;
! 1003: if ( !UNIGZ(dn1) ) {
! 1004: for ( k = 0; k < i; k++ )
! 1005: for ( l = 0, nmk = rmat[k]; l < col; l++ ) {
! 1006: mulgz(nmk[l],dn1,&q); nmk[l] = q;
! 1007: }
! 1008: for ( l = 0, nmk = rmat[i]; l < j; l++ ) {
! 1009: mulgz(nmk[l],dn1,&q); nmk[l] = q;
! 1010: }
! 1011: }
! 1012: rmat[i][j] = nm1;
! 1013: mulgz(dn0,dn1,&q); dn0 = q;
! 1014: }
! 1015: }
! 1016: *dn = dn0;
! 1017: return 1;
! 1018: }
! 1019:
! 1020: int gz_intmtoratm2(MAT mat,GZ md,MAT nm,GZ *dn,int *stat)
! 1021: {
! 1022: int row,col,i,j,ret;
! 1023: GZ dn0,dn1,t,s,b;
! 1024: GZ *w,*tmi;
! 1025: GZ **tmat;
! 1026:
! 1027: bshiftgz(md,1,&t);
! 1028: isqrtgz(t,&s);
! 1029: bshiftgz(s,64,&b);
! 1030: tmat = (GZ **)mat->body;
! 1031: if ( UNIGZ(md) ) return 0;
! 1032: row = mat->row; col = mat->col;
! 1033: dn0 = ONEGZ;
! 1034: for ( i = 0; i < row; i++ )
! 1035: if ( cmpgz(dn[i],dn0) > 0 ) dn0 = dn[i];
! 1036: w = (GZ *)MALLOC(col*sizeof(GZ));
! 1037: for ( i = 0; i < row; i++ )
! 1038: if ( stat[i] == 0 ) {
! 1039: for ( j = 0, tmi = tmat[i]; j < col; j++ )
! 1040: mulgz(tmi[j],dn0,&w[j]);
! 1041: ret = gz_intvtoratv(w,col,md,b,BDY(nm)[i],&dn[i]);
! 1042: if ( ret ) {
! 1043: stat[i] = 1;
! 1044: mulgz(dn0,dn[i],&t); dn[i] = t; dn0 = t;
! 1045: }
! 1046: }
! 1047: for ( i = 0; i < row; i++ ) if ( !stat[i] ) break;
! 1048: if ( i == row ) return 1;
! 1049: else return 0;
! 1050: }
! 1051:
! 1052: int gz_intvtoratv(GZ *v,int n,GZ md,GZ b,GZ *nm,GZ *dn)
! 1053: {
! 1054: GZ dn0,dn1,q,s,u,nm1,unm,udn,dmy;
! 1055: GZ *nmk;
! 1056: int j,l,col,ret,sgn;
! 1057:
! 1058: for ( j = 0; j < n; j++ ) nm[j] = 0;
! 1059: dn0 = ONEGZ;
! 1060: for ( j = 0; j < n; j++ ) {
! 1061: if ( !v[j] ) continue;
! 1062: mulgz(v[j],dn0,&s);
! 1063: divqrgz(s,md,&dmy,&u);
! 1064: ret = gz_inttorat(u,md,b,&sgn,&unm,&udn);
! 1065: if ( !ret ) return 0;
! 1066: if ( sgn < 0 ) chsgngz(unm,&nm1);
! 1067: else nm1 = unm;
! 1068: dn1 = udn;
! 1069: if ( !UNIGZ(dn1) )
! 1070: for ( l = 0; l < j; l++ ) {
! 1071: mulgz(nm[l],dn1,&q); nm[l] = q;
! 1072: }
! 1073: nm[j] = nm1;
! 1074: mulgz(dn0,dn1,&q); dn0 = q;
! 1075: }
! 1076: *dn = dn0;
! 1077: return 1;
! 1078: }
! 1079:
! 1080: /* assuming 0 < c < m */
! 1081:
! 1082: int gz_inttorat(GZ c,GZ m,GZ b,int *sgnp,GZ *nmp,GZ *dnp)
! 1083: {
! 1084: GZ qq,t,u1,v1,r1;
! 1085: GZ q,u2,v2,r2;
! 1086:
! 1087: u1 = 0; v1 = ONEGZ; u2 = m; v2 = c;
! 1088: while ( cmpgz(v2,b) >= 0 ) {
! 1089: divqrgz(u2,v2,&q,&r2); u2 = v2; v2 = r2;
! 1090: mulgz(q,v1,&t); subgz(u1,t,&r1); u1 = v1; v1 = r1;
! 1091: }
! 1092: if ( cmpgz(v1,b) >= 0 ) return 0;
! 1093: else {
! 1094: *nmp = v2;
! 1095: if ( mpz_sgn(BDY(v1))<0 ) {
! 1096: *sgnp = -1; chsgngz(v1,dnp);
! 1097: } else {
! 1098: *sgnp = 1; *dnp = v1;
! 1099: }
! 1100: return 1;
! 1101: }
! 1102: }
! 1103:
! 1104: extern int f4_nocheck;
! 1105:
! 1106: int gz_gensolve_check(MAT mat,MAT nm,GZ dn,int *rind,int *cind)
! 1107: {
! 1108: int row,col,rank,clen,i,j,k,l;
! 1109: GZ s,t;
! 1110: GZ *w;
! 1111: GZ *mati,*nmk;
! 1112:
! 1113: if ( f4_nocheck ) return 1;
! 1114: row = mat->row; col = mat->col; rank = nm->row; clen = nm->col;
! 1115: w = (GZ *)MALLOC(clen*sizeof(GZ));
! 1116: for ( i = 0; i < row; i++ ) {
! 1117: mati = (GZ *)mat->body[i];
! 1118: bzero(w,clen*sizeof(GZ));
! 1119: for ( k = 0; k < rank; k++ )
! 1120: for ( l = 0, nmk = (GZ *)nm->body[k]; l < clen; l++ ) {
! 1121: mulgz(mati[rind[k]],nmk[l],&t); addgz(w[l],t,&s); w[l] = s;
! 1122: }
! 1123: for ( j = 0; j < clen; j++ ) {
! 1124: mulgz(dn,mati[cind[j]],&t);
! 1125: if ( cmpgz(w[j],t) ) break;
! 1126: }
! 1127: if ( j != clen ) break;
! 1128: }
! 1129: if ( i != row ) return 0;
! 1130: else return 1;
! 1131: }
! 1132:
! 1133: int gz_gensolve_check2(MAT mat,MAT nm,GZ *dn,int *rind,int *cind)
! 1134: {
! 1135: int row,col,rank,clen,i,j,k,l;
! 1136: GZ s,t,u,d;
! 1137: GZ *w,*m;
! 1138: GZ *mati,*nmk;
! 1139:
! 1140: if ( f4_nocheck ) return 1;
! 1141: row = mat->row; col = mat->col; rank = nm->row; clen = nm->col;
! 1142: w = (GZ *)MALLOC(clen*sizeof(GZ));
! 1143: m = (GZ *)MALLOC(clen*sizeof(GZ));
! 1144: for ( d = dn[0], i = 1; i < rank; i++ ) {
! 1145: lcmgz(d,dn[i],&t); d = t;
! 1146: }
! 1147: for ( i = 0; i < rank; i++ ) divsgz(d,dn[i],&m[i]);
! 1148: for ( i = 0; i < row; i++ ) {
! 1149: mati = (GZ *)mat->body[i];
! 1150: bzero(w,clen*sizeof(GZ));
! 1151: for ( k = 0; k < rank; k++ ) {
! 1152: mulgz(mati[rind[k]],m[k],&u);
! 1153: for ( l = 0, nmk = (GZ *)nm->body[k]; l < clen; l++ ) {
! 1154: mulgz(u,nmk[l],&t); addgz(w[l],t,&s); w[l] = s;
! 1155: }
! 1156: }
! 1157: for ( j = 0; j < clen; j++ ) {
! 1158: mulgz(d,mati[cind[j]],&t);
! 1159: if ( cmpgz(w[j],t) ) break;
! 1160: }
! 1161: if ( j != clen ) break;
! 1162: }
! 1163: if ( i != row ) return 0;
! 1164: else return 1;
! 1165: }
! 1166:
! 1167: void isqrtgz(GZ a,GZ *r)
! 1168: {
! 1169: int k;
! 1170: GZ x,t,x2,xh,quo,rem;
! 1171: Q two;
! 1172:
! 1173: if ( !a ) *r = 0;
! 1174: else if ( UNIGZ(a) ) *r = ONEGZ;
! 1175: else {
! 1176: k = gz_bits((GQ)a); /* a <= 2^k-1 */
! 1177: bshiftgz(ONEGZ,-((k>>1)+(k&1)),&x); /* a <= x^2 */
! 1178: STOQ(2,two);
! 1179: while ( 1 ) {
! 1180: pwrgz(x,two,&t);
! 1181: if ( cmpgz(t,a) <= 0 ) {
! 1182: *r = x; return;
! 1183: } else {
! 1184: if ( mpz_tstbit(BDY(x),0) ) addgz(x,a,&t);
! 1185: else t = a;
! 1186: bshiftgz(x,-1,&x2); divqrgz(t,x2,&quo,&rem);
! 1187: bshiftgz(x,1,&xh); addgz(quo,xh,&x);
! 1188: }
! 1189: }
! 1190: }
! 1191: }
! 1192:
! 1193: void bshiftgz(GZ a,int n,GZ *r)
! 1194: {
! 1195: mpz_t t;
! 1196:
! 1197: if ( !a ) *r = 0;
! 1198: else if ( n == 0 ) *r = a;
! 1199: else if ( n < 0 ) {
! 1200: mpz_init(t); mpz_mul_2exp(t,BDY(a),-n); MPZTOGZ(t,*r);
! 1201: } else {
! 1202: mpz_init(t); mpz_fdiv_q_2exp(t,BDY(a),n);
! 1203: if ( !mpz_sgn(t) ) *r = 0;
! 1204: else MPZTOGZ(t,*r);
! 1205: }
! 1206: }
! 1207:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>