Annotation of OpenXM_contrib2/asir2000/builtin/dp-supp.c, Revision 1.67
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.67 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/builtin/dp-supp.c,v 1.66 2017/08/31 02:36:20 noro Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "base.h"
1.16 noro 52: #include "inline.h"
1.1 noro 53: #include "parse.h"
54: #include "ox.h"
55:
1.66 noro 56: #define HMAG(p) (p_mag((P)BDY(p)->c))
1.5 noro 57:
1.1 noro 58: extern int (*cmpdl)();
1.5 noro 59: extern double pz_t_e,pz_t_d,pz_t_d1,pz_t_c;
60: extern int dp_nelim,dp_fcoeffs;
1.7 noro 61: extern int NoGCD;
62: extern int GenTrace;
63: extern NODE TraceList;
64:
1.37 noro 65: int show_orderspec;
66:
67: void print_composite_order_spec(struct order_spec *spec);
1.66 noro 68: void dpm_rest(DPM,DPM *);
1.37 noro 69:
1.7 noro 70: /*
71: * content reduction
72: *
73: */
74:
1.46 noro 75: static NODE RatDenomList;
76:
77: void init_denomlist()
78: {
1.67 ! noro 79: RatDenomList = 0;
1.46 noro 80: }
81:
82: void add_denomlist(P f)
83: {
1.67 ! noro 84: NODE n;
1.46 noro 85:
1.67 ! noro 86: if ( OID(f)==O_P ) {
! 87: MKNODE(n,f,RatDenomList); RatDenomList = n;
! 88: }
1.46 noro 89: }
90:
91: LIST get_denomlist()
92: {
1.67 ! noro 93: LIST l;
1.46 noro 94:
1.67 ! noro 95: MKLIST(l,RatDenomList); RatDenomList = 0;
! 96: return l;
1.46 noro 97: }
98:
1.20 noro 99: void dp_ptozp(DP p,DP *rp)
1.7 noro 100: {
1.67 ! noro 101: MP m,mr,mr0;
! 102: int i,n;
! 103: Q *w;
! 104: Q dvr;
! 105: P t;
! 106:
! 107: if ( !p )
! 108: *rp = 0;
! 109: else {
! 110: for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
! 111: w = (Q *)ALLOCA(n*sizeof(Q));
! 112: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 113: if ( NUM(m->c) )
! 114: w[i] = (Q)m->c;
! 115: else
! 116: ptozp((P)m->c,1,&w[i],&t);
! 117: sortbynm(w,n);
! 118: qltozl(w,n,&dvr);
! 119: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 120: NEXTMP(mr0,mr); divsp(CO,(P)m->c,(P)dvr,(P *)&mr->c); mr->dl = m->dl;
! 121: }
! 122: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 123: }
1.7 noro 124: }
125:
1.20 noro 126: void dp_ptozp2(DP p0,DP p1,DP *hp,DP *rp)
1.7 noro 127: {
1.67 ! noro 128: DP t,s,h,r;
! 129: MP m,mr,mr0,m0;
1.7 noro 130:
1.67 ! noro 131: addd(CO,p0,p1,&t); dp_ptozp(t,&s);
! 132: if ( !p0 ) {
! 133: h = 0; r = s;
! 134: } else if ( !p1 ) {
! 135: h = s; r = 0;
! 136: } else {
! 137: for ( mr0 = 0, m = BDY(s), m0 = BDY(p0); m0;
! 138: m = NEXT(m), m0 = NEXT(m0) ) {
! 139: NEXTMP(mr0,mr); mr->c = m->c; mr->dl = m->dl;
! 140: }
! 141: NEXT(mr) = 0; MKDP(p0->nv,mr0,h); MKDP(p0->nv,m,r);
! 142: }
! 143: if ( h )
! 144: h->sugar = p0->sugar;
! 145: if ( r )
! 146: r->sugar = p1->sugar;
! 147: *hp = h; *rp = r;
1.39 ohara 148: }
149:
1.66 noro 150: void dpm_ptozp(DPM p,DPM *rp)
151: {
1.67 ! noro 152: DMM m,mr,mr0;
! 153: int i,n;
! 154: Q *w;
! 155: Q dvr;
! 156: P t;
! 157:
! 158: if ( !p )
! 159: *rp = 0;
! 160: else {
! 161: for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
! 162: w = (Q *)ALLOCA(n*sizeof(Q));
! 163: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 164: if ( NUM(m->c) )
! 165: w[i] = (Q)m->c;
! 166: else
! 167: ptozp((P)m->c,1,&w[i],&t);
! 168: sortbynm(w,n);
! 169: qltozl(w,n,&dvr);
! 170: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 171: NEXTDMM(mr0,mr); divsp(CO,(P)m->c,(P)dvr,(P *)&mr->c); mr->dl = m->dl; mr->pos = m->pos;
! 172: }
! 173: NEXT(mr) = 0; MKDPM(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 174: }
1.66 noro 175: }
176:
177: void dpm_ptozp2(DPM p0,DPM p1,DPM *hp,DPM *rp)
178: {
1.67 ! noro 179: DPM t,s,h,r;
! 180: DMM m,mr,mr0,m0;
1.66 noro 181:
1.67 ! noro 182: adddpm(CO,p0,p1,&t); dpm_ptozp(t,&s);
! 183: if ( !p0 ) {
! 184: h = 0; r = s;
! 185: } else if ( !p1 ) {
! 186: h = s; r = 0;
! 187: } else {
! 188: for ( mr0 = 0, m = BDY(s), m0 = BDY(p0); m0;
! 189: m = NEXT(m), m0 = NEXT(m0) ) {
! 190: NEXTDMM(mr0,mr); mr->c = m->c; mr->dl = m->dl; mr->pos = m->pos;
! 191: }
! 192: NEXT(mr) = 0; MKDPM(p0->nv,mr0,h); MKDPM(p0->nv,m,r);
! 193: }
! 194: if ( h )
! 195: h->sugar = p0->sugar;
! 196: if ( r )
! 197: r->sugar = p1->sugar;
! 198: *hp = h; *rp = r;
1.66 noro 199: }
200:
201:
1.39 ohara 202: void dp_ptozp3(DP p,Q *dvr,DP *rp)
203: {
1.67 ! noro 204: MP m,mr,mr0;
! 205: int i,n;
! 206: Q *w;
! 207: P t;
! 208:
! 209: if ( !p ) {
! 210: *rp = 0; *dvr = 0;
! 211: }else {
! 212: for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
! 213: w = (Q *)ALLOCA(n*sizeof(Q));
! 214: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 215: if ( NUM(m->c) )
! 216: w[i] = (Q)m->c;
! 217: else
! 218: ptozp((P)m->c,1,&w[i],&t);
! 219: sortbynm(w,n);
! 220: qltozl(w,n,dvr);
! 221: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 222: NEXTMP(mr0,mr); divsp(CO,(P)m->c,(P)(*dvr),(P *)&mr->c); mr->dl = m->dl;
! 223: }
! 224: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 225: }
1.7 noro 226: }
1.1 noro 227:
1.20 noro 228: void dp_idiv(DP p,Q c,DP *rp)
1.1 noro 229: {
1.67 ! noro 230: Q t;
! 231: N nm,q;
! 232: int sgn,s;
! 233: MP mr0,m,mr;
! 234:
! 235: if ( !p )
! 236: *rp = 0;
! 237: else if ( MUNIQ((Q)c) )
! 238: *rp = p;
! 239: else if ( MUNIQ((Q)c) )
! 240: chsgnd(p,rp);
! 241: else {
! 242: nm = NM(c); sgn = SGN(c);
! 243: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 244: NEXTMP(mr0,mr);
! 245:
! 246: divsn(NM((Q)(m->c)),nm,&q);
! 247: s = sgn*SGN((Q)(m->c));
! 248: NTOQ(q,s,t);
! 249: mr->c = (Obj)t;
! 250: mr->dl = m->dl;
! 251: }
! 252: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);
! 253: if ( *rp )
! 254: (*rp)->sugar = p->sugar;
! 255: }
1.1 noro 256: }
257:
1.20 noro 258: void dp_mbase(NODE hlist,NODE *mbase)
1.1 noro 259: {
1.67 ! noro 260: DL *dl;
! 261: DL d;
1.65 noro 262: int *t;
1.67 ! noro 263: int i,j,k,n,nvar,td;
1.1 noro 264:
1.67 ! noro 265: n = length(hlist); nvar = ((DP)BDY(hlist))->nv;
! 266: dl = (DL *)MALLOC(n*sizeof(DL));
! 267: NEWDL(d,nvar); *mbase = 0;
! 268: for ( i = 0; i < n; i++, hlist = NEXT(hlist) ) {
! 269: dl[i] = BDY((DP)BDY(hlist))->dl;
1.65 noro 270: /* trivial ideal check */
1.67 ! noro 271: if ( (*cmpdl)(nvar,d,dl[i]) == 0 ) {
1.65 noro 272: return;
273: }
274: }
275: /* zero-dim. ideal check */
276: for ( i = 0; i < nvar; i++ ) {
277: for ( j = 0; j < n; j++ ) {
278: for ( k = 0, t = dl[j]->d; k < nvar; k++ )
279: if ( k != i && t[k] != 0 ) break;
280: if ( k == nvar ) break;
281: }
282: if ( j == n )
283: error("dp_mbase : input ideal is not zero-dimensional");
284: }
1.67 ! noro 285: while ( 1 ) {
! 286: insert_to_node(d,mbase,nvar);
! 287: for ( i = nvar-1; i >= 0; ) {
! 288: d->d[i]++;
! 289: d->td += MUL_WEIGHT(1,i);
! 290: for ( j = 0; j < n; j++ ) {
! 291: if ( _dl_redble(dl[j],d,nvar) )
! 292: break;
! 293: }
! 294: if ( j < n ) {
! 295: for ( j = nvar-1; j >= i; j-- )
! 296: d->d[j] = 0;
! 297: for ( j = 0, td = 0; j < i; j++ )
! 298: td += MUL_WEIGHT(d->d[j],j);
! 299: d->td = td;
! 300: i--;
! 301: } else
! 302: break;
! 303: }
! 304: if ( i < 0 )
! 305: break;
! 306: }
1.1 noro 307: }
308:
1.20 noro 309: int _dl_redble(DL d1,DL d2,int nvar)
1.1 noro 310: {
1.67 ! noro 311: int i;
1.1 noro 312:
1.67 ! noro 313: if ( d1->td > d2->td )
! 314: return 0;
! 315: for ( i = 0; i < nvar; i++ )
! 316: if ( d1->d[i] > d2->d[i] )
! 317: break;
! 318: if ( i < nvar )
! 319: return 0;
! 320: else
! 321: return 1;
1.1 noro 322: }
323:
1.20 noro 324: void insert_to_node(DL d,NODE *n,int nvar)
1.1 noro 325: {
1.67 ! noro 326: DL d1;
! 327: MP m;
! 328: DP dp;
! 329: NODE n0,n1,n2;
! 330:
! 331: NEWDL(d1,nvar); d1->td = d->td;
! 332: bcopy((char *)d->d,(char *)d1->d,nvar*sizeof(int));
! 333: NEWMP(m); m->dl = d1; m->c = (Obj)ONE; NEXT(m) = 0;
! 334: MKDP(nvar,m,dp); dp->sugar = d->td;
! 335: if ( !(*n) ) {
! 336: MKNODE(n1,dp,0); *n = n1;
! 337: } else {
! 338: for ( n1 = *n, n0 = 0; n1; n0 = n1, n1 = NEXT(n1) )
! 339: if ( (*cmpdl)(nvar,d,BDY((DP)BDY(n1))->dl) > 0 ) {
! 340: MKNODE(n2,dp,n1);
! 341: if ( !n0 )
! 342: *n = n2;
! 343: else
! 344: NEXT(n0) = n2;
! 345: break;
! 346: }
! 347: if ( !n1 ) {
! 348: MKNODE(n2,dp,0); NEXT(n0) = n2;
! 349: }
! 350: }
1.1 noro 351: }
352:
1.20 noro 353: void dp_vtod(Q *c,DP p,DP *rp)
1.1 noro 354: {
1.67 ! noro 355: MP mr0,m,mr;
! 356: int i;
1.1 noro 357:
1.67 ! noro 358: if ( !p )
! 359: *rp = 0;
! 360: else {
! 361: for ( mr0 = 0, m = BDY(p), i = 0; m; m = NEXT(m), i++ ) {
! 362: NEXTMP(mr0,mr); mr->c = (Obj)c[i]; mr->dl = m->dl;
! 363: }
! 364: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);
! 365: (*rp)->sugar = p->sugar;
! 366: }
1.1 noro 367: }
368:
1.8 noro 369: extern int mpi_mag;
370: extern int PCoeffs;
371:
1.20 noro 372: void dp_ptozp_d(DP p,DP *rp)
1.1 noro 373: {
1.67 ! noro 374: int i,j,k,l,n,nsep;
! 375: MP m;
! 376: NODE tn,n0,n1,n2,n3;
! 377: struct oVECT v;
! 378: VECT c,cs;
! 379: VECT qi,ri;
! 380: LIST *qr;
! 381: Obj dmy;
! 382: Q d0,d1,gcd,a,u,u1;
! 383: Q *q,*r;
! 384: STRING iqr_v;
! 385: pointer *b;
! 386: N qn,gn;
! 387: double get_rtime();
! 388: int blen;
! 389: NODE dist;
! 390: int ndist;
! 391: double t0;
! 392: double t_e,t_d,t_d1,t_c;
! 393: extern int DP_NFStat;
! 394: extern LIST Dist;
! 395: void Pox_rpc();
! 396: void Pox_pop_local();
! 397:
! 398: if ( !p )
! 399: *rp = 0;
! 400: else {
! 401: if ( PCoeffs ) {
! 402: dp_ptozp(p,rp); return;
! 403: }
! 404: if ( !Dist || p_mag((P)BDY(p)->c) <= mpi_mag ) {
! 405: dist = 0; ndist = 0;
! 406: if ( DP_NFStat ) fprintf(asir_out,"L");
! 407: } else {
! 408: dist = BDY(Dist); ndist = length(dist);
! 409: if ( DP_NFStat ) fprintf(asir_out,"D");
! 410: }
! 411: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
! 412: nsep = ndist + 1;
! 413: if ( n <= nsep ) {
! 414: dp_ptozp(p,rp); return;
! 415: }
! 416: t0 = get_rtime();
! 417: dp_dtov(p,&c);
! 418: igcdv_estimate(c,&d0);
! 419: t_e = get_rtime()-t0;
! 420: t0 = get_rtime();
! 421: dp_dtov(p,&c);
! 422: sepvect(c,nsep,&cs);
! 423: MKSTR(iqr_v,"iqr");
! 424: qr = (LIST *)CALLOC(nsep,sizeof(LIST));
! 425: q = (Q *)CALLOC(n,sizeof(Q));
! 426: r = (Q *)CALLOC(n,sizeof(Q));
! 427: for ( i = 0, tn = dist, b = BDY(cs); i < ndist; i++, tn = NEXT(tn) ) {
! 428: MKNODE(n3,d0,0); MKNODE(n2,b[i],n3);
! 429: MKNODE(n1,iqr_v,n2); MKNODE(n0,BDY(tn),n1);
! 430: Pox_rpc(n0,&dmy);
! 431: }
! 432: iqrv(b[i],d0,&qr[i]);
! 433: dp_dtov(p,&c);
! 434: for ( i = 0, tn = dist; i < ndist; i++, tn = NEXT(tn) ) {
! 435: Pox_pop_local(tn,&qr[i]);
! 436: if ( OID(qr[i]) == O_ERR ) {
! 437: printexpr(CO,(Obj)qr[i]);
! 438: error("dp_ptozp_d : aborted");
! 439: }
! 440: }
! 441: t_d = get_rtime()-t0;
! 442: t_d1 = t_d/n;
! 443: t0 = get_rtime();
! 444: for ( i = j = 0; i < nsep; i++ ) {
! 445: tn = BDY(qr[i]); qi = (VECT)BDY(tn); ri = (VECT)BDY(NEXT(tn));
! 446: for ( k = 0, l = qi->len; k < l; k++, j++ ) {
! 447: q[j] = (Q)BDY(qi)[k]; r[j] = (Q)BDY(ri)[k];
! 448: }
! 449: }
! 450: v.id = O_VECT; v.len = n; v.body = (pointer *)r; igcdv(&v,&d1);
! 451: if ( d1 ) {
! 452: gcdn(NM(d0),NM(d1),&gn); NTOQ(gn,1,gcd);
! 453: divsn(NM(d0),gn,&qn); NTOQ(qn,1,a);
! 454: for ( i = 0; i < n; i++ ) {
! 455: mulq(a,q[i],&u);
! 456: if ( r[i] ) {
! 457: divsn(NM(r[i]),gn,&qn); NTOQ(qn,SGN(r[i]),u1);
! 458: addq(u,u1,&q[i]);
! 459: } else
! 460: q[i] = u;
! 461: }
! 462: } else
! 463: gcd = d0;
! 464: dp_vtod(q,p,rp);
! 465: t_c = get_rtime()-t0;
! 466: blen=p_mag((P)gcd);
! 467: pz_t_e += t_e; pz_t_d += t_d; pz_t_d1 += t_d1; pz_t_c += t_c;
! 468: if ( 0 )
! 469: fprintf(stderr,"(%d,%d)",p_mag((P)d0)-blen,blen);
! 470: }
1.1 noro 471: }
472:
1.20 noro 473: void dp_ptozp2_d(DP p0,DP p1,DP *hp,DP *rp)
1.1 noro 474: {
1.67 ! noro 475: DP t,s,h,r;
! 476: MP m,mr,mr0,m0;
1.1 noro 477:
1.67 ! noro 478: addd(CO,p0,p1,&t); dp_ptozp_d(t,&s);
! 479: if ( !p0 ) {
! 480: h = 0; r = s;
! 481: } else if ( !p1 ) {
! 482: h = s; r = 0;
! 483: } else {
! 484: for ( mr0 = 0, m = BDY(s), m0 = BDY(p0); m0;
! 485: m = NEXT(m), m0 = NEXT(m0) ) {
! 486: NEXTMP(mr0,mr); mr->c = m->c; mr->dl = m->dl;
! 487: }
! 488: NEXT(mr) = 0; MKDP(p0->nv,mr0,h); MKDP(p0->nv,m,r);
! 489: }
! 490: if ( h )
! 491: h->sugar = p0->sugar;
! 492: if ( r )
! 493: r->sugar = p1->sugar;
! 494: *hp = h; *rp = r;
1.5 noro 495: }
496:
1.22 noro 497: int have_sf_coef(P p)
498: {
1.67 ! noro 499: DCP dc;
1.22 noro 500:
1.67 ! noro 501: if ( !p )
! 502: return 0;
! 503: else if ( NUM(p) )
! 504: return NID((Num)p) == N_GFS ? 1 : 0;
! 505: else {
! 506: for ( dc = DC(p); dc; dc = NEXT(dc) )
! 507: if ( have_sf_coef(COEF(dc)) )
! 508: return 1;
! 509: return 0;
! 510: }
1.22 noro 511: }
512:
1.25 noro 513: void head_coef(P p,Num *c)
514: {
1.67 ! noro 515: if ( !p )
! 516: *c = 0;
! 517: else if ( NUM(p) )
! 518: *c = (Num)p;
! 519: else
! 520: head_coef(COEF(DC(p)),c);
1.25 noro 521: }
522:
523: void dp_monic_sf(DP p,DP *rp)
524: {
1.67 ! noro 525: Num c;
1.25 noro 526:
1.67 ! noro 527: if ( !p )
! 528: *rp = 0;
! 529: else {
! 530: head_coef((P)BDY(p)->c,&c);
! 531: divsdc(CO,p,(P)c,rp);
! 532: }
1.25 noro 533: }
534:
1.20 noro 535: void dp_prim(DP p,DP *rp)
1.5 noro 536: {
1.67 ! noro 537: P t,g;
! 538: DP p1;
! 539: MP m,mr,mr0;
! 540: int i,n;
! 541: P *w;
! 542: Q *c;
! 543: Q dvr;
! 544: NODE tn;
! 545:
! 546: if ( !p )
! 547: *rp = 0;
! 548: else if ( dp_fcoeffs == N_GFS ) {
! 549: for ( m = BDY(p); m; m = NEXT(m) )
! 550: if ( OID(m->c) == O_N ) {
! 551: /* GCD of coeffs = 1 */
! 552: dp_monic_sf(p,rp);
! 553: return;
! 554: } else break;
! 555: /* compute GCD over the finite fieid */
! 556: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
! 557: w = (P *)ALLOCA(n*sizeof(P));
! 558: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 559: w[i] = (P)m->c;
! 560: gcdsf(CO,w,n,&g);
! 561: if ( NUM(g) )
! 562: dp_monic_sf(p,rp);
! 563: else {
! 564: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 565: NEXTMP(mr0,mr); divsp(CO,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
! 566: }
! 567: NEXT(mr) = 0; MKDP(p->nv,mr0,p1); p1->sugar = p->sugar;
! 568: dp_monic_sf(p1,rp);
! 569: }
! 570: return;
! 571: } else if ( dp_fcoeffs )
! 572: *rp = p;
! 573: else if ( NoGCD )
! 574: dp_ptozp(p,rp);
! 575: else {
! 576: dp_ptozp(p,&p1); p = p1;
! 577: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
! 578: if ( n == 1 ) {
! 579: m = BDY(p);
! 580: NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 581: MKDP(p->nv,mr,*rp); (*rp)->sugar = p->sugar;
! 582: return;
! 583: }
! 584: w = (P *)ALLOCA(n*sizeof(P));
! 585: c = (Q *)ALLOCA(n*sizeof(Q));
! 586: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 587: if ( NUM(m->c) ) {
! 588: c[i] = (Q)m->c; w[i] = (P)ONE;
! 589: } else
! 590: ptozp((P)m->c,1,&c[i],&w[i]);
! 591: qltozl(c,n,&dvr); heu_nezgcdnpz(CO,w,n,&t); mulp(CO,t,(P)dvr,&g);
! 592: if ( NUM(g) )
! 593: *rp = p;
! 594: else {
! 595: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 596: NEXTMP(mr0,mr); divsp(CO,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
! 597: }
! 598: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 599: add_denomlist(g);
! 600: }
! 601: }
1.5 noro 602: }
603:
1.20 noro 604: void heu_nezgcdnpz(VL vl,P *pl,int m,P *pr)
1.5 noro 605: {
1.67 ! noro 606: int i,r;
! 607: P gcd,t,s1,s2,u;
! 608: Q rq;
! 609: DCP dc;
! 610: extern int DP_Print;
! 611:
! 612: while ( 1 ) {
! 613: for ( i = 0, s1 = 0; i < m; i++ ) {
! 614: r = random(); UTOQ(r,rq);
! 615: mulp(vl,pl[i],(P)rq,&t); addp(vl,s1,t,&u); s1 = u;
! 616: }
! 617: for ( i = 0, s2 = 0; i < m; i++ ) {
! 618: r = random(); UTOQ(r,rq);
! 619: mulp(vl,pl[i],(P)rq,&t); addp(vl,s2,t,&u); s2 = u;
! 620: }
! 621: ezgcdp(vl,s1,s2,&gcd);
! 622: if ( DP_Print > 2 )
! 623: { fprintf(asir_out,"(%d)",nmonop(gcd)); fflush(asir_out); }
! 624: for ( i = 0; i < m; i++ ) {
! 625: if ( !divtpz(vl,pl[i],gcd,&t) )
! 626: break;
! 627: }
! 628: if ( i == m )
! 629: break;
! 630: }
! 631: *pr = gcd;
1.5 noro 632: }
633:
1.20 noro 634: void dp_prim_mod(DP p,int mod,DP *rp)
1.5 noro 635: {
1.67 ! noro 636: P t,g;
! 637: MP m,mr,mr0;
1.5 noro 638:
1.67 ! noro 639: if ( !p )
! 640: *rp = 0;
! 641: else if ( NoGCD )
! 642: *rp = p;
! 643: else {
! 644: for ( m = BDY(p), g = (P)m->c, m = NEXT(m); m; m = NEXT(m) ) {
! 645: gcdprsmp(CO,mod,g,(P)m->c,&t); g = t;
! 646: }
! 647: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 648: NEXTMP(mr0,mr); divsmp(CO,mod,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
! 649: }
! 650: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 651: }
1.5 noro 652: }
653:
1.20 noro 654: void dp_cont(DP p,Q *rp)
1.5 noro 655: {
1.67 ! noro 656: VECT v;
1.5 noro 657:
1.67 ! noro 658: dp_dtov(p,&v); igcdv(v,rp);
1.5 noro 659: }
660:
1.20 noro 661: void dp_dtov(DP dp,VECT *rp)
1.5 noro 662: {
1.67 ! noro 663: MP m,t;
! 664: int i,n;
! 665: VECT v;
! 666: pointer *p;
! 667:
! 668: m = BDY(dp);
! 669: for ( t = m, n = 0; t; t = NEXT(t), n++ );
! 670: MKVECT(v,n);
! 671: for ( i = 0, p = BDY(v), t = m; i < n; t = NEXT(t), i++ )
! 672: p[i] = (pointer)(t->c);
! 673: *rp = v;
1.5 noro 674: }
675:
1.7 noro 676: /*
677: * s-poly computation
678: *
679: */
1.5 noro 680:
1.20 noro 681: void dp_sp(DP p1,DP p2,DP *rp)
1.5 noro 682: {
1.67 ! noro 683: int i,n,td;
! 684: int *w;
! 685: DL d1,d2,d;
! 686: MP m;
! 687: DP t,s1,s2,u;
! 688: Q c,c1,c2;
! 689: N gn,tn;
! 690:
! 691: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 692: w = (int *)ALLOCA(n*sizeof(int));
! 693: for ( i = 0, td = 0; i < n; i++ ) {
! 694: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 695: }
! 696:
! 697: NEWDL(d,n); d->td = td - d1->td;
! 698: for ( i = 0; i < n; i++ )
! 699: d->d[i] = w[i] - d1->d[i];
! 700: c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
! 701: if ( INT(c1) && INT(c2) ) {
! 702: gcdn(NM(c1),NM(c2),&gn);
! 703: if ( !UNIN(gn) ) {
! 704: divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
! 705: divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
! 706: }
! 707: }
! 708:
! 709: NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
! 710: MKDP(n,m,s1); s1->sugar = d->td; muld(CO,s1,p1,&t);
! 711:
! 712: NEWDL(d,n); d->td = td - d2->td;
! 713: for ( i = 0; i < n; i++ )
! 714: d->d[i] = w[i] - d2->d[i];
! 715: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
! 716: MKDP(n,m,s2); s2->sugar = d->td; muld(CO,s2,p2,&u);
! 717:
! 718: subd(CO,t,u,rp);
! 719: if ( GenTrace ) {
! 720: LIST hist;
! 721: NODE node;
! 722:
! 723: node = mknode(4,ONE,NULLP,s1,ONE);
! 724: MKLIST(hist,node);
! 725: MKNODE(TraceList,hist,0);
! 726:
! 727: node = mknode(4,ONE,NULLP,NULLP,ONE);
! 728: chsgnd(s2,(DP *)&ARG2(node));
! 729: MKLIST(hist,node);
! 730: MKNODE(node,hist,TraceList); TraceList = node;
! 731: }
1.14 noro 732: }
733:
1.66 noro 734: void dpm_sp(DPM p1,DPM p2,DPM *rp)
735: {
1.67 ! noro 736: int i,n,td;
! 737: int *w;
! 738: DL d1,d2,d;
! 739: MP m;
! 740: DP s1,s2;
1.66 noro 741: DPM t,u;
1.67 ! noro 742: Q c,c1,c2;
! 743: N gn,tn;
1.66 noro 744:
1.67 ! noro 745: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
1.66 noro 746: if ( BDY(p1)->pos != BDY(p2)->pos ) {
747: *rp = 0;
748: return;
749: }
1.67 ! noro 750: w = (int *)ALLOCA(n*sizeof(int));
! 751: for ( i = 0, td = 0; i < n; i++ ) {
! 752: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 753: }
! 754:
! 755: NEWDL(d,n); d->td = td - d1->td;
! 756: for ( i = 0; i < n; i++ )
! 757: d->d[i] = w[i] - d1->d[i];
! 758: c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
! 759: if ( INT(c1) && INT(c2) ) {
! 760: gcdn(NM(c1),NM(c2),&gn);
! 761: if ( !UNIN(gn) ) {
! 762: divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
! 763: divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
! 764: }
! 765: }
! 766:
! 767: NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
! 768: MKDP(n,m,s1); s1->sugar = d->td; mulobjdpm(CO,(Obj)s1,p1,&t);
! 769:
! 770: NEWDL(d,n); d->td = td - d2->td;
! 771: for ( i = 0; i < n; i++ )
! 772: d->d[i] = w[i] - d2->d[i];
! 773: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
! 774: MKDP(n,m,s2); s2->sugar = d->td; mulobjdpm(CO,(Obj)s2,p2,&u);
! 775:
! 776: subdpm(CO,t,u,rp);
! 777: if ( GenTrace ) {
! 778: LIST hist;
! 779: NODE node;
! 780:
! 781: node = mknode(4,ONE,NULLP,s1,ONE);
! 782: MKLIST(hist,node);
! 783: MKNODE(TraceList,hist,0);
! 784:
! 785: node = mknode(4,ONE,NULLP,NULLP,ONE);
! 786: chsgnd(s2,(DP *)&ARG2(node));
! 787: MKLIST(hist,node);
! 788: MKNODE(node,hist,TraceList); TraceList = node;
! 789: }
1.66 noro 790: }
791:
1.20 noro 792: void _dp_sp_dup(DP p1,DP p2,DP *rp)
1.14 noro 793: {
1.67 ! noro 794: int i,n,td;
! 795: int *w;
! 796: DL d1,d2,d;
! 797: MP m;
! 798: DP t,s1,s2,u;
! 799: Q c,c1,c2;
! 800: N gn,tn;
! 801:
! 802: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 803: w = (int *)ALLOCA(n*sizeof(int));
! 804: for ( i = 0, td = 0; i < n; i++ ) {
! 805: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 806: }
! 807:
! 808: _NEWDL(d,n); d->td = td - d1->td;
! 809: for ( i = 0; i < n; i++ )
! 810: d->d[i] = w[i] - d1->d[i];
! 811: c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
! 812: if ( INT(c1) && INT(c2) ) {
! 813: gcdn(NM(c1),NM(c2),&gn);
! 814: if ( !UNIN(gn) ) {
! 815: divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
! 816: divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
! 817: }
! 818: }
! 819:
! 820: _NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
! 821: _MKDP(n,m,s1); s1->sugar = d->td; _muld_dup(CO,s1,p1,&t); _free_dp(s1);
! 822:
! 823: _NEWDL(d,n); d->td = td - d2->td;
! 824: for ( i = 0; i < n; i++ )
! 825: d->d[i] = w[i] - d2->d[i];
! 826: _NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0;
! 827: _MKDP(n,m,s2); s2->sugar = d->td; _muld_dup(CO,s2,p2,&u); _free_dp(s2);
! 828:
! 829: _addd_destructive(CO,t,u,rp);
! 830: if ( GenTrace ) {
! 831: LIST hist;
! 832: NODE node;
! 833:
! 834: node = mknode(4,ONE,NULLP,s1,ONE);
! 835: MKLIST(hist,node);
! 836: MKNODE(TraceList,hist,0);
! 837:
! 838: node = mknode(4,ONE,NULLP,NULLP,ONE);
! 839: chsgnd(s2,(DP *)&ARG2(node));
! 840: MKLIST(hist,node);
! 841: MKNODE(node,hist,TraceList); TraceList = node;
! 842: }
1.7 noro 843: }
844:
1.20 noro 845: void dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
1.7 noro 846: {
1.67 ! noro 847: int i,n,td;
! 848: int *w;
! 849: DL d1,d2,d;
! 850: MP m;
! 851: DP t,s,u;
! 852:
! 853: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 854: w = (int *)ALLOCA(n*sizeof(int));
! 855: for ( i = 0, td = 0; i < n; i++ ) {
! 856: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 857: }
! 858: NEWDL_NOINIT(d,n); d->td = td - d1->td;
! 859: for ( i = 0; i < n; i++ )
! 860: d->d[i] = w[i] - d1->d[i];
! 861: NEWMP(m); m->dl = d; m->c = (Obj)BDY(p2)->c; NEXT(m) = 0;
! 862: MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p1,s,&t);
! 863: NEWDL_NOINIT(d,n); d->td = td - d2->td;
! 864: for ( i = 0; i < n; i++ )
! 865: d->d[i] = w[i] - d2->d[i];
! 866: NEWMP(m); m->dl = d; m->c = (Obj)BDY(p1)->c; NEXT(m) = 0;
! 867: MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p2,s,&u);
! 868: submd(CO,mod,t,u,rp);
1.7 noro 869: }
870:
1.20 noro 871: void _dp_sp_mod_dup(DP p1,DP p2,int mod,DP *rp)
1.7 noro 872: {
1.67 ! noro 873: int i,n,td;
! 874: int *w;
! 875: DL d1,d2,d;
! 876: MP m;
! 877: DP t,s,u;
! 878:
! 879: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 880: w = (int *)ALLOCA(n*sizeof(int));
! 881: for ( i = 0, td = 0; i < n; i++ ) {
! 882: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 883: }
! 884: _NEWDL(d,n); d->td = td - d1->td;
! 885: for ( i = 0; i < n; i++ )
! 886: d->d[i] = w[i] - d1->d[i];
! 887: _NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
! 888: _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p1,&t); _free_dp(s);
! 889: _NEWDL(d,n); d->td = td - d2->td;
! 890: for ( i = 0; i < n; i++ )
! 891: d->d[i] = w[i] - d2->d[i];
! 892: _NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
! 893: _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p2,&u); _free_dp(s);
! 894: _addmd_destructive(mod,t,u,rp);
1.7 noro 895: }
896:
1.20 noro 897: void _dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
1.7 noro 898: {
1.67 ! noro 899: int i,n,td;
! 900: int *w;
! 901: DL d1,d2,d;
! 902: MP m;
! 903: DP t,s,u;
! 904:
! 905: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 906: w = (int *)ALLOCA(n*sizeof(int));
! 907: for ( i = 0, td = 0; i < n; i++ ) {
! 908: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 909: }
! 910: NEWDL(d,n); d->td = td - d1->td;
! 911: for ( i = 0; i < n; i++ )
! 912: d->d[i] = w[i] - d1->d[i];
! 913: NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
! 914: MKDP(n,m,s); s->sugar = d->td; mulmd_dup(mod,s,p1,&t);
! 915: NEWDL(d,n); d->td = td - d2->td;
! 916: for ( i = 0; i < n; i++ )
! 917: d->d[i] = w[i] - d2->d[i];
! 918: NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
! 919: MKDP(n,m,s); s->sugar = d->td; mulmd_dup(mod,s,p2,&u);
! 920: addmd_destructive(mod,t,u,rp);
1.7 noro 921: }
922:
923: /*
924: * m-reduction
1.13 noro 925: * do content reduction over Z or Q(x,...)
926: * do nothing over finite fields
1.7 noro 927: *
928: */
929:
1.20 noro 930: void dp_red(DP p0,DP p1,DP p2,DP *head,DP *rest,P *dnp,DP *multp)
1.7 noro 931: {
1.67 ! noro 932: int i,n;
! 933: DL d1,d2,d;
! 934: MP m;
! 935: DP t,s,r,h;
! 936: Q c,c1,c2;
! 937: N gn,tn;
! 938: P g,a;
! 939: P p[2];
! 940:
! 941: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 942: NEWDL(d,n); d->td = d1->td - d2->td;
! 943: for ( i = 0; i < n; i++ )
! 944: d->d[i] = d1->d[i]-d2->d[i];
! 945: c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
! 946: if ( dp_fcoeffs == N_GFS ) {
! 947: p[0] = (P)c1; p[1] = (P)c2;
! 948: gcdsf(CO,p,2,&g);
! 949: divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
! 950: } else if ( dp_fcoeffs ) {
! 951: /* do nothing */
! 952: } else if ( INT(c1) && INT(c2) ) {
! 953: gcdn(NM(c1),NM(c2),&gn);
! 954: if ( !UNIN(gn) ) {
! 955: divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
! 956: divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
! 957: }
! 958: } else {
! 959: ezgcdpz(CO,(P)c1,(P)c2,&g);
! 960: divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
! 961: add_denomlist(g);
! 962: }
! 963: NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 964: *multp = s;
! 965: muld(CO,s,p2,&t); muldc(CO,p1,(Obj)c2,&s); addd(CO,s,t,&r);
! 966: muldc(CO,p0,(Obj)c2,&h);
! 967: *head = h; *rest = r; *dnp = (P)c2;
1.7 noro 968: }
969:
1.66 noro 970: void dpm_red(DPM p0,DPM p1,DPM p2,DPM *head,DPM *rest,P *dnp,DP *multp)
971: {
1.67 ! noro 972: int i,n,pos;
! 973: DL d1,d2,d;
! 974: MP m;
1.66 noro 975: DP s;
1.67 ! noro 976: DPM t,r,h,u,w;
! 977: Q c,c1,c2;
! 978: N gn,tn;
! 979: P g,a;
! 980: P p[2];
1.66 noro 981:
1.67 ! noro 982: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl; pos = BDY(p1)->pos;
1.66 noro 983: if ( pos != BDY(p2)->pos )
984: error("dpm_red : cannot happen");
1.67 ! noro 985: NEWDL(d,n); d->td = d1->td - d2->td;
! 986: for ( i = 0; i < n; i++ )
! 987: d->d[i] = d1->d[i]-d2->d[i];
! 988: c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
! 989: if ( dp_fcoeffs == N_GFS ) {
! 990: p[0] = (P)c1; p[1] = (P)c2;
! 991: gcdsf(CO,p,2,&g);
! 992: divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
! 993: } else if ( dp_fcoeffs ) {
! 994: /* do nothing */
! 995: } else if ( INT(c1) && INT(c2) ) {
! 996: gcdn(NM(c1),NM(c2),&gn);
! 997: if ( !UNIN(gn) ) {
! 998: divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
! 999: divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
! 1000: }
! 1001: } else {
! 1002: ezgcdpz(CO,(P)c1,(P)c2,&g);
! 1003: divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
! 1004: add_denomlist(g);
! 1005: }
! 1006: NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 1007: *multp = s;
! 1008: mulobjdpm(CO,(Obj)s,p2,&u); mulobjdpm(CO,(Obj)c2,p1,&w); adddpm(CO,u,w,&r);
! 1009: mulobjdpm(CO,(Obj)c2,p0,&h);
! 1010: *head = h; *rest = r; *dnp = (P)c2;
1.66 noro 1011: }
1012:
1013:
1.41 noro 1014: /*
1015: * m-reduction by a marked poly
1016: * do content reduction over Z or Q(x,...)
1017: * do nothing over finite fields
1018: *
1019: */
1020:
1021:
1022: void dp_red_marked(DP p0,DP p1,DP p2,DP hp2,DP *head,DP *rest,P *dnp,DP *multp)
1023: {
1.67 ! noro 1024: int i,n;
! 1025: DL d1,d2,d;
! 1026: MP m;
! 1027: DP t,s,r,h;
! 1028: Q c,c1,c2;
! 1029: N gn,tn;
! 1030: P g,a;
! 1031: P p[2];
! 1032:
! 1033: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(hp2)->dl;
! 1034: NEWDL(d,n); d->td = d1->td - d2->td;
! 1035: for ( i = 0; i < n; i++ )
! 1036: d->d[i] = d1->d[i]-d2->d[i];
! 1037: c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(hp2)->c;
! 1038: if ( dp_fcoeffs == N_GFS ) {
! 1039: p[0] = (P)c1; p[1] = (P)c2;
! 1040: gcdsf(CO,p,2,&g);
! 1041: divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
! 1042: } else if ( dp_fcoeffs ) {
! 1043: /* do nothing */
! 1044: } else if ( INT(c1) && INT(c2) ) {
! 1045: gcdn(NM(c1),NM(c2),&gn);
! 1046: if ( !UNIN(gn) ) {
! 1047: divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
! 1048: divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
! 1049: }
! 1050: } else {
! 1051: ezgcdpz(CO,(P)c1,(P)c2,&g);
! 1052: divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
! 1053: }
! 1054: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 1055: *multp = s;
! 1056: muld(CO,s,p2,&t); muldc(CO,p1,(Obj)c2,&s); subd(CO,s,t,&r);
! 1057: muldc(CO,p0,(Obj)c2,&h);
! 1058: *head = h; *rest = r; *dnp = (P)c2;
1.41 noro 1059: }
1060:
1.55 noro 1061: void dp_red_marked_mod(DP p0,DP p1,DP p2,DP hp2,int mod,DP *head,DP *rest,P *dnp,DP *multp)
1.44 noro 1062: {
1.67 ! noro 1063: int i,n;
! 1064: DL d1,d2,d;
! 1065: MP m;
! 1066: DP t,s,r,h;
! 1067: P c1,c2,g,u;
! 1068:
! 1069: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(hp2)->dl;
! 1070: NEWDL(d,n); d->td = d1->td - d2->td;
! 1071: for ( i = 0; i < n; i++ )
! 1072: d->d[i] = d1->d[i]-d2->d[i];
! 1073: c1 = (P)BDY(p1)->c; c2 = (P)BDY(hp2)->c;
! 1074: gcdprsmp(CO,mod,c1,c2,&g);
! 1075: divsmp(CO,mod,c1,g,&u); c1 = u; divsmp(CO,mod,c2,g,&u); c2 = u;
! 1076: if ( NUM(c2) ) {
! 1077: divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;
! 1078: }
! 1079: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
! 1080: MKDP(n,m,s); s->sugar = d->td;
! 1081: *multp = s;
! 1082: mulmd(CO,mod,s,p2,&t);
! 1083: if ( NUM(c2) ) {
! 1084: submd(CO,mod,p1,t,&r); h = p0;
! 1085: } else {
! 1086: mulmdc(CO,mod,p1,c2,&s); submd(CO,mod,s,t,&r); mulmdc(CO,mod,p0,c2,&h);
! 1087: }
! 1088: *head = h; *rest = r; *dnp = c2;
1.44 noro 1089: }
1090:
1.13 noro 1091: /* m-reduction over a field */
1092:
1.20 noro 1093: void dp_red_f(DP p1,DP p2,DP *rest)
1.13 noro 1094: {
1.67 ! noro 1095: int i,n;
! 1096: DL d1,d2,d;
! 1097: MP m;
! 1098: DP t,s;
! 1099: Obj a,b;
! 1100:
! 1101: n = p1->nv;
! 1102: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 1103:
! 1104: NEWDL(d,n); d->td = d1->td - d2->td;
! 1105: for ( i = 0; i < n; i++ )
! 1106: d->d[i] = d1->d[i]-d2->d[i];
! 1107:
! 1108: NEWMP(m); m->dl = d;
! 1109: divr(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); chsgnr(a,&b);
! 1110: C(m) = (Obj)b;
! 1111: NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
1.13 noro 1112:
1.67 ! noro 1113: muld(CO,s,p2,&t); addd(CO,p1,t,rest);
1.13 noro 1114: }
1115:
1.66 noro 1116: void dpm_red_f(DPM p1,DPM p2,DPM *rest)
1117: {
1.67 ! noro 1118: int i,n;
! 1119: DL d1,d2,d;
! 1120: MP m;
! 1121: DPM t;
1.66 noro 1122: DP s;
1.67 ! noro 1123: Obj a,b;
1.66 noro 1124:
1.67 ! noro 1125: n = p1->nv;
! 1126: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
1.66 noro 1127:
1.67 ! noro 1128: NEWDL(d,n); d->td = d1->td - d2->td;
! 1129: for ( i = 0; i < n; i++ )
! 1130: d->d[i] = d1->d[i]-d2->d[i];
1.66 noro 1131:
1.67 ! noro 1132: NEWMP(m); m->dl = d;
! 1133: arf_div(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); arf_chsgn(a,&b);
! 1134: C(m) = b;
! 1135: NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
1.66 noro 1136:
1.67 ! noro 1137: mulobjdpm(CO,(Obj)s,p2,&t); adddpm(CO,p1,t,rest);
1.66 noro 1138: }
1139:
1140:
1.20 noro 1141: void dp_red_mod(DP p0,DP p1,DP p2,int mod,DP *head,DP *rest,P *dnp)
1.7 noro 1142: {
1.67 ! noro 1143: int i,n;
! 1144: DL d1,d2,d;
! 1145: MP m;
! 1146: DP t,s,r,h;
! 1147: P c1,c2,g,u;
! 1148:
! 1149: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 1150: NEWDL(d,n); d->td = d1->td - d2->td;
! 1151: for ( i = 0; i < n; i++ )
! 1152: d->d[i] = d1->d[i]-d2->d[i];
! 1153: c1 = (P)BDY(p1)->c; c2 = (P)BDY(p2)->c;
! 1154: gcdprsmp(CO,mod,c1,c2,&g);
! 1155: divsmp(CO,mod,c1,g,&u); c1 = u; divsmp(CO,mod,c2,g,&u); c2 = u;
! 1156: if ( NUM(c2) ) {
! 1157: divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;
! 1158: }
! 1159: NEWMP(m); m->dl = d; chsgnmp(mod,(P)c1,(P *)&m->c); NEXT(m) = 0;
! 1160: MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,s,p2,&t);
! 1161: if ( NUM(c2) ) {
! 1162: addmd(CO,mod,p1,t,&r); h = p0;
! 1163: } else {
! 1164: mulmdc(CO,mod,p1,c2,&s); addmd(CO,mod,s,t,&r); mulmdc(CO,mod,p0,c2,&h);
! 1165: }
! 1166: *head = h; *rest = r; *dnp = c2;
1.7 noro 1167: }
1168:
1.10 noro 1169: struct oEGT eg_red_mod;
1170:
1.20 noro 1171: void _dp_red_mod_destructive(DP p1,DP p2,int mod,DP *rp)
1.7 noro 1172: {
1.67 ! noro 1173: int i,n;
! 1174: DL d1,d2,d;
! 1175: MP m;
! 1176: DP t,s;
! 1177: int c,c1,c2;
! 1178: extern int do_weyl;
! 1179:
! 1180: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 1181: _NEWDL(d,n); d->td = d1->td - d2->td;
! 1182: for ( i = 0; i < n; i++ )
! 1183: d->d[i] = d1->d[i]-d2->d[i];
! 1184: c = invm(ITOS(BDY(p2)->c),mod);
! 1185: c2 = ITOS(BDY(p1)->c);
! 1186: DMAR(c,c2,0,mod,c1);
! 1187: _NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod-c1); NEXT(m) = 0;
1.16 noro 1188: #if 0
1.67 ! noro 1189: _MKDP(n,m,s); s->sugar = d->td;
! 1190: _mulmd_dup(mod,s,p2,&t); _free_dp(s);
1.16 noro 1191: #else
1.67 ! noro 1192: if ( do_weyl ) {
! 1193: _MKDP(n,m,s); s->sugar = d->td;
! 1194: _mulmd_dup(mod,s,p2,&t); _free_dp(s);
! 1195: } else {
! 1196: _mulmdm_dup(mod,p2,m,&t); _FREEMP(m);
! 1197: }
1.16 noro 1198: #endif
1.10 noro 1199: /* get_eg(&t0); */
1.67 ! noro 1200: _addmd_destructive(mod,p1,t,rp);
1.10 noro 1201: /* get_eg(&t1); add_eg(&eg_red_mod,&t0,&t1); */
1.7 noro 1202: }
1203:
1204: /*
1205: * normal form computation
1206: *
1207: */
1.5 noro 1208:
1.20 noro 1209: void dp_true_nf(NODE b,DP g,DP *ps,int full,DP *rp,P *dnp)
1.5 noro 1210: {
1.67 ! noro 1211: DP u,p,d,s,t,dmy;
! 1212: NODE l;
! 1213: MP m,mr;
! 1214: int i,n;
! 1215: int *wb;
! 1216: int sugar,psugar;
! 1217: P dn,tdn,tdn1;
! 1218:
! 1219: dn = (P)ONE;
! 1220: if ( !g ) {
! 1221: *rp = 0; *dnp = dn; return;
! 1222: }
! 1223: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1224: wb = (int *)ALLOCA(n*sizeof(int));
! 1225: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1226: wb[i] = QTOS((Q)BDY(l));
! 1227: sugar = g->sugar;
! 1228: for ( d = 0; g; ) {
! 1229: for ( u = 0, i = 0; i < n; i++ ) {
! 1230: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1231: dp_red(d,g,p,&t,&u,&tdn,&dmy);
! 1232: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1233: sugar = MAX(sugar,psugar);
! 1234: if ( !u ) {
! 1235: if ( d )
! 1236: d->sugar = sugar;
! 1237: *rp = d; *dnp = dn; return;
! 1238: } else {
! 1239: d = t;
! 1240: mulp(CO,dn,tdn,&tdn1); dn = tdn1;
! 1241: }
! 1242: break;
! 1243: }
! 1244: }
! 1245: if ( u )
! 1246: g = u;
! 1247: else if ( !full ) {
! 1248: if ( g ) {
! 1249: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1250: }
! 1251: *rp = g; *dnp = dn; return;
! 1252: } else {
! 1253: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1254: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1255: addd(CO,d,t,&s); d = s;
! 1256: dp_rest(g,&t); g = t;
! 1257: }
! 1258: }
! 1259: if ( d )
! 1260: d->sugar = sugar;
! 1261: *rp = d; *dnp = dn;
1.5 noro 1262: }
1263:
1.43 noro 1264: void dp_removecont2(DP p1,DP p2,DP *r1p,DP *r2p,Q *contp)
1265: {
1.67 ! noro 1266: struct oVECT v;
! 1267: int i,n1,n2,n;
! 1268: MP m,m0,t;
! 1269: Q *w;
! 1270: Q h;
! 1271:
! 1272: if ( p1 ) {
! 1273: for ( i = 0, m = BDY(p1); m; m = NEXT(m), i++ );
! 1274: n1 = i;
! 1275: } else
! 1276: n1 = 0;
! 1277: if ( p2 ) {
! 1278: for ( i = 0, m = BDY(p2); m; m = NEXT(m), i++ );
! 1279: n2 = i;
! 1280: } else
! 1281: n2 = 0;
! 1282: n = n1+n2;
! 1283: if ( !n ) {
! 1284: *r1p = 0; *r2p = 0; *contp = ONE; return;
! 1285: }
! 1286: w = (Q *)ALLOCA(n*sizeof(Q));
! 1287: v.len = n;
! 1288: v.body = (pointer *)w;
! 1289: i = 0;
! 1290: if ( p1 )
! 1291: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = (Q)m->c;
! 1292: if ( p2 )
! 1293: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = (Q)m->c;
! 1294: h = w[0]; removecont_array((P *)w,n,1); divq(h,w[0],contp);
! 1295: i = 0;
! 1296: if ( p1 ) {
! 1297: for ( m0 = 0, t = BDY(p1); i < n1; i++, t = NEXT(t) ) {
! 1298: NEXTMP(m0,m); m->c = (Obj)w[i]; m->dl = t->dl;
! 1299: }
! 1300: NEXT(m) = 0;
! 1301: MKDP(p1->nv,m0,*r1p); (*r1p)->sugar = p1->sugar;
! 1302: } else
! 1303: *r1p = 0;
! 1304: if ( p2 ) {
! 1305: for ( m0 = 0, t = BDY(p2); i < n; i++, t = NEXT(t) ) {
! 1306: NEXTMP(m0,m); m->c = (Obj)w[i]; m->dl = t->dl;
! 1307: }
! 1308: NEXT(m) = 0;
! 1309: MKDP(p2->nv,m0,*r2p); (*r2p)->sugar = p2->sugar;
! 1310: } else
! 1311: *r2p = 0;
1.43 noro 1312: }
1313:
1.41 noro 1314: /* true nf by a marked GB */
1315:
1.43 noro 1316: void dp_true_nf_marked(NODE b,DP g,DP *ps,DP *hps,DP *rp,P *nmp,P *dnp)
1.41 noro 1317: {
1.67 ! noro 1318: DP u,p,d,s,t,dmy,hp;
! 1319: NODE l;
! 1320: MP m,mr;
! 1321: int i,n,hmag;
! 1322: int *wb;
! 1323: int sugar,psugar,multiple;
! 1324: P nm,tnm1,dn,tdn,tdn1;
! 1325: Q cont;
! 1326:
! 1327: multiple = 0;
! 1328: hmag = multiple*HMAG(g);
! 1329: nm = (P)ONE;
! 1330: dn = (P)ONE;
! 1331: if ( !g ) {
! 1332: *rp = 0; *dnp = dn; return;
! 1333: }
! 1334: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1335: wb = (int *)ALLOCA(n*sizeof(int));
! 1336: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1337: wb[i] = QTOS((Q)BDY(l));
! 1338: sugar = g->sugar;
! 1339: for ( d = 0; g; ) {
! 1340: for ( u = 0, i = 0; i < n; i++ ) {
! 1341: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1342: p = ps[wb[i]];
! 1343: dp_red_marked(d,g,p,hp,&t,&u,&tdn,&dmy);
! 1344: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1345: sugar = MAX(sugar,psugar);
! 1346: if ( !u ) {
! 1347: goto last;
! 1348: } else {
! 1349: d = t;
! 1350: mulp(CO,dn,tdn,&tdn1); dn = tdn1;
! 1351: }
! 1352: break;
! 1353: }
! 1354: }
! 1355: if ( u ) {
! 1356: g = u;
! 1357: if ( multiple && ((d && HMAG(d)>hmag) || (HMAG(g)>hmag)) ) {
! 1358: dp_removecont2(d,g,&t,&u,&cont); d = t; g = u;
! 1359: mulp(CO,nm,(P)cont,&tnm1); nm = tnm1;
! 1360: if ( d )
! 1361: hmag = multiple*HMAG(d);
! 1362: else
! 1363: hmag = multiple*HMAG(g);
! 1364: }
! 1365: } else {
! 1366: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1367: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1368: addd(CO,d,t,&s); d = s;
! 1369: dp_rest(g,&t); g = t;
! 1370: }
! 1371: }
1.43 noro 1372: last:
1.67 ! noro 1373: if ( d ) {
! 1374: dp_removecont2(d,0,&t,&u,&cont); d = t;
! 1375: mulp(CO,nm,(P)cont,&tnm1); nm = tnm1;
! 1376: d->sugar = sugar;
! 1377: }
! 1378: *rp = d; *nmp = nm; *dnp = dn;
1.41 noro 1379: }
1380:
1.44 noro 1381: void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)
1382: {
1.67 ! noro 1383: DP hp,u,p,d,s,t,dmy;
! 1384: NODE l;
! 1385: MP m,mr;
! 1386: int i,n;
! 1387: int *wb;
! 1388: int sugar,psugar;
! 1389: P dn,tdn,tdn1;
! 1390:
! 1391: dn = (P)ONEM;
! 1392: if ( !g ) {
! 1393: *rp = 0; *dnp = dn; return;
! 1394: }
! 1395: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1396: wb = (int *)ALLOCA(n*sizeof(int));
! 1397: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1398: wb[i] = QTOS((Q)BDY(l));
! 1399: sugar = g->sugar;
! 1400: for ( d = 0; g; ) {
! 1401: for ( u = 0, i = 0; i < n; i++ ) {
! 1402: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1403: p = ps[wb[i]];
! 1404: dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn,&dmy);
! 1405: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1406: sugar = MAX(sugar,psugar);
! 1407: if ( !u ) {
! 1408: if ( d )
! 1409: d->sugar = sugar;
! 1410: *rp = d; *dnp = dn; return;
! 1411: } else {
! 1412: d = t;
! 1413: mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
! 1414: }
! 1415: break;
! 1416: }
! 1417: }
! 1418: if ( u )
! 1419: g = u;
! 1420: else {
! 1421: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1422: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1423: addmd(CO,mod,d,t,&s); d = s;
! 1424: dp_rest(g,&t); g = t;
! 1425: }
! 1426: }
! 1427: if ( d )
! 1428: d->sugar = sugar;
! 1429: *rp = d; *dnp = dn;
1.44 noro 1430: }
1431:
1.47 noro 1432: /* true nf by a marked GB and collect quotients */
1433:
1434: DP *dp_true_nf_and_quotient_marked (NODE b,DP g,DP *ps,DP *hps,DP *rp,P *dnp)
1435: {
1.67 ! noro 1436: DP u,p,d,s,t,dmy,hp,mult;
! 1437: DP *q;
! 1438: NODE l;
! 1439: MP m,mr;
! 1440: int i,n,j;
! 1441: int *wb;
! 1442: int sugar,psugar,multiple;
! 1443: P nm,tnm1,dn,tdn,tdn1;
! 1444: Q cont;
! 1445:
! 1446: dn = (P)ONE;
! 1447: if ( !g ) {
! 1448: *rp = 0; *dnp = dn; return 0;
! 1449: }
! 1450: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1451: wb = (int *)ALLOCA(n*sizeof(int));
! 1452: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1453: wb[i] = QTOS((Q)BDY(l));
! 1454: q = (DP *)MALLOC(n*sizeof(DP));
! 1455: for ( i = 0; i < n; i++ ) q[i] = 0;
! 1456: sugar = g->sugar;
! 1457: for ( d = 0; g; ) {
! 1458: for ( u = 0, i = 0; i < n; i++ ) {
! 1459: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1460: p = ps[wb[i]];
! 1461: dp_red_marked(d,g,p,hp,&t,&u,&tdn,&mult);
! 1462: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1463: sugar = MAX(sugar,psugar);
! 1464: for ( j = 0; j < n; j++ ) {
! 1465: muldc(CO,q[j],(Obj)tdn,&dmy); q[j] = dmy;
! 1466: }
! 1467: addd(CO,q[wb[i]],mult,&dmy); q[wb[i]] = dmy;
! 1468: mulp(CO,dn,tdn,&tdn1); dn = tdn1;
! 1469: d = t;
! 1470: if ( !u ) goto last;
! 1471: break;
! 1472: }
! 1473: }
! 1474: if ( u ) {
! 1475: g = u;
! 1476: } else {
! 1477: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1478: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1479: addd(CO,d,t,&s); d = s;
! 1480: dp_rest(g,&t); g = t;
! 1481: }
! 1482: }
1.47 noro 1483: last:
1.67 ! noro 1484: if ( d ) d->sugar = sugar;
! 1485: *rp = d; *dnp = dn;
! 1486: return q;
1.47 noro 1487: }
1488:
1.55 noro 1489: DP *dp_true_nf_and_quotient_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)
1490: {
1.67 ! noro 1491: DP u,p,d,s,t,dmy,hp,mult;
! 1492: DP *q;
! 1493: NODE l;
! 1494: MP m,mr;
! 1495: int i,n,j;
! 1496: int *wb;
! 1497: int sugar,psugar;
! 1498: P dn,tdn,tdn1;
! 1499:
! 1500: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1501: q = (DP *)MALLOC(n*sizeof(DP));
! 1502: for ( i = 0; i < n; i++ ) q[i] = 0;
! 1503: dn = (P)ONEM;
! 1504: if ( !g ) {
! 1505: *rp = 0; *dnp = dn; return 0;
! 1506: }
! 1507: wb = (int *)ALLOCA(n*sizeof(int));
! 1508: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1509: wb[i] = QTOS((Q)BDY(l));
! 1510: sugar = g->sugar;
! 1511: for ( d = 0; g; ) {
! 1512: for ( u = 0, i = 0; i < n; i++ ) {
! 1513: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1514: p = ps[wb[i]];
! 1515: dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn,&mult);
! 1516: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1517: sugar = MAX(sugar,psugar);
! 1518: for ( j = 0; j < n; j++ ) {
! 1519: mulmdc(CO,mod,q[j],(P)tdn,&dmy); q[j] = dmy;
! 1520: }
! 1521: addmd(CO,mod,q[wb[i]],mult,&dmy); q[wb[i]] = dmy;
! 1522: mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
! 1523: d = t;
! 1524: if ( !u ) goto last;
! 1525: break;
! 1526: }
! 1527: }
! 1528: if ( u )
! 1529: g = u;
! 1530: else {
! 1531: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1532: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1533: addmd(CO,mod,d,t,&s); d = s;
! 1534: dp_rest(g,&t); g = t;
! 1535: }
! 1536: }
1.55 noro 1537: last:
1.67 ! noro 1538: if ( d )
! 1539: d->sugar = sugar;
! 1540: *rp = d; *dnp = dn;
! 1541: return q;
1.55 noro 1542: }
1543:
1.13 noro 1544: /* nf computation over Z */
1545:
1.20 noro 1546: void dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,DP *rp)
1.5 noro 1547: {
1.67 ! noro 1548: DP u,p,d,s,t,dmy1;
! 1549: P dmy;
! 1550: NODE l;
! 1551: MP m,mr;
! 1552: int i,n;
! 1553: int *wb;
! 1554: int hmag;
! 1555: int sugar,psugar;
! 1556:
! 1557: if ( !g ) {
! 1558: *rp = 0; return;
! 1559: }
! 1560: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1561: wb = (int *)ALLOCA(n*sizeof(int));
! 1562: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1563: wb[i] = QTOS((Q)BDY(l));
! 1564:
! 1565: hmag = multiple*HMAG(g);
! 1566: sugar = g->sugar;
! 1567:
! 1568: for ( d = 0; g; ) {
! 1569: for ( u = 0, i = 0; i < n; i++ ) {
! 1570: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1571: dp_red(d,g,p,&t,&u,&dmy,&dmy1);
! 1572: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1573: sugar = MAX(sugar,psugar);
! 1574: if ( !u ) {
! 1575: if ( d )
! 1576: d->sugar = sugar;
! 1577: *rp = d; return;
! 1578: }
! 1579: d = t;
! 1580: break;
! 1581: }
! 1582: }
! 1583: if ( u ) {
! 1584: g = u;
! 1585: if ( d ) {
! 1586: if ( multiple && HMAG(d) > hmag ) {
! 1587: dp_ptozp2(d,g,&t,&u); d = t; g = u;
! 1588: hmag = multiple*HMAG(d);
! 1589: }
! 1590: } else {
! 1591: if ( multiple && HMAG(g) > hmag ) {
! 1592: dp_ptozp(g,&t); g = t;
! 1593: hmag = multiple*HMAG(g);
! 1594: }
! 1595: }
! 1596: }
! 1597: else if ( !full ) {
! 1598: if ( g ) {
! 1599: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1600: }
! 1601: *rp = g; return;
! 1602: } else {
! 1603: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1604: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1605: addd(CO,d,t,&s); d = s;
! 1606: dp_rest(g,&t); g = t;
! 1607:
! 1608: }
! 1609: }
! 1610: if ( d )
! 1611: d->sugar = sugar;
! 1612: *rp = d;
1.5 noro 1613: }
1614:
1.66 noro 1615: void dpm_nf_z(NODE b,DPM g,DPM *ps,int full,int multiple,DPM *rp)
1616: {
1.67 ! noro 1617: DPM u,p,d,s,t;
1.66 noro 1618: DP dmy1;
1.67 ! noro 1619: P dmy;
! 1620: NODE l;
! 1621: DMM m,mr;
! 1622: int i,n;
! 1623: int *wb;
! 1624: int hmag;
! 1625: int sugar,psugar;
! 1626:
! 1627: if ( !g ) {
! 1628: *rp = 0; return;
! 1629: }
! 1630: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1631: wb = (int *)ALLOCA(n*sizeof(int));
! 1632: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1633: wb[i] = QTOS((Q)BDY(l));
! 1634:
! 1635: hmag = multiple*HMAG(g);
! 1636: sugar = g->sugar;
! 1637:
! 1638: for ( d = 0; g; ) {
! 1639: for ( u = 0, i = 0; i < n; i++ ) {
! 1640: if ( dpm_redble(g,p = ps[wb[i]]) ) {
! 1641: dpm_red(d,g,p,&t,&u,&dmy,&dmy1);
! 1642: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1643: sugar = MAX(sugar,psugar);
! 1644: if ( !u ) {
! 1645: if ( d )
! 1646: d->sugar = sugar;
! 1647: *rp = d; return;
! 1648: }
! 1649: d = t;
! 1650: break;
! 1651: }
! 1652: }
! 1653: if ( u ) {
! 1654: g = u;
! 1655: if ( d ) {
! 1656: if ( multiple && HMAG(d) > hmag ) {
! 1657: dpm_ptozp2(d,g,&t,&u); d = t; g = u;
! 1658: hmag = multiple*HMAG(d);
! 1659: }
! 1660: } else {
! 1661: if ( multiple && HMAG(g) > hmag ) {
! 1662: dpm_ptozp(g,&t); g = t;
! 1663: hmag = multiple*HMAG(g);
! 1664: }
! 1665: }
! 1666: }
! 1667: else if ( !full ) {
! 1668: if ( g ) {
! 1669: MKDPM(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1670: }
! 1671: *rp = g; return;
! 1672: } else {
! 1673: m = BDY(g); NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos;
! 1674: NEXT(mr) = 0; MKDPM(g->nv,mr,t); t->sugar = mr->dl->td;
! 1675: adddpm(CO,d,t,&s); d = s;
! 1676: dpm_rest(g,&t); g = t;
! 1677: }
! 1678: }
! 1679: if ( d )
! 1680: d->sugar = sugar;
! 1681: *rp = d;
1.66 noro 1682: }
1683:
1.13 noro 1684: /* nf computation over a field */
1685:
1.20 noro 1686: void dp_nf_f(NODE b,DP g,DP *ps,int full,DP *rp)
1.13 noro 1687: {
1.67 ! noro 1688: DP u,p,d,s,t;
! 1689: NODE l;
! 1690: MP m,mr;
! 1691: int i,n;
! 1692: int *wb;
! 1693: int sugar,psugar;
! 1694:
! 1695: if ( !g ) {
! 1696: *rp = 0; return;
! 1697: }
! 1698: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1699: wb = (int *)ALLOCA(n*sizeof(int));
! 1700: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1701: wb[i] = QTOS((Q)BDY(l));
! 1702:
! 1703: sugar = g->sugar;
! 1704: for ( d = 0; g; ) {
! 1705: for ( u = 0, i = 0; i < n; i++ ) {
! 1706: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1707: dp_red_f(g,p,&u);
! 1708: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1709: sugar = MAX(sugar,psugar);
! 1710: if ( !u ) {
! 1711: if ( d )
! 1712: d->sugar = sugar;
! 1713: *rp = d; return;
! 1714: }
! 1715: break;
! 1716: }
! 1717: }
! 1718: if ( u )
! 1719: g = u;
! 1720: else if ( !full ) {
! 1721: if ( g ) {
! 1722: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1723: }
! 1724: *rp = g; return;
! 1725: } else {
! 1726: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1727: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1728: addd(CO,d,t,&s); d = s;
! 1729: dp_rest(g,&t); g = t;
! 1730: }
! 1731: }
! 1732: if ( d )
! 1733: d->sugar = sugar;
! 1734: *rp = d;
1.13 noro 1735: }
1736:
1.66 noro 1737: void dpm_nf_f(NODE b,DPM g,DPM *ps,int full,DPM *rp)
1738: {
1.67 ! noro 1739: DPM u,p,d,s,t;
! 1740: NODE l;
! 1741: DMM m,mr;
! 1742: int i,n;
! 1743: int *wb;
! 1744: int sugar,psugar;
! 1745:
! 1746: if ( !g ) {
! 1747: *rp = 0; return;
! 1748: }
! 1749: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1750: wb = (int *)ALLOCA(n*sizeof(int));
! 1751: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1752: wb[i] = QTOS((Q)BDY(l));
! 1753:
! 1754: sugar = g->sugar;
! 1755: for ( d = 0; g; ) {
! 1756: for ( u = 0, i = 0; i < n; i++ ) {
! 1757: if ( dpm_redble(g,p = ps[wb[i]]) ) {
! 1758: dpm_red_f(g,p,&u);
! 1759: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1760: sugar = MAX(sugar,psugar);
! 1761: if ( !u ) {
! 1762: if ( d )
! 1763: d->sugar = sugar;
! 1764: *rp = d; return;
! 1765: }
! 1766: break;
! 1767: }
! 1768: }
! 1769: if ( u )
! 1770: g = u;
! 1771: else if ( !full ) {
! 1772: if ( g ) {
! 1773: MKDPM(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1774: }
! 1775: *rp = g; return;
! 1776: } else {
! 1777: m = BDY(g); NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos;
! 1778: NEXT(mr) = 0; MKDPM(g->nv,mr,t); t->sugar = mr->dl->td;
! 1779: adddpm(CO,d,t,&s); d = s;
! 1780: dpm_rest(g,&t); g = t;
! 1781: }
! 1782: }
! 1783: if ( d )
! 1784: d->sugar = sugar;
! 1785: *rp = d;
1.66 noro 1786: }
1787:
1.13 noro 1788: /* nf computation over GF(mod) (only for internal use) */
1789:
1.20 noro 1790: void dp_nf_mod(NODE b,DP g,DP *ps,int mod,int full,DP *rp)
1.5 noro 1791: {
1.67 ! noro 1792: DP u,p,d,s,t;
! 1793: P dmy;
! 1794: NODE l;
! 1795: MP m,mr;
! 1796: int sugar,psugar;
! 1797:
! 1798: if ( !g ) {
! 1799: *rp = 0; return;
! 1800: }
! 1801: sugar = g->sugar;
! 1802: for ( d = 0; g; ) {
! 1803: for ( u = 0, l = b; l; l = NEXT(l) ) {
! 1804: if ( dp_redble(g,p = ps[(int)BDY(l)]) ) {
! 1805: dp_red_mod(d,g,p,mod,&t,&u,&dmy);
! 1806: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1807: sugar = MAX(sugar,psugar);
! 1808: if ( !u ) {
! 1809: if ( d )
! 1810: d->sugar = sugar;
! 1811: *rp = d; return;
! 1812: }
! 1813: d = t;
! 1814: break;
! 1815: }
! 1816: }
! 1817: if ( u )
! 1818: g = u;
! 1819: else if ( !full ) {
! 1820: if ( g ) {
! 1821: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1822: }
! 1823: *rp = g; return;
! 1824: } else {
! 1825: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1826: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1827: addmd(CO,mod,d,t,&s); d = s;
! 1828: dp_rest(g,&t); g = t;
! 1829: }
! 1830: }
! 1831: if ( d )
! 1832: d->sugar = sugar;
! 1833: *rp = d;
1.5 noro 1834: }
1835:
1.20 noro 1836: void dp_true_nf_mod(NODE b,DP g,DP *ps,int mod,int full,DP *rp,P *dnp)
1.5 noro 1837: {
1.67 ! noro 1838: DP u,p,d,s,t;
! 1839: NODE l;
! 1840: MP m,mr;
! 1841: int i,n;
! 1842: int *wb;
! 1843: int sugar,psugar;
! 1844: P dn,tdn,tdn1;
! 1845:
! 1846: dn = (P)ONEM;
! 1847: if ( !g ) {
! 1848: *rp = 0; *dnp = dn; return;
! 1849: }
! 1850: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1851: wb = (int *)ALLOCA(n*sizeof(int));
! 1852: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1853: wb[i] = QTOS((Q)BDY(l));
! 1854: sugar = g->sugar;
! 1855: for ( d = 0; g; ) {
! 1856: for ( u = 0, i = 0; i < n; i++ ) {
! 1857: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1858: dp_red_mod(d,g,p,mod,&t,&u,&tdn);
! 1859: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1860: sugar = MAX(sugar,psugar);
! 1861: if ( !u ) {
! 1862: if ( d )
! 1863: d->sugar = sugar;
! 1864: *rp = d; *dnp = dn; return;
! 1865: } else {
! 1866: d = t;
! 1867: mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
! 1868: }
! 1869: break;
! 1870: }
! 1871: }
! 1872: if ( u )
! 1873: g = u;
! 1874: else if ( !full ) {
! 1875: if ( g ) {
! 1876: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1877: }
! 1878: *rp = g; *dnp = dn; return;
! 1879: } else {
! 1880: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1881: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1882: addmd(CO,mod,d,t,&s); d = s;
! 1883: dp_rest(g,&t); g = t;
! 1884: }
! 1885: }
! 1886: if ( d )
! 1887: d->sugar = sugar;
! 1888: *rp = d; *dnp = dn;
1.5 noro 1889: }
1890:
1.20 noro 1891: void _dp_nf_mod_destructive(NODE b,DP g,DP *ps,int mod,int full,DP *rp)
1.5 noro 1892: {
1.67 ! noro 1893: DP u,p,d;
! 1894: NODE l;
! 1895: MP m,mrd;
! 1896: int sugar,psugar,n,h_reducible;
! 1897:
! 1898: if ( !g ) {
! 1899: *rp = 0; return;
! 1900: }
! 1901: sugar = g->sugar;
! 1902: n = g->nv;
! 1903: for ( d = 0; g; ) {
! 1904: for ( h_reducible = 0, l = b; l; l = NEXT(l) ) {
! 1905: if ( dp_redble(g,p = ps[(int)BDY(l)]) ) {
! 1906: h_reducible = 1;
! 1907: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1908: _dp_red_mod_destructive(g,p,mod,&u); g = u;
! 1909: sugar = MAX(sugar,psugar);
! 1910: if ( !g ) {
! 1911: if ( d )
! 1912: d->sugar = sugar;
! 1913: _dptodp(d,rp); _free_dp(d); return;
! 1914: }
! 1915: break;
! 1916: }
! 1917: }
! 1918: if ( !h_reducible ) {
! 1919: /* head term is not reducible */
! 1920: if ( !full ) {
! 1921: if ( g )
! 1922: g->sugar = sugar;
! 1923: _dptodp(g,rp); _free_dp(g); return;
! 1924: } else {
! 1925: m = BDY(g);
! 1926: if ( NEXT(m) ) {
! 1927: BDY(g) = NEXT(m); NEXT(m) = 0;
! 1928: } else {
! 1929: _FREEDP(g); g = 0;
! 1930: }
! 1931: if ( d ) {
! 1932: for ( mrd = BDY(d); NEXT(mrd); mrd = NEXT(mrd) );
! 1933: NEXT(mrd) = m;
! 1934: } else {
! 1935: _MKDP(n,m,d);
! 1936: }
! 1937: }
! 1938: }
! 1939: }
! 1940: if ( d )
! 1941: d->sugar = sugar;
! 1942: _dptodp(d,rp); _free_dp(d);
1.5 noro 1943: }
1.13 noro 1944:
1945: /* reduction by linear base over a field */
1946:
1.20 noro 1947: void dp_lnf_f(DP p1,DP p2,NODE g,DP *r1p,DP *r2p)
1.13 noro 1948: {
1.67 ! noro 1949: DP r1,r2,b1,b2,t,s;
! 1950: Obj c,c1,c2;
! 1951: NODE l,b;
! 1952: int n;
! 1953:
! 1954: if ( !p1 ) {
! 1955: *r1p = p1; *r2p = p2; return;
! 1956: }
! 1957: n = p1->nv;
! 1958: for ( l = g, r1 = p1, r2 = p2; l; l = NEXT(l) ) {
! 1959: if ( !r1 ) {
! 1960: *r1p = r1; *r2p = r2; return;
! 1961: }
! 1962: b = BDY((LIST)BDY(l)); b1 = (DP)BDY(b);
! 1963: if ( dl_equal(n,BDY(r1)->dl,BDY(b1)->dl) ) {
! 1964: b2 = (DP)BDY(NEXT(b));
! 1965: divr(CO,(Obj)ONE,(Obj)BDY(b1)->c,&c1);
! 1966: mulr(CO,c1,(Obj)BDY(r1)->c,&c2); chsgnr(c2,&c);
! 1967: muldc(CO,b1,(Obj)c,&t); addd(CO,r1,t,&s); r1 = s;
! 1968: muldc(CO,b2,(Obj)c,&t); addd(CO,r2,t,&s); r2 = s;
! 1969: }
! 1970: }
! 1971: *r1p = r1; *r2p = r2;
1.13 noro 1972: }
1973:
1974: /* reduction by linear base over GF(mod) */
1.5 noro 1975:
1.20 noro 1976: void dp_lnf_mod(DP p1,DP p2,NODE g,int mod,DP *r1p,DP *r2p)
1.5 noro 1977: {
1.67 ! noro 1978: DP r1,r2,b1,b2,t,s;
! 1979: P c;
! 1980: MQ c1,c2;
! 1981: NODE l,b;
! 1982: int n;
! 1983:
! 1984: if ( !p1 ) {
! 1985: *r1p = p1; *r2p = p2; return;
! 1986: }
! 1987: n = p1->nv;
! 1988: for ( l = g, r1 = p1, r2 = p2; l; l = NEXT(l) ) {
! 1989: if ( !r1 ) {
! 1990: *r1p = r1; *r2p = r2; return;
! 1991: }
! 1992: b = BDY((LIST)BDY(l)); b1 = (DP)BDY(b);
! 1993: if ( dl_equal(n,BDY(r1)->dl,BDY(b1)->dl) ) {
! 1994: b2 = (DP)BDY(NEXT(b));
! 1995: invmq(mod,(MQ)BDY(b1)->c,&c1);
! 1996: mulmq(mod,c1,(MQ)BDY(r1)->c,&c2); chsgnmp(mod,(P)c2,&c);
! 1997: mulmdc(CO,mod,b1,c,&t); addmd(CO,mod,r1,t,&s); r1 = s;
! 1998: mulmdc(CO,mod,b2,c,&t); addmd(CO,mod,r2,t,&s); r2 = s;
! 1999: }
! 2000: }
! 2001: *r1p = r1; *r2p = r2;
1.5 noro 2002: }
2003:
1.20 noro 2004: void dp_nf_tab_mod(DP p,LIST *tab,int mod,DP *rp)
1.5 noro 2005: {
1.67 ! noro 2006: DP s,t,u;
! 2007: MP m;
! 2008: DL h;
! 2009: int i,n;
! 2010:
! 2011: if ( !p ) {
! 2012: *rp = p; return;
! 2013: }
! 2014: n = p->nv;
! 2015: for ( s = 0, i = 0, m = BDY(p); m; m = NEXT(m) ) {
! 2016: h = m->dl;
! 2017: while ( !dl_equal(n,h,BDY((DP)BDY(BDY(tab[i])))->dl ) )
! 2018: i++;
! 2019: mulmdc(CO,mod,(DP)BDY(NEXT(BDY(tab[i]))),(P)m->c,&t);
! 2020: addmd(CO,mod,s,t,&u); s = u;
! 2021: }
! 2022: *rp = s;
1.24 noro 2023: }
2024:
2025: void dp_nf_tab_f(DP p,LIST *tab,DP *rp)
2026: {
1.67 ! noro 2027: DP s,t,u;
! 2028: MP m;
! 2029: DL h;
! 2030: int i,n;
! 2031:
! 2032: if ( !p ) {
! 2033: *rp = p; return;
! 2034: }
! 2035: n = p->nv;
! 2036: for ( s = 0, i = 0, m = BDY(p); m; m = NEXT(m) ) {
! 2037: h = m->dl;
! 2038: while ( !dl_equal(n,h,BDY((DP)BDY(BDY(tab[i])))->dl ) )
! 2039: i++;
! 2040: muldc(CO,(DP)BDY(NEXT(BDY(tab[i]))),m->c,&t);
! 2041: addd(CO,s,t,&u); s = u;
! 2042: }
! 2043: *rp = s;
1.5 noro 2044: }
2045:
1.7 noro 2046: /*
2047: * setting flags
1.30 noro 2048: * call create_order_spec with vl=0 to set old type order.
1.7 noro 2049: *
2050: */
2051:
1.27 noro 2052: int create_order_spec(VL vl,Obj obj,struct order_spec **specp)
1.5 noro 2053: {
1.67 ! noro 2054: int i,j,n,s,row,col,ret,wlen;
! 2055: struct order_spec *spec;
! 2056: struct order_pair *l;
1.62 noro 2057: Obj wp,wm;
1.67 ! noro 2058: NODE node,t,tn,wpair;
! 2059: MAT m;
! 2060: VECT v;
! 2061: pointer **b,*bv;
! 2062: int **w;
! 2063:
! 2064: if ( vl && obj && OID(obj) == O_LIST ) {
! 2065: ret = create_composite_order_spec(vl,(LIST)obj,specp);
! 2066: if ( show_orderspec )
! 2067: print_composite_order_spec(*specp);
! 2068: return ret;
! 2069: }
! 2070:
! 2071: *specp = spec = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2072: if ( !obj || NUM(obj) ) {
! 2073: spec->id = 0; spec->obj = obj;
! 2074: spec->ord.simple = QTOS((Q)obj);
! 2075: return 1;
! 2076: } else if ( OID(obj) == O_LIST ) {
1.62 noro 2077: /* module order; obj = [0|1,w,ord] or [0|1,ord] */
1.67 ! noro 2078: node = BDY((LIST)obj);
! 2079: if ( !BDY(node) || NUM(BDY(node)) ) {
1.62 noro 2080: switch ( length(node) ) {
2081: case 2:
1.67 ! noro 2082: create_order_spec(0,(Obj)BDY(NEXT(node)),&spec);
! 2083: spec->id += 256; spec->obj = obj;
1.62 noro 2084: spec->top_weight = 0;
2085: spec->module_rank = 0;
2086: spec->module_top_weight = 0;
1.67 ! noro 2087: spec->ispot = (BDY(node)!=0);
! 2088: if ( spec->ispot ) {
! 2089: n = QTOS((Q)BDY(node));
! 2090: if ( n < 0 )
! 2091: spec->pot_nelim = -n;
! 2092: else
! 2093: spec->pot_nelim = 0;
! 2094: }
1.62 noro 2095: break;
2096:
2097: case 3:
1.67 ! noro 2098: create_order_spec(0,(Obj)BDY(NEXT(NEXT(node))),&spec);
! 2099: spec->id += 256; spec->obj = obj;
! 2100: spec->ispot = (BDY(node)!=0);
1.62 noro 2101: node = NEXT(node);
2102: if ( !BDY(node) || OID(BDY(node)) != O_LIST )
1.67 ! noro 2103: error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
1.62 noro 2104: wpair = BDY((LIST)BDY(node));
2105: if ( length(wpair) != 2 )
1.67 ! noro 2106: error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
1.62 noro 2107:
2108: wp = BDY(wpair);
2109: wm = BDY(NEXT(wpair));
2110: if ( !wp || OID(wp) != O_LIST || !wm || OID(wm) != O_LIST )
1.67 ! noro 2111: error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
1.62 noro 2112: spec->nv = length(BDY((LIST)wp));
2113: spec->top_weight = (int *)MALLOC_ATOMIC(spec->nv*sizeof(int));
1.67 ! noro 2114: for ( i = 0, t = BDY((LIST)wp); i < spec->nv; t = NEXT(t), i++ )
1.62 noro 2115: spec->top_weight[i] = QTOS((Q)BDY(t));
2116:
2117: spec->module_rank = length(BDY((LIST)wm));
2118: spec->module_top_weight = (int *)MALLOC_ATOMIC(spec->module_rank*sizeof(int));
1.67 ! noro 2119: for ( i = 0, t = BDY((LIST)wm); i < spec->module_rank; t = NEXT(t), i++ )
1.62 noro 2120: spec->module_top_weight[i] = QTOS((Q)BDY(t));
2121: break;
2122: default:
1.67 ! noro 2123: error("create_order_spec : invalid arguments for module order");
1.62 noro 2124: }
2125:
1.67 ! noro 2126: *specp = spec;
! 2127: return 1;
! 2128: } else {
1.62 noro 2129: /* block order in polynomial ring */
1.67 ! noro 2130: for ( n = 0, t = node; t; t = NEXT(t), n++ );
! 2131: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
! 2132: for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {
! 2133: tn = BDY((LIST)BDY(t)); l[i].order = QTOS((Q)BDY(tn));
! 2134: tn = NEXT(tn); l[i].length = QTOS((Q)BDY(tn));
! 2135: s += l[i].length;
! 2136: }
! 2137: spec->id = 1; spec->obj = obj;
! 2138: spec->ord.block.order_pair = l;
! 2139: spec->ord.block.length = n; spec->nv = s;
! 2140: return 1;
! 2141: }
! 2142: } else if ( OID(obj) == O_MAT ) {
! 2143: m = (MAT)obj; row = m->row; col = m->col; b = BDY(m);
! 2144: w = almat(row,col);
! 2145: for ( i = 0; i < row; i++ )
! 2146: for ( j = 0; j < col; j++ )
! 2147: w[i][j] = QTOS((Q)b[i][j]);
! 2148: spec->id = 2; spec->obj = obj;
! 2149: spec->nv = col; spec->ord.matrix.row = row;
! 2150: spec->ord.matrix.matrix = w;
! 2151: return 1;
! 2152: } else
! 2153: return 0;
1.5 noro 2154: }
2155:
1.28 noro 2156: void print_composite_order_spec(struct order_spec *spec)
2157: {
1.67 ! noro 2158: int nv,n,len,i,j,k,start;
! 2159: struct weight_or_block *worb;
1.28 noro 2160:
1.67 ! noro 2161: nv = spec->nv;
! 2162: n = spec->ord.composite.length;
! 2163: worb = spec->ord.composite.w_or_b;
! 2164: for ( i = 0; i < n; i++, worb++ ) {
! 2165: len = worb->length;
! 2166: printf("[ ");
! 2167: switch ( worb->type ) {
! 2168: case IS_DENSE_WEIGHT:
! 2169: for ( j = 0; j < len; j++ )
! 2170: printf("%d ",worb->body.dense_weight[j]);
! 2171: for ( ; j < nv; j++ )
! 2172: printf("0 ");
! 2173: break;
! 2174: case IS_SPARSE_WEIGHT:
! 2175: for ( j = 0, k = 0; j < nv; j++ )
! 2176: if ( j == worb->body.sparse_weight[k].pos )
! 2177: printf("%d ",worb->body.sparse_weight[k++].value);
! 2178: else
! 2179: printf("0 ");
! 2180: break;
! 2181: case IS_BLOCK:
! 2182: start = worb->body.block.start;
! 2183: for ( j = 0; j < start; j++ ) printf("0 ");
! 2184: switch ( worb->body.block.order ) {
! 2185: case 0:
! 2186: for ( k = 0; k < len; k++, j++ ) printf("R ");
! 2187: break;
! 2188: case 1:
! 2189: for ( k = 0; k < len; k++, j++ ) printf("G ");
! 2190: break;
! 2191: case 2:
! 2192: for ( k = 0; k < len; k++, j++ ) printf("L ");
! 2193: break;
! 2194: }
! 2195: for ( ; j < nv; j++ ) printf("0 ");
! 2196: break;
! 2197: }
! 2198: printf("]\n");
! 2199: }
1.38 noro 2200: }
2201:
2202: struct order_spec *append_block(struct order_spec *spec,
1.67 ! noro 2203: int nv,int nalg,int ord)
1.38 noro 2204: {
1.67 ! noro 2205: MAT m,mat;
! 2206: int i,j,row,col,n;
! 2207: Q **b,**wp;
! 2208: int **w;
! 2209: NODE t,s,s0;
! 2210: struct order_pair *l,*l0;
! 2211: int n0,nv0;
! 2212: LIST list0,list1,list;
! 2213: Q oq,nq;
! 2214: struct order_spec *r;
! 2215:
! 2216: r = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2217: switch ( spec->id ) {
! 2218: case 0:
! 2219: STOQ(spec->ord.simple,oq); STOQ(nv,nq);
! 2220: t = mknode(2,oq,nq); MKLIST(list0,t);
! 2221: STOQ(ord,oq); STOQ(nalg,nq);
! 2222: t = mknode(2,oq,nq); MKLIST(list1,t);
! 2223: t = mknode(2,list0,list1); MKLIST(list,t);
! 2224: l = (struct order_pair *)MALLOC_ATOMIC(2*sizeof(struct order_pair));
! 2225: l[0].order = spec->ord.simple; l[0].length = nv;
! 2226: l[1].order = ord; l[1].length = nalg;
! 2227: r->id = 1; r->obj = (Obj)list;
! 2228: r->ord.block.order_pair = l;
! 2229: r->ord.block.length = 2;
! 2230: r->nv = nv+nalg;
! 2231: break;
! 2232: case 1:
! 2233: if ( spec->nv != nv )
! 2234: error("append_block : number of variables mismatch");
! 2235: l0 = spec->ord.block.order_pair;
! 2236: n0 = spec->ord.block.length;
! 2237: nv0 = spec->nv;
! 2238: list0 = (LIST)spec->obj;
! 2239: n = n0+1;
! 2240: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
! 2241: for ( i = 0; i < n0; i++ )
! 2242: l[i] = l0[i];
! 2243: l[i].order = ord; l[i].length = nalg;
! 2244: for ( t = BDY(list0), s0 = 0; t; t = NEXT(t) ) {
! 2245: NEXTNODE(s0,s); BDY(s) = BDY(t);
! 2246: }
! 2247: STOQ(ord,oq); STOQ(nalg,nq);
! 2248: t = mknode(2,oq,nq); MKLIST(list,t);
! 2249: NEXTNODE(s0,s); BDY(s) = (pointer)list; NEXT(s) = 0;
! 2250: MKLIST(list,s0);
! 2251: r->id = 1; r->obj = (Obj)list;
! 2252: r->ord.block.order_pair = l;
! 2253: r->ord.block.length = n;
! 2254: r->nv = nv+nalg;
! 2255: break;
! 2256: case 2:
! 2257: if ( spec->nv != nv )
! 2258: error("append_block : number of variables mismatch");
! 2259: m = (MAT)spec->obj;
! 2260: row = m->row; col = m->col; b = (Q **)BDY(m);
! 2261: w = almat(row+nalg,col+nalg);
! 2262: MKMAT(mat,row+nalg,col+nalg); wp = (Q **)BDY(mat);
! 2263: for ( i = 0; i < row; i++ )
! 2264: for ( j = 0; j < col; j++ ) {
! 2265: w[i][j] = QTOS(b[i][j]);
! 2266: wp[i][j] = b[i][j];
! 2267: }
! 2268: for ( i = 0; i < nalg; i++ ) {
! 2269: w[i+row][i+col] = 1;
! 2270: wp[i+row][i+col] = ONE;
! 2271: }
! 2272: r->id = 2; r->obj = (Obj)mat;
! 2273: r->nv = col+nalg; r->ord.matrix.row = row+nalg;
! 2274: r->ord.matrix.matrix = w;
! 2275: break;
! 2276: case 3:
! 2277: default:
! 2278: /* XXX */
! 2279: error("append_block : not implemented yet");
! 2280: }
! 2281: return r;
1.28 noro 2282: }
2283:
1.37 noro 2284: int comp_sw(struct sparse_weight *a, struct sparse_weight *b)
2285: {
1.67 ! noro 2286: if ( a->pos > b->pos ) return 1;
! 2287: else if ( a->pos < b->pos ) return -1;
! 2288: else return 0;
1.37 noro 2289: }
2290:
1.27 noro 2291: /* order = [w_or_b, w_or_b, ... ] */
2292: /* w_or_b = w or b */
2293: /* w = [1,2,...] or [x,1,y,2,...] */
2294: /* b = [@lex,x,y,...,z] etc */
2295:
2296: int create_composite_order_spec(VL vl,LIST order,struct order_spec **specp)
2297: {
1.67 ! noro 2298: NODE wb,t,p;
! 2299: struct order_spec *spec;
! 2300: VL tvl;
! 2301: int n,i,j,k,l,start,end,len,w;
! 2302: int *dw;
! 2303: struct sparse_weight *sw;
! 2304: struct weight_or_block *w_or_b;
! 2305: Obj a0;
! 2306: NODE a;
! 2307: V v,sv,ev;
! 2308: SYMBOL sym;
! 2309: int *top;
! 2310:
! 2311: /* l = number of vars in vl */
! 2312: for ( l = 0, tvl = vl; tvl; tvl = NEXT(tvl), l++ );
! 2313: /* n = number of primitives in order */
! 2314: wb = BDY(order);
! 2315: n = length(wb);
! 2316: *specp = spec = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2317: spec->id = 3;
! 2318: spec->obj = (Obj)order;
! 2319: spec->nv = l;
! 2320: spec->ord.composite.length = n;
! 2321: w_or_b = spec->ord.composite.w_or_b = (struct weight_or_block *)
! 2322: MALLOC(sizeof(struct weight_or_block)*(n+1));
! 2323:
! 2324: /* top : register the top variable in each w_or_b specification */
! 2325: top = (int *)ALLOCA(l*sizeof(int));
! 2326: for ( i = 0; i < l; i++ ) top[i] = 0;
! 2327:
! 2328: for ( t = wb, i = 0; t; t = NEXT(t), i++ ) {
! 2329: if ( !BDY(t) || OID((Obj)BDY(t)) != O_LIST )
! 2330: error("a list of lists must be specified for the key \"order\"");
! 2331: a = BDY((LIST)BDY(t));
! 2332: len = length(a);
! 2333: a0 = (Obj)BDY(a);
! 2334: if ( !a0 || OID(a0) == O_N ) {
! 2335: /* a is a dense weight vector */
! 2336: dw = (int *)MALLOC(sizeof(int)*len);
! 2337: for ( j = 0, p = a; j < len; p = NEXT(p), j++ ) {
! 2338: if ( !INT((Q)BDY(p)) )
! 2339: error("a dense weight vector must be specified as a list of integers");
! 2340: dw[j] = QTOS((Q)BDY(p));
! 2341: }
! 2342: w_or_b[i].type = IS_DENSE_WEIGHT;
! 2343: w_or_b[i].length = len;
! 2344: w_or_b[i].body.dense_weight = dw;
! 2345:
! 2346: /* find the top */
! 2347: for ( k = 0; k < len && !dw[k]; k++ );
! 2348: if ( k < len ) top[k] = 1;
! 2349:
! 2350: } else if ( OID(a0) == O_P ) {
! 2351: /* a is a sparse weight vector */
! 2352: len >>= 1;
! 2353: sw = (struct sparse_weight *)
! 2354: MALLOC(sizeof(struct sparse_weight)*len);
! 2355: for ( j = 0, p = a; j < len; j++ ) {
! 2356: if ( !BDY(p) || OID((P)BDY(p)) != O_P )
! 2357: error("a sparse weight vector must be specified as [var1,weight1,...]");
! 2358: v = VR((P)BDY(p)); p = NEXT(p);
! 2359: for ( tvl = vl, k = 0; tvl && tvl->v != v;
! 2360: k++, tvl = NEXT(tvl) );
! 2361: if ( !tvl )
! 2362: error("invalid variable name in a sparse weight vector");
! 2363: sw[j].pos = k;
! 2364: if ( !INT((Q)BDY(p)) )
! 2365: error("a sparse weight vector must be specified as [var1,weight1,...]");
! 2366: sw[j].value = QTOS((Q)BDY(p)); p = NEXT(p);
! 2367: }
! 2368: qsort(sw,len,sizeof(struct sparse_weight),
! 2369: (int (*)(const void *,const void *))comp_sw);
! 2370: w_or_b[i].type = IS_SPARSE_WEIGHT;
! 2371: w_or_b[i].length = len;
! 2372: w_or_b[i].body.sparse_weight = sw;
! 2373:
! 2374: /* find the top */
! 2375: for ( k = 0; k < len && !sw[k].value; k++ );
! 2376: if ( k < len ) top[sw[k].pos] = 1;
! 2377: } else if ( OID(a0) == O_RANGE ) {
! 2378: /* [range(v1,v2),w] */
! 2379: sv = VR((P)(((RANGE)a0)->start));
! 2380: ev = VR((P)(((RANGE)a0)->end));
! 2381: for ( tvl = vl, start = 0; tvl && tvl->v != sv; start++, tvl = NEXT(tvl) );
! 2382: if ( !tvl )
! 2383: error("invalid range");
! 2384: for ( end = start; tvl && tvl->v != ev; end++, tvl = NEXT(tvl) );
! 2385: if ( !tvl )
! 2386: error("invalid range");
! 2387: len = end-start+1;
! 2388: sw = (struct sparse_weight *)
! 2389: MALLOC(sizeof(struct sparse_weight)*len);
! 2390: w = QTOS((Q)BDY(NEXT(a)));
! 2391: for ( tvl = vl, k = 0; k < start; k++, tvl = NEXT(tvl) );
! 2392: for ( j = 0 ; k <= end; k++, tvl = NEXT(tvl), j++ ) {
! 2393: sw[j].pos = k;
! 2394: sw[j].value = w;
! 2395: }
! 2396: w_or_b[i].type = IS_SPARSE_WEIGHT;
! 2397: w_or_b[i].length = len;
! 2398: w_or_b[i].body.sparse_weight = sw;
! 2399:
! 2400: /* register the top */
! 2401: if ( w ) top[start] = 1;
! 2402: } else if ( OID(a0) == O_SYMBOL ) {
! 2403: /* a is a block */
! 2404: sym = (SYMBOL)a0; a = NEXT(a); len--;
! 2405: if ( OID((Obj)BDY(a)) == O_RANGE ) {
! 2406: sv = VR((P)(((RANGE)BDY(a))->start));
! 2407: ev = VR((P)(((RANGE)BDY(a))->end));
! 2408: for ( tvl = vl, start = 0; tvl && tvl->v != sv; start++, tvl = NEXT(tvl) );
! 2409: if ( !tvl )
! 2410: error("invalid range");
! 2411: for ( end = start; tvl && tvl->v != ev; end++, tvl = NEXT(tvl) );
! 2412: if ( !tvl )
! 2413: error("invalid range");
! 2414: len = end-start+1;
! 2415: } else {
! 2416: for ( start = 0, tvl = vl; tvl->v != VR((P)BDY(a));
! 2417: tvl = NEXT(tvl), start++ );
! 2418: for ( p = NEXT(a), tvl = NEXT(tvl); p;
! 2419: p = NEXT(p), tvl = NEXT(tvl) ) {
! 2420: if ( !BDY(p) || OID((P)BDY(p)) != O_P )
! 2421: error("a block must be specified as [ordsymbol,var1,var2,...]");
! 2422: if ( tvl->v != VR((P)BDY(p)) ) break;
! 2423: }
! 2424: if ( p )
! 2425: error("a block must be contiguous in the variable list");
! 2426: }
! 2427: w_or_b[i].type = IS_BLOCK;
! 2428: w_or_b[i].length = len;
! 2429: w_or_b[i].body.block.start = start;
! 2430: if ( !strcmp(sym->name,"@grlex") )
! 2431: w_or_b[i].body.block.order = 0;
! 2432: else if ( !strcmp(sym->name,"@glex") )
! 2433: w_or_b[i].body.block.order = 1;
! 2434: else if ( !strcmp(sym->name,"@lex") )
! 2435: w_or_b[i].body.block.order = 2;
! 2436: else
! 2437: error("invalid ordername");
! 2438: /* register the tops */
! 2439: for ( j = 0, k = start; j < len; j++, k++ )
! 2440: top[k] = 1;
! 2441: }
! 2442: }
! 2443: for ( k = 0; k < l && top[k]; k++ );
! 2444: if ( k < l ) {
! 2445: /* incomplete order specification; add @grlex */
! 2446: w_or_b[n].type = IS_BLOCK;
! 2447: w_or_b[n].length = l;
! 2448: w_or_b[n].body.block.start = 0;
! 2449: w_or_b[n].body.block.order = 0;
! 2450: spec->ord.composite.length = n+1;
! 2451: }
1.27 noro 2452: }
2453:
1.35 noro 2454: /* module order spec */
2455:
2456: void create_modorder_spec(int id,LIST shift,struct modorder_spec **s)
2457: {
1.67 ! noro 2458: struct modorder_spec *spec;
! 2459: NODE n,t;
! 2460: LIST list;
! 2461: int *ds;
! 2462: int i,l;
! 2463: Q q;
! 2464:
! 2465: *s = spec = (struct modorder_spec *)MALLOC(sizeof(struct modorder_spec));
! 2466: spec->id = id;
! 2467: if ( shift ) {
! 2468: n = BDY(shift);
! 2469: spec->len = l = length(n);
! 2470: spec->degree_shift = ds = (int *)MALLOC_ATOMIC(l*sizeof(int));
! 2471: for ( t = n, i = 0; t; t = NEXT(t), i++ )
! 2472: ds[i] = QTOS((Q)BDY(t));
! 2473: } else {
! 2474: spec->len = 0;
! 2475: spec->degree_shift = 0;
! 2476: }
! 2477: STOQ(id,q);
! 2478: n = mknode(2,q,shift);
! 2479: MKLIST(list,n);
! 2480: spec->obj = (Obj)list;
1.35 noro 2481: }
2482:
1.7 noro 2483: /*
2484: * converters
2485: *
2486: */
2487:
1.20 noro 2488: void dp_homo(DP p,DP *rp)
1.5 noro 2489: {
1.67 ! noro 2490: MP m,mr,mr0;
! 2491: int i,n,nv,td;
! 2492: DL dl,dlh;
! 2493:
! 2494: if ( !p )
! 2495: *rp = 0;
! 2496: else {
! 2497: n = p->nv; nv = n + 1;
! 2498: m = BDY(p); td = sugard(m);
! 2499: for ( mr0 = 0; m; m = NEXT(m) ) {
! 2500: NEXTMP(mr0,mr); mr->c = m->c;
! 2501: dl = m->dl;
! 2502: mr->dl = dlh = (DL)MALLOC_ATOMIC((nv+1)*sizeof(int));
! 2503: dlh->td = td;
! 2504: for ( i = 0; i < n; i++ )
! 2505: dlh->d[i] = dl->d[i];
! 2506: dlh->d[n] = td - dl->td;
! 2507: }
! 2508: NEXT(mr) = 0; MKDP(nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2509: }
1.5 noro 2510: }
2511:
1.20 noro 2512: void dp_dehomo(DP p,DP *rp)
1.5 noro 2513: {
1.67 ! noro 2514: MP m,mr,mr0;
! 2515: int i,n,nv;
! 2516: DL dl,dlh;
! 2517:
! 2518: if ( !p )
! 2519: *rp = 0;
! 2520: else {
! 2521: n = p->nv; nv = n - 1;
! 2522: m = BDY(p);
! 2523: for ( mr0 = 0; m; m = NEXT(m) ) {
! 2524: NEXTMP(mr0,mr); mr->c = m->c;
! 2525: dlh = m->dl;
! 2526: mr->dl = dl = (DL)MALLOC_ATOMIC((nv+1)*sizeof(int));
! 2527: dl->td = dlh->td - dlh->d[nv];
! 2528: for ( i = 0; i < nv; i++ )
! 2529: dl->d[i] = dlh->d[i];
! 2530: }
! 2531: NEXT(mr) = 0; MKDP(nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2532: }
1.5 noro 2533: }
2534:
1.20 noro 2535: void dp_mod(DP p,int mod,NODE subst,DP *rp)
1.5 noro 2536: {
1.67 ! noro 2537: MP m,mr,mr0;
! 2538: P t,s,s1;
! 2539: V v;
! 2540: NODE tn;
! 2541:
! 2542: if ( !p )
! 2543: *rp = 0;
! 2544: else {
! 2545: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 2546: for ( tn = subst, s = (P)m->c; tn; tn = NEXT(tn) ) {
! 2547: v = VR((P)BDY(tn)); tn = NEXT(tn);
! 2548: substp(CO,s,v,(P)BDY(tn),&s1); s = s1;
! 2549: }
! 2550: ptomp(mod,s,&t);
! 2551: if ( t ) {
! 2552: NEXTMP(mr0,mr); mr->c = (Obj)t; mr->dl = m->dl;
! 2553: }
! 2554: }
! 2555: if ( mr0 ) {
! 2556: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2557: } else
! 2558: *rp = 0;
! 2559: }
1.5 noro 2560: }
2561:
1.20 noro 2562: void dp_rat(DP p,DP *rp)
1.5 noro 2563: {
1.67 ! noro 2564: MP m,mr,mr0;
1.5 noro 2565:
1.67 ! noro 2566: if ( !p )
! 2567: *rp = 0;
! 2568: else {
! 2569: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 2570: NEXTMP(mr0,mr); mptop((P)m->c,(P *)&mr->c); mr->dl = m->dl;
! 2571: }
! 2572: if ( mr0 ) {
! 2573: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2574: } else
! 2575: *rp = 0;
! 2576: }
1.5 noro 2577: }
2578:
2579:
1.27 noro 2580: void homogenize_order(struct order_spec *old,int n,struct order_spec **newp)
1.5 noro 2581: {
1.67 ! noro 2582: struct order_pair *l;
! 2583: int length,nv,row,i,j;
! 2584: int **newm,**oldm;
! 2585: struct order_spec *new;
! 2586: int onv,nnv,nlen,olen,owlen;
! 2587: struct weight_or_block *owb,*nwb;
! 2588:
! 2589: *newp = new = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2590: switch ( old->id ) {
! 2591: case 0:
! 2592: switch ( old->ord.simple ) {
! 2593: case 0:
! 2594: new->id = 0; new->ord.simple = 0; break;
! 2595: case 1:
! 2596: l = (struct order_pair *)
! 2597: MALLOC_ATOMIC(2*sizeof(struct order_pair));
! 2598: l[0].length = n; l[0].order = 1;
! 2599: l[1].length = 1; l[1].order = 2;
! 2600: new->id = 1;
! 2601: new->ord.block.order_pair = l;
! 2602: new->ord.block.length = 2; new->nv = n+1;
! 2603: break;
! 2604: case 2:
! 2605: new->id = 0; new->ord.simple = 1; break;
! 2606: case 3: case 4: case 5:
! 2607: new->id = 0; new->ord.simple = old->ord.simple+3;
! 2608: dp_nelim = n-1; break;
! 2609: case 6: case 7: case 8: case 9:
! 2610: new->id = 0; new->ord.simple = old->ord.simple; break;
! 2611: default:
! 2612: error("homogenize_order : invalid input");
! 2613: }
! 2614: break;
! 2615: case 1: case 257:
! 2616: length = old->ord.block.length;
! 2617: l = (struct order_pair *)
! 2618: MALLOC_ATOMIC((length+1)*sizeof(struct order_pair));
! 2619: bcopy((char *)old->ord.block.order_pair,(char *)l,length*sizeof(struct order_pair));
! 2620: l[length].order = 2; l[length].length = 1;
! 2621: new->id = old->id; new->nv = n+1;
! 2622: new->ord.block.order_pair = l;
! 2623: new->ord.block.length = length+1;
! 2624: new->ispot = old->ispot;
! 2625: break;
! 2626: case 2: case 258:
! 2627: nv = old->nv; row = old->ord.matrix.row;
! 2628: oldm = old->ord.matrix.matrix; newm = almat(row+1,nv+1);
! 2629: for ( i = 0; i <= nv; i++ )
! 2630: newm[0][i] = 1;
! 2631: for ( i = 0; i < row; i++ ) {
! 2632: for ( j = 0; j < nv; j++ )
! 2633: newm[i+1][j] = oldm[i][j];
! 2634: newm[i+1][j] = 0;
! 2635: }
! 2636: new->id = old->id; new->nv = nv+1;
! 2637: new->ord.matrix.row = row+1; new->ord.matrix.matrix = newm;
! 2638: new->ispot = old->ispot;
! 2639: break;
! 2640: case 3: case 259:
! 2641: onv = old->nv;
! 2642: nnv = onv+1;
! 2643: olen = old->ord.composite.length;
! 2644: nlen = olen+1;
! 2645: owb = old->ord.composite.w_or_b;
! 2646: nwb = (struct weight_or_block *)
! 2647: MALLOC(nlen*sizeof(struct weight_or_block));
! 2648: for ( i = 0; i < olen; i++ ) {
! 2649: nwb[i].type = owb[i].type;
! 2650: switch ( owb[i].type ) {
! 2651: case IS_DENSE_WEIGHT:
! 2652: owlen = owb[i].length;
! 2653: nwb[i].length = owlen+1;
! 2654: nwb[i].body.dense_weight = (int *)MALLOC((owlen+1)*sizeof(int));
! 2655: for ( j = 0; j < owlen; j++ )
! 2656: nwb[i].body.dense_weight[j] = owb[i].body.dense_weight[j];
! 2657: nwb[i].body.dense_weight[owlen] = 0;
! 2658: break;
! 2659: case IS_SPARSE_WEIGHT:
! 2660: nwb[i].length = owb[i].length;
! 2661: nwb[i].body.sparse_weight = owb[i].body.sparse_weight;
! 2662: break;
! 2663: case IS_BLOCK:
! 2664: nwb[i].length = owb[i].length;
! 2665: nwb[i].body.block = owb[i].body.block;
! 2666: break;
! 2667: }
! 2668: }
! 2669: nwb[i].type = IS_SPARSE_WEIGHT;
! 2670: nwb[i].body.sparse_weight =
! 2671: (struct sparse_weight *)MALLOC(sizeof(struct sparse_weight));
! 2672: nwb[i].body.sparse_weight[0].pos = onv;
! 2673: nwb[i].body.sparse_weight[0].value = 1;
! 2674: new->id = old->id;
! 2675: new->nv = nnv;
! 2676: new->ord.composite.length = nlen;
! 2677: new->ord.composite.w_or_b = nwb;
! 2678: new->ispot = old->ispot;
! 2679: print_composite_order_spec(new);
! 2680: break;
! 2681: case 256: /* simple module order */
! 2682: switch ( old->ord.simple ) {
! 2683: case 0:
! 2684: new->id = 256; new->ord.simple = 0; break;
! 2685: case 1:
! 2686: l = (struct order_pair *)
! 2687: MALLOC_ATOMIC(2*sizeof(struct order_pair));
! 2688: l[0].length = n; l[0].order = old->ord.simple;
! 2689: l[1].length = 1; l[1].order = 2;
! 2690: new->id = 257;
! 2691: new->ord.block.order_pair = l;
! 2692: new->ord.block.length = 2; new->nv = n+1;
! 2693: break;
! 2694: case 2:
! 2695: new->id = 256; new->ord.simple = 1; break;
! 2696: default:
! 2697: error("homogenize_order : invalid input");
! 2698: }
! 2699: new->ispot = old->ispot;
! 2700: break;
! 2701: default:
! 2702: error("homogenize_order : invalid input");
! 2703: }
1.7 noro 2704: }
2705:
1.20 noro 2706: void qltozl(Q *w,int n,Q *dvr)
1.7 noro 2707: {
1.67 ! noro 2708: N nm,dn;
! 2709: N g,l1,l2,l3;
! 2710: Q c,d;
! 2711: int i;
! 2712: struct oVECT v;
! 2713:
! 2714: for ( i = 0; i < n; i++ )
! 2715: if ( w[i] && !INT(w[i]) )
! 2716: break;
! 2717: if ( i == n ) {
! 2718: v.id = O_VECT; v.len = n; v.body = (pointer *)w;
! 2719: igcdv(&v,dvr); return;
! 2720: }
! 2721: for ( i = 0; !w[i]; i++ );
! 2722: c = w[i]; nm = NM(c); dn = INT(c) ? ONEN : DN(c);
! 2723: for ( i++; i < n; i++ ) {
! 2724: c = w[i];
! 2725: if ( !c ) continue;
! 2726: l1 = INT(c) ? ONEN : DN(c);
! 2727: gcdn(nm,NM(c),&g); nm = g;
! 2728: gcdn(dn,l1,&l2); muln(dn,l1,&l3); divsn(l3,l2,&dn);
! 2729: }
! 2730: if ( UNIN(dn) )
! 2731: NTOQ(nm,1,d);
! 2732: else
! 2733: NDTOQ(nm,dn,1,d);
! 2734: *dvr = d;
1.7 noro 2735: }
1.5 noro 2736:
1.20 noro 2737: int comp_nm(Q *a,Q *b)
1.7 noro 2738: {
1.67 ! noro 2739: return cmpn((*a)?NM(*a):0,(*b)?NM(*b):0);
1.7 noro 2740: }
2741:
1.20 noro 2742: void sortbynm(Q *w,int n)
1.7 noro 2743: {
1.67 ! noro 2744: qsort(w,n,sizeof(Q),(int (*)(const void *,const void *))comp_nm);
1.7 noro 2745: }
1.5 noro 2746:
2747:
1.7 noro 2748: /*
2749: * simple operations
2750: *
2751: */
1.5 noro 2752:
1.20 noro 2753: int dp_redble(DP p1,DP p2)
1.7 noro 2754: {
1.67 ! noro 2755: int i,n;
! 2756: DL d1,d2;
1.5 noro 2757:
1.67 ! noro 2758: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 2759: if ( d1->td < d2->td )
! 2760: return 0;
! 2761: else {
! 2762: for ( i = 0, n = p1->nv; i < n; i++ )
! 2763: if ( d1->d[i] < d2->d[i] )
! 2764: return 0;
! 2765: return 1;
! 2766: }
1.5 noro 2767: }
2768:
1.66 noro 2769: int dpm_redble(DPM p1,DPM p2)
2770: {
1.67 ! noro 2771: int i,n;
! 2772: DL d1,d2;
1.66 noro 2773:
2774: if ( BDY(p1)->pos != BDY(p2)->pos ) return 0;
1.67 ! noro 2775: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 2776: if ( d1->td < d2->td )
! 2777: return 0;
! 2778: else {
! 2779: for ( i = 0, n = p1->nv; i < n; i++ )
! 2780: if ( d1->d[i] < d2->d[i] )
! 2781: return 0;
! 2782: return 1;
! 2783: }
1.66 noro 2784: }
2785:
2786:
1.20 noro 2787: void dp_subd(DP p1,DP p2,DP *rp)
1.5 noro 2788: {
1.67 ! noro 2789: int i,n;
! 2790: DL d1,d2,d;
! 2791: MP m;
! 2792: DP s;
! 2793:
! 2794: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 2795: NEWDL(d,n); d->td = d1->td - d2->td;
! 2796: for ( i = 0; i < n; i++ )
! 2797: d->d[i] = d1->d[i]-d2->d[i];
! 2798: NEWMP(m); m->dl = d; m->c = (Obj)ONE; NEXT(m) = 0;
! 2799: MKDP(n,m,s); s->sugar = d->td;
! 2800: *rp = s;
1.7 noro 2801: }
2802:
1.20 noro 2803: void dltod(DL d,int n,DP *rp)
1.7 noro 2804: {
1.67 ! noro 2805: MP m;
! 2806: DP s;
1.7 noro 2807:
1.67 ! noro 2808: NEWMP(m); m->dl = d; m->c = (Obj)ONE; NEXT(m) = 0;
! 2809: MKDP(n,m,s); s->sugar = d->td;
! 2810: *rp = s;
1.5 noro 2811: }
2812:
1.20 noro 2813: void dp_hm(DP p,DP *rp)
1.5 noro 2814: {
1.67 ! noro 2815: MP m,mr;
1.5 noro 2816:
1.67 ! noro 2817: if ( !p )
! 2818: *rp = 0;
! 2819: else {
! 2820: m = BDY(p);
! 2821: NEWMP(mr); mr->dl = m->dl; mr->c = m->c; NEXT(mr) = 0;
! 2822: MKDP(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2823: }
1.5 noro 2824: }
2825:
1.35 noro 2826: void dp_ht(DP p,DP *rp)
2827: {
1.67 ! noro 2828: MP m,mr;
1.35 noro 2829:
1.67 ! noro 2830: if ( !p )
! 2831: *rp = 0;
! 2832: else {
! 2833: m = BDY(p);
! 2834: NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 2835: MKDP(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2836: }
1.35 noro 2837: }
2838:
1.66 noro 2839: void dpm_hm(DPM p,DPM *rp)
2840: {
1.67 ! noro 2841: DMM m,mr;
1.66 noro 2842:
1.67 ! noro 2843: if ( !p )
! 2844: *rp = 0;
! 2845: else {
! 2846: m = BDY(p);
! 2847: NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos; NEXT(mr) = 0;
! 2848: MKDPM(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2849: }
1.66 noro 2850: }
2851:
2852: void dpm_ht(DPM p,DPM *rp)
2853: {
1.67 ! noro 2854: DMM m,mr;
1.66 noro 2855:
1.67 ! noro 2856: if ( !p )
! 2857: *rp = 0;
! 2858: else {
! 2859: m = BDY(p);
! 2860: NEWDMM(mr); mr->dl = m->dl; mr->pos = m->pos; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 2861: MKDPM(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2862: }
1.66 noro 2863: }
2864:
2865:
1.20 noro 2866: void dp_rest(DP p,DP *rp)
1.5 noro 2867: {
1.67 ! noro 2868: MP m;
1.5 noro 2869:
1.67 ! noro 2870: m = BDY(p);
! 2871: if ( !NEXT(m) )
! 2872: *rp = 0;
! 2873: else {
! 2874: MKDP(p->nv,NEXT(m),*rp);
! 2875: if ( *rp )
! 2876: (*rp)->sugar = p->sugar;
! 2877: }
1.5 noro 2878: }
2879:
1.66 noro 2880: void dpm_rest(DPM p,DPM *rp)
2881: {
1.67 ! noro 2882: DMM m;
1.66 noro 2883:
1.67 ! noro 2884: m = BDY(p);
! 2885: if ( !NEXT(m) )
! 2886: *rp = 0;
! 2887: else {
! 2888: MKDPM(p->nv,NEXT(m),*rp);
! 2889: if ( *rp )
! 2890: (*rp)->sugar = p->sugar;
! 2891: }
1.66 noro 2892: }
2893:
1.20 noro 2894: DL lcm_of_DL(int nv,DL dl1,DL dl2,DL dl)
1.5 noro 2895: {
1.67 ! noro 2896: register int i, *d1, *d2, *d, td;
1.5 noro 2897:
1.67 ! noro 2898: if ( !dl ) NEWDL(dl,nv);
! 2899: d = dl->d, d1 = dl1->d, d2 = dl2->d;
! 2900: for ( td = 0, i = 0; i < nv; d1++, d2++, d++, i++ ) {
! 2901: *d = *d1 > *d2 ? *d1 : *d2;
! 2902: td += MUL_WEIGHT(*d,i);
! 2903: }
! 2904: dl->td = td;
! 2905: return dl;
1.5 noro 2906: }
2907:
1.20 noro 2908: int dl_equal(int nv,DL dl1,DL dl2)
1.5 noro 2909: {
2910: register int *d1, *d2, n;
2911:
2912: if ( dl1->td != dl2->td ) return 0;
2913: for ( d1 = dl1->d, d2 = dl2->d, n = nv; --n >= 0; d1++, d2++ )
2914: if ( *d1 != *d2 ) return 0;
2915: return 1;
2916: }
2917:
1.20 noro 2918: int dp_nt(DP p)
1.5 noro 2919: {
1.67 ! noro 2920: int i;
! 2921: MP m;
1.5 noro 2922:
1.67 ! noro 2923: if ( !p )
! 2924: return 0;
! 2925: else {
! 2926: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
! 2927: return i;
! 2928: }
1.5 noro 2929: }
2930:
1.20 noro 2931: int dp_homogeneous(DP p)
1.15 noro 2932: {
1.67 ! noro 2933: MP m;
! 2934: int d;
1.15 noro 2935:
1.67 ! noro 2936: if ( !p )
! 2937: return 1;
! 2938: else {
! 2939: m = BDY(p);
! 2940: d = m->dl->td;
! 2941: m = NEXT(m);
! 2942: for ( ; m; m = NEXT(m) ) {
! 2943: if ( m->dl->td != d )
! 2944: return 0;
! 2945: }
! 2946: return 1;
! 2947: }
1.16 noro 2948: }
2949:
1.20 noro 2950: void _print_mp(int nv,MP m)
1.16 noro 2951: {
1.67 ! noro 2952: int i;
1.16 noro 2953:
1.67 ! noro 2954: if ( !m )
! 2955: return;
! 2956: for ( ; m; m = NEXT(m) ) {
! 2957: fprintf(stderr,"%d<",ITOS(C(m)));
! 2958: for ( i = 0; i < nv; i++ ) {
! 2959: fprintf(stderr,"%d",m->dl->d[i]);
! 2960: if ( i != nv-1 )
! 2961: fprintf(stderr," ");
! 2962: }
! 2963: fprintf(stderr,">",C(m));
! 2964: }
! 2965: fprintf(stderr,"\n");
1.15 noro 2966: }
1.26 noro 2967:
2968: static int cmp_mp_nvar;
2969:
2970: int comp_mp(MP *a,MP *b)
2971: {
1.67 ! noro 2972: return -(*cmpdl)(cmp_mp_nvar,(*a)->dl,(*b)->dl);
1.26 noro 2973: }
2974:
2975: void dp_sort(DP p,DP *rp)
2976: {
1.67 ! noro 2977: MP t,mp,mp0;
! 2978: int i,n;
! 2979: DP r;
! 2980: MP *w;
! 2981:
! 2982: if ( !p ) {
! 2983: *rp = 0;
! 2984: return;
! 2985: }
! 2986: for ( t = BDY(p), n = 0; t; t = NEXT(t), n++ );
! 2987: w = (MP *)ALLOCA(n*sizeof(MP));
! 2988: for ( t = BDY(p), i = 0; i < n; t = NEXT(t), i++ )
! 2989: w[i] = t;
! 2990: cmp_mp_nvar = NV(p);
! 2991: qsort(w,n,sizeof(MP),(int (*)(const void *,const void *))comp_mp);
! 2992: mp0 = 0;
! 2993: for ( i = n-1; i >= 0; i-- ) {
! 2994: NEWMP(mp); mp->dl = w[i]->dl; C(mp) = C(w[i]);
! 2995: NEXT(mp) = mp0; mp0 = mp;
! 2996: }
! 2997: MKDP(p->nv,mp0,r);
! 2998: r->sugar = p->sugar;
! 2999: *rp = r;
1.26 noro 3000: }
3001:
1.32 noro 3002: DP extract_initial_term_from_dp(DP p,int *weight,int n);
3003: LIST extract_initial_term(LIST f,int *weight,int n);
3004:
3005: DP extract_initial_term_from_dp(DP p,int *weight,int n)
3006: {
1.67 ! noro 3007: int w,t,i,top;
! 3008: MP m,r0,r;
! 3009: DP dp;
! 3010:
! 3011: if ( !p ) return 0;
! 3012: top = 1;
! 3013: for ( m = BDY(p); m; m = NEXT(m) ) {
! 3014: for ( i = 0, t = 0; i < n; i++ )
! 3015: t += weight[i]*m->dl->d[i];
! 3016: if ( top || t > w ) {
! 3017: r0 = 0;
! 3018: w = t;
! 3019: top = 0;
! 3020: }
! 3021: if ( t == w ) {
! 3022: NEXTMP(r0,r);
! 3023: r->dl = m->dl;
! 3024: r->c = m->c;
! 3025: }
! 3026: }
! 3027: NEXT(r) = 0;
! 3028: MKDP(p->nv,r0,dp);
! 3029: return dp;
1.32 noro 3030: }
3031:
3032: LIST extract_initial_term(LIST f,int *weight,int n)
3033: {
1.67 ! noro 3034: NODE nd,r0,r;
! 3035: Obj p;
! 3036: LIST l;
! 3037:
! 3038: nd = BDY(f);
! 3039: for ( r0 = 0; nd; nd = NEXT(nd) ) {
! 3040: NEXTNODE(r0,r);
! 3041: p = (Obj)BDY(nd);
! 3042: BDY(r) = (pointer)extract_initial_term_from_dp((DP)p,weight,n);
! 3043: }
! 3044: if ( r0 ) NEXT(r) = 0;
! 3045: MKLIST(l,r0);
! 3046: return l;
1.32 noro 3047: }
3048:
3049: LIST dp_initial_term(LIST f,struct order_spec *ord)
3050: {
1.67 ! noro 3051: int n,l,i;
! 3052: struct weight_or_block *worb;
! 3053: int *weight;
! 3054:
! 3055: switch ( ord->id ) {
! 3056: case 2: /* matrix order */
! 3057: /* extract the first row */
! 3058: n = ord->nv;
! 3059: weight = ord->ord.matrix.matrix[0];
! 3060: return extract_initial_term(f,weight,n);
! 3061: case 3: /* composite order */
! 3062: /* the first w_or_b */
! 3063: worb = ord->ord.composite.w_or_b;
! 3064: switch ( worb->type ) {
! 3065: case IS_DENSE_WEIGHT:
! 3066: n = worb->length;
! 3067: weight = worb->body.dense_weight;
! 3068: return extract_initial_term(f,weight,n);
! 3069: case IS_SPARSE_WEIGHT:
! 3070: n = ord->nv;
! 3071: weight = (int *)ALLOCA(n*sizeof(int));
! 3072: for ( i = 0; i < n; i++ ) weight[i] = 0;
! 3073: l = worb->length;
! 3074: for ( i = 0; i < l; i++ )
! 3075: weight[worb->body.sparse_weight[i].pos]
! 3076: = worb->body.sparse_weight[i].value;
! 3077: return extract_initial_term(f,weight,n);
! 3078: default:
! 3079: error("dp_initial_term : unsupported order");
! 3080: }
! 3081: default:
! 3082: error("dp_initial_term : unsupported order");
! 3083: }
1.32 noro 3084: }
3085:
3086: int highest_order_dp(DP p,int *weight,int n);
3087: LIST highest_order(LIST f,int *weight,int n);
3088:
3089: int highest_order_dp(DP p,int *weight,int n)
3090: {
1.67 ! noro 3091: int w,t,i,top;
! 3092: MP m;
1.32 noro 3093:
1.67 ! noro 3094: if ( !p ) return -1;
! 3095: top = 1;
! 3096: for ( m = BDY(p); m; m = NEXT(m) ) {
! 3097: for ( i = 0, t = 0; i < n; i++ )
! 3098: t += weight[i]*m->dl->d[i];
! 3099: if ( top || t > w ) {
! 3100: w = t;
! 3101: top = 0;
! 3102: }
! 3103: }
! 3104: return w;
1.32 noro 3105: }
3106:
3107: LIST highest_order(LIST f,int *weight,int n)
3108: {
1.67 ! noro 3109: int h;
! 3110: NODE nd,r0,r;
! 3111: Obj p;
! 3112: LIST l;
! 3113: Q q;
! 3114:
! 3115: nd = BDY(f);
! 3116: for ( r0 = 0; nd; nd = NEXT(nd) ) {
! 3117: NEXTNODE(r0,r);
! 3118: p = (Obj)BDY(nd);
! 3119: h = highest_order_dp((DP)p,weight,n);
! 3120: STOQ(h,q);
! 3121: BDY(r) = (pointer)q;
! 3122: }
! 3123: if ( r0 ) NEXT(r) = 0;
! 3124: MKLIST(l,r0);
! 3125: return l;
1.32 noro 3126: }
3127:
3128: LIST dp_order(LIST f,struct order_spec *ord)
3129: {
1.67 ! noro 3130: int n,l,i;
! 3131: struct weight_or_block *worb;
! 3132: int *weight;
! 3133:
! 3134: switch ( ord->id ) {
! 3135: case 2: /* matrix order */
! 3136: /* extract the first row */
! 3137: n = ord->nv;
! 3138: weight = ord->ord.matrix.matrix[0];
! 3139: return highest_order(f,weight,n);
! 3140: case 3: /* composite order */
! 3141: /* the first w_or_b */
! 3142: worb = ord->ord.composite.w_or_b;
! 3143: switch ( worb->type ) {
! 3144: case IS_DENSE_WEIGHT:
! 3145: n = worb->length;
! 3146: weight = worb->body.dense_weight;
! 3147: return highest_order(f,weight,n);
! 3148: case IS_SPARSE_WEIGHT:
! 3149: n = ord->nv;
! 3150: weight = (int *)ALLOCA(n*sizeof(int));
! 3151: for ( i = 0; i < n; i++ ) weight[i] = 0;
! 3152: l = worb->length;
! 3153: for ( i = 0; i < l; i++ )
! 3154: weight[worb->body.sparse_weight[i].pos]
! 3155: = worb->body.sparse_weight[i].value;
! 3156: return highest_order(f,weight,n);
! 3157: default:
! 3158: error("dp_initial_term : unsupported order");
! 3159: }
! 3160: default:
! 3161: error("dp_initial_term : unsupported order");
! 3162: }
1.35 noro 3163: }
3164:
3165: int dpv_ht(DPV p,DP *h)
3166: {
1.67 ! noro 3167: int len,max,maxi,i,t;
! 3168: DP *e;
! 3169: MP m,mr;
! 3170:
! 3171: len = p->len;
! 3172: e = p->body;
! 3173: max = -1;
! 3174: maxi = -1;
! 3175: for ( i = 0; i < len; i++ )
! 3176: if ( e[i] && (t = BDY(e[i])->dl->td) > max ) {
! 3177: max = t;
! 3178: maxi = i;
! 3179: }
! 3180: if ( max < 0 ) {
! 3181: *h = 0;
! 3182: return -1;
! 3183: } else {
! 3184: m = BDY(e[maxi]);
! 3185: NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 3186: MKDP(e[maxi]->nv,mr,*h); (*h)->sugar = mr->dl->td; /* XXX */
! 3187: return maxi;
! 3188: }
1.32 noro 3189: }
1.42 noro 3190:
3191: /* return 1 if 0 <_w1 v && v <_w2 0 */
3192:
3193: int in_c12(int n,int *v,int row1,int **w1,int row2, int **w2)
3194: {
1.67 ! noro 3195: int t1,t2;
1.42 noro 3196:
1.67 ! noro 3197: t1 = compare_zero(n,v,row1,w1);
! 3198: t2 = compare_zero(n,v,row2,w2);
! 3199: if ( t1 > 0 && t2 < 0 ) return 1;
! 3200: else return 0;
1.42 noro 3201: }
3202:
3203: /* 0 < u => 1, 0 > u => -1 */
3204:
3205: int compare_zero(int n,int *u,int row,int **w)
3206: {
1.67 ! noro 3207: int i,j,t;
! 3208: int *wi;
1.42 noro 3209:
1.67 ! noro 3210: for ( i = 0; i < row; i++ ) {
! 3211: wi = w[i];
! 3212: for ( j = 0, t = 0; j < n; j++ ) t += u[j]*wi[j];
! 3213: if ( t > 0 ) return 1;
! 3214: else if ( t < 0 ) return -1;
! 3215: }
! 3216: return 0;
1.42 noro 3217: }
3218:
3219: /* functions for generic groebner walk */
3220: /* u=0 means u=-infty */
3221:
3222: int compare_facet_preorder(int n,int *u,int *v,
1.67 ! noro 3223: int row1,int **w1,int row2,int **w2)
1.42 noro 3224: {
1.67 ! noro 3225: int i,j,s,t,tu,tv;
! 3226: int *w2i,*uv;
1.42 noro 3227:
1.67 ! noro 3228: if ( !u ) return 1;
! 3229: uv = W_ALLOC(n);
! 3230: for ( i = 0; i < row2; i++ ) {
! 3231: w2i = w2[i];
! 3232: for ( j = 0, tu = tv = 0; j < n; j++ )
! 3233: if ( s = w2i[j] ) {
! 3234: tu += s*u[j]; tv += s*v[j];
! 3235: }
! 3236: for ( j = 0; j < n; j++ ) uv[j] = u[j]*tv-v[j]*tu;
! 3237: t = compare_zero(n,uv,row1,w1);
! 3238: if ( t > 0 ) return 1;
! 3239: else if ( t < 0 ) return 0;
! 3240: }
! 3241: return 1;
1.42 noro 3242: }
3243:
1.48 noro 3244: Q inner_product_with_small_vector(VECT w,int *v)
3245: {
1.67 ! noro 3246: int n,i;
! 3247: Q q,s,t,u;
1.48 noro 3248:
1.67 ! noro 3249: n = w->len;
! 3250: s = 0;
! 3251: for ( i = 0; i < n; i++ ) {
! 3252: STOQ(v[i],q); mulq((Q)w->body[i],q,&t); addq(t,s,&u); s = u;
! 3253: }
! 3254: return s;
1.48 noro 3255: }
3256:
3257: Q compute_last_t(NODE g,NODE gh,Q t,VECT w1,VECT w2,NODE *homo,VECT *wp)
3258: {
1.67 ! noro 3259: int n,i;
! 3260: int *wt;
! 3261: Q last,d1,d2,dn,nm,s,t1;
! 3262: VECT wd,wt1,wt2,w;
! 3263: NODE tg,tgh;
! 3264: MP f;
! 3265: int *h;
! 3266: NODE r0,r;
! 3267: MP m0,m;
! 3268: DP d;
! 3269:
! 3270: n = w1->len;
! 3271: wt = W_ALLOC(n);
! 3272: last = ONE;
! 3273: /* t1 = 1-t */
! 3274: for ( tg = g, tgh = gh; tg; tg = NEXT(tg), tgh = NEXT(tgh ) ) {
! 3275: f = BDY((DP)BDY(tg));
! 3276: h = BDY((DP)BDY(tgh))->dl->d;
! 3277: for ( ; f; f = NEXT(f) ) {
! 3278: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3279: for ( i = 0; i < n && !wt[i]; i++ );
! 3280: if ( i == n ) continue;
! 3281: d1 = inner_product_with_small_vector(w1,wt);
! 3282: d2 = inner_product_with_small_vector(w2,wt);
! 3283: nm = d1; subq(d1,d2,&dn);
! 3284: /* if d1=d2 then nothing happens */
! 3285: if ( !dn ) continue;
! 3286: /* s satisfies ds = 0*/
! 3287: divq(nm,dn,&s);
! 3288:
! 3289: if ( cmpq(s,t) > 0 && cmpq(s,last) < 0 )
! 3290: last = s;
! 3291: else if ( !cmpq(s,t) ) {
! 3292: if ( cmpq(d2,0) < 0 ) {
! 3293: last = t;
! 3294: break;
! 3295: }
! 3296: }
! 3297: }
! 3298: }
! 3299: if ( !last ) {
! 3300: dn = ONE; nm = 0;
! 3301: } else {
! 3302: NTOQ(NM(last),1,nm);
! 3303: if ( INT(last) ) dn = ONE;
! 3304: else {
! 3305: NTOQ(DN(last),1,dn);
! 3306: }
! 3307: }
! 3308: /* (1-n/d)*w1+n/d*w2 -> w=(d-n)*w1+n*w2 */
! 3309: subq(dn,nm,&t1); mulvect(CO,(Obj)w1,(Obj)t1,(Obj *)&wt1);
! 3310: mulvect(CO,(Obj)w2,(Obj)nm,(Obj *)&wt2); addvect(CO,wt1,wt2,&w);
! 3311:
! 3312: r0 = 0;
! 3313: for ( tg = g, tgh = gh; tg; tg = NEXT(tg), tgh = NEXT(tgh ) ) {
! 3314: f = BDY((DP)BDY(tg));
! 3315: h = BDY((DP)BDY(tgh))->dl->d;
! 3316: for ( m0 = 0; f; f = NEXT(f) ) {
! 3317: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3318: for ( i = 0; i < n && !wt[i]; i++ );
! 3319: if ( !inner_product_with_small_vector(w,wt) ) {
! 3320: NEXTMP(m0,m); m->c = f->c; m->dl = f->dl;
! 3321: }
! 3322: }
! 3323: NEXT(m) = 0;
! 3324: MKDP(((DP)BDY(tg))->nv,m0,d); d->sugar = ((DP)BDY(tg))->sugar;
! 3325: NEXTNODE(r0,r); BDY(r) = (pointer)d;
! 3326: }
! 3327: NEXT(r) = 0;
! 3328: *homo = r0;
! 3329: *wp = w;
! 3330: return last;
1.48 noro 3331: }
3332:
1.42 noro 3333: /* return 0 if last_w = infty */
3334:
3335: NODE compute_last_w(NODE g,NODE gh,int n,int **w,
1.67 ! noro 3336: int row1,int **w1,int row2,int **w2)
1.42 noro 3337: {
1.67 ! noro 3338: DP d;
! 3339: MP f,m0,m;
! 3340: int *wt,*v,*h;
! 3341: NODE t,s,n0,tn,n1,r0,r;
! 3342: int i;
! 3343:
! 3344: wt = W_ALLOC(n);
! 3345: n0 = 0;
! 3346: for ( t = g, s = gh; t; t = NEXT(t), s = NEXT(s) ) {
! 3347: f = BDY((DP)BDY(t));
! 3348: h = BDY((DP)BDY(s))->dl->d;
! 3349: for ( ; f; f = NEXT(f) ) {
! 3350: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3351: for ( i = 0; i < n && !wt[i]; i++ );
! 3352: if ( i == n ) continue;
! 3353:
! 3354: if ( in_c12(n,wt,row1,w1,row2,w2) &&
! 3355: compare_facet_preorder(n,*w,wt,row1,w1,row2,w2) ) {
! 3356: v = (int *)MALLOC_ATOMIC(n*sizeof(int));
! 3357: for ( i = 0; i < n; i++ ) v[i] = wt[i];
! 3358: MKNODE(n1,v,n0); n0 = n1;
! 3359: }
! 3360: }
! 3361: }
! 3362: if ( !n0 ) return 0;
! 3363: for ( t = n0; t; t = NEXT(t) ) {
! 3364: v = (int *)BDY(t);
! 3365: for ( s = n0; s; s = NEXT(s) )
! 3366: if ( !compare_facet_preorder(n,v,(int *)BDY(s),row1,w1,row2,w2) )
! 3367: break;
! 3368: if ( !s ) {
! 3369: *w = v;
! 3370: break;
! 3371: }
! 3372: }
! 3373: if ( !t )
! 3374: error("compute_last_w : cannot happen");
! 3375: r0 = 0;
! 3376: for ( t = g, s = gh; t; t = NEXT(t), s = NEXT(s) ) {
! 3377: f = BDY((DP)BDY(t));
! 3378: h = BDY((DP)BDY(s))->dl->d;
! 3379: for ( m0 = 0; f; f = NEXT(f) ) {
! 3380: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3381: for ( i = 0; i < n && !wt[i]; i++ );
! 3382: if ( i == n ||
! 3383: (compare_facet_preorder(n,wt,*w,row1,w1,row2,w2)
! 3384: && compare_facet_preorder(n,*w,wt,row1,w1,row2,w2)) ) {
! 3385: NEXTMP(m0,m); m->c = f->c; m->dl = f->dl;
! 3386: }
! 3387: }
! 3388: NEXT(m) = 0;
! 3389: MKDP(((DP)BDY(t))->nv,m0,d); d->sugar = ((DP)BDY(t))->sugar;
! 3390: NEXTNODE(r0,r); BDY(r) = (pointer)d;
! 3391: }
! 3392: NEXT(r) = 0;
! 3393: return r0;
1.42 noro 3394: }
1.44 noro 3395:
3396: /* compute a sufficient set of d(f)=u-v */
3397:
3398: NODE compute_essential_df(DP *g,DP *gh,int ng)
3399: {
1.67 ! noro 3400: int nv,i,j,k,t,lj;
! 3401: NODE r,r1,ri,rt,r0;
! 3402: MP m;
! 3403: MP *mj;
! 3404: DL di,hj,dl,dlt;
! 3405: int *d,*dt;
! 3406: LIST l;
! 3407: Q q;
! 3408:
! 3409: nv = g[0]->nv;
! 3410: r = 0;
! 3411: for ( j = 0; j < ng; j++ ) {
! 3412: for ( m = BDY(g[j]), lj = 0; m; m = NEXT(m), lj++ );
! 3413: mj = (MP *)ALLOCA(lj*sizeof(MP));
! 3414: for ( m = BDY(g[j]), k = 0; m; m = NEXT(m), k++ )
! 3415: mj[k] = m;
! 3416: for ( i = 0; i < lj; i++ ) {
! 3417: for ( di = mj[i]->dl, k = i+1; k < lj; k++ )
! 3418: if ( _dl_redble(di,mj[k]->dl,nv) ) break;
! 3419: if ( k < lj ) mj[i] = 0;
! 3420: }
! 3421: hj = BDY(gh[j])->dl;
! 3422: _NEWDL(dl,nv); d = dl->d;
! 3423: r0 = r;
! 3424: for ( i = 0; i < lj; i++ ) {
! 3425: if ( mj[i] && !dl_equal(nv,di=mj[i]->dl,hj) ) {
! 3426: for ( k = 0, t = 0; k < nv; k++ ) {
! 3427: d[k] = hj->d[k]-di->d[k];
! 3428: t += d[k];
! 3429: }
! 3430: dl->td = t;
1.45 noro 3431: #if 1
1.67 ! noro 3432: for ( rt = r0; rt; rt = NEXT(rt) ) {
! 3433: dlt = (DL)BDY(rt);
! 3434: if ( dlt->td != dl->td ) continue;
! 3435: for ( dt = dlt->d, k = 0; k < nv; k++ )
! 3436: if ( d[k] != dt[k] ) break;
! 3437: if ( k == nv ) break;
! 3438: }
1.45 noro 3439: #else
1.67 ! noro 3440: rt = 0;
1.45 noro 3441: #endif
1.67 ! noro 3442: if ( !rt ) {
! 3443: MKNODE(r1,dl,r); r = r1;
! 3444: _NEWDL(dl,nv); d = dl->d;
! 3445: }
! 3446: }
! 3447: }
! 3448: }
! 3449: for ( rt = r; rt; rt = NEXT(rt) ) {
! 3450: dl = (DL)BDY(rt); d = dl->d;
! 3451: ri = 0;
! 3452: for ( k = nv-1; k >= 0; k-- ) {
! 3453: STOQ(d[k],q);
! 3454: MKNODE(r1,q,ri); ri = r1;
! 3455: }
! 3456: MKNODE(r1,0,ri); MKLIST(l,r1);
! 3457: BDY(rt) = (pointer)l;
! 3458: }
! 3459: return r;
1.44 noro 3460: }
1.57 noro 3461:
3462: int comp_bits_divisible(int *a,int *b,int n)
3463: {
1.67 ! noro 3464: int bpi,i,wi,bi;
1.57 noro 3465:
1.67 ! noro 3466: bpi = (sizeof(int)/sizeof(char))*8;
! 3467: for ( i = 0; i < n; i++ ) {
! 3468: wi = i/bpi; bi = i%bpi;
! 3469: if ( !(a[wi]&(1<<bi)) && (b[wi]&(1<<bi)) ) return 0;
! 3470: }
! 3471: return 1;
1.57 noro 3472: }
3473:
3474: int comp_bits_lex(int *a,int *b,int n)
3475: {
1.67 ! noro 3476: int bpi,i,wi,ba,bb,bi;
1.57 noro 3477:
1.67 ! noro 3478: bpi = (sizeof(int)/sizeof(char))*8;
! 3479: for ( i = 0; i < n; i++ ) {
! 3480: wi = i/bpi; bi = i%bpi;
! 3481: ba = (a[wi]&(1<<bi))?1:0;
! 3482: bb = (b[wi]&(1<<bi))?1:0;
! 3483: if ( ba > bb ) return 1;
! 3484: else if ( ba < bb ) return -1;
! 3485: }
! 3486: return 0;
1.57 noro 3487: }
3488:
3489: NODE mono_raddec(NODE ideal)
3490: {
1.67 ! noro 3491: DP p;
! 3492: int nv,w,i,bpi,di,c,len;
! 3493: int *d,*s,*u,*new;
! 3494: NODE t,t1,v,r,rem,prev;
! 3495:
! 3496: if( !ideal ) return 0;
! 3497: p = (DP)BDY(ideal);
! 3498: nv = NV(p);
! 3499: bpi = (sizeof(int)/sizeof(char))*8;
! 3500: w = (nv+(bpi-1))/bpi;
! 3501: d = p->body->dl->d;
! 3502: if ( !NEXT(ideal) ) {
! 3503: for ( t = 0, i = nv-1; i >= 0; i-- ) {
! 3504: if ( d[i] ) {
! 3505: s = (int *)CALLOC(w,sizeof(int));
! 3506: s[i/bpi] |= 1<<(i%bpi);
! 3507: MKNODE(t1,s,t);
! 3508: t = t1;
! 3509: }
! 3510: }
! 3511: return t;
! 3512: }
! 3513: rem = mono_raddec(NEXT(ideal));
! 3514: r = 0;
! 3515: len = w*sizeof(int);
! 3516: u = (int *)CALLOC(w,sizeof(int));
! 3517: for ( i = nv-1; i >= 0; i-- ) {
! 3518: if ( d[i] ) {
! 3519: for ( t = rem; t; t = NEXT(t) ) {
! 3520: bcopy((char *)BDY(t),(char *)u,len);
! 3521: u[i/bpi] |= 1<<(i%bpi);
! 3522: for ( v = r; v; v = NEXT(v) ) {
! 3523: if ( comp_bits_divisible(u,(int *)BDY(v),nv) ) break;
! 3524: }
! 3525: if ( v ) continue;
! 3526: for ( v = r, prev = 0; v; v = NEXT(v) ) {
! 3527: if ( comp_bits_divisible((int *)BDY(v),u,nv) ) {
! 3528: if ( prev ) NEXT(prev) = NEXT(v);
! 3529: else r = NEXT(r);
! 3530: } else prev =v;
! 3531: }
! 3532: for ( v = r, prev = 0; v; prev = v, v = NEXT(v) ) {
! 3533: if ( comp_bits_lex(u,(int *)BDY(v),nv) < 0 ) break;
! 3534: }
! 3535: new = (int *)CALLOC(w,sizeof(int));
! 3536: bcopy((char *)u,(char *)new,len);
! 3537: MKNODE(t1,new,v);
! 3538: if ( prev ) NEXT(prev) = t1;
! 3539: else r = t1;
! 3540: }
! 3541: }
! 3542: }
! 3543: return r;
1.57 noro 3544: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>