Annotation of OpenXM_contrib2/asir2000/builtin/gr.c, Revision 1.55
1.8 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.9 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.8 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.55 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/builtin/gr.c,v 1.54 2003/10/08 09:09:04 noro Exp $
1.8 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "parse.h"
52: #include "base.h"
53: #include "ox.h"
54:
1.27 noro 55: #if defined(__GNUC__)
56: #define INLINE inline
57: #elif defined(VISUAL)
58: #define INLINE __inline
59: #else
60: #define INLINE
61: #endif
62:
1.1 noro 63: #define HMAG(p) (p_mag(BDY(p)->c))
64:
1.37 noro 65: #define NEWDP_pairs ((DP_pairs)MALLOC(sizeof(struct dp_pairs)))
1.1 noro 66:
1.37 noro 67: static DP_pairs collect_pairs_of_hdlcm( DP_pairs d1, DP_pairs *prest );
68: double get_rtime();
1.1 noro 69:
1.14 noro 70: struct oEGT eg_nf,eg_nfm;
71: struct oEGT eg_znfm,eg_pz,eg_np,eg_ra,eg_mc,eg_gc;
1.1 noro 72: int TP,NBP,NMP,NFP,NDP,ZR,NZR;
73:
74: extern int (*cmpdl)();
1.5 noro 75: extern int do_weyl;
1.1 noro 76:
1.13 noro 77: extern DP_Print;
78:
1.1 noro 79: extern int dp_nelim;
80: extern int dp_fcoeffs;
81: static DP *ps,*psm;
82: static DL *psh;
83: static P *psc;
84:
85: static int *pss;
86: static int psn,pslen;
1.16 noro 87: static int NVars,CNVars;
1.1 noro 88: static VL VC;
1.14 noro 89:
1.16 noro 90: int PCoeffs;
1.14 noro 91: int DP_Print = 0;
1.46 noro 92: int DP_PrintShort = 0;
1.14 noro 93: int DP_Multiple = 0;
1.16 noro 94: int DP_NFStat = 0;
1.14 noro 95: LIST Dist = 0;
96: int NoGCD = 0;
97: int GenTrace = 0;
98: int OXCheck = -1;
99:
1.54 noro 100: int NoSugar = 0;
1.1 noro 101: static int NoCriB = 0;
102: static int NoGC = 0;
103: static int NoMC = 0;
104: static int NoRA = 0;
105: static int ShowMag = 0;
106: static int Stat = 0;
107: static int Denominator = 1;
1.53 noro 108: int Top = 0;
109: int Reverse = 0;
1.1 noro 110: static int Max_mag = 0;
1.42 noro 111: static int Max_coef = 0;
1.54 noro 112: char *Demand = 0;
1.1 noro 113: static int PtozpRA = 0;
1.14 noro 114:
1.1 noro 115: int doing_f4;
1.7 noro 116: NODE TraceList;
1.23 noro 117: NODE AllTraceList;
1.1 noro 118:
1.37 noro 119: void Pox_cmo_rpc(NODE,Obj *);
120: void Pox_rpc(NODE,Obj *);
121: void Pox_pop_local(NODE,Obj *);
122:
123: INLINE int eqdl(int nv,DL dl1,DL dl2)
1.1 noro 124: {
125: int i;
1.51 noro 126: int *p1,*p2;
1.1 noro 127:
128: if ( dl1->td != dl2->td )
129: return 0;
1.51 noro 130: i = nv-1;
131: p1 = dl1->d;
132: p2 = dl2->d;
133: while ( i >= 7 ) {
134: if ( *p1++ != *p2++ ) return 0;
135: if ( *p1++ != *p2++ ) return 0;
136: if ( *p1++ != *p2++ ) return 0;
137: if ( *p1++ != *p2++ ) return 0;
138: if ( *p1++ != *p2++ ) return 0;
139: if ( *p1++ != *p2++ ) return 0;
140: if ( *p1++ != *p2++ ) return 0;
141: if ( *p1++ != *p2++ ) return 0;
142: i -= 8;
143: }
144: switch ( i ) {
145: case 6:
146: if ( *p1++ != *p2++ ) return 0;
147: if ( *p1++ != *p2++ ) return 0;
148: if ( *p1++ != *p2++ ) return 0;
149: if ( *p1++ != *p2++ ) return 0;
150: if ( *p1++ != *p2++ ) return 0;
151: if ( *p1++ != *p2++ ) return 0;
152: if ( *p1++ != *p2++ ) return 0;
153: return 1;
154: case 5:
155: if ( *p1++ != *p2++ ) return 0;
156: if ( *p1++ != *p2++ ) return 0;
157: if ( *p1++ != *p2++ ) return 0;
158: if ( *p1++ != *p2++ ) return 0;
159: if ( *p1++ != *p2++ ) return 0;
160: if ( *p1++ != *p2++ ) return 0;
161: return 1;
162: case 4:
163: if ( *p1++ != *p2++ ) return 0;
164: if ( *p1++ != *p2++ ) return 0;
165: if ( *p1++ != *p2++ ) return 0;
166: if ( *p1++ != *p2++ ) return 0;
167: if ( *p1++ != *p2++ ) return 0;
168: return 1;
169: case 3:
170: if ( *p1++ != *p2++ ) return 0;
171: if ( *p1++ != *p2++ ) return 0;
172: if ( *p1++ != *p2++ ) return 0;
173: if ( *p1++ != *p2++ ) return 0;
174: return 1;
175: case 2:
176: if ( *p1++ != *p2++ ) return 0;
177: if ( *p1++ != *p2++ ) return 0;
178: if ( *p1++ != *p2++ ) return 0;
179: return 1;
180: case 1:
181: if ( *p1++ != *p2++ ) return 0;
182: if ( *p1++ != *p2++ ) return 0;
183: return 1;
184: case 0:
185: if ( *p1++ != *p2++ ) return 0;
186: return 1;
187: default:
188: return 1;
189: }
1.1 noro 190: }
191:
1.5 noro 192: /* b[] should be cleared */
193:
1.37 noro 194: void _dpmod_to_vect(DP f,DL *at,int *b)
1.1 noro 195: {
196: int i,nv;
197: MP m;
198:
199: nv = f->nv;
200: for ( m = BDY(f), i = 0; m; m = NEXT(m), i++ ) {
201: for ( ; !eqdl(nv,m->dl,at[i]); i++ );
202: b[i] = ITOS(m->c);
203: }
204: }
205:
1.30 noro 206: /* [t,findex] -> tf -> compressed vector */
207:
1.37 noro 208: void _tf_to_vect_compress(NODE tf,DL *at,CDP *b)
1.30 noro 209: {
210: int i,j,k,nv,len;
211: DL t,s,d1;
212: DP f;
213: MP m;
214: CDP r;
215:
216: t = (DL)BDY(tf);
217: f = ps[(int)BDY(NEXT(tf))];
218:
219: nv = f->nv;
220: for ( m = BDY(f), len = 0; m; m = NEXT(m), len++ );
221: r = (CDP)MALLOC(sizeof(struct oCDP));
222: r->len = len;
1.32 noro 223: r->psindex = (int)BDY(NEXT(tf));
1.33 noro 224: r->body = (unsigned int *)MALLOC_ATOMIC(sizeof(unsigned int)*len);
1.30 noro 225:
1.34 noro 226: NEWDL_NOINIT(s,nv);
1.30 noro 227: for ( m = BDY(f), i = j = 0; m; m = NEXT(m), j++ ) {
228: d1 = m->dl;
229: s->td = t->td+d1->td;
230: for ( k = 0; k < nv; k++ )
231: s->d[k] = t->d[k]+d1->d[k];
232: for ( ; !eqdl(nv,s,at[i]); i++ );
1.32 noro 233: r->body[j] = i;
1.30 noro 234: }
235: *b = r;
236: }
237:
1.37 noro 238: void dp_to_vect(DP f,DL *at,Q *b)
1.1 noro 239: {
240: int i,nv;
241: MP m;
242:
243: nv = f->nv;
244: for ( m = BDY(f), i = 0; m; m = NEXT(m), i++ ) {
245: for ( ; !eqdl(nv,m->dl,at[i]); i++ );
246: b[i] =(Q)m->c;
247: }
248: }
249:
1.37 noro 250: NODE dp_dllist(DP f)
1.1 noro 251: {
1.2 noro 252: MP m;
253: NODE mp,mp0;
1.1 noro 254:
1.2 noro 255: if ( !f )
256: return 0;
1.1 noro 257: mp0 = 0;
258: for ( m = BDY(f); m; m = NEXT(m) ) {
1.2 noro 259: NEXTNODE(mp0,mp); BDY(mp) = (pointer)m->dl;
1.1 noro 260: }
261: NEXT(mp) = 0;
1.2 noro 262: return mp0;
263: }
264:
1.37 noro 265: NODE mul_dllist(DL d,DP f)
1.30 noro 266: {
267: MP m;
268: NODE mp,mp0;
269: DL t,d1;
270: int i,nv;
271:
272: if ( !f )
273: return 0;
274: nv = NV(f);
275: mp0 = 0;
276: for ( m = BDY(f); m; m = NEXT(m) ) {
277: NEXTNODE(mp0,mp);
1.34 noro 278: NEWDL_NOINIT(t,nv);
1.30 noro 279: d1 = m->dl;
280: t->td = d->td+d1->td;
281: for ( i = 0; i < nv; i++ )
282: t->d[i] = d->d[i]+d1->d[i];
283: BDY(mp) = (pointer)t;
284: }
285: NEXT(mp) = 0;
286: return mp0;
287: }
288:
1.37 noro 289: void pdl(NODE f)
1.2 noro 290: {
291: while ( f ) {
292: printdl(BDY(f)); f = NEXT(f);
293: }
294: fflush(stdout);
295: printf("\n");
1.1 noro 296: }
297:
1.37 noro 298: void dp_gr_main(LIST f,LIST v,Num homo,int modular,int field,struct order_spec *ord,LIST *rp)
1.1 noro 299: {
300: int i,mindex,m,nochk;
301: struct order_spec ord1;
1.23 noro 302: Q q;
1.1 noro 303: VL fv,vv,vc;
304: NODE fd,fd0,fi,fi0,r,r0,t,subst,x,s,xx;
1.23 noro 305: NODE ind,ind0;
306: LIST trace,gbindex;
1.55 ! noro 307: int input_is_dp = 0;
1.1 noro 308:
1.21 noro 309: mindex = 0; nochk = 0; dp_fcoeffs = field;
1.1 noro 310: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&vc);
311: NVars = length((NODE)vv); PCoeffs = vc ? 1 : 0; VC = vc;
312: CNVars = homo ? NVars+1 : NVars;
313: if ( ord->id && NVars != ord->nv )
314: error("dp_gr_main : invalid order specification");
315: initd(ord);
316: if ( homo ) {
317: homogenize_order(ord,NVars,&ord1);
318: for ( fd0 = fi0 = 0, t = BDY(f); t; t = NEXT(t) ) {
319: NEXTNODE(fd0,fd); NEXTNODE(fi0,fi);
1.55 ! noro 320: if ( BDY(t) && OID(BDY(t)) == O_DP ) {
! 321: dp_sort((DP)BDY(t),(DP *)&BDY(fi)); input_is_dp = 1;
! 322: } else
! 323: ptod(CO,vv,(P)BDY(t),(DP *)&BDY(fi));
! 324: dp_homo((DP)BDY(fi),(DP *)&BDY(fd));
1.1 noro 325: }
326: if ( fd0 ) NEXT(fd) = 0;
327: if ( fi0 ) NEXT(fi) = 0;
328: initd(&ord1);
329: } else {
330: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.55 ! noro 331: NEXTNODE(fd0,fd);
! 332: if ( BDY(t) && OID(BDY(t)) == O_DP ) {
! 333: dp_sort((DP)BDY(t),(DP *)&BDY(fd)); input_is_dp = 1;
! 334: } else
! 335: ptod(CO,vv,(P)BDY(t),(DP *)&BDY(fd));
1.1 noro 336: }
337: if ( fd0 ) NEXT(fd) = 0;
338: fi0 = fd0;
339: }
340: if ( modular < 0 ) {
341: modular = -modular; nochk = 1;
342: }
343: if ( modular )
1.19 noro 344: m = modular > 1 ? modular : get_lprime(mindex);
1.1 noro 345: else
346: m = 0;
347: makesubst(vc,&subst);
348: setup_arrays(fd0,0,&s);
349: init_stat();
350: while ( 1 ) {
351: if ( homo ) {
352: initd(&ord1); CNVars = NVars+1;
353: }
1.12 noro 354: if ( DP_Print && modular ) {
1.1 noro 355: fprintf(asir_out,"mod= %d, eval = ",m); printsubst(subst);
356: }
357: x = gb(s,m,subst);
358: if ( x ) {
359: if ( homo ) {
360: reducebase_dehomo(x,&xx); x = xx;
361: initd(ord); CNVars = NVars;
362: }
363: reduceall(x,&xx); x = xx;
364: if ( modular ) {
365: if ( nochk || (membercheck(fi0,x) && gbcheck(x)) )
366: break;
367: } else
368: break;
369: }
370: if ( modular )
371: if ( modular > 1 ) {
372: *rp = 0; return;
373: } else
1.19 noro 374: m = get_lprime(++mindex);
1.1 noro 375: makesubst(vc,&subst);
376: psn = length(s);
377: for ( i = psn; i < pslen; i++ ) {
378: pss[i] = 0; psh[i] = 0; psc[i] = 0; ps[i] = 0;
379: }
380: }
1.23 noro 381: for ( r0 = 0, ind0 = 0; x; x = NEXT(x) ) {
1.1 noro 382: NEXTNODE(r0,r); dp_load((int)BDY(x),&ps[(int)BDY(x)]);
1.55 ! noro 383: if ( input_is_dp )
! 384: BDY(r) = (pointer)ps[(int)BDY(x)];
! 385: else
! 386: dtop(CO,vv,ps[(int)BDY(x)],(P *)&BDY(r));
1.23 noro 387: NEXTNODE(ind0,ind);
388: STOQ((int)BDY(x),q); BDY(ind) = q;
1.1 noro 389: }
390: if ( r0 ) NEXT(r) = 0;
1.23 noro 391: if ( ind0 ) NEXT(ind) = 0;
1.1 noro 392: MKLIST(*rp,r0);
1.23 noro 393: MKLIST(gbindex,ind0);
394:
395: if ( GenTrace && OXCheck < 0 ) {
396:
397: x = AllTraceList;
398: for ( r = 0; x; x = NEXT(x) ) {
399: MKNODE(r0,BDY(x),r); r = r0;
400: }
401: MKLIST(trace,r);
402: r0 = mknode(3,*rp,gbindex,trace);
403: MKLIST(*rp,r0);
404: }
1.1 noro 405: print_stat();
406: if ( ShowMag )
1.42 noro 407: fprintf(asir_out,"\nMax_mag=%d, Max_coef=%d\n",Max_mag, Max_coef);
1.1 noro 408: }
409:
1.37 noro 410: void dp_gr_mod_main(LIST f,LIST v,Num homo,int m,struct order_spec *ord,LIST *rp)
1.1 noro 411: {
412: struct order_spec ord1;
413: VL fv,vv,vc;
414: NODE fd,fd0,r,r0,t,x,s,xx;
415: DP a,b,c;
1.55 ! noro 416: extern struct oEGT eg_red_mod;
! 417: int input_is_dp = 0;
1.1 noro 418:
419: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&vc);
420: NVars = length((NODE)vv); PCoeffs = vc ? 1 : 0; VC = vc;
421: CNVars = homo ? NVars+1 : NVars;
422: if ( ord->id && NVars != ord->nv )
423: error("dp_gr_mod_main : invalid order specification");
424: initd(ord);
425: if ( homo ) {
426: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.55 ! noro 427: if ( BDY(t) && OID(BDY(t)) == O_DP ) {
! 428: dp_sort((DP)BDY(t),&a); input_is_dp = 1;
! 429: } else
! 430: ptod(CO,vv,(P)BDY(t),&a);
! 431: dp_homo(a,&b);
1.1 noro 432: if ( PCoeffs )
433: dp_mod(b,m,0,&c);
434: else
435: _dp_mod(b,m,(NODE)0,&c);
436: if ( c ) {
437: NEXTNODE(fd0,fd); BDY(fd) = (pointer)c;
438: }
439: }
440: homogenize_order(ord,NVars,&ord1); initd(&ord1);
441: } else {
442: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.55 ! noro 443: if ( BDY(t) && OID(BDY(t)) == O_DP ) {
! 444: dp_sort((DP)BDY(t),&b); input_is_dp = 1;
! 445: } else
! 446: ptod(CO,vv,(P)BDY(t),&b);
1.1 noro 447: if ( PCoeffs )
448: dp_mod(b,m,0,&c);
449: else
450: _dp_mod(b,m,0,&c);
451: if ( c ) {
452: NEXTNODE(fd0,fd); BDY(fd) = (pointer)c;
453: }
454: }
455: }
456: if ( fd0 ) NEXT(fd) = 0;
457: setup_arrays(fd0,m,&s);
458: init_stat();
459: if ( homo ) {
460: initd(&ord1); CNVars = NVars+1;
461: }
1.17 noro 462: /* init_eg(&eg_red_mod); */
1.1 noro 463: x = gb_mod(s,m);
1.17 noro 464: /* print_eg("Red_mod",&eg_red_mod); */
1.1 noro 465: if ( homo ) {
466: reducebase_dehomo(x,&xx); x = xx;
467: initd(ord); CNVars = NVars;
468: }
469: reduceall_mod(x,m,&xx); x = xx;
470: if ( PCoeffs )
471: for ( r0 = 0; x; x = NEXT(x) ) {
472: NEXTNODE(r0,r); mdtop(CO,m,vv,ps[(int)BDY(x)],(P *)&BDY(r));
473: }
474: else
475: for ( r0 = 0; x; x = NEXT(x) ) {
476: NEXTNODE(r0,r); _dtop_mod(CO,vv,ps[(int)BDY(x)],(P *)&BDY(r));
477: }
478: print_stat();
479: if ( r0 ) NEXT(r) = 0;
480: MKLIST(*rp,r0);
481: }
482:
1.37 noro 483: void dp_f4_main(LIST f,LIST v,struct order_spec *ord,LIST *rp)
1.1 noro 484: {
1.37 noro 485: int homogen;
1.1 noro 486: VL fv,vv,vc;
1.37 noro 487: NODE fd,fd0,r,r0,t,x,s,xx;
1.55 ! noro 488: int input_is_dp = 0;
1.1 noro 489:
1.22 noro 490: dp_fcoeffs = 0;
1.1 noro 491: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&vc);
492: NVars = length((NODE)vv); PCoeffs = vc ? 1 : 0; VC = vc;
493: CNVars = NVars;
494: if ( ord->id && NVars != ord->nv )
495: error("dp_f4_main : invalid order specification");
496: initd(ord);
1.27 noro 497: for ( fd0 = 0, t = BDY(f), homogen = 1; t; t = NEXT(t) ) {
1.55 ! noro 498: NEXTNODE(fd0,fd);
! 499: if ( BDY(t) && OID(BDY(t)) == O_DP ) {
! 500: dp_sort((DP)BDY(t),(DP *)&BDY(fd)); input_is_dp = 1;
! 501: } else
! 502: ptod(CO,vv,(P)BDY(t),(DP *)&BDY(fd));
1.27 noro 503: if ( homogen )
504: homogen = dp_homogeneous(BDY(fd));
1.1 noro 505: }
506: if ( fd0 ) NEXT(fd) = 0;
507: setup_arrays(fd0,0,&s);
508: x = gb_f4(s);
1.27 noro 509: if ( !homogen ) {
510: reduceall(x,&xx); x = xx;
511: }
1.1 noro 512: for ( r0 = 0; x; x = NEXT(x) ) {
513: NEXTNODE(r0,r); dp_load((int)BDY(x),&ps[(int)BDY(x)]);
1.55 ! noro 514: if ( input_is_dp )
! 515: BDY(r) = (pointer)ps[(int)BDY(x)];
! 516: else
! 517: dtop(CO,vv,ps[(int)BDY(x)],(P *)&BDY(r));
1.1 noro 518: }
519: if ( r0 ) NEXT(r) = 0;
520: MKLIST(*rp,r0);
521: }
522:
1.37 noro 523: void dp_f4_mod_main(LIST f,LIST v,int m,struct order_spec *ord,LIST *rp)
1.1 noro 524: {
1.37 noro 525: int homogen;
1.1 noro 526: VL fv,vv,vc;
1.5 noro 527: DP b,c,c1;
1.37 noro 528: NODE fd,fd0,r,r0,t,x,s,xx;
1.55 ! noro 529: int input_is_dp = 0;
1.1 noro 530:
531: dp_fcoeffs = 0;
532: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&vc);
533: NVars = length((NODE)vv); PCoeffs = vc ? 1 : 0; VC = vc;
534: CNVars = NVars;
535: if ( ord->id && NVars != ord->nv )
536: error("dp_f4_mod_main : invalid order specification");
537: initd(ord);
1.27 noro 538: for ( fd0 = 0, t = BDY(f), homogen = 1; t; t = NEXT(t) ) {
1.55 ! noro 539: if ( BDY(t) && OID(BDY(t)) == O_DP ) {
! 540: dp_sort((DP)BDY(t),&b); input_is_dp = 1;
! 541: } else
! 542: ptod(CO,vv,(P)BDY(t),&b);
1.27 noro 543: if ( homogen )
544: homogen = dp_homogeneous(b);
1.1 noro 545: _dp_mod(b,m,0,&c);
1.5 noro 546: _dp_monic(c,m,&c1);
1.1 noro 547: if ( c ) {
1.5 noro 548: NEXTNODE(fd0,fd); BDY(fd) = (pointer)c1;
1.1 noro 549: }
550: }
551: if ( fd0 ) NEXT(fd) = 0;
552: setup_arrays(fd0,m,&s);
1.35 noro 553: init_stat();
1.36 noro 554: if ( do_weyl )
555: x = gb_f4_mod_old(s,m);
556: else
557: x = gb_f4_mod(s,m);
1.27 noro 558: if ( !homogen ) {
559: reduceall_mod(x,m,&xx); x = xx;
560: }
1.1 noro 561: for ( r0 = 0; x; x = NEXT(x) ) {
562: NEXTNODE(r0,r); _dtop_mod(CO,vv,ps[(int)BDY(x)],(P *)&BDY(r));
563: }
564: if ( r0 ) NEXT(r) = 0;
565: MKLIST(*rp,r0);
1.35 noro 566: print_stat();
1.1 noro 567: }
568:
1.37 noro 569: NODE gb_f4(NODE f)
1.1 noro 570: {
1.37 noro 571: int i,k,nh,row,col,nv;
1.1 noro 572: NODE r,g,gall;
1.2 noro 573: NODE s,s0;
1.1 noro 574: DP_pairs d,dm,dr,t;
1.37 noro 575: DP nf,nf1,f2,sp,sd,tdp;
1.1 noro 576: MP mp,mp0;
1.37 noro 577: NODE blist,bt;
1.1 noro 578: DL *ht,*at;
579: MAT mat,nm;
580: int *rind,*cind;
581: int rank,nred;
582: Q dn;
1.37 noro 583: struct oEGT tmp0,tmp1,eg_split_symb;
1.1 noro 584: extern struct oEGT eg_mod,eg_elim,eg_chrem,eg_gschk,eg_intrat,eg_symb;
585:
586: init_eg(&eg_mod); init_eg(&eg_elim); init_eg(&eg_chrem);
587: init_eg(&eg_gschk); init_eg(&eg_intrat); init_eg(&eg_symb);
588:
589: doing_f4 = 1;
590: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
591: i = (int)BDY(r);
592: d = updpairs(d,g,i);
593: g = updbase(g,i);
594: gall = append_one(gall,i);
595: }
596: if ( gall )
597: nv = ((DP)ps[(int)BDY(gall)])->nv;
598: while ( d ) {
599: get_eg(&tmp0);
600: minsugar(d,&dm,&dr); d = dr;
1.12 noro 601: if ( DP_Print )
1.1 noro 602: fprintf(asir_out,"sugar=%d\n",dm->sugar);
603: blist = 0; s0 = 0;
604: /* asph : sum of all head terms of spoly */
605: for ( t = dm; t; t = NEXT(t) ) {
606: dp_sp(ps[t->dp1],ps[t->dp2],&sp);
607: if ( sp ) {
608: MKNODE(bt,sp,blist); blist = bt;
1.2 noro 609: s0 = symb_merge(s0,dp_dllist(sp),nv);
1.1 noro 610: }
611: }
612: /* s0 : all the terms appeared in symbolic redunction */
1.2 noro 613: for ( s = s0, nred = 0; s; s = NEXT(s) ) {
1.1 noro 614: for ( r = gall; r; r = NEXT(r) )
1.2 noro 615: if ( _dl_redble(BDY(ps[(int)BDY(r)])->dl,BDY(s),nv) )
1.1 noro 616: break;
617: if ( r ) {
1.2 noro 618: dltod(BDY(s),nv,&tdp);
619: dp_subd(tdp,ps[(int)BDY(r)],&sd);
1.5 noro 620: muld(CO,sd,ps[(int)BDY(r)],&f2);
1.1 noro 621: MKNODE(bt,f2,blist); blist = bt;
1.2 noro 622: s = symb_merge(s,dp_dllist(f2),nv);
1.1 noro 623: nred++;
624: }
625: }
626:
627: /* the first nred polys in blist are reducers */
628: /* row = the number of all the polys */
629: for ( r = blist, row = 0; r; r = NEXT(r), row++ );
630: ht = (DL *)MALLOC(nred*sizeof(DL));
631: for ( r = blist, i = 0; i < nred; r = NEXT(r), i++ )
632: ht[i] = BDY((DP)BDY(r))->dl;
1.2 noro 633: for ( s = s0, col = 0; s; s = NEXT(s), col++ );
1.1 noro 634: at = (DL *)MALLOC(col*sizeof(DL));
1.2 noro 635: for ( s = s0, i = 0; i < col; s = NEXT(s), i++ )
636: at[i] = (DL)BDY(s);
1.1 noro 637: MKMAT(mat,row,col);
638: for ( i = 0, r = blist; i < row; r = NEXT(r), i++ )
639: dp_to_vect(BDY(r),at,(Q *)mat->body[i]);
640: get_eg(&tmp1); add_eg(&eg_symb,&tmp0,&tmp1);
641: init_eg(&eg_split_symb); add_eg(&eg_split_symb,&tmp0,&tmp1);
1.12 noro 642: if ( DP_Print ) {
1.1 noro 643: print_eg("Symb",&eg_split_symb);
644: fprintf(asir_out,"mat : %d x %d",row,col);
645: fflush(asir_out);
646: }
1.3 noro 647: #if 0
648: rank = generic_gauss_elim_hensel(mat,&nm,&dn,&rind,&cind);
649: #else
1.1 noro 650: rank = generic_gauss_elim(mat,&nm,&dn,&rind,&cind);
1.3 noro 651: #endif
1.12 noro 652: if ( DP_Print )
1.1 noro 653: fprintf(asir_out,"done rank = %d\n",rank,row,col);
654: for ( i = 0; i < rank; i++ ) {
655: for ( k = 0; k < nred; k++ )
656: if ( !cmpdl(nv,at[rind[i]],ht[k]) )
657: break;
658: if ( k == nred ) {
659: /* this is a new base */
660: mp0 = 0;
661: NEXTMP(mp0,mp); mp->dl = at[rind[i]]; mp->c = (P)dn;
662: for ( k = 0; k < col-rank; k++ )
663: if ( nm->body[i][k] ) {
664: NEXTMP(mp0,mp); mp->dl = at[cind[k]];
665: mp->c = (P)nm->body[i][k];
666: }
667: NEXT(mp) = 0;
668: MKDP(nv,mp0,nf); nf->sugar = dm->sugar;
669: dp_ptozp(nf,&nf1);
670: nh = newps(nf1,0,0);
671: d = updpairs(d,g,nh);
672: g = updbase(g,nh);
673: gall = append_one(gall,nh);
674: }
675: }
676: }
1.12 noro 677: if ( DP_Print ) {
1.1 noro 678: print_eg("Symb",&eg_symb);
679: print_eg("Mod",&eg_mod); print_eg("GaussElim",&eg_elim);
680: print_eg("ChRem",&eg_chrem); print_eg("IntToRat",&eg_intrat);
681: print_eg("Check",&eg_gschk);
682: }
683: return g;
684: }
685:
1.5 noro 686: /* initial bases are monic */
687:
1.32 noro 688: unsigned int **psca;
1.51 noro 689: GeoBucket create_bucket();
690: DL remove_head_bucket(GeoBucket,int);
1.32 noro 691:
1.37 noro 692: NODE gb_f4_mod(NODE f,int m)
1.1 noro 693: {
694: int i,j,k,nh,row,col,nv;
695: NODE r,g,gall;
1.29 noro 696: NODE s,s0;
1.1 noro 697: DP_pairs d,dm,dr,t;
1.37 noro 698: DP nf,sp,sd,tdp;
1.1 noro 699: MP mp,mp0;
1.37 noro 700: NODE blist,bt,bt1,dt;
701: DL *at,*st;
1.24 noro 702: int **spmat;
703: CDP *redmat;
1.25 noro 704: int *colstat,*w,*w1;
1.35 noro 705: int rank,nred,nsp,nsp0,nonzero,spcol;
1.24 noro 706: int *indred,*isred;
707: CDP ri;
1.32 noro 708: int pscalen;
1.51 noro 709: GeoBucket bucket;
710: DL head;
1.50 noro 711: struct oEGT tmp0,tmp1,eg_split_symb,eg_split_conv,eg_split_elim1,eg_split_elim2;
712: extern struct oEGT eg_symb,eg_conv,eg_elim1,eg_elim2;
1.1 noro 713:
1.32 noro 714: /* initialize coeffcient array list of ps[] */
715: pscalen = pslen;
716: psca = (unsigned int **)MALLOC(pscalen*sizeof(unsigned int *));
717:
1.50 noro 718: init_eg(&eg_symb); init_eg(&eg_conv); init_eg(&eg_elim1); init_eg(&eg_elim2);
1.1 noro 719: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
720: i = (int)BDY(r);
721: d = updpairs(d,g,i);
722: g = updbase(g,i);
723: gall = append_one(gall,i);
1.32 noro 724: dptoca(ps[i],&psca[i]);
1.1 noro 725: }
726: if ( gall )
727: nv = ((DP)ps[(int)BDY(gall)])->nv;
728: while ( d ) {
729: get_eg(&tmp0);
730: minsugar(d,&dm,&dr); d = dr;
1.12 noro 731: if ( DP_Print )
1.1 noro 732: fprintf(asir_out,"sugar=%d\n",dm->sugar);
1.51 noro 733: blist = 0;
734: bucket = create_bucket();
1.1 noro 735: /* asph : sum of all head terms of spoly */
736: for ( t = dm; t; t = NEXT(t) ) {
1.13 noro 737: _dp_sp_mod(ps[t->dp1],ps[t->dp2],m,&sp);
1.36 noro 738: /* fprintf(stderr,"splen=%d-",dp_nt(sp)); */
1.1 noro 739: if ( sp ) {
740: MKNODE(bt,sp,blist); blist = bt;
1.51 noro 741: add_bucket(bucket,dp_dllist(sp),nv);
1.36 noro 742: /* fprintf(stderr,"%d-",length(s0)); */
1.1 noro 743: }
744: }
1.51 noro 745: #if 0
1.35 noro 746: if ( DP_Print )
747: fprintf(asir_out,"initial spmat : %d x %d ",length(blist),length(s0));
1.51 noro 748: #endif
1.24 noro 749: /* s0 : all the terms appeared in symbolic reduction */
1.51 noro 750: nred = 0;
751: s0 = 0;
752: while ( 1 ) {
753: head = remove_head_bucket(bucket,nv);
754: if ( !head ) break;
755: else {
756: NEXTNODE(s0,s);
757: BDY(s) = (pointer)head;
758: }
1.29 noro 759: for ( r = gall; r; r = NEXT(r) )
1.51 noro 760: if ( _dl_redble(BDY(ps[(int)BDY(r)])->dl,head,nv) )
1.29 noro 761: break;
762: if ( r ) {
1.51 noro 763: dltod(head,nv,&tdp);
1.29 noro 764: dp_subd(tdp,ps[(int)BDY(r)],&sd);
1.30 noro 765: dt = mul_dllist(BDY(sd)->dl,ps[(int)BDY(r)]);
1.51 noro 766: add_bucket(bucket,NEXT(dt),nv);
1.48 noro 767: /* fprintf(stderr,"[%d]",length(dt)); */
1.30 noro 768: /* list of [t,f] */
769: bt1 = mknode(2,BDY(sd)->dl,BDY(r));
770: MKNODE(bt,bt1,blist); blist = bt;
1.48 noro 771: /* fprintf(stderr,"%d-",length(s0)); */
1.29 noro 772: nred++;
1.1 noro 773: }
774: }
1.51 noro 775: if ( s0 ) NEXT(s) = 0;
1.36 noro 776: /* fprintf(stderr,"\n"); */
1.50 noro 777: get_eg(&tmp1); add_eg(&eg_symb,&tmp0,&tmp1);
778: init_eg(&eg_split_symb); add_eg(&eg_split_symb,&tmp0,&tmp1);
779:
1.35 noro 780: if ( DP_Print )
781: fprintf(asir_out,"number of reducers : %d\n",nred);
1.1 noro 782:
1.50 noro 783: get_eg(&tmp0);
1.1 noro 784: /* the first nred polys in blist are reducers */
785: /* row = the number of all the polys */
786: for ( r = blist, row = 0; r; r = NEXT(r), row++ );
1.5 noro 787:
788: /* col = number of all terms */
1.29 noro 789: for ( s = s0, col = 0; s; s = NEXT(s), col++ );
1.5 noro 790:
791: /* head terms of all terms */
1.1 noro 792: at = (DL *)MALLOC(col*sizeof(DL));
1.29 noro 793: for ( s = s0, i = 0; i < col; s = NEXT(s), i++ )
794: at[i] = (DL)BDY(s);
1.5 noro 795:
796: /* store coefficients separately in spmat and redmat */
797: nsp = row-nred;
798:
799: /* reducer matrix */
1.25 noro 800: /* indred : register the position of the head term */
1.24 noro 801: redmat = (CDP *)MALLOC(nred*sizeof(CDP));
1.5 noro 802: for ( i = 0, r = blist; i < nred; r = NEXT(r), i++ )
1.30 noro 803: _tf_to_vect_compress(BDY(r),at,&redmat[i]);
1.32 noro 804:
1.5 noro 805: /* register the position of the head term */
1.31 noro 806: indred = (int *)MALLOC_ATOMIC(nred*sizeof(int));
1.5 noro 807: bzero(indred,nred*sizeof(int));
1.31 noro 808: isred = (int *)MALLOC_ATOMIC(col*sizeof(int));
1.5 noro 809: bzero(isred,col*sizeof(int));
810: for ( i = 0; i < nred; i++ ) {
811: ri = redmat[i];
1.32 noro 812: indred[i] = ri->body[0];
1.24 noro 813: isred[indred[i]] = 1;
1.5 noro 814: }
815:
816: spcol = col-nred;
817: /* head terms not in ht */
818: st = (DL *)MALLOC(spcol*sizeof(DL));
819: for ( j = 0, k = 0; j < col; j++ )
820: if ( !isred[j] )
821: st[k++] = at[j];
1.50 noro 822: get_eg(&tmp1); add_eg(&eg_conv,&tmp0,&tmp1);
823: init_eg(&eg_split_conv); add_eg(&eg_split_conv,&tmp0,&tmp1);
1.5 noro 824:
1.24 noro 825: get_eg(&tmp1);
1.5 noro 826: /* spoly matrix; stored in reduced form; terms in ht[] are omitted */
1.25 noro 827: spmat = (int **)MALLOC(nsp*sizeof(int *));
1.31 noro 828: w = (int *)MALLOC_ATOMIC(col*sizeof(int));
1.25 noro 829:
830: /* skip reducers in blist */
831: for ( i = 0, r = blist; i < nred; r = NEXT(r), i++ );
832: for ( i = 0; r; r = NEXT(r) ) {
1.5 noro 833: bzero(w,col*sizeof(int));
834: _dpmod_to_vect(BDY(r),at,w);
1.24 noro 835: reduce_sp_by_red_mod_compress(w,redmat,indred,nred,col,m);
1.25 noro 836: for ( j = 0; j < col; j++ )
837: if ( w[j] )
838: break;
839: if ( j < col ) {
840: w1 = (int *)MALLOC_ATOMIC(spcol*sizeof(int));
841: for ( j = 0, k = 0; j < col; j++ )
842: if ( !isred[j] )
843: w1[k++] = w[j];
844: spmat[i] = w1;
845: i++;
846: }
1.5 noro 847: }
1.25 noro 848: /* update nsp */
1.35 noro 849: nsp0 = nsp;
1.25 noro 850: nsp = i;
1.5 noro 851:
1.30 noro 852: /* XXX free redmat explicitly */
853: for ( k = 0; k < nred; k++ ) {
854: GC_free(BDY(redmat[k]));
855: GC_free(redmat[k]);
856: }
857:
1.5 noro 858: get_eg(&tmp0); add_eg(&eg_elim1,&tmp1,&tmp0);
859: init_eg(&eg_split_elim1); add_eg(&eg_split_elim1,&tmp1,&tmp0);
860:
861: colstat = (int *)MALLOC_ATOMIC(spcol*sizeof(int));
1.25 noro 862: bzero(colstat,spcol*sizeof(int));
1.5 noro 863: for ( i = 0, nonzero=0; i < nsp; i++ )
864: for ( j = 0; j < spcol; j++ )
865: if ( spmat[i][j] )
1.1 noro 866: nonzero++;
1.17 noro 867: if ( DP_Print && nsp )
1.5 noro 868: fprintf(asir_out,"spmat : %d x %d (nonzero=%f%%)...",
869: nsp,spcol,((double)nonzero*100)/(nsp*spcol));
1.17 noro 870: if ( nsp )
871: rank = generic_gauss_elim_mod(spmat,nsp,spcol,m,colstat);
872: else
873: rank = 0;
1.5 noro 874: get_eg(&tmp1); add_eg(&eg_elim2,&tmp0,&tmp1);
875: init_eg(&eg_split_elim2); add_eg(&eg_split_elim2,&tmp0,&tmp1);
876:
1.12 noro 877: if ( DP_Print ) {
1.1 noro 878: fprintf(asir_out,"done rank = %d\n",rank,row,col);
879: print_eg("Symb",&eg_split_symb);
1.50 noro 880: print_eg("Conv",&eg_split_conv);
1.5 noro 881: print_eg("Elim1",&eg_split_elim1);
882: print_eg("Elim2",&eg_split_elim2);
1.1 noro 883: fprintf(asir_out,"\n");
884: }
1.25 noro 885:
1.35 noro 886: NZR += rank;
887: ZR += nsp0-rank;
888:
1.25 noro 889: if ( !rank )
890: continue;
891:
1.5 noro 892: for ( j = 0, i = 0; j < spcol; j++ )
1.1 noro 893: if ( colstat[j] ) {
1.5 noro 894: mp0 = 0;
1.13 noro 895: NEXTMP(mp0,mp); mp->dl = st[j]; mp->c = STOI(1);
1.5 noro 896: for ( k = j+1; k < spcol; k++ )
897: if ( !colstat[k] && spmat[i][k] ) {
1.13 noro 898: NEXTMP(mp0,mp); mp->dl = st[k];
1.5 noro 899: mp->c = STOI(spmat[i][k]);
1.1 noro 900: }
1.5 noro 901: NEXT(mp) = 0;
902: MKDP(nv,mp0,nf); nf->sugar = dm->sugar;
903: nh = newps_mod(nf,m);
1.32 noro 904: if ( nh == pscalen ) {
905: psca = (unsigned int **)
906: REALLOC(psca,2*pscalen*sizeof(unsigned int *));
907: pscalen *= 2;
908: }
909: dptoca(ps[nh],&psca[nh]);
1.5 noro 910: d = updpairs(d,g,nh);
911: g = updbase(g,nh);
912: gall = append_one(gall,nh);
1.1 noro 913: i++;
914: }
1.30 noro 915:
916: /* XXX free spmat[] explicitly */
917: for ( j = 0; j < nsp; j++ ) {
918: GC_free(spmat[j]);
919: }
1.36 noro 920: }
921: if ( DP_Print ) {
922: print_eg("Symb",&eg_symb);
1.50 noro 923: print_eg("Conv",&eg_conv);
1.36 noro 924: print_eg("Elim1",&eg_elim1);
925: print_eg("Elim2",&eg_elim2);
926: fflush(asir_out);
927: }
928: return g;
929: }
930:
1.37 noro 931: NODE gb_f4_mod_old(NODE f,int m)
1.36 noro 932: {
933: int i,j,k,nh,row,col,nv;
934: NODE r,g,gall;
935: NODE s,s0;
936: DP_pairs d,dm,dr,t;
1.37 noro 937: DP nf,f2,sp,sd,sdm,tdp;
1.36 noro 938: MP mp,mp0;
1.37 noro 939: NODE blist,bt;
1.36 noro 940: DL *ht,*at,*st;
941: int **spmat,**redmat;
942: int *colstat,*w;
943: int rank,nred,nsp,nonzero,spcol;
944: int *indred,*isred,*ri;
1.37 noro 945: struct oEGT tmp0,tmp1,eg_split_symb,eg_split_elim1,eg_split_elim2;
1.36 noro 946: extern struct oEGT eg_symb,eg_elim1,eg_elim2;
947:
948: init_eg(&eg_symb); init_eg(&eg_elim1); init_eg(&eg_elim2);
949: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
950: i = (int)BDY(r);
951: d = updpairs(d,g,i);
952: g = updbase(g,i);
953: gall = append_one(gall,i);
954: }
955: if ( gall )
956: nv = ((DP)ps[(int)BDY(gall)])->nv;
957: while ( d ) {
958: get_eg(&tmp0);
959: minsugar(d,&dm,&dr); d = dr;
960: if ( DP_Print )
961: fprintf(asir_out,"sugar=%d\n",dm->sugar);
962: blist = 0; s0 = 0;
963: /* asph : sum of all head terms of spoly */
964: for ( t = dm; t; t = NEXT(t) ) {
965: _dp_sp_mod(ps[t->dp1],ps[t->dp2],m,&sp);
966: if ( sp ) {
967: MKNODE(bt,sp,blist); blist = bt;
968: s0 = symb_merge(s0,dp_dllist(sp),nv);
969: }
970: }
971: /* s0 : all the terms appeared in symbolic redunction */
972: for ( s = s0, nred = 0; s; s = NEXT(s) ) {
973: for ( r = gall; r; r = NEXT(r) )
974: if ( _dl_redble(BDY(ps[(int)BDY(r)])->dl,BDY(s),nv) )
975: break;
976: if ( r ) {
977: dltod(BDY(s),nv,&tdp);
978: dp_subd(tdp,ps[(int)BDY(r)],&sd);
979: _dp_mod(sd,m,0,&sdm);
980: mulmd_dup(m,sdm,ps[(int)BDY(r)],&f2);
981: MKNODE(bt,f2,blist); blist = bt;
982: s = symb_merge(s,dp_dllist(f2),nv);
983: nred++;
984: }
985: }
986:
987: get_eg(&tmp1); add_eg(&eg_symb,&tmp0,&tmp1);
988: init_eg(&eg_split_symb); add_eg(&eg_split_symb,&tmp0,&tmp1);
989:
990: /* the first nred polys in blist are reducers */
991: /* row = the number of all the polys */
992: for ( r = blist, row = 0; r; r = NEXT(r), row++ );
993:
994: /* head terms of reducers */
995: ht = (DL *)MALLOC(nred*sizeof(DL));
996: for ( r = blist, i = 0; i < nred; r = NEXT(r), i++ )
997: ht[i] = BDY((DP)BDY(r))->dl;
998:
999: /* col = number of all terms */
1000: for ( s = s0, col = 0; s; s = NEXT(s), col++ );
1001:
1002: /* head terms of all terms */
1003: at = (DL *)MALLOC(col*sizeof(DL));
1004: for ( s = s0, i = 0; i < col; s = NEXT(s), i++ )
1005: at[i] = (DL)BDY(s);
1006:
1007: /* store coefficients separately in spmat and redmat */
1008: nsp = row-nred;
1009:
1010: /* reducer matrix */
1011: redmat = (int **)almat(nred,col);
1012: for ( i = 0, r = blist; i < nred; r = NEXT(r), i++ )
1013: _dpmod_to_vect(BDY(r),at,redmat[i]);
1014: /* XXX */
1015: /* reduce_reducers_mod(redmat,nred,col,m); */
1016: /* register the position of the head term */
1017: indred = (int *)MALLOC(nred*sizeof(int));
1018: bzero(indred,nred*sizeof(int));
1019: isred = (int *)MALLOC(col*sizeof(int));
1020: bzero(isred,col*sizeof(int));
1021: for ( i = 0; i < nred; i++ ) {
1022: ri = redmat[i];
1023: for ( j = 0; j < col && !ri[j]; j++ );
1024: indred[i] = j;
1025: isred[j] = 1;
1026: }
1027:
1028: spcol = col-nred;
1029: /* head terms not in ht */
1030: st = (DL *)MALLOC(spcol*sizeof(DL));
1031: for ( j = 0, k = 0; j < col; j++ )
1032: if ( !isred[j] )
1033: st[k++] = at[j];
1034:
1035: /* spoly matrix; stored in reduced form; terms in ht[] are omitted */
1036: spmat = almat(nsp,spcol);
1037: w = (int *)MALLOC(col*sizeof(int));
1038: for ( ; i < row; r = NEXT(r), i++ ) {
1039: bzero(w,col*sizeof(int));
1040: _dpmod_to_vect(BDY(r),at,w);
1041: reduce_sp_by_red_mod(w,redmat,indred,nred,col,m);
1042: for ( j = 0, k = 0; j < col; j++ )
1043: if ( !isred[j] )
1044: spmat[i-nred][k++] = w[j];
1045: }
1046:
1047: get_eg(&tmp0); add_eg(&eg_elim1,&tmp1,&tmp0);
1048: init_eg(&eg_split_elim1); add_eg(&eg_split_elim1,&tmp1,&tmp0);
1049:
1050: colstat = (int *)MALLOC_ATOMIC(spcol*sizeof(int));
1051: for ( i = 0, nonzero=0; i < nsp; i++ )
1052: for ( j = 0; j < spcol; j++ )
1053: if ( spmat[i][j] )
1054: nonzero++;
1055: if ( DP_Print && nsp )
1056: fprintf(asir_out,"spmat : %d x %d (nonzero=%f%%)...",
1057: nsp,spcol,((double)nonzero*100)/(nsp*spcol));
1058: if ( nsp )
1059: rank = generic_gauss_elim_mod(spmat,nsp,spcol,m,colstat);
1060: else
1061: rank = 0;
1062: get_eg(&tmp1); add_eg(&eg_elim2,&tmp0,&tmp1);
1063: init_eg(&eg_split_elim2); add_eg(&eg_split_elim2,&tmp0,&tmp1);
1064:
1065: if ( DP_Print ) {
1066: fprintf(asir_out,"done rank = %d\n",rank,row,col);
1067: print_eg("Symb",&eg_split_symb);
1068: print_eg("Elim1",&eg_split_elim1);
1069: print_eg("Elim2",&eg_split_elim2);
1070: fprintf(asir_out,"\n");
1071: }
1072: for ( j = 0, i = 0; j < spcol; j++ )
1073: if ( colstat[j] ) {
1074: mp0 = 0;
1075: NEXTMP(mp0,mp); mp->dl = st[j]; mp->c = STOI(1);
1076: for ( k = j+1; k < spcol; k++ )
1077: if ( !colstat[k] && spmat[i][k] ) {
1078: NEXTMP(mp0,mp); mp->dl = st[k];
1079: mp->c = STOI(spmat[i][k]);
1080: }
1081: NEXT(mp) = 0;
1082: MKDP(nv,mp0,nf); nf->sugar = dm->sugar;
1083: nh = newps_mod(nf,m);
1084: d = updpairs(d,g,nh);
1085: g = updbase(g,nh);
1086: gall = append_one(gall,nh);
1087: i++;
1088: }
1.1 noro 1089: }
1.12 noro 1090: if ( DP_Print ) {
1.1 noro 1091: print_eg("Symb",&eg_symb);
1.5 noro 1092: print_eg("Elim1",&eg_elim1);
1093: print_eg("Elim2",&eg_elim2);
1.1 noro 1094: fflush(asir_out);
1095: }
1096: return g;
1097: }
1098:
1.37 noro 1099: int DPPlength(DP_pairs n)
1.1 noro 1100: {
1101: int i;
1102:
1103: for ( i = 0; n; n = NEXT(n), i++ );
1104: return i;
1105: }
1106:
1.37 noro 1107: void printdl(DL dl)
1.1 noro 1108: {
1109: int i;
1110:
1111: fprintf(asir_out,"<<");
1112: for ( i = 0; i < CNVars-1; i++ )
1113: fprintf(asir_out,"%d,",dl->d[i]);
1114: fprintf(asir_out,"%d>>",dl->d[i]);
1115: }
1116:
1.37 noro 1117: void pltovl(LIST l,VL *vl)
1.1 noro 1118: {
1119: NODE n;
1120: VL r,r0;
1121:
1122: n = BDY(l);
1123: for ( r0 = 0; n; n = NEXT(n) ) {
1124: NEXTVL(r0,r); r->v = VR((P)BDY(n));
1125: }
1126: if ( r0 ) NEXT(r) = 0;
1127: *vl = r0;
1128: }
1129:
1.37 noro 1130: void makesubst(VL v,NODE *s)
1.1 noro 1131: {
1132: NODE r,r0;
1133: Q q;
1134: unsigned int n;
1135:
1136: for ( r0 = 0; v; v = NEXT(v) ) {
1137: NEXTNODE(r0,r); BDY(r) = (pointer)v->v;
1138: #if defined(_PA_RISC1_1)
1139: n = mrand48()&BMASK; UTOQ(n,q);
1140: #else
1141: n = random(); UTOQ(n,q);
1142: #endif
1143: NEXTNODE(r0,r); BDY(r) = (pointer)q;
1144: }
1145: if ( r0 ) NEXT(r) = 0;
1146: *s = r0;
1147: }
1148:
1.37 noro 1149: void printsubst(NODE s)
1.1 noro 1150: {
1151: fputc('[',asir_out);
1152: while ( s ) {
1153: printv(CO,(V)BDY(s)); s = NEXT(s);
1154: fprintf(asir_out,"->%d",QTOS((Q)BDY(s)));
1155: if ( NEXT(s) ) {
1156: fputc(',',asir_out); s = NEXT(s);
1157: } else
1158: break;
1159: }
1160: fprintf(asir_out,"]\n"); return;
1161: }
1162:
1.37 noro 1163: void vlminus(VL v,VL w,VL *d)
1.1 noro 1164: {
1165: int i,j,n,m;
1166: V *va,*wa;
1167: V a;
1168: VL r,r0;
1169: VL t;
1170:
1171: for ( n = 0, t = v; t; t = NEXT(t), n++ );
1172: va = (V *)ALLOCA(n*sizeof(V));
1173: for ( i = 0, t = v; t; t = NEXT(t), i++ )
1174: va[i] = t->v;
1175: for ( m = 0, t = w; t; t = NEXT(t), m++ );
1176: wa = (V *)ALLOCA(m*sizeof(V));
1177: for ( i = 0, t = w; t; t = NEXT(t), i++ )
1178: wa[i] = t->v;
1179: for ( i = 0; i < n; i++ ) {
1180: a = va[i];
1181: for ( j = 0; j < m; j++ )
1182: if ( a == wa[j] )
1183: break;
1184: if ( j < m )
1185: va[i] = 0;
1186: }
1187: for ( r0 = 0, i = 0; i < n; i++ )
1188: if ( va[i] ) { NEXTVL(r0,r); r->v = va[i]; }
1189: if ( r0 ) NEXT(r) = 0;
1190: *d = r0;
1191: }
1192:
1.37 noro 1193: int validhc(P a,int m,NODE s)
1.1 noro 1194: {
1195: P c,c1;
1196: V v;
1197:
1198: if ( !a )
1199: return 0;
1200: for ( c = a; s; s = NEXT(s) ) {
1201: v = (V)BDY(s); s = NEXT(s);
1202: substp(CO,c,v,(P)BDY(s),&c1); c = c1;
1203: }
1204: ptomp(m,c,&c1);
1205: return c1 ? 1 : 0;
1206: }
1207:
1.37 noro 1208: void setup_arrays(NODE f,int m,NODE *r)
1.1 noro 1209: {
1210: int i;
1.7 noro 1211: NODE s,s0,f0;
1.1 noro 1212:
1.17 noro 1213: #if 1
1.7 noro 1214: f0 = f = NODE_sortb(f,1);
1.17 noro 1215: #else
1216: f0 = f;
1217: #endif
1.1 noro 1218: psn = length(f); pslen = 2*psn;
1219: ps = (DP *)MALLOC(pslen*sizeof(DP));
1220: psh = (DL *)MALLOC(pslen*sizeof(DL));
1221: pss = (int *)MALLOC(pslen*sizeof(int));
1222: psc = (P *)MALLOC(pslen*sizeof(P));
1223: for ( i = 0; i < psn; i++, f = NEXT(f) ) {
1224: prim_part((DP)BDY(f),m,&ps[i]);
1225: if ( Demand )
1.7 noro 1226: dp_save(i,(Obj)ps[i],0);
1.1 noro 1227: psh[i] = BDY(ps[i])->dl;
1228: pss[i] = ps[i]->sugar;
1229: psc[i] = BDY(ps[i])->c;
1230: }
1.23 noro 1231: if ( GenTrace ) {
1.7 noro 1232: Q q;
1233: STRING fname;
1234: LIST input;
1.23 noro 1235: NODE arg,t,t1;
1.37 noro 1236: Obj obj;
1.23 noro 1237:
1238: t = 0;
1239: for ( i = psn-1; i >= 0; i-- ) {
1240: MKNODE(t1,ps[i],t);
1241: t = t1;
1242: }
1243: MKLIST(input,t);
1.7 noro 1244:
1.23 noro 1245: if ( OXCheck >= 0 ) {
1246: STOQ(OXCheck,q);
1247: MKSTR(fname,"register_input");
1248: arg = mknode(3,q,fname,input);
1.37 noro 1249: Pox_cmo_rpc(arg,&obj);
1.23 noro 1250: } else if ( OXCheck < 0 ) {
1251: MKNODE(AllTraceList,input,0);
1252: }
1.7 noro 1253: }
1.1 noro 1254: for ( s0 = 0, i = 0; i < psn; i++ ) {
1255: NEXTNODE(s0,s); BDY(s) = (pointer)i;
1256: }
1257: if ( s0 ) NEXT(s) = 0;
1258: *r = s0;
1259: }
1260:
1.37 noro 1261: void prim_part(DP f,int m,DP *r)
1.1 noro 1262: {
1.7 noro 1263: P d,t;
1264:
1.1 noro 1265: if ( m > 0 ) {
1266: if ( PCoeffs )
1267: dp_prim_mod(f,m,r);
1268: else
1.49 noro 1269: _dp_monic(f,m,r);
1.1 noro 1270: } else {
1.44 noro 1271: if ( dp_fcoeffs || PCoeffs )
1.1 noro 1272: dp_prim(f,r);
1273: else
1274: dp_ptozp(f,r);
1.7 noro 1275: if ( GenTrace && TraceList ) {
1.23 noro 1276: /* adust the denominator according to the final
1277: content reduction */
1.7 noro 1278: divsp(CO,BDY(f)->c,BDY(*r)->c,&d);
1279: mulp(CO,(P)ARG3(BDY((LIST)BDY(TraceList))),d,&t);
1280: ARG3(BDY((LIST)BDY(TraceList))) = t;
1281: }
1.1 noro 1282: }
1283: }
1284:
1.37 noro 1285: NODE /* of DP */ NODE_sortb_insert( DP newdp, NODE /* of DP */ nd, int dec )
1.1 noro 1286: {
1287: register NODE last, p;
1288: register DL newdl = BDY(newdp)->dl;
1289: register int (*cmpfun)() = cmpdl, nv = CNVars;
1290: NODE newnd;
1291: int sgn = dec ? 1 : -1;
1292: MKNODE( newnd, newdp, 0 );
1293: if ( !(last = nd) || sgn*(*cmpfun)( nv, newdl, BDY((DP) BDY(last))->dl ) > 0 ) {
1294: NEXT(newnd) = last;
1295: return newnd;
1296: }
1297: for ( ; p = NEXT(last); last = p )
1298: if ( sgn*(*cmpfun)( nv, newdl, BDY((DP) BDY(p))->dl ) > 0 ) break;
1299: if ( p ) NEXT(NEXT(last) = newnd) = p;
1300: else NEXT(last) = newnd;
1301: return nd;
1302: }
1303:
1.37 noro 1304: NODE NODE_sortb( NODE node, int dec )
1.1 noro 1305: {
1306: register NODE nd, ans;
1307:
1308: for ( ans = 0, nd = node; nd; nd = NEXT(nd) )
1309: ans = NODE_sortb_insert( (DP) BDY(nd), ans, dec );
1310: return ans;
1311: }
1312:
1.37 noro 1313: NODE /* of index */ NODE_sortbi_insert( int newdpi, NODE /* of index */ nd, int dec )
1.1 noro 1314: {
1315: register NODE last, p;
1316: register DL newdl = psh[newdpi];
1317: register int (*cmpfun)() = cmpdl, nv = CNVars;
1318: NODE newnd;
1319: int sgn = dec ? 1 : -1;
1320: MKNODE( newnd, newdpi, 0 );
1321: if ( !(last = nd) || sgn*(*cmpfun)( nv, newdl, psh[(int)BDY(last)] ) > 0 ) {
1322: NEXT(newnd) = last;
1323: return newnd;
1324: }
1325: for ( ; p = NEXT(last); last = p )
1326: if ( sgn*(*cmpfun)( nv, newdl, psh[(int)BDY(p)] ) > 0 ) break;
1327: if ( p ) NEXT(NEXT(last) = newnd) = p;
1328: else NEXT(last) = newnd;
1329: return nd;
1330: }
1331:
1.37 noro 1332: NODE NODE_sortbi( NODE node, int dec )
1.1 noro 1333: {
1334: register NODE nd, ans;
1335:
1336: for ( ans = 0, nd = node; nd; nd = NEXT(nd) )
1337: ans = NODE_sortbi_insert( (int) BDY(nd), ans, dec );
1338: return ans;
1339: }
1340:
1.37 noro 1341: void reduceall(NODE in,NODE *h)
1.1 noro 1342: {
1343: NODE r,t,top;
1344: int n,i,j;
1345: int *w;
1346: DP g,g1;
1347: struct oEGT tmp0,tmp1;
1348:
1349: if ( NoRA ) {
1350: *h = in; return;
1351: }
1.12 noro 1352: if ( DP_Print || DP_PrintShort ) {
1.1 noro 1353: fprintf(asir_out,"reduceall\n"); fflush(asir_out);
1354: }
1355: r = NODE_sortbi(in,0);
1356: n = length(r);
1357: w = (int *)ALLOCA(n*sizeof(int));
1358: for ( i = 0, t = r; i < n; i++, t = NEXT(t) )
1359: w[i] = (int)BDY(t);
1360: for ( i = 0; i < n; i++ ) {
1361: for ( top = 0, j = n-1; j >= 0; j-- )
1362: if ( j != i ) {
1363: MKNODE(t,(pointer)w[j],top); top = t;
1364: }
1365: get_eg(&tmp0);
1366: dp_load(w[i],&ps[w[i]]);
1367:
1.7 noro 1368: if ( GenTrace ) {
1369: Q q;
1370: NODE node;
1371: LIST hist;
1372:
1373: STOQ(w[i],q);
1374: node = mknode(4,ONE,q,ONE,ONE);
1375: MKLIST(hist,node);
1376: MKNODE(TraceList,hist,0);
1377: }
1.16 noro 1378: _dp_nf(top,ps[w[i]],ps,1,&g);
1.1 noro 1379: prim_part(g,0,&g1);
1380: get_eg(&tmp1); add_eg(&eg_ra,&tmp0,&tmp1);
1.12 noro 1381: if ( DP_Print || DP_PrintShort ) {
1.1 noro 1382: fprintf(asir_out,"."); fflush(asir_out);
1383: }
1384: w[i] = newps(g1,0,(NODE)0);
1385: }
1386: for ( top = 0, j = n-1; j >= 0; j-- ) {
1387: MKNODE(t,(pointer)w[j],top); top = t;
1388: }
1389: *h = top;
1.12 noro 1390: if ( DP_Print || DP_PrintShort )
1.1 noro 1391: fprintf(asir_out,"\n");
1392: }
1393:
1.37 noro 1394: void reduceall_mod(NODE in,int m,NODE *h)
1.1 noro 1395: {
1396: NODE r,t,top;
1397: int n,i,j;
1398: int *w;
1.12 noro 1399: DP g,p;
1.1 noro 1400: struct oEGT tmp0,tmp1;
1401:
1402: if ( NoRA ) {
1403: *h = in; return;
1404: }
1.12 noro 1405: if ( DP_Print || DP_PrintShort ) {
1.1 noro 1406: fprintf(asir_out,"reduceall\n"); fflush(asir_out);
1407: }
1408: r = NODE_sortbi(in,0);
1409: n = length(r);
1410: w = (int *)ALLOCA(n*sizeof(int));
1411: for ( i = 0, t = r; i < n; i++, t = NEXT(t) )
1412: w[i] = (int)BDY(t);
1413: for ( i = 0; i < n; i++ ) {
1414: for ( top = 0, j = n-1; j >= 0; j-- )
1415: if ( j != i ) {
1416: MKNODE(t,(pointer)w[j],top); top = t;
1417: }
1418: get_eg(&tmp0);
1419: if ( PCoeffs )
1420: dp_nf_mod(top,ps[w[i]],ps,m,1,&g);
1.12 noro 1421: else {
1422: dpto_dp(ps[w[i]],&p);
1423: _dp_nf_mod_destructive(top,p,ps,m,1,&g);
1424: }
1.1 noro 1425: get_eg(&tmp1); add_eg(&eg_ra,&tmp0,&tmp1);
1.12 noro 1426: if ( DP_Print || DP_PrintShort ) {
1.1 noro 1427: fprintf(asir_out,"."); fflush(asir_out);
1428: }
1429: w[i] = newps_mod(g,m);
1430: }
1431: for ( top = 0, j = n-1; j >= 0; j-- ) {
1432: MKNODE(t,(pointer)w[j],top); top = t;
1433: }
1434: *h = top;
1.12 noro 1435: if ( DP_Print || DP_PrintShort )
1.1 noro 1436: fprintf(asir_out,"\n");
1437: }
1438:
1.37 noro 1439: int newps(DP a,int m,NODE subst)
1.1 noro 1440: {
1441: if ( m && !validhc(!a?0:BDY(a)->c,m,subst) )
1442: return -1;
1443: if ( psn == pslen ) {
1444: pslen *= 2;
1445: ps = (DP *)REALLOC((char *)ps,pslen*sizeof(DP));
1446: psh = (DL *)REALLOC((char *)psh,pslen*sizeof(DL));
1447: pss = (int *)REALLOC((char *)pss,pslen*sizeof(int));
1448: psc = (P *)REALLOC((char *)psc,pslen*sizeof(P));
1449: if ( m )
1450: psm = (DP *)REALLOC((char *)psm,pslen*sizeof(DP));
1451: }
1452: if ( Demand ) {
1453: if ( doing_f4 )
1454: ps[psn] = a;
1455: else
1456: ps[psn] = 0;
1.7 noro 1457: dp_save(psn,(Obj)a,0);
1.1 noro 1458: } else
1459: ps[psn] = a;
1460: psh[psn] = BDY(a)->dl;
1461: pss[psn] = a->sugar;
1462: psc[psn] = BDY(a)->c;
1463: if ( m )
1464: _dp_mod(a,m,subst,&psm[psn]);
1.7 noro 1465: if ( GenTrace ) {
1466: NODE tn,tr,tr1;
1.23 noro 1467: LIST trace,trace1;
1468: NODE arg;
1469: Q q1,q2;
1470: STRING fname;
1.37 noro 1471: Obj obj;
1.7 noro 1472:
1473: /* reverse the TraceList */
1474: tn = TraceList;
1475: for ( tr = 0; tn; tn = NEXT(tn) ) {
1476: MKNODE(tr1,BDY(tn),tr); tr = tr1;
1477: }
1478: MKLIST(trace,tr);
1479: if ( OXCheck >= 0 ) {
1480: STOQ(OXCheck,q1);
1481: MKSTR(fname,"check_trace");
1482: STOQ(psn,q2);
1483: arg = mknode(5,q1,fname,a,q2,trace);
1.37 noro 1484: Pox_cmo_rpc(arg,&obj);
1.23 noro 1485: } else if ( OXCheck < 0 ) {
1486: STOQ(psn,q1);
1487: tn = mknode(2,q1,trace);
1488: MKLIST(trace1,tn);
1489: MKNODE(tr,trace1,AllTraceList);
1490: AllTraceList = tr;
1.7 noro 1491: } else
1492: dp_save(psn,(Obj)trace,"t");
1493: TraceList = 0;
1494: }
1.1 noro 1495: return psn++;
1496: }
1497:
1.37 noro 1498: int newps_nosave(DP a,int m,NODE subst)
1.1 noro 1499: {
1500: if ( m && !validhc(!a?0:BDY(a)->c,m,subst) )
1501: return -1;
1502: if ( psn == pslen ) {
1503: pslen *= 2;
1504: ps = (DP *)REALLOC((char *)ps,pslen*sizeof(DP));
1505: psh = (DL *)REALLOC((char *)psh,pslen*sizeof(DL));
1506: pss = (int *)REALLOC((char *)pss,pslen*sizeof(int));
1507: psc = (P *)REALLOC((char *)psc,pslen*sizeof(P));
1508: if ( m )
1509: psm = (DP *)REALLOC((char *)psm,pslen*sizeof(DP));
1510: }
1511: ps[psn] = 0;
1512: psh[psn] = BDY(a)->dl;
1513: pss[psn] = a->sugar;
1514: psc[psn] = BDY(a)->c;
1515: if ( m )
1516: _dp_mod(a,m,subst,&psm[psn]);
1517: return psn++;
1518: }
1519:
1.37 noro 1520: int newps_mod(DP a,int m)
1.1 noro 1521: {
1522: if ( psn == pslen ) {
1523: pslen *= 2;
1524: ps = (DP *)REALLOC((char *)ps,pslen*sizeof(DP));
1525: psh = (DL *)REALLOC((char *)psh,pslen*sizeof(DL));
1526: pss = (int *)REALLOC((char *)pss,pslen*sizeof(int));
1527: psc = (P *)REALLOC((char *)psc,pslen*sizeof(P)); /* XXX */
1528: }
1529: ps[psn] = a;
1530: psh[psn] = BDY(ps[psn])->dl;
1531: pss[psn] = ps[psn]->sugar;
1532: return psn++;
1533: }
1534:
1.37 noro 1535: void reducebase_dehomo(NODE f,NODE *g)
1.1 noro 1536: {
1537: int n,i,j,k;
1538: int *r;
1539: DL *w,d;
1540: DP u;
1541: NODE t,top;
1542:
1543: n = length(f);
1544: w = (DL *)ALLOCA(n*sizeof(DL));
1545: r = (int *)ALLOCA(n*sizeof(int));
1546: for ( i = 0, t = f; i < n; i++, t = NEXT(t) ) {
1547: r[i] = (int)BDY(t); w[i] = psh[r[i]];
1548: }
1549: for ( i = 0; i < n; i++ ) {
1550: for ( j = 0, d = w[i]; j < n; j++ ) {
1551: if ( j != i ) {
1552: for ( k = 0; k < NVars; k++ )
1553: if ( d->d[k] < w[j]->d[k] )
1554: break;
1555: if ( k == NVars )
1556: break;
1557: }
1558: }
1559: if ( j != n )
1560: r[i] = -1;
1561: }
1562: for ( top = 0, i = n-1; i >= 0; i-- )
1563: if ( r[i] >= 0 ) {
1.7 noro 1564: dp_load(r[i],&ps[r[i]]); dp_dehomo(ps[r[i]],&u);
1565: if ( GenTrace ) {
1566: Q q;
1567: LIST hist;
1568: NODE node;
1569:
1570: STOQ(r[i],q);
1571: node = mknode(4,0,q,0,0);
1572: MKLIST(hist,node);
1573: MKNODE(TraceList,hist,0);
1574: }
1575: j = newps(u,0,0);
1.1 noro 1576: MKNODE(t,j,top); top = t;
1577: }
1578: *g = top;
1579: }
1580:
1.37 noro 1581: NODE append_one(NODE f,int n)
1.1 noro 1582: {
1583: NODE t;
1584:
1585: if ( Reverse || !f ) {
1586: MKNODE(t,(pointer)n,f); return t;
1587: } else {
1588: for ( t = f; NEXT(t); t = NEXT(t) );
1589: MKNODE(NEXT(t),(pointer)n,0);
1590: return f;
1591: }
1592: }
1593:
1.37 noro 1594: DP_pairs minp( DP_pairs d, DP_pairs *prest )
1.1 noro 1595: {
1596: register DP_pairs m, ml, p, l;
1597: register DL lcm;
1598: register int s, nv = CNVars;
1599: register int (*cmpfun)() = cmpdl;
1600:
1601: if ( !(p = NEXT(m = d)) ) {
1602: *prest = p;
1603: NEXT(m) = 0;
1604: return m;
1605: }
1606: for ( lcm = m->lcm, s = m->sugar, ml = 0, l = m; p; p = NEXT(l = p) )
1607: if ( NoSugar ? (*cmpfun)( nv, lcm, p->lcm ) >= 0 :
1608: (s > p->sugar || s == p->sugar && (*cmpfun)( nv, lcm, p->lcm ) >= 0) )
1609: ml = l, lcm = (m = p)->lcm, s = p->sugar;
1610: if ( !ml ) *prest = NEXT(m);
1611: else {
1612: NEXT(ml) = NEXT(m);
1613: *prest = d;
1614: }
1615: NEXT(m) = 0;
1616: return m;
1617: }
1618:
1.37 noro 1619: void minsugar(DP_pairs d,DP_pairs *dm,DP_pairs *dr)
1.1 noro 1620: {
1621: int msugar;
1622: DP_pairs t,dm0,dr0,dmt,drt;
1623:
1624: for ( msugar = d->sugar, t = NEXT(d); t; t = NEXT(t) )
1625: if ( t->sugar < msugar )
1626: msugar = t->sugar;
1627: dm0 = 0; dr0 = 0;
1628: for ( t = d; t; t = NEXT(t) ) {
1629: if ( t->sugar == msugar ) {
1630: NEXTDPP(dm0,dmt);
1631: dmt->dp1 = t->dp1; dmt->dp2 = t->dp2;
1632: dmt->lcm = t->lcm; dmt->sugar = t->sugar;
1633: } else {
1634: NEXTDPP(dr0,drt);
1635: drt->dp1 = t->dp1; drt->dp2 = t->dp2;
1636: drt->lcm = t->lcm; drt->sugar = t->sugar;
1637: }
1638: }
1639: if ( dm0 ) NEXT(dmt) = 0;
1640: if ( dr0 ) NEXT(drt) = 0;
1641: *dm = dm0; *dr = dr0;
1642: }
1643:
1.37 noro 1644: NODE gb(NODE f,int m,NODE subst)
1.1 noro 1645: {
1.42 noro 1646: int i,nh,prev,mag,mag0,magt;
1.1 noro 1647: NODE r,g,gall;
1.37 noro 1648: DP_pairs d;
1.1 noro 1649: DP_pairs l;
1650: DP h,nf,nfm,dp1,dp2;
1651: MP mp;
1.37 noro 1652: struct oEGT tnf0,tnf1,tnfm0,tnfm1,tpz0,tpz1,tnp0,tnp1;
1.1 noro 1653: int skip_nf_flag;
1654: double t_0;
1.7 noro 1655: Q q;
1.6 noro 1656: int new_sugar;
1.1 noro 1657: static prev_sugar = -1;
1658:
1659: Max_mag = 0;
1.42 noro 1660: Max_coef = 0;
1.1 noro 1661: prev = 1;
1662: doing_f4 = 0;
1663: if ( m ) {
1664: psm = (DP *)MALLOC(pslen*sizeof(DP));
1665: for ( i = 0; i < psn; i++ )
1666: if ( psh[i] && !validhc(psc[i],m,subst) )
1667: return 0;
1668: else
1669: _dp_mod(ps[i],m,subst,&psm[i]);
1670: }
1671: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
1672: i = (int)BDY(r);
1673: d = updpairs(d,g,i);
1674: g = updbase(g,i);
1675: gall = append_one(gall,i);
1676: }
1677: while ( d ) {
1.14 noro 1678: l = minp(d,&d);
1.1 noro 1679: if ( m ) {
1.6 noro 1680: _dp_sp_mod_dup(psm[l->dp1],psm[l->dp2],m,&h);
1.10 noro 1681: if ( h )
1682: new_sugar = h->sugar;
1.1 noro 1683: get_eg(&tnfm0);
1.6 noro 1684: _dp_nf_mod_destructive(gall,h,psm,m,0,&nfm);
1.1 noro 1685: get_eg(&tnfm1); add_eg(&eg_nfm,&tnfm0,&tnfm1);
1686: } else
1687: nfm = (DP)1;
1688: if ( nfm ) {
1689: if ( Demand ) {
1690: if ( dp_load_t(psn,&nf) ) {
1691: skip_nf_flag = 1;
1692: goto skip_nf;
1693: } else {
1694: skip_nf_flag = 0;
1695: dp_load(l->dp1,&dp1); dp_load(l->dp2,&dp2);
1696: dp_sp(dp1,dp2,&h);
1697: }
1698: } else
1699: dp_sp(ps[l->dp1],ps[l->dp2],&h);
1.7 noro 1700: if ( GenTrace ) {
1701: STOQ(l->dp1,q); ARG1(BDY((LIST)BDY(NEXT(TraceList)))) = q;
1702: STOQ(l->dp2,q); ARG1(BDY((LIST)BDY(TraceList))) = q;
1703: }
1.10 noro 1704: if ( h )
1705: new_sugar = h->sugar;
1.1 noro 1706: get_eg(&tnf0);
1707: t_0 = get_rtime();
1.18 noro 1708: if ( PCoeffs || dp_fcoeffs )
1.16 noro 1709: _dp_nf(gall,h,ps,!Top,&nf);
1710: else
1.21 noro 1711: _dp_nf_z(gall,h,ps,!Top,DP_Multiple,&nf);
1.50 noro 1712: if ( DP_Print && nf )
1.1 noro 1713: fprintf(asir_out,"(%.3g)",get_rtime()-t_0);
1714: get_eg(&tnf1); add_eg(&eg_nf,&tnf0,&tnf1);
1715: } else
1716: nf = 0;
1717: skip_nf:
1718: if ( nf ) {
1719: NZR++;
1720: get_eg(&tpz0);
1721: prim_part(nf,0,&h);
1722: get_eg(&tpz1); add_eg(&eg_pz,&tpz0,&tpz1);
1723: get_eg(&tnp0);
1724: if ( Demand && skip_nf_flag )
1725: nh = newps_nosave(h,m,subst);
1726: else
1727: nh = newps(h,m,subst);
1728: get_eg(&tnp1); add_eg(&eg_np,&tnp0,&tnp1);
1729: if ( nh < 0 )
1730: return 0;
1731: d = updpairs(d,g,nh);
1732: g = updbase(g,nh);
1733: gall = append_one(gall,nh);
1734: if ( !dp_fcoeffs && ShowMag ) {
1.42 noro 1735: for ( mag = 0, mag0 = 0, mp = BDY(h); mp; mp = NEXT(mp) ) {
1736: magt = p_mag((P)mp->c);
1737: mag0 = MAX(mag0,magt);
1738: mag += magt;
1739: }
1740: Max_coef = MAX(Max_coef,mag0);
1.1 noro 1741: Max_mag = MAX(Max_mag,mag);
1742: }
1.12 noro 1743: if ( DP_Print ) {
1.1 noro 1744: if ( !prev )
1745: fprintf(asir_out,"\n");
1746: print_split_e(&tnf0,&tnf1); print_split_e(&tpz0,&tpz1);
1747: printdl(psh[nh]);
1748: fprintf(asir_out,"(%d,%d),nb=%d,nab=%d,rp=%d,sugar=%d",
1749: l->dp1,l->dp2,length(g),length(gall),DPPlength(d),
1750: pss[nh]);
1751: if ( ShowMag )
1.42 noro 1752: fprintf(asir_out,",mag=(%d,%d)",mag,mag0);
1.1 noro 1753: fprintf(asir_out,"\n"); fflush(asir_out);
1.12 noro 1754: } else if ( DP_PrintShort ) {
1.1 noro 1755: fprintf(asir_out,"+"); fflush(asir_out);
1756: }
1757: prev = 1;
1758: } else {
1759: if ( m )
1760: add_eg(&eg_znfm,&tnfm0,&tnfm1);
1761: ZR++;
1.12 noro 1762: if ( DP_Print || DP_PrintShort ) {
1.6 noro 1763: if ( new_sugar != prev_sugar ) {
1764: fprintf(asir_out,"[%d]",new_sugar);
1765: prev_sugar = new_sugar;
1.1 noro 1766: }
1767: fprintf(asir_out,"."); fflush(asir_out); prev = 0;
1768: }
1769: }
1770: }
1.12 noro 1771: if ( DP_Print || DP_PrintShort )
1.1 noro 1772: fprintf(asir_out,"gb done\n");
1773: return g;
1774: }
1775:
1.37 noro 1776: NODE gb_mod(NODE f,int m)
1.1 noro 1777: {
1778: int i,nh,prev;
1779: NODE r,g,gall;
1.37 noro 1780: DP_pairs d;
1.1 noro 1781: DP_pairs l;
1782: DP h,nf;
1.37 noro 1783: struct oEGT tnfm0,tnfm1,tpz0,tpz1;
1.1 noro 1784:
1785: prev = 1;
1786: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
1787: i = (int)BDY(r);
1788: d = updpairs(d,g,i);
1789: g = updbase(g,i);
1790: gall = append_one(gall,i);
1791: }
1792: while ( d ) {
1.14 noro 1793: l = minp(d,&d);
1.1 noro 1794: if ( PCoeffs ) {
1795: dp_sp_mod(ps[l->dp1],ps[l->dp2],m,&h);
1.14 noro 1796: get_eg(&tnfm0);
1.1 noro 1797: dp_nf_mod(gall,h,ps,m,!Top,&nf);
1798: } else {
1.6 noro 1799: _dp_sp_mod_dup(ps[l->dp1],ps[l->dp2],m,&h);
1.14 noro 1800: get_eg(&tnfm0);
1.6 noro 1801: _dp_nf_mod_destructive(gall,h,ps,m,!Top,&nf);
1.1 noro 1802: }
1803: get_eg(&tnfm1); add_eg(&eg_nfm,&tnfm0,&tnfm1);
1804: if ( nf ) {
1805: NZR++;
1806: get_eg(&tpz0);
1807: prim_part(nf,m,&h);
1808: get_eg(&tpz1); add_eg(&eg_pz,&tpz0,&tpz1);
1809: nh = newps_mod(h,m);
1810: if ( nh < 0 )
1811: return 0;
1812: d = updpairs(d,g,nh);
1813: g = updbase(g,nh);
1814: gall = append_one(gall,nh);
1.12 noro 1815: if ( DP_Print ) {
1.1 noro 1816: if ( !prev )
1817: fprintf(asir_out,"\n");
1818: print_split_eg(&tnfm0,&tnfm1); fflush(asir_out);
1819: fprintf(asir_out,"(%d,%d),nb=%d,nab=%d,rp=%d,sugar=%d",l->dp1,l->dp2,length(g),length(gall),DPPlength(d),pss[nh]);
1820: printdl(psh[nh]); fprintf(asir_out,"\n"); fflush(asir_out);
1.12 noro 1821: } else if ( DP_PrintShort ) {
1.6 noro 1822: fprintf(asir_out,"+"); fflush(asir_out);
1.1 noro 1823: }
1824: prev = 1;
1825: } else {
1826: add_eg(&eg_znfm,&tnfm0,&tnfm1);
1827: ZR++;
1.12 noro 1828: if ( DP_Print || DP_PrintShort ) {
1.1 noro 1829: fprintf(asir_out,"."); fflush(asir_out); prev = 0;
1830: }
1831: }
1832: }
1.12 noro 1833: if ( DP_Print || DP_PrintShort )
1.1 noro 1834: fprintf(asir_out,"gb_mod done\n");
1835: return g;
1836: }
1837:
1.37 noro 1838: DP_pairs updpairs( DP_pairs d, NODE /* of index */ g, int t)
1.1 noro 1839: {
1.14 noro 1840: register DP_pairs d1, dd, nd;
1841: int dl,dl1;
1.1 noro 1842:
1.14 noro 1843: if ( !g ) return d;
1844: if ( !NoCriB && d ) {
1845: dl = DPPlength(d);
1846: d = criterion_B( d, t );
1847: dl -= DPPlength(d); NBP += dl;
1.1 noro 1848: }
1.14 noro 1849: d1 = newpairs( g, t );
1850: if ( NEXT(d1) ) {
1851: dl = DPPlength(d1); TP += dl;
1852: d1 = criterion_M( d1 );
1853: dl1 = DPPlength(d1); NMP += (dl-dl1); dl = dl1;
1854: d1 = criterion_F( d1 );
1855: dl1 = DPPlength(d1); NFP += (dl-dl1); dl = dl1;
1856: } else
1857: dl = 1;
1858: if ( !do_weyl )
1859: for ( dd = 0; d1; d1 = nd ) {
1860: nd = NEXT(d1);
1861: if ( !criterion_2( d1->dp1, d1->dp2 ) ) {
1862: NEXT(d1) = dd;
1863: dd = d1;
1.1 noro 1864: }
1865: }
1.14 noro 1866: else
1867: dd = d1;
1868: dl1 = DPPlength(dd); NDP += (dl-dl1);
1869: if ( !(nd = d) ) return dd;
1870: while ( nd = NEXT(d1 = nd) ) ;
1871: NEXT(d1) = dd;
1872: return d;
1.1 noro 1873: }
1874:
1.37 noro 1875: DP_pairs newpairs( NODE /* of index */ g, int t )
1.14 noro 1876: {
1877: register NODE r;
1878: register DL tdl = psh[t];
1879: register int ts;
1880: register DP_pairs p, last;
1881: int dp;
1882: register DL dl;
1883: register int s;
1.1 noro 1884:
1.14 noro 1885: ts = pss[t] - tdl->td;
1886: for ( last = 0, r = g; r; r = NEXT(r) ) {
1887: NEXT(p = NEWDP_pairs) = last;
1888: last = p;
1889: dp = p->dp1 = (int)BDY(r); p->dp2 = t;
1890: p->lcm = lcm_of_DL(CNVars, dl = psh[dp], tdl, (DL)0 );
1891: #if 0
1892: if ( do_weyl )
1.41 noro 1893: p->sugar = dl_weyl_weight(p->lcm);
1.14 noro 1894: else
1895: #endif
1896: p->sugar = (ts > (s = pss[dp] - dl->td) ? ts : s) + p->lcm->td;
1897: }
1898: return last;
1899: }
1.1 noro 1900:
1.37 noro 1901: DP_pairs criterion_B( DP_pairs d, int s )
1.1 noro 1902: {
1.14 noro 1903: register DP_pairs dd, p;
1904: register DL tij, t = psh[s], dltmp;
1.1 noro 1905:
1.14 noro 1906: if ( !d ) return 0;
1907: NEWDL( dltmp, CNVars );
1908: for ( dd = 0; d; d = p ) {
1909: p = NEXT(d),
1910: tij = d->lcm;
1911: if ( tij->td != lcm_of_DL(CNVars, tij, t, dltmp )->td
1912: || !dl_equal(CNVars, tij, dltmp )
1913: || (tij->td == lcm_of_DL(CNVars, psh[d->dp1], t, dltmp )->td
1914: && dl_equal(CNVars, dltmp, tij ))
1915: || (tij->td == lcm_of_DL(CNVars, psh[d->dp2], t, dltmp )->td
1916: && dl_equal(CNVars, dltmp, tij )) ) {
1917: NEXT(d) = dd;
1918: dd = d;
1919: }
1.1 noro 1920: }
1.14 noro 1921: return dd;
1922: }
1.1 noro 1923:
1.37 noro 1924: DP_pairs criterion_M( DP_pairs d1 )
1.14 noro 1925: {
1926: register DP_pairs dd, e, d3, d2, p;
1927: register DL itdl, jtdl;
1928: register int itdltd, jtdltd;
1.1 noro 1929:
1.14 noro 1930: for ( dd = 0, e = d1; e; e = d3 ) {
1931: if ( !(d2 = NEXT(e)) ) {
1932: NEXT(e) = dd;
1933: return e;
1934: }
1935: itdltd = (itdl = e->lcm)->td;
1936: for ( d3 = 0; d2; d2 = p ) {
1937: p = NEXT(d2),
1938: jtdltd = (jtdl = d2->lcm)->td;
1939: if ( jtdltd == itdltd )
1940: if ( dl_equal(CNVars, itdl, jtdl ) ) ;
1941: else if ( dl_redble( jtdl, itdl ) ) continue;
1942: else if ( dl_redble( itdl, jtdl ) ) goto delit;
1943: else ;
1944: else if ( jtdltd > itdltd )
1945: if ( dl_redble( jtdl, itdl ) ) continue;
1.1 noro 1946: else ;
1947: else if ( dl_redble( itdl, jtdl ) ) goto delit;
1948: NEXT(d2) = d3;
1949: d3 = d2;
1950: }
1951: NEXT(e) = dd;
1952: dd = e;
1953: continue;
1954: /**/
1955: delit: NEXT(d2) = d3;
1956: d3 = d2;
1957: for ( ; p; p = d2 ) {
1958: d2 = NEXT(p);
1959: NEXT(p) = d3;
1960: d3 = p;
1961: }
1962: }
1963: return dd;
1964: }
1965:
1.37 noro 1966: static DP_pairs collect_pairs_of_hdlcm( DP_pairs d1, DP_pairs *prest )
1.1 noro 1967: {
1968: register DP_pairs w, p, r, s;
1969: register DL ti;
1970: register int td;
1971:
1972: td = (ti = (w = d1)->lcm)->td;
1973: s = NEXT(w);
1974: NEXT(w) = 0;
1975: for ( r = 0; s; s = p ) {
1976: p = NEXT(s);
1977: if ( td == s->lcm->td && dl_equal(CNVars, ti, s->lcm ) )
1978: {
1979: NEXT(s) = w;
1980: w = s;
1981: } else {
1982: NEXT(s) = r;
1983: r = s;
1984: }
1985: }
1986: *prest = r;
1987: return w;
1988: }
1989:
1.37 noro 1990: int criterion_2( int dp1, int dp2 )
1.1 noro 1991: {
1992: register int i, *d1, *d2;
1993:
1994: d1 = psh[dp1]->d, d2 = psh[dp2]->d;
1995: for ( i = CNVars; --i >= 0; d1++, d2++ )
1996: if ( (*d1 <= *d2 ? *d1 : *d2) > 0 ) return 0;
1997: return 1;
1998: }
1999:
1.37 noro 2000: DP_pairs criterion_F( DP_pairs d1 )
1.1 noro 2001: {
2002: DP_pairs rest, head;
2003: register DP_pairs last, p, r, w;
2004: register int s;
2005:
2006: for ( head = last = 0, p = d1; NEXT(p); ) {
2007: s = (r = w = collect_pairs_of_hdlcm( p, &rest ))->sugar;
2008: while ( w = NEXT(w) )
1.52 noro 2009: if ( !do_weyl && criterion_2( w->dp1, w->dp2 ) ) {
1.1 noro 2010: r = w;
2011: break;
2012: } else if ( w->sugar < s ) s = (r = w)->sugar;
2013: if ( last ) NEXT(last) = r;
2014: else head = r;
2015: NEXT(last = r) = 0;
2016: if ( !(p = rest) ) return head;
2017: }
2018: if ( !last ) return p;
2019: NEXT(last) = p;
2020: return head;
2021: }
2022:
1.37 noro 2023: NODE updbase(NODE g,int t)
1.1 noro 2024: {
2025: g = remove_reducibles(g,t);
2026: g = append_one(g,t);
2027: return g;
2028: }
2029:
1.37 noro 2030: NODE /* of index */ remove_reducibles(NODE /* of index */ nd, int newdp )
1.1 noro 2031: {
2032: register DL dl, dln;
2033: register NODE last, p, head;
2034: register int td;
2035:
2036: dl = psh[newdp];
2037: td = dl->td;
2038: for ( head = last = 0, p = nd; p; ) {
2039: dln = psh[(int)BDY(p)];
2040: if ( dln->td >= td && dl_redble( dln, dl ) ) {
2041: p = NEXT(p);
2042: if ( last ) NEXT(last) = p;
2043: } else {
2044: if ( !last ) head = p;
2045: p = NEXT(last = p);
2046: }
2047: }
2048: return head;
2049: }
2050:
1.37 noro 2051: int dl_redble(DL dl1,DL dl2)
1.1 noro 2052: {
2053: register int n, *d1, *d2;
2054:
2055: for ( d1 = dl1->d, d2 = dl2->d, n = CNVars; --n >= 0; d1++, d2++ )
2056: if ( *d1 < *d2 ) return 0;
2057: return 1;
1.5 noro 2058: }
2059:
1.41 noro 2060: #if 0
2061: int dl_weyl_weight(DL dl)
1.5 noro 2062: {
2063: int n,w,i;
2064:
2065: n = CNVars/2;
2066: for ( i = 0, w = 0; i < n; i++ )
2067: w += (-dl->d[i]+dl->d[n+i]);
2068: return w;
1.1 noro 2069: }
1.41 noro 2070: #endif
1.1 noro 2071:
1.37 noro 2072: int gbcheck(NODE f)
1.1 noro 2073: {
2074: int i;
2075: NODE r,g,gall;
2076: DP_pairs d,l;
2077: DP h,nf,dp1,dp2;
2078: struct oEGT tmp0,tmp1;
2079:
2080: if ( NoGC )
2081: return 1;
2082: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
2083: i = (int)BDY(r);
2084: d = updpairs(d,g,i);
2085: g = updbase(g,i);
2086: gall = append_one(gall,i);
2087: }
1.12 noro 2088: if ( DP_Print || DP_PrintShort ) {
1.1 noro 2089: fprintf(asir_out,"gbcheck total %d pairs\n",DPPlength(d)); fflush(asir_out);
2090: }
2091: while ( d ) {
2092: l = d; d = NEXT(d);
2093: get_eg(&tmp0);
1.17 noro 2094: dp_load(l->dp1,&dp1); dp_load(l->dp2,&dp2);
2095: dp_sp(dp1,dp2,&h);
2096: /* fprintf(stderr,"{%d,%d}",l->dp1,l->dp2); */
1.16 noro 2097: _dp_nf(gall,h,ps,1,&nf);
1.1 noro 2098: get_eg(&tmp1); add_eg(&eg_gc,&tmp0,&tmp1);
1.12 noro 2099: if ( DP_Print || DP_PrintShort ) {
1.1 noro 2100: fprintf(asir_out,"."); fflush(asir_out);
2101: }
2102: if ( nf )
2103: return 0;
2104: }
1.12 noro 2105: if ( DP_Print || DP_PrintShort )
1.1 noro 2106: fprintf(asir_out,"\n");
2107: return 1;
1.38 noro 2108: }
2109:
1.40 noro 2110: void gbcheck_list(NODE f,int n,VECT *gp,LIST *pp)
1.38 noro 2111: {
2112: int i;
2113: NODE r,g,gall,u,u0,t;
1.39 noro 2114: VECT vect;
1.38 noro 2115: LIST pair;
2116: DP_pairs d,l;
2117: Q q1,q2;
2118:
1.40 noro 2119: /* we need the following settings */
2120: NVars = CNVars = n;
1.39 noro 2121: setup_arrays(f,0,&r);
2122: for ( gall = g = 0, d = 0; r; r = NEXT(r) ) {
1.38 noro 2123: i = (int)BDY(r);
2124: d = updpairs(d,g,i);
2125: g = updbase(g,i);
2126: gall = append_one(gall,i);
2127: }
1.39 noro 2128: NEWVECT(vect); vect->len = psn; vect->body = (pointer)ps;
2129: *gp = vect;
2130:
1.38 noro 2131: for ( u0 = 0, l = d; l; l = NEXT(l) ) {
2132: NEXTNODE(u0,u);
2133: STOQ(l->dp1,q1);
2134: STOQ(l->dp2,q2);
2135: t = mknode(2,q1,q2);
2136: MKLIST(pair,t);
2137: BDY(u) = (pointer)pair;
2138: }
2139: if ( u0 )
2140: NEXT(u) = 0;
1.39 noro 2141: MKLIST(*pp,u0);
1.1 noro 2142: }
2143:
1.37 noro 2144: int membercheck(NODE f,NODE x)
1.1 noro 2145: {
2146: DP g;
2147: struct oEGT tmp0,tmp1;
2148:
2149: if ( NoMC )
2150: return 1;
1.12 noro 2151: if ( DP_Print || DP_PrintShort ) {
1.1 noro 2152: fprintf(asir_out,"membercheck\n"); fflush(asir_out);
2153: }
2154: for ( ; f; f = NEXT(f) ) {
2155: get_eg(&tmp0);
1.16 noro 2156: _dp_nf(x,(DP)BDY(f),ps,1,&g);
1.1 noro 2157: get_eg(&tmp1); add_eg(&eg_mc,&tmp0,&tmp1);
1.12 noro 2158: if ( DP_Print ) {
1.1 noro 2159: print_split_eg(&tmp0,&tmp1); fflush(asir_out);
1.12 noro 2160: } else if ( DP_PrintShort ) {
1.1 noro 2161: fprintf(asir_out,"."); fflush(asir_out);
2162: }
2163: if ( g )
2164: return 0;
2165: }
1.12 noro 2166: if ( DP_Print || DP_PrintShort )
1.1 noro 2167: fprintf(asir_out,"\n");
2168: return 1;
2169: }
2170:
1.37 noro 2171: void dp_set_flag(Obj name,Obj value)
1.1 noro 2172: {
2173: char *n;
2174: int v;
1.43 noro 2175: Q ratio;
1.1 noro 2176:
2177: if ( OID(name) != O_STR )
2178: return;
2179: n = BDY((STRING)name);
2180: if ( !strcmp(n,"Demand") ) {
2181: Demand = value ? BDY((STRING)value) : 0; return;
2182: }
2183: if ( !strcmp(n,"Dist") ) {
2184: Dist = (LIST)value; return;
2185: }
1.43 noro 2186: if ( !strcmp(n,"Content") ) {
2187: ratio = (Q)value;
2188: if ( ratio ) {
2189: DP_Multiple = BD(NM(ratio))[0];
2190: Denominator = INT(ratio) ? 1 : BD(DN(ratio))[0];
2191: } else {
2192: DP_Multiple = 0;
2193: Denominator = 1;
2194: }
2195: }
1.1 noro 2196: if ( value && OID(value) != O_N )
2197: return;
2198: v = QTOS((Q)value);
2199: if ( !strcmp(n,"NoSugar") )
2200: NoSugar = v;
2201: else if ( !strcmp(n,"NoCriB") )
2202: NoCriB = v;
2203: else if ( !strcmp(n,"NoGC") )
2204: NoGC = v;
2205: else if ( !strcmp(n,"NoMC") )
2206: NoMC = v;
2207: else if ( !strcmp(n,"NoRA") )
2208: NoRA = v;
2209: else if ( !strcmp(n,"NoGCD") )
2210: NoGCD = v;
2211: else if ( !strcmp(n,"Top") )
2212: Top = v;
2213: else if ( !strcmp(n,"ShowMag") )
2214: ShowMag = v;
1.14 noro 2215: else if ( !strcmp(n,"PrintShort") )
1.12 noro 2216: DP_PrintShort = v;
1.14 noro 2217: else if ( !strcmp(n,"Print") )
1.12 noro 2218: DP_Print = v;
1.14 noro 2219: else if ( !strcmp(n,"NFStat") )
2220: DP_NFStat = v;
1.1 noro 2221: else if ( !strcmp(n,"Stat") )
2222: Stat = v;
2223: else if ( !strcmp(n,"Reverse") )
2224: Reverse = v;
2225: else if ( !strcmp(n,"Multiple") )
1.14 noro 2226: DP_Multiple = v;
1.1 noro 2227: else if ( !strcmp(n,"Denominator") )
2228: Denominator = v;
2229: else if ( !strcmp(n,"PtozpRA") )
2230: PtozpRA = v;
1.7 noro 2231: else if ( !strcmp(n,"GenTrace") )
2232: GenTrace = v;
2233: else if ( !strcmp(n,"OXCheck") )
2234: OXCheck = v;
1.1 noro 2235: }
2236:
1.37 noro 2237: void dp_make_flaglist(LIST *list)
1.1 noro 2238: {
1.43 noro 2239: Q v,nm,dn;
1.1 noro 2240: STRING name,path;
2241: NODE n,n1;
2242:
1.43 noro 2243: #if 0
1.14 noro 2244: STOQ(DP_Multiple,v); MKNODE(n,v,0); MKSTR(name,"DP_Multiple"); MKNODE(n1,name,n); n = n1;
1.1 noro 2245: STOQ(Denominator,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"Denominator"); MKNODE(n1,name,n); n = n1;
1.43 noro 2246: #else
2247: if ( DP_Multiple ) {
2248: STOQ(DP_Multiple,nm); STOQ(Denominator,dn); divq(nm,dn,&v);
2249: } else
2250: v = 0;
2251: MKNODE(n,v,0); MKSTR(name,"Content"); MKNODE(n1,name,n); n = n1;
2252: #endif
1.1 noro 2253: MKNODE(n1,Dist,n); n = n1; MKSTR(name,"Dist"); MKNODE(n1,name,n); n = n1;
2254: STOQ(Reverse,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"Reverse"); MKNODE(n1,name,n); n = n1;
2255: STOQ(Stat,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"Stat"); MKNODE(n1,name,n); n = n1;
1.14 noro 2256: STOQ(DP_Print,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"Print"); MKNODE(n1,name,n); n = n1;
1.20 noro 2257: STOQ(DP_PrintShort,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"PrintShort"); MKNODE(n1,name,n); n = n1;
1.14 noro 2258: STOQ(DP_NFStat,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NFStat"); MKNODE(n1,name,n); n = n1;
1.7 noro 2259: STOQ(OXCheck,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"OXCheck"); MKNODE(n1,name,n); n = n1;
2260: STOQ(GenTrace,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"GenTrace"); MKNODE(n1,name,n); n = n1;
1.1 noro 2261: STOQ(PtozpRA,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"PtozpRA"); MKNODE(n1,name,n); n = n1;
2262: STOQ(ShowMag,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"ShowMag"); MKNODE(n1,name,n); n = n1;
2263: STOQ(Top,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"Top"); MKNODE(n1,name,n); n = n1;
2264: STOQ(NoGCD,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NoGCD"); MKNODE(n1,name,n); n = n1;
2265: STOQ(NoRA,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NoRA"); MKNODE(n1,name,n); n = n1;
2266: STOQ(NoMC,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NoMC"); MKNODE(n1,name,n); n = n1;
2267: STOQ(NoGC,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NoGC"); MKNODE(n1,name,n); n = n1;
2268: STOQ(NoCriB,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NoCriB"); MKNODE(n1,name,n); n = n1;
2269: STOQ(NoSugar,v); MKNODE(n1,v,n); n = n1; MKSTR(name,"NoSugar"); MKNODE(n1,name,n); n = n1;
2270: if ( Demand )
2271: MKSTR(path,Demand);
2272: else
2273: path = 0;
2274: MKNODE(n1,path,n); n = n1; MKSTR(name,"Demand"); MKNODE(n1,name,n); n = n1;
2275: MKLIST(*list,n);
2276: }
2277:
2278: #define DELIM '/'
2279:
1.37 noro 2280: void dp_save(int index,Obj p,char *prefix)
1.1 noro 2281: {
2282: FILE *fp;
2283: char path[BUFSIZ];
2284:
1.7 noro 2285: if ( prefix )
2286: sprintf(path,"%s%c%s%d",Demand,DELIM,prefix,index);
2287: else
2288: sprintf(path,"%s%c%d",Demand,DELIM,index);
1.1 noro 2289: if ( !(fp = fopen(path,"wb") ) )
2290: error("dp_save : cannot open a file");
1.7 noro 2291: savevl(fp,VC); saveobj(fp,p); fclose(fp);
1.1 noro 2292: }
2293:
1.37 noro 2294: void dp_load(int index,DP *p)
1.1 noro 2295: {
2296: FILE *fp;
2297: char path[BUFSIZ];
2298:
2299: if ( !Demand || ps[index] )
2300: *p = ps[index];
2301: else {
2302: sprintf(path,"%s%c%d",Demand,DELIM,index);
2303: if ( !(fp = fopen(path,"rb") ) )
2304: error("dp_load : cannot open a file");
1.45 noro 2305: if ( PCoeffs )
2306: loadvl(fp);
2307: else
2308: skipvl(fp);
2309: loadobj(fp,(Obj *)p); fclose(fp);
1.1 noro 2310: }
2311: }
2312:
1.37 noro 2313: int dp_load_t(int index,DP *p)
1.1 noro 2314: {
2315: FILE *fp;
2316: char path[BUFSIZ];
2317:
2318: sprintf(path,"%s%c%d",Demand,DELIM,index);
2319: if ( !(fp = fopen(path,"rb") ) )
2320: return 0;
2321: else {
1.45 noro 2322: if ( PCoeffs )
2323: loadvl(fp);
2324: else
2325: skipvl(fp);
2326: loadobj(fp,(Obj *)p); fclose(fp); return 1;
1.1 noro 2327: }
2328: }
2329:
2330: void init_stat() {
2331: init_eg(&eg_nf); init_eg(&eg_nfm); init_eg(&eg_znfm);
1.14 noro 2332: init_eg(&eg_pz); init_eg(&eg_np);
1.1 noro 2333: init_eg(&eg_ra); init_eg(&eg_mc); init_eg(&eg_gc);
1.35 noro 2334: ZR = NZR = TP = NMP = NBP = NFP = NDP = 0;
1.1 noro 2335: }
2336:
2337: void print_stat() {
1.12 noro 2338: if ( !DP_Print && !Stat )
1.1 noro 2339: return;
2340: print_eg("NF",&eg_nf); print_eg("NFM",&eg_nfm); print_eg("ZNFM",&eg_znfm);
1.14 noro 2341: print_eg("PZ",&eg_pz); print_eg("NP",&eg_np);
1.1 noro 2342: print_eg("RA",&eg_ra); print_eg("MC",&eg_mc); print_eg("GC",&eg_gc);
2343: fprintf(asir_out,"T=%d,B=%d M=%d F=%d D=%d ZR=%d NZR=%d\n",TP,NBP,NMP,NFP,NDP,ZR,NZR);
2344: }
1.14 noro 2345:
2346: /*
2347: * dp_nf used in gb()
2348: *
2349: */
2350:
2351: double pz_t_e, pz_t_d, pz_t_d1, pz_t_c, im_t_s, im_t_r;
2352:
2353: extern int GenTrace;
2354: extern NODE TraceList;
1.15 noro 2355: extern int mpi_mag;
2356:
1.37 noro 2357: void dp_mulc_d(DP p,P c,DP *r)
1.15 noro 2358: {
2359: if ( Dist && BDY(Dist)
2360: && HMAG(p) > mpi_mag
2361: && p_mag((P)c) > mpi_mag ) {
2362: if ( DP_NFStat ) fprintf(asir_out,"~");
2363: dp_imul_d(p,(Q)c,r);
2364: } else {
2365: if ( DP_NFStat ) fprintf(asir_out,"_");
2366: muldc(CO,p,c,r);
2367: }
2368: }
1.14 noro 2369:
1.37 noro 2370: void _dp_nf(NODE b,DP g,DP *ps,int full,DP *rp)
1.16 noro 2371: {
2372: DP u,p,d,s,t,mult;
2373: P coef;
2374: NODE l;
2375: MP m,mr;
2376: int sugar,psugar;
2377:
2378: if ( !g ) {
2379: *rp = 0; return;
2380: }
2381: sugar = g->sugar;
2382: for ( d = 0; g; ) {
2383: for ( u = 0, l = b; l; l = NEXT(l) ) {
2384: if ( dl_redble(BDY(g)->dl,psh[(int)BDY(l)]) ) {
2385: dp_load((int)BDY(l),&p);
2386: /* t+u = coef*(d+g) - mult*p (t = coef*d) */
2387: dp_red(d,g,p,&t,&u,&coef,&mult);
2388: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
2389: sugar = MAX(sugar,psugar);
2390: if ( GenTrace ) {
2391: LIST hist;
2392: Q cq;
2393: NODE node,node0;
2394:
2395: STOQ((int)BDY(l),cq);
2396: node0 = mknode(4,coef,cq,mult,ONE);
2397: MKLIST(hist,node0);
2398: MKNODE(node,hist,TraceList); TraceList = node;
2399: }
2400: if ( !u ) {
2401: if ( d )
2402: d->sugar = sugar;
2403: *rp = d; return;
2404: }
2405: d = t;
2406: break;
2407: }
2408: }
2409: if ( u )
2410: g = u;
2411: else if ( !full ) {
2412: if ( g ) {
2413: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
2414: }
2415: *rp = g; return;
2416: } else {
2417: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
2418: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
2419: addd(CO,d,t,&s); d = s;
2420: dp_rest(g,&t); g = t;
2421: }
2422: }
2423: if ( d )
2424: d->sugar = sugar;
2425: *rp = d;
2426: }
2427:
1.37 noro 2428: void _dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,DP *r)
1.14 noro 2429: {
1.37 noro 2430: DP u,dp,rp,t,t1,red,shift;
1.14 noro 2431: Q dc,rc,dcq,rcq,cont,hr,hred,cr,cred,mcred,c,gcd,cq;
2432: NODE l;
2433: int hmag,denom;
2434: int sugar,psugar;
2435: STRING imul;
1.37 noro 2436: double t_0,tt,t_p,t_m,t_g,t_a;
1.14 noro 2437: LIST hist;
2438: NODE node;
2439: Q rcred,mrcred;
2440:
2441: if ( !g ) {
2442: *r = 0; return;
2443: }
2444: pz_t_e = pz_t_d = pz_t_d1 = pz_t_c = 0;
1.15 noro 2445: t_p = t_m = t_g = t_a = 0;
1.14 noro 2446:
2447: denom = Denominator?Denominator:1;
2448: hmag = multiple*HMAG(g)/denom;
2449: sugar = g->sugar;
2450:
2451: dc = 0; dp = 0; rc = ONE; rp = g;
2452: MKSTR(imul,"dp_imul_index");
2453:
2454: /* g = dc*dp+rc*rp */
2455: for ( ; rp; ) {
2456: for ( u = 0, l = b; l; l = NEXT(l) ) {
2457: if ( dl_redble(BDY(rp)->dl,psh[(int)BDY(l)]) ) {
2458: t_0 = get_rtime();
2459: dp_load((int)BDY(l),&red);
2460: hr = (Q)BDY(rp)->c; hred = (Q)BDY(red)->c;
2461: igcd_cofactor((Q)BDY(rp)->c,(Q)BDY(red)->c,&gcd,&cred,&cr);
1.15 noro 2462: tt = get_rtime(); t_p += tt-t_0;
1.14 noro 2463:
2464: dp_subd(rp,red,&shift);
1.37 noro 2465: dp_mulc_d(rp,(P)cr,&t);
1.14 noro 2466: chsgnp((P)cred,(P *)&mcred);
1.37 noro 2467: dp_mulc_d(red,(P)mcred,&t1);
1.15 noro 2468: muld(CO,shift,t1,&t1);
2469: addd(CO,t,t1,&u);
2470: t_m += get_rtime()-tt;
1.14 noro 2471:
2472: psugar = (BDY(rp)->dl->td - BDY(red)->dl->td) + red->sugar;
2473: sugar = MAX(sugar,psugar);
1.15 noro 2474:
1.14 noro 2475: if ( GenTrace ) {
2476: /* u = cr*rp + (-cred)*shift*red */
2477: STOQ((int)BDY(l),cq);
2478: node = mknode(4,cr,cq,0,0);
2479: mulq(cred,rc,&rcred);
2480: chsgnnum((Num)rcred,(Num *)&mrcred);
2481: muldc(CO,shift,(P)mrcred,(DP *)&ARG2(node));
2482: MKLIST(hist,node);
2483: }
1.15 noro 2484:
1.14 noro 2485: if ( !u ) {
2486: if ( dp )
2487: dp->sugar = sugar;
2488: *r = dp;
2489: if ( GenTrace ) {
2490: ARG3(BDY(hist)) = ONE;
2491: MKNODE(node,hist,TraceList); TraceList = node;
2492: }
2493: goto final;
2494: }
2495: break;
2496: }
2497: }
2498: if ( u ) {
2499: if ( multiple && HMAG(u) > hmag ) {
2500: t_0 = get_rtime();
1.16 noro 2501: dp_ptozp_d(u,&rp);
1.15 noro 2502: tt = get_rtime(); t_g += tt-t_0;
2503:
2504: divsq((Q)BDY(u)->c,(Q)BDY(rp)->c,&cont);
1.14 noro 2505: if ( !dp_fcoeffs && DP_NFStat ) {
1.15 noro 2506: fprintf(asir_out,
2507: "(%d)",p_mag((P)cont)*100/p_mag((P)BDY(u)->c));
1.14 noro 2508: fflush(asir_out);
2509: }
1.15 noro 2510: mulq(cr,dc,&dcq); mulq(cont,rc,&rcq);
1.14 noro 2511: igcd_cofactor(dcq,rcq,&gcd,&dc,&rc);
1.15 noro 2512: t_a = get_rtime()-tt;
2513:
1.14 noro 2514: hmag = multiple*HMAG(rp)/denom;
2515: if ( GenTrace ) {
2516: ARG3(BDY(hist)) = (pointer)gcd;
2517: MKNODE(node,hist,TraceList); TraceList = node;
2518: }
2519: } else {
1.15 noro 2520: rp = u;
1.14 noro 2521: t_0 = get_rtime();
1.15 noro 2522: mulq(cr,dc,&dc);
2523: t_a += get_rtime()-t_0;
1.14 noro 2524: if ( GenTrace ) {
2525: ARG3(BDY(hist)) = (pointer)ONE;
2526: MKNODE(node,hist,TraceList); TraceList = node;
2527: }
2528: }
2529: } else if ( !full ) {
2530: if ( rp ) {
2531: MKDP(rp->nv,BDY(rp),t); t->sugar = sugar; rp = t;
2532: }
2533: *r = rp;
2534: goto final;
2535: } else {
2536: t_0 = get_rtime();
2537: mulq((Q)BDY(rp)->c,rc,&c);
1.15 noro 2538: igcd_cofactor(dc,c,&dc,&dcq,&cq);
2539: muldc(CO,dp,(P)dcq,&t);
2540: dp_hm(rp,&t1); BDY(t1)->c = (P)cq; addd(CO,t,t1,&dp);
2541: dp_rest(rp,&rp);
2542: t_a += get_rtime()-t_0;
1.14 noro 2543: }
2544: }
2545: if ( GenTrace ) {
2546: mulq(ARG3(BDY((LIST)BDY(TraceList))),dc,&cq);
2547: ARG3(BDY((LIST)BDY(TraceList))) = (pointer)cq;
2548: }
2549: if ( dp )
2550: dp->sugar = sugar;
2551: *r = dp;
2552: final:
2553: if ( DP_NFStat )
1.15 noro 2554: fprintf(asir_out,
2555: "(%.3g %.3g %.3g %.3g %.3g %.3g %.3g %.3g)",
2556: t_p,t_m,t_g,t_a,
1.14 noro 2557: pz_t_e, pz_t_d, pz_t_d1, pz_t_c);
2558: }
2559:
2560: void imulv();
2561:
1.37 noro 2562: void dp_imul_d(DP p,Q q,DP *rp)
1.14 noro 2563: {
2564: int nsep,ndist,i,j,k,l,n;
2565: double t0,t1,t2;
2566: Q *s;
2567: pointer *b;
2568: VECT c,cs,ri;
2569: VECT *r;
2570: MP m;
1.37 noro 2571: NODE tn,dist,n0;
2572: Obj obj;
1.14 noro 2573: STRING imul;
2574: extern LIST Dist;
2575:
2576: if ( !p || !q ) {
2577: *rp = 0; return;
2578: }
2579: dist = BDY(Dist);
2580: for ( tn = dist, ndist = 0; tn; tn = NEXT(tn), ndist++ );
2581: nsep = ndist + 1;
2582: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
2583: if ( n <= nsep ) {
2584: muldc(CO,p,(P)q,rp); return;
2585: }
2586: MKSTR(imul,"imulv");
2587: t0 = get_rtime();
2588: dp_dtov(p,&c);
2589: sepvect(c,nsep,&cs);
2590: r = (VECT *)CALLOC(nsep,sizeof(VECT *));
2591: for ( i = 0, tn = dist, b = BDY(cs); i < ndist; i++, tn = NEXT(tn) ) {
2592: n0 = mknode(4,BDY(tn),imul,b[i],q);
1.37 noro 2593: Pox_rpc(n0,&obj);
1.14 noro 2594: }
2595: t1 = get_rtime();
2596: im_t_s += t1 - t0;
2597: imulv(b[i],q,&r[i]);
2598: t1 = get_rtime();
2599: for ( i = 0, tn = dist; i < ndist; i++, tn = NEXT(tn) ) {
2600: MKNODE(n0,BDY(tn),0);
1.37 noro 2601: Pox_pop_local(n0,&obj); r[i] = (VECT)obj;
1.14 noro 2602: if ( OID(r[i]) == O_ERR ) {
2603: printexpr(CO,(Obj)r[i]);
2604: error("dp_imul_d : aborted");
2605: }
2606: }
2607: t2 = get_rtime();
2608: im_t_r += t2 - t1;
2609: s = (Q *)CALLOC(n,sizeof(Q));
2610: for ( i = j = 0; i < nsep; i++ ) {
2611: for ( k = 0, ri = r[i], l = ri->len; k < l; k++, j++ ) {
2612: s[j] = (Q)BDY(ri)[k];
2613: }
2614: }
2615: dp_vtod(s,p,rp);
2616: }
2617:
1.37 noro 2618: void imulv(VECT w,Q c,VECT *rp)
1.14 noro 2619: {
2620: int n,i;
2621: VECT r;
2622:
2623: n = w->len;
2624: MKVECT(r,n); *rp = r;
2625: for ( i = 0; i < n; i++ )
2626: mulq((Q)BDY(w)[i],(Q)c,(Q *)&BDY(r)[i]);
1.32 noro 2627: }
2628:
1.37 noro 2629: void dptoca(DP p,unsigned int **rp)
1.32 noro 2630: {
2631: int i;
2632: MP m;
2633: unsigned int *r;
2634:
2635: if ( !p )
2636: *rp = 0;
2637: else {
2638: for ( m = BDY(p), i = 0; m; m = NEXT(m), i++ );
2639: *rp = r = (unsigned int *)MALLOC_ATOMIC(i*sizeof(unsigned int));
2640: for ( m = BDY(p), i = 0; m; m = NEXT(m), i++ )
2641: r[i] = ITOS(C(m));
2642: }
1.14 noro 2643: }
2644:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>