Annotation of OpenXM_contrib2/asir2000/engine/EZ.c, Revision 1.4
1.2 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.4 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/EZ.c,v 1.3 2000/08/22 05:04:03 noro Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51:
52: void ezgcdp(vl,p1,p2,pr)
53: VL vl;
54: P p1,p2;
55: P *pr;
56: {
1.4 ! noro 57: P f1,f2;
! 58: Q c;
1.1 noro 59:
1.4 ! noro 60: if ( !p1 )
! 61: if ( !p2 )
! 62: *pr = 0;
! 63: else
! 64: *pr = p2;
! 65: else if ( !p2 )
! 66: *pr = p1;
! 67: else {
! 68: if ( !qpcheck((Obj)p1) || !qpcheck((Obj)p2) )
! 69: error("ezgcdp : invalid argument");
! 70: ptozp(p1,1,&c,&f1);
! 71: ptozp(p2,1,&c,&f2);
! 72: ezgcdpz(vl,f1,f2,pr);
! 73: }
1.1 noro 74: }
75:
76: /*
77: * p1, p2 : integer coefficient
78: * returns gcd(pp(p1),pp(p2)) * gcd(cont(p1),cont(p2))
79: */
80:
81: void ezgcdpz(vl,p1,p2,pr)
82: VL vl;
83: P p1,p2,*pr;
84: {
1.4 ! noro 85: P f1,f2,t,s,g,gcd;
! 86: P fc1,fc2,cont;
! 87: VL tvl,svl;
! 88: V v1,v2;
! 89: DCP dc,dc1,dc2;
! 90: N cn;
! 91: Q cq;
! 92: Q c1,c2,c;
! 93: P g1,g2;
! 94: P mgcd;
! 95: extern int nez;
! 96: P pm[2];
! 97:
! 98: if ( nez ) {
! 99: pm[0] = p1; pm[1] = p2; nezgcdnpz(vl,pm,2,pr); return;
! 100: }
! 101: monomialfctr(vl,p1,&f1,&dc1); p1 = f1;
! 102: monomialfctr(vl,p2,&f2,&dc2); p2 = f2;
! 103: for ( mgcd = (P)ONE; dc1; dc1 = NEXT(dc1) )
! 104: for ( v1 = VR(dc1->c), dc = dc2; dc; dc = NEXT(dc) )
! 105: if ( v1 == VR(dc->c) ) {
! 106: pwrp(vl,dc->c,cmpq(dc1->d,dc->d)>=0?dc->d:dc1->d,&t);
! 107: mulp(vl,mgcd,t,&s); mgcd = s; break;
! 108: }
! 109:
! 110: if ( NUM(p1) ) {
! 111: if ( NUM(p2) ) {
! 112: gcdn(NM((Q)p1),NM((Q)p2),&cn); NTOQ(cn,1,c);
! 113: } else {
! 114: ptozp(p2,1,&c2,&t);
! 115: gcdn(NM((Q)p1),NM(c2),&cn); NTOQ(cn,1,c);
! 116: }
! 117: mulp(vl,(P)c,mgcd,pr);
! 118: return;
! 119: } else if ( NUM(p2) ) {
! 120: ptozp(p1,1,&c1,&t);
! 121: gcdn(NM(c1),NM((Q)p2),&cn); NTOQ(cn,1,c);
! 122: mulp(vl,(P)c,mgcd,pr);
! 123: return;
! 124: }
! 125:
! 126: ptozp(p1,1,&c1,&g1); ptozp(p2,1,&c2,&g2);
! 127: gcdn(NM(c1),NM(c2),&cn); NTOQ(cn,1,cq);
! 128:
! 129: if ( ( v1 = VR(f1) ) != ( v2 = VR(f2) ) ) {
! 130: while ( v1 != VR(vl) && v2 != VR(vl) )
! 131: vl = NEXT(vl);
! 132: if ( v1 == VR(vl) ) {
! 133: pcp(vl,f1,&g,&fc1);
! 134: ezgcdpz(vl,fc1,f2,&t);
! 135: } else {
! 136: pcp(vl,f2,&g,&fc2);
! 137: ezgcdpz(vl,fc2,f1,&t);
! 138: }
! 139: mulp(vl,t,(P)cq,&s); mulp(vl,s,mgcd,pr);
! 140: return;
! 141: }
! 142:
! 143: pcp(vl,f1,&g1,&fc1); pcp(vl,f2,&g2,&fc2);
! 144: ezgcdpz(vl,fc1,fc2,&cont);
! 145: clctv(vl,g1,&tvl); clctv(vl,g2,&svl);
! 146: if ( !NEXT(tvl) && !NEXT(svl) ) {
! 147: uezgcdpz(vl,g1,g2,&t);
! 148: mulp(vl,t,cont,&s); mulp(vl,s,(P)cq,&t); mulp(vl,t,mgcd,pr);
! 149: return;
! 150: }
! 151:
! 152: if ( homdeg(g1) > homdeg(g2) ) {
! 153: t = g1; g1 = g2; g2 = t;
! 154: }
! 155: sqfrp(vl,g1,&dc);
! 156: for ( g = g2, gcd = (P)ONE; dc && !NUM(g); dc = NEXT(dc) ) {
! 157: if ( NUM(COEF(dc)) )
! 158: continue;
! 159: ezgcdpp(vl,dc,g,&t);
! 160: if ( NUM(t) )
! 161: continue;
! 162: mulp(vl,gcd,t,&s); gcd = s;
! 163: divsp(vl,g,t,&s); g = s;
! 164: }
! 165: mulp(vl,gcd,cont,&t); mulp(vl,t,(P)cq,&s); mulp(vl,s,mgcd,pr);
1.1 noro 166: }
167:
168: void uezgcdpz(vl,p1,p2,pr)
169: VL vl;
170: P p1,p2,*pr;
171: {
1.4 ! noro 172: P g1,g2,gcd,t,s,g;
! 173: DCP dc;
! 174: N cn;
! 175: Q c1,c2,cq;
! 176: P f1,f2;
! 177:
! 178: if ( NUM(p1) ) {
! 179: if ( NUM(p2) ) {
! 180: gcdn(NM((Q)p1),NM((Q)p2),&cn); NTOQ(cn,1,cq),*pr = (P)cq;
! 181: return;
! 182: } else {
! 183: ptozp(p2,1,&c2,&t);
! 184: gcdn(NM((Q)p1),NM(c2),&cn); NTOQ(cn,1,cq),*pr = (P)cq;
! 185: return;
! 186: }
! 187: } else if ( NUM(p2) ) {
! 188: ptozp(p1,1,&c1,&t);
! 189: gcdn(NM(c1),NM((Q)p2),&cn); NTOQ(cn,1,cq),*pr = (P)cq;
! 190: return;
! 191: }
! 192:
! 193: ptozp(p1,1,&c1,&f1); ptozp(p2,1,&c2,&f2);
! 194: gcdn(NM(c1),NM(c2),&cn); NTOQ(cn,1,cq);
! 195: if ( UDEG(f1) > UDEG(f2) ) {
! 196: g1 = f2; g2 = f1;
! 197: } else {
! 198: g1 = f1; g2 = f2;
! 199: }
! 200: usqp(g1,&dc);
! 201: for ( g = g2, gcd = (P)ONE; dc && !NUM(g); dc = NEXT(dc) ) {
! 202: if ( NUM(COEF(dc)) )
! 203: continue;
! 204: uezgcdpp(dc,g,&t);
! 205: if ( NUM(t) )
! 206: continue;
! 207: mulp(CO,gcd,t,&s); gcd = s;
! 208: divsp(CO,g,t,&s); g = s;
! 209: }
! 210: mulp(vl,gcd,(P)cq,pr);
1.1 noro 211: }
212:
213: /*
1.4 ! noro 214: dc : dc pair c^d
! 215: r = gcd(c^d,f)
1.1 noro 216: */
217:
218: void ezgcdpp(vl,dc,f,r)
219: VL vl;
220: DCP dc;
221: P f;
222: P *r;
223: {
1.4 ! noro 224: int k;
! 225: P g,h,t,s,gcd;
1.1 noro 226:
1.4 ! noro 227: if ( NUM(f) ) {
! 228: *r = (P)ONE;
! 229: return;
! 230: }
! 231: k = QTOS(DEG(dc)) - 1;
! 232: /* ezgcd1p(vl,COEF(dc),f,&gcd); */
! 233: ezgcdnp(vl,COEF(dc),&f,1,&gcd);
! 234: g = gcd; divsp(vl,f,gcd,&h);
! 235: for ( ; k > 0; k-- ) {
! 236: /* ezgcd1p(vl,g,h,&t); */
! 237: ezgcdnp(vl,g,&h,1,&t);
! 238: if ( NUM(t) )
! 239: break;
! 240: mulp(vl,gcd,t,&s); gcd = s;
! 241: divsp(vl,h,t,&s); h = s;
! 242: }
! 243: *r = gcd;
1.1 noro 244: }
245:
246: void ezgcd1p(vl,p0,p1,gcdp)
247: VL vl;
248: P p0,p1;
249: P *gcdp;
250: {
1.4 ! noro 251: VL nvl,tvl,vl0,vl1,vl2;
! 252: P f0,f1,t;
1.1 noro 253:
1.4 ! noro 254: clctv(vl,p0,&vl0); clctv(vl,p1,&vl1); mergev(vl,vl0,vl1,&vl2);
! 255: minchdegp(vl,p0,&tvl,&t); reordvar(vl2,tvl->v,&nvl);
! 256: reorderp(nvl,vl,p0,&f0); reorderp(nvl,vl,p1,&f1);
! 257: ezgcdnp(nvl,f0,&f1,1,&t);
! 258: reorderp(vl,nvl,t,gcdp);
1.1 noro 259: }
260:
261: void uezgcdpp(dc,f,r)
262: DCP dc;
263: P f;
264: P *r;
265: {
1.4 ! noro 266: int k;
! 267: P g,h,t,s,gcd;
1.1 noro 268:
1.4 ! noro 269: if ( NUM(f) ) {
! 270: *r = (P)ONE;
! 271: return;
! 272: }
! 273:
! 274: k = QTOS(DEG(dc)) - 1;
! 275: uezgcd1p(COEF(dc),f,&gcd);
! 276: g = gcd; divsp(CO,f,gcd,&h);
! 277: for ( ; k > 0; k-- ) {
! 278: uezgcd1p(g,h,&t);
! 279: if ( NUM(t) )
! 280: break;
! 281: mulp(CO,gcd,t,&s); gcd = s;
! 282: divsp(CO,h,t,&s); h = s;
! 283: }
! 284: *r = gcd;
1.1 noro 285: }
286:
287: /*
288: * pr = gcd(p0,ps[0],...,ps[m-1])
289: *
290: * p0 is already square-free and primitive.
291: * ps[i] is at least primitive.
292: *
293: */
294:
295: void ezgcdnp(vl,p0,ps,m,pr)
296: VL vl;
297: int m;
298: P p0,*ps,*pr;
299: {
1.4 ! noro 300: /* variables */
! 301: P p00,g,h,g0,h0,a0,b0;
! 302: P lp0,lgp0,lp00,lg,lg0,cbd,tq,t;
! 303: P *tps;
! 304: VL nvl1,nvl2,nvl,tvl;
! 305: V v;
! 306: int i,j,k,d0,dg,dg0,dmin;
! 307: VN vn0,vn1,vnt;
! 308: int nv,flag;
! 309:
! 310: /* set-up */
! 311: if ( NUM(p0) ) {
! 312: *pr = (P) ONE;
! 313: return;
! 314: }
! 315: for ( v = VR(p0), i = 0; i < m; i++ )
! 316: if ( NUM(ps[i]) || (v != VR(ps[i])) ) {
! 317: *pr = (P)ONE;
! 318: return;
! 319: }
! 320: tps = (P *) ALLOCA(m*sizeof(P));
! 321: for ( i = 0; i < m; i++ )
! 322: tps[i] = ps[i];
! 323: sortplist(tps,m);
! 324: /* deg(tps[0]) <= deg(tps[1]) <= ... */
! 325:
! 326: if ( !cmpq(DEG(DC(p0)),ONE) ) {
! 327: if ( divcheck(vl,tps,m,(P)ONE,p0) )
! 328: *pr = p0;
! 329: else
! 330: *pr = (P)ONE;
! 331: return;
! 332: }
! 333:
! 334: lp0 = LC(p0); lg = lp0; dmin = d0 = deg(v,p0);
! 335: clctv(vl,p0,&nvl);
! 336: for ( i = 0; i < m; i++ ) {
! 337: clctv(vl,tps[i],&nvl1); mergev(vl,nvl,nvl1,&nvl2);
! 338: nvl = nvl2;
! 339: ezgcdpz(nvl,lg,LC(tps[i]),&t); lg = t;
! 340: }
! 341:
! 342: mulp(nvl,p0,lg,&lgp0);
! 343: k = dbound(v,lgp0) + 1;
! 344: cbound(nvl,lgp0,(Q *)&cbd);
! 345: for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++ );
! 346: W_CALLOC(nv,struct oVN,vn0); W_CALLOC(nv,struct oVN,vnt);
! 347: W_CALLOC(nv,struct oVN,vn1);
! 348: for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
! 349: vn1[i].v = vn0[i].v = tvl->v;
! 350:
! 351: /* main loop */
! 352: for ( dg = deg(v,tps[0]) + 1; ; next(vn0) )
! 353: do {
! 354: for ( i = 0, j = 0; vn0[i].v; i++ )
! 355: if ( vn0[i].n ) vnt[j++].v = (V)i;
! 356: vnt[j].n = 0;
! 357:
! 358: /* find b s.t. LC(p0)(b), LC(tps[i])(b) != 0 */
! 359: mulsgn(vn0,vnt,j,vn1);
! 360: substvp(nvl,p0,vn1,&p00);
! 361: flag = (!zerovpchk(nvl,lp0,vn1) && sqfrchk(p00));
! 362: for ( i = 0; flag && (i < m); i++ )
! 363: flag &= (!zerovpchk(nvl,LC(tps[i]),vn1));
! 364: if ( !flag )
! 365: continue;
! 366:
! 367: /* substitute y -> b */
! 368: substvp(nvl,lg,vn1,&lg0);
! 369: lp00 = LC(p00);
! 370: /* extended-gcd in 1-variable */
! 371: uexgcdnp(nvl,p00,tps,m,vn1,(Q)cbd,&g0,&h0,&a0,&b0,(Q *)&tq);
! 372: if ( NUM(g0) ) {
! 373: *pr = (P)ONE;
! 374: return;
! 375: } else if ( dg > ( dg0 = deg(v,g0) ) ) {
! 376: dg = dg0;
! 377: if ( dg == d0 ) {
! 378: if ( divcheck(nvl,tps,m,lp0,p0) ) {
! 379: *pr = p0;
! 380: return;
! 381: }
! 382: } else if ( dg == deg(v,tps[0]) ) {
! 383: if ( divtpz(nvl,p0,tps[0],&t) &&
! 384: divcheck(nvl,tps+1,m-1,LC(tps[0]),tps[0]) ) {
! 385: *pr = tps[0];
! 386: return;
! 387: } else
! 388: break;
! 389: } else {
! 390: henmv(nvl,vn1,lgp0,g0,h0,a0,b0,
! 391: lg,lp0,lg0,lp00,(Q)tq,k,&g,&h);
! 392: if ( divtpz(nvl,lgp0,g,&t) &&
! 393: divcheck(nvl,tps,m,lg,g) ) {
! 394: pcp(nvl,g,pr,&t);
! 395: return;
! 396: }
! 397: }
! 398: }
! 399: } while ( !nextbin(vnt,j) );
1.1 noro 400: }
401:
402: /*
1.4 ! noro 403: f : sqfr
1.1 noro 404: */
405:
406: void uezgcd1p(f,g,r)
407: P f,g;
408: P *r;
409: {
1.4 ! noro 410: UM wf,wf1,wf2,wg,wg1,wgcd,wcof;
! 411: int d1,d2,dg,m,index,n;
! 412: ML list;
! 413: DCP dc;
! 414: P t;
! 415: Q c;
! 416:
! 417: if ( NUM(f) || NUM(g) ) {
! 418: *r = (P)ONE;
! 419: return;
! 420: }
! 421: ptozp(f,1,&c,&t); f = t; ptozp(g,1,&c,&t); g = t;
! 422: d1 = UDEG(f); d2 = UDEG(g);
! 423: n = MAX(d1,d2)+1;
! 424: wf = W_UMALLOC(n); wf1 = W_UMALLOC(n);
! 425: wf2 = W_UMALLOC(n); wg = W_UMALLOC(n);
! 426: wg1 = W_UMALLOC(n); wgcd = W_UMALLOC(n);
! 427: wcof = W_UMALLOC(n);
! 428:
! 429: for ( index = INDEX, dg = MIN(d1,d2)+1; ; ) {
! 430: m = sprime[index++];
! 431: if ( !rem(NM((Q)UCOEF(f)),m) || !rem(NM((Q)UCOEF(g)),m))
! 432: continue;
! 433: ptoum(m,f,wf); cpyum(wf,wf1);
! 434: diffum(m,wf1,wf2); gcdum(m,wf1,wf2,wgcd);
! 435: if ( DEG(wgcd) > 0 )
! 436: continue;
! 437: ptoum(m,g,wg); cpyum(wg,wg1); cpyum(wf,wf1);
! 438: gcdum(m,wf1,wg1,wgcd);
! 439: if ( dg <= DEG(wgcd) )
! 440: continue;
! 441: else
! 442: dg = DEG(wgcd);
! 443: if ( dg == 0 ) {
! 444: *r = (P)ONE;
! 445: return;
! 446: } else if ( dg == d1 ) {
! 447: if ( divtpz(CO,g,f,&t) ) {
! 448: *r = f;
! 449: return;
! 450: }
! 451: } else if ( dg == d2 ) {
! 452: if ( divtpz(CO,f,g,&t) ) {
! 453: *r = g;
! 454: return;
! 455: }
! 456: } else {
! 457: divum(m,wf,wgcd,wcof);
! 458: ezgcdhensel(f,m,wcof,wgcd,&list);
! 459: dtest(f,list,1,&dc);
! 460: if ( NEXT(dc) ) {
! 461: if ( divtpz(CO,g,COEF(dc),&t) ) {
! 462: *r = COEF(dc);
! 463: return;
! 464: }
! 465: }
! 466: }
! 467: }
1.1 noro 468: }
1.4 ! noro 469:
1.1 noro 470: void uexgcdnp(vl,p1,ps,n,vn,cbd,g,h,a,b,q)
471: VL vl;
472: P p1;
473: P *ps;
474: int n;
475: VN vn;
476: Q cbd;
477: P *g,*h,*a,*b;
478: Q *q;
479: {
1.4 ! noro 480: UM wg,wh,wg1,wh1,wgcd,wt;
! 481: P t,s,gcd,cof,gk,hk,ak,bk;
! 482: Q c,tq,bb,tq1,qk;
! 483: int mod,k,i,index,d;
! 484:
! 485: ptozp(p1,1,&c,&gcd);
! 486: for ( i = 0; i < n; i++ ) {
! 487: substvp(vl,ps[i],vn,&t);
! 488: uezgcd1p(gcd,t,&s);
! 489: if ( NUM(s) ) {
! 490: *g = (P)ONE; *h = p1; *a = 0; *b = (P)ONE;
! 491: return;
! 492: } else
! 493: gcd = s;
! 494: }
! 495:
! 496: if ( !dcomp(p1,gcd) ) {
! 497: *g = p1; *h = (P)ONE; *a = 0; *b = (P)ONE;
! 498: return;
! 499: }
! 500:
! 501: divsp(CO,p1,gcd,&cof);
! 502: d = UDEG(p1)+1;
! 503: wg = W_UMALLOC(d); wh = W_UMALLOC(d);
! 504: wg1 = W_UMALLOC(d); wh1 = W_UMALLOC(d);
! 505: wgcd = W_UMALLOC(d); wt = W_UMALLOC(d);
! 506: for ( index = INDEX; ; ) {
! 507: mod = sprime[index++];
! 508: if ( !rem(NM((Q)LC(p1)),mod) )
! 509: continue;
! 510: ptoum(mod,gcd,wg); ptoum(mod,cof,wh);
! 511: cpyum(wg,wg1); cpyum(wh,wh1);
! 512: gcdum(mod,wg,wh,wt); cpyum(wt,wgcd);
! 513: if ( DEG(wgcd) > 0 )
! 514: continue;
! 515: STOQ(mod,tq); addq(cbd,cbd,&bb);
! 516: for ( k = 1; cmpq(tq,bb) < 0; k++ ) {
! 517: mulq(tq,tq,&tq1); tq = tq1;
! 518: }
! 519: henzq(p1,gcd,wg1,cof,wh1,mod,k,&gk,&hk,&bk,&ak,&qk);
! 520: break;
! 521: }
! 522: *g = gk; *h = hk; *a = ak; *b = bk; *q = tq;
1.1 noro 523: }
524:
525: void ezgcdhensel(f,mod,cof,gcd,listp)
526: P f;
527: int mod;
528: UM gcd,cof;
529: ML *listp;
530: {
1.4 ! noro 531: register int i,j;
! 532: int q,n,bound;
! 533: int *p;
! 534: int **pp;
! 535: ML blist,clist,bqlist,cqlist,rlist;
! 536: UM *b;
! 537: LUM fl,tl;
! 538: LUM *l;
! 539: LUM LUMALLOC();
! 540:
! 541: blist = W_MLALLOC(2);
! 542: blist->n = 2; blist->mod = mod;
! 543: blist->c[0] = (pointer)cof; blist->c[1] = (pointer)gcd;
! 544: gcdgen(f,blist,&clist);
! 545: henprep(f,blist,clist,&bqlist,&cqlist);
! 546: n = bqlist->n; q = bqlist->mod;
! 547: bqlist->bound = cqlist->bound = bound = mignotte(q,f);
! 548:
! 549: if ( bound == 1 ) {
! 550: *listp = rlist = MLALLOC(n);
! 551: rlist->n = n;
! 552: rlist->mod = q;
! 553: rlist->bound = bound;
! 554:
! 555: for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c;
! 556: i < n; i++ ) {
! 557: tl = LUMALLOC(DEG(b[i]),1);
! 558: l[i] = tl;
! 559: p = COEF(b[i]);
! 560:
! 561: for ( j = 0, pp = COEF(tl);
! 562: j <= DEG(tl); j++ )
! 563: pp[j][0] = p[j];
! 564: }
! 565: } else {
! 566: W_LUMALLOC((int)UDEG(f),bound,fl);
! 567: ptolum(q,bound,f,fl);
! 568: henmain(fl,bqlist,cqlist,listp);
! 569: }
1.1 noro 570: }
571:
572: void ezgcdnpz(vl,ps,m,pr)
573: VL vl;
574: P *ps,*pr;
575: int m;
576: {
1.4 ! noro 577: P t,s,gcd;
! 578: P cont;
! 579: VL tvl,svl,nvl;
! 580: int i;
! 581: DCP dc;
! 582: N cn;
! 583: Q cq;
! 584: P *pl,*ppl,*pcl;
! 585: Q *cl;
! 586: V v;
! 587:
! 588: pl = (P *)ALLOCA((m+1)*sizeof(P));
! 589: cl = (Q *)ALLOCA((m+1)*sizeof(Q));
! 590: for ( i = 0; i < m; i++ )
! 591: ptozp(ps[i],1,&cl[i],&pl[i]);
! 592: for ( i = 1, cq = cl[0]; i < m; i++ ) {
! 593: gcdn(NM(cl[i]),NM(cq),&cn); NTOQ(cn,1,cq);
! 594: }
! 595: for ( i = 0; i < m; i++ )
! 596: if ( NUM(pl[i]) ) {
! 597: *pr = (P)cq;
! 598: return;
! 599: }
! 600:
! 601: for ( i = 0, nvl = 0; i < m; i++ ) {
! 602: clctv(vl,ps[i],&tvl); mergev(vl,nvl,tvl,&svl); nvl = svl;
! 603: }
! 604:
! 605: ppl = (P *)ALLOCA((m+1)*sizeof(P));
! 606: pcl = (P *)ALLOCA((m+1)*sizeof(P));
! 607: for ( i = 0, v = nvl->v; i < m; i++ )
! 608: if ( v == VR(pl[i]) )
! 609: pcp(nvl,pl[i],&ppl[i],&pcl[i]);
! 610: else {
! 611: ppl[i] = (P)ONE; pcl[i] = pl[i];
! 612: }
! 613: ezgcdnpz(nvl,pcl,m,&cont);
! 614:
! 615: for ( i = 0; i < m; i++ )
! 616: if ( NUM(ppl[i]) ) {
! 617: mulp(nvl,cont,(P)cq,pr);
! 618: return;
! 619: }
! 620: sortplist(ppl,m);
! 621: sqfrp(nvl,ppl[0],&dc);
! 622: for ( dc = NEXT(dc), gcd = (P)ONE; dc; dc = NEXT(dc) ) {
! 623: if ( NUM(COEF(dc)) )
! 624: continue;
! 625: ezgcdnpp(vl,dc,ppl+1,m-1,&t);
! 626: if ( NUM(t) )
! 627: continue;
! 628: mulp(vl,gcd,t,&s); gcd = s;
! 629: }
! 630: mulp(vl,gcd,cont,&t); mulp(vl,t,(P)cq,pr);
1.1 noro 631: }
632:
633: void ezgcdnpp(vl,dc,pl,m,r)
634: VL vl;
635: DCP dc;
636: P *pl;
637: int m;
638: P *r;
639: {
1.4 ! noro 640: int i,k;
! 641: P g,t,s,gcd;
! 642: P *pm;
! 643:
! 644: ezgcdnp(vl,COEF(dc),pl,m,&gcd);
! 645: if ( NUM(gcd) ) {
! 646: *r = (P)ONE;
! 647: return;
! 648: }
! 649: pm = (P *) ALLOCA((m+1)*sizeof(P));
! 650: for ( i = 0; i < m; i++ ) {
! 651: divsp(vl,pl[i],gcd,&pm[i]);
! 652: if ( NUM(pm[i]) ) {
! 653: *r = gcd;
! 654: return;
! 655: }
! 656: }
! 657: for ( g = gcd, k = QTOS(DEG(dc)) - 1; k > 0; k-- ) {
! 658: ezgcdnp(vl,g,pm,m,&t);
! 659: if ( NUM(t) )
! 660: break;
! 661: mulp(vl,gcd,t,&s); gcd = s;
! 662: for ( i = 0; i < m; i++ ) {
! 663: divsp(vl,pm[i],t,&s);
! 664: if ( NUM(s) ) {
! 665: *r = gcd;
! 666: return;
! 667: }
! 668: pm[i] = s;
! 669: }
! 670: }
! 671: *r = gcd;
1.1 noro 672: }
673:
674: void pcp(vl,p,pp,c)
675: VL vl;
676: P p;
677: P *pp,*c;
678: {
1.4 ! noro 679: P f,g,n;
! 680: DCP dc;
! 681: P *pl;
! 682: int i,m;
! 683: extern int nez;
! 684:
! 685: if ( NUM(p) ) {
! 686: *c = p;
! 687: *pp = (P)ONE;
! 688: } else {
! 689: for ( m = 0, dc = DC(p); dc; dc = NEXT(dc), m++ );
! 690: if ( m == 1 ) {
! 691: *c = COEF(DC(p));
! 692: divsp(vl,p,*c,pp);
! 693: return;
! 694: }
! 695: ptozp(p,1,(Q *)&n,&f);
! 696: pl = (P *)ALLOCA((m+1)*sizeof(P));
! 697: for ( i = 0, dc = DC(f); i < m; dc = NEXT(dc), i++ )
! 698: pl[i] = COEF(dc);
! 699: if ( nez )
! 700: nezgcdnpz(vl,pl,m,&g);
! 701: else
! 702: ezgcdnpz(vl,pl,m,&g);
! 703: mulp(vl,g,n,c); divsp(vl,f,g,pp);
! 704: }
1.1 noro 705: }
706:
707: #if 0
708: pcp(vl,p,pp,c)
709: VL vl;
710: P p;
711: P *pp,*c;
712: {
1.4 ! noro 713: P f,g,n,t;
! 714: DCP dc;
1.1 noro 715:
1.4 ! noro 716: if ( NUM(p) ) {
! 717: *c = p;
! 718: *pp = (P)ONE;
! 719: } else {
! 720: ptozp(p,1,&n,&f);
! 721: for ( g = LC(f), dc = NEXT(DC(f)); dc; dc = NEXT(dc) ) {
! 722: ezgcdpz(vl,g,COEF(dc),&t); g = t;
! 723: }
! 724: mulp(vl,g,n,c);
! 725: divsp(vl,f,g,pp);
! 726: }
1.1 noro 727: }
728: #endif
729:
730: int divcheck(vl,ps,m,l,p)
731: VL vl;
732: int m;
733: P *ps,l,p;
734: {
1.4 ! noro 735: int i;
! 736: P r,t;
1.1 noro 737:
1.4 ! noro 738: for ( i = 0; i < m; i++ ) {
! 739: mulp(vl,ps[i],l,&t);
! 740: if ( !divtpz(vl,t,p,&r) )
! 741: return ( 0 );
! 742: }
! 743: return ( 1 );
1.1 noro 744: }
745:
746: void sortplist(plist,n)
747: P *plist;
748: int n;
749: {
1.4 ! noro 750: int i,j;
! 751: P t;
1.1 noro 752:
1.4 ! noro 753: for ( i = 0; i < n; i++ )
! 754: for ( j = i + 1; j < n; j++ )
! 755: if ( cmpq(DEG(DC(plist[i])),DEG(DC(plist[j]))) > 0 ) {
! 756: t = plist[i]; plist[i] = plist[j]; plist[j] = t;
! 757: }
1.1 noro 758: }
759:
760: int dcomp(p1,p2)
761: P p1,p2;
762: {
1.4 ! noro 763: return ( cmpq(DEG(DC(p1)),DEG(DC(p2))) );
1.1 noro 764: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>