Annotation of OpenXM_contrib2/asir2000/engine/nd.c, Revision 1.215
1.215 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.214 2013/09/27 07:00:45 noro Exp $ */
1.2 noro 2:
1.94 noro 3: #include "nd.h"
1.63 noro 4:
1.198 noro 5: struct oEGT eg_search;
6:
1.131 noro 7: int diag_period = 6;
1.202 noro 8: int weight_check = 1;
1.61 noro 9: int (*ndl_compare_function)(UINT *a1,UINT *a2);
1.94 noro 10: int nd_dcomp;
11: NM _nm_free_list;
12: ND _nd_free_list;
13: ND_pairs _ndp_free_list;
1.150 noro 14: NODE nd_hcf;
1.32 noro 15:
1.146 noro 16: static NODE nd_subst;
17: static VL nd_vc;
1.121 noro 18: static int nd_ntrans;
1.117 noro 19: static int nd_nalg;
1.103 noro 20: #if 0
1.74 noro 21: static int ndv_alloc;
1.103 noro 22: #endif
1.87 noro 23: #if 1
1.69 noro 24: static int nd_f4_nsp=0x7fffffff;
1.87 noro 25: #else
26: static int nd_f4_nsp=50;
27: #endif
1.42 noro 28: static double nd_scale=2;
1.61 noro 29: static UINT **nd_bound;
1.42 noro 30: static struct order_spec *nd_ord;
31: static EPOS nd_epos;
1.43 noro 32: static BlockMask nd_blockmask;
1.42 noro 33: static int nd_nvar;
34: static int nd_isrlex;
35: static int nd_epw,nd_bpe,nd_wpd,nd_exporigin;
1.61 noro 36: static UINT nd_mask[32];
37: static UINT nd_mask0,nd_mask1;
1.42 noro 38:
1.20 noro 39: static NDV *nd_ps;
1.215 ! noro 40: static NDV *nd_ps_gz;
1.53 noro 41: static NDV *nd_ps_trace;
1.215 ! noro 42: static NDV *nd_ps_sym;
! 43: static NDV *nd_ps_trace_sym;
1.42 noro 44: static RHist *nd_psh;
45: static int nd_psn,nd_pslen;
46: static RHist *nd_red;
1.96 noro 47: static int *nd_work_vector;
48: static int **nd_matrix;
49: static int nd_matrix_len;
1.97 noro 50: static struct weight_or_block *nd_worb;
51: static int nd_worb_len;
1.42 noro 52: static int nd_found,nd_create,nd_notfirst;
53: static int nmv_adv;
1.77 noro 54: static int nd_demand;
1.174 noro 55: static int nd_module,nd_ispot,nd_mpos,nd_pot_nelim;
1.167 noro 56: static NODE nd_tracelist;
57: static NODE nd_alltracelist;
1.195 noro 58: static int nd_gentrace,nd_gensyz,nd_nora,nd_newelim,nd_intersect;
1.187 noro 59: static int *nd_gbblock;
1.209 noro 60: static NODE nd_nzlist,nd_check_splist;
61: static int nd_splist;
1.1 noro 62:
1.119 noro 63: NumberField get_numberfield();
1.114 noro 64: UINT *nd_det_compute_bound(NDV **dm,int n,int j);
65: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d);
1.152 ohara 66: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr);
1.118 noro 67: int nd_monic(int m,ND *p);
1.129 noro 68: NDV plain_vect_to_ndv_q(Q *mat,int col,UINT *s0vect);
1.157 noro 69: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank);
70: NDV pltondv(VL vl,VL dvl,LIST p);
71: void pltozpl(LIST l,Q *cont,LIST *pp);
1.159 noro 72: void ndl_max(UINT *d1,unsigned *d2,UINT *d);
1.167 noro 73: void nmtodp(int mod,NM m,DP *r);
74: NODE reverse_node(NODE n);
75: P ndc_div(int mod,union oNDC a,union oNDC b);
76: P ndctop(int mod,union oNDC c);
77: void finalize_tracelist(int i,P cont);
78: void conv_ilist(int demand,int trace,NODE g,int **indp);
1.172 noro 79: void parse_nd_option(NODE opt);
1.198 noro 80: void dltondl(int n,DL dl,UINT *r);
81: DP ndvtodp(int mod,NDV p);
1.204 noro 82: DP ndtodp(int mod,ND p);
1.215 ! noro 83: NDV ndvtondvgz(NDV p);
! 84: NDV ndvgztondv(NDV p);
! 85: ND ndtondgz(ND p);
! 86: ND ndgztond(ND p);
1.114 noro 87:
1.149 noro 88: extern int Denominator,DP_Multiple;
89:
1.1 noro 90: void nd_free_private_storage()
91: {
1.157 noro 92: _nm_free_list = 0;
93: _ndp_free_list = 0;
1.71 noro 94: #if 0
1.157 noro 95: GC_gcollect();
1.71 noro 96: #endif
1.1 noro 97: }
98:
99: void _NM_alloc()
100: {
1.157 noro 101: NM p;
102: int i;
1.1 noro 103:
1.157 noro 104: for ( i = 0; i < 1024; i++ ) {
1.200 noro 105: p = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1.157 noro 106: p->next = _nm_free_list; _nm_free_list = p;
107: }
1.1 noro 108: }
109:
110: void _ND_alloc()
111: {
1.157 noro 112: ND p;
113: int i;
1.1 noro 114:
1.157 noro 115: for ( i = 0; i < 1024; i++ ) {
1.200 noro 116: p = (ND)MALLOC(sizeof(struct oND));
1.157 noro 117: p->body = (NM)_nd_free_list; _nd_free_list = p;
118: }
1.1 noro 119: }
120:
121: void _NDP_alloc()
122: {
1.157 noro 123: ND_pairs p;
124: int i;
1.1 noro 125:
1.157 noro 126: for ( i = 0; i < 1024; i++ ) {
1.200 noro 127: p = (ND_pairs)MALLOC(sizeof(struct oND_pairs)
1.157 noro 128: +(nd_wpd-1)*sizeof(UINT));
129: p->next = _ndp_free_list; _ndp_free_list = p;
130: }
1.1 noro 131: }
132:
1.30 noro 133: INLINE int nd_length(ND p)
1.1 noro 134: {
1.157 noro 135: NM m;
136: int i;
1.1 noro 137:
1.157 noro 138: if ( !p )
139: return 0;
140: else {
141: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
142: return i;
143: }
1.1 noro 144: }
145:
1.61 noro 146: INLINE int ndl_reducible(UINT *d1,UINT *d2)
1.1 noro 147: {
1.157 noro 148: UINT u1,u2;
149: int i,j;
1.1 noro 150:
1.157 noro 151: if ( nd_module && (MPOS(d1) != MPOS(d2)) ) return 0;
152:
153: if ( TD(d1) < TD(d2) ) return 0;
1.65 noro 154: #if USE_UNROLL
1.157 noro 155: switch ( nd_bpe ) {
156: case 3:
157: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
158: u1 = d1[i]; u2 = d2[i];
159: if ( (u1&0x38000000) < (u2&0x38000000) ) return 0;
160: if ( (u1& 0x7000000) < (u2& 0x7000000) ) return 0;
161: if ( (u1& 0xe00000) < (u2& 0xe00000) ) return 0;
162: if ( (u1& 0x1c0000) < (u2& 0x1c0000) ) return 0;
163: if ( (u1& 0x38000) < (u2& 0x38000) ) return 0;
164: if ( (u1& 0x7000) < (u2& 0x7000) ) return 0;
165: if ( (u1& 0xe00) < (u2& 0xe00) ) return 0;
166: if ( (u1& 0x1c0) < (u2& 0x1c0) ) return 0;
167: if ( (u1& 0x38) < (u2& 0x38) ) return 0;
168: if ( (u1& 0x7) < (u2& 0x7) ) return 0;
169: }
170: return 1;
171: break;
172: case 4:
173: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
174: u1 = d1[i]; u2 = d2[i];
175: if ( (u1&0xf0000000) < (u2&0xf0000000) ) return 0;
176: if ( (u1& 0xf000000) < (u2& 0xf000000) ) return 0;
177: if ( (u1& 0xf00000) < (u2& 0xf00000) ) return 0;
178: if ( (u1& 0xf0000) < (u2& 0xf0000) ) return 0;
179: if ( (u1& 0xf000) < (u2& 0xf000) ) return 0;
180: if ( (u1& 0xf00) < (u2& 0xf00) ) return 0;
181: if ( (u1& 0xf0) < (u2& 0xf0) ) return 0;
182: if ( (u1& 0xf) < (u2& 0xf) ) return 0;
183: }
184: return 1;
185: break;
186: case 6:
187: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
188: u1 = d1[i]; u2 = d2[i];
189: if ( (u1&0x3f000000) < (u2&0x3f000000) ) return 0;
190: if ( (u1& 0xfc0000) < (u2& 0xfc0000) ) return 0;
191: if ( (u1& 0x3f000) < (u2& 0x3f000) ) return 0;
192: if ( (u1& 0xfc0) < (u2& 0xfc0) ) return 0;
193: if ( (u1& 0x3f) < (u2& 0x3f) ) return 0;
194: }
195: return 1;
196: break;
197: case 8:
198: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
199: u1 = d1[i]; u2 = d2[i];
200: if ( (u1&0xff000000) < (u2&0xff000000) ) return 0;
201: if ( (u1& 0xff0000) < (u2& 0xff0000) ) return 0;
202: if ( (u1& 0xff00) < (u2& 0xff00) ) return 0;
203: if ( (u1& 0xff) < (u2& 0xff) ) return 0;
204: }
205: return 1;
206: break;
207: case 16:
208: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
209: u1 = d1[i]; u2 = d2[i];
210: if ( (u1&0xffff0000) < (u2&0xffff0000) ) return 0;
211: if ( (u1& 0xffff) < (u2& 0xffff) ) return 0;
212: }
213: return 1;
214: break;
215: case 32:
216: for ( i = nd_exporigin; i < nd_wpd; i++ )
217: if ( d1[i] < d2[i] ) return 0;
218: return 1;
219: break;
220: default:
221: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
222: u1 = d1[i]; u2 = d2[i];
223: for ( j = 0; j < nd_epw; j++ )
224: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
225: }
226: return 1;
227: }
1.65 noro 228: #else
1.157 noro 229: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
230: u1 = d1[i]; u2 = d2[i];
231: for ( j = 0; j < nd_epw; j++ )
232: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
233: }
234: return 1;
1.65 noro 235: #endif
1.1 noro 236: }
237:
1.61 noro 238: /*
239: * If the current order is a block order,
240: * then the last block is length 1 and contains
241: * the homo variable. Otherwise, the original
242: * order is either 0 or 2.
243: */
244:
1.164 noro 245: void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepos,int ompos,int weight)
1.23 noro 246: {
1.157 noro 247: int w,i,e,n,omask0;
1.61 noro 248:
1.157 noro 249: omask0 = obpe==32?0xffffffff:((1<<obpe)-1);
250: n = nd_nvar-1;
251: ndl_zero(r);
252: for ( i = 0; i < n; i++ ) {
253: e = GET_EXP_OLD(d,i);
254: PUT_EXP(r,i,e);
255: }
256: w = TD(d);
257: PUT_EXP(r,nd_nvar-1,weight-w);
1.164 noro 258: if ( nd_module ) MPOS(r) = d[ompos];
1.157 noro 259: TD(r) = weight;
260: if ( nd_blockmask ) ndl_weight_mask(r);
1.61 noro 261: }
262:
263: void ndl_dehomogenize(UINT *d)
264: {
1.157 noro 265: UINT mask;
266: UINT h;
267: int i,bits;
268:
269: if ( nd_blockmask ) {
270: h = GET_EXP(d,nd_nvar-1);
271: XOR_EXP(d,nd_nvar-1,h);
272: TD(d) -= h;
273: ndl_weight_mask(d);
274: } else {
275: if ( nd_isrlex ) {
276: if ( nd_bpe == 32 ) {
277: h = d[nd_exporigin];
278: for ( i = nd_exporigin+1; i < nd_wpd; i++ )
279: d[i-1] = d[i];
280: d[i-1] = 0;
281: TD(d) -= h;
282: } else {
283: bits = nd_epw*nd_bpe;
284: mask = bits==32?0xffffffff:((1<<(nd_epw*nd_bpe))-1);
285: h = (d[nd_exporigin]>>((nd_epw-1)*nd_bpe))&nd_mask0;
286: for ( i = nd_exporigin; i < nd_wpd; i++ )
287: d[i] = ((d[i]<<nd_bpe)&mask)
288: |(i+1<nd_wpd?((d[i+1]>>((nd_epw-1)*nd_bpe))&nd_mask0):0);
289: TD(d) -= h;
290: }
291: } else {
292: h = GET_EXP(d,nd_nvar-1);
293: XOR_EXP(d,nd_nvar-1,h);
294: TD(d) -= h;
295: }
296: }
1.23 noro 297: }
298:
1.61 noro 299: void ndl_lcm(UINT *d1,unsigned *d2,UINT *d)
1.1 noro 300: {
1.157 noro 301: UINT t1,t2,u,u1,u2;
302: int i,j,l;
303:
304: if ( nd_module && (MPOS(d1) != MPOS(d2)) )
305: error("ndl_lcm : inconsistent monomials");
306: #if USE_UNROLL
307: switch ( nd_bpe ) {
308: case 3:
309: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
310: u1 = d1[i]; u2 = d2[i];
311: t1 = (u1&0x38000000); t2 = (u2&0x38000000); u = t1>t2?t1:t2;
312: t1 = (u1& 0x7000000); t2 = (u2& 0x7000000); u |= t1>t2?t1:t2;
313: t1 = (u1& 0xe00000); t2 = (u2& 0xe00000); u |= t1>t2?t1:t2;
314: t1 = (u1& 0x1c0000); t2 = (u2& 0x1c0000); u |= t1>t2?t1:t2;
315: t1 = (u1& 0x38000); t2 = (u2& 0x38000); u |= t1>t2?t1:t2;
316: t1 = (u1& 0x7000); t2 = (u2& 0x7000); u |= t1>t2?t1:t2;
317: t1 = (u1& 0xe00); t2 = (u2& 0xe00); u |= t1>t2?t1:t2;
318: t1 = (u1& 0x1c0); t2 = (u2& 0x1c0); u |= t1>t2?t1:t2;
319: t1 = (u1& 0x38); t2 = (u2& 0x38); u |= t1>t2?t1:t2;
320: t1 = (u1& 0x7); t2 = (u2& 0x7); u |= t1>t2?t1:t2;
321: d[i] = u;
322: }
323: break;
324: case 4:
325: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
326: u1 = d1[i]; u2 = d2[i];
327: t1 = (u1&0xf0000000); t2 = (u2&0xf0000000); u = t1>t2?t1:t2;
328: t1 = (u1& 0xf000000); t2 = (u2& 0xf000000); u |= t1>t2?t1:t2;
329: t1 = (u1& 0xf00000); t2 = (u2& 0xf00000); u |= t1>t2?t1:t2;
330: t1 = (u1& 0xf0000); t2 = (u2& 0xf0000); u |= t1>t2?t1:t2;
331: t1 = (u1& 0xf000); t2 = (u2& 0xf000); u |= t1>t2?t1:t2;
332: t1 = (u1& 0xf00); t2 = (u2& 0xf00); u |= t1>t2?t1:t2;
333: t1 = (u1& 0xf0); t2 = (u2& 0xf0); u |= t1>t2?t1:t2;
334: t1 = (u1& 0xf); t2 = (u2& 0xf); u |= t1>t2?t1:t2;
335: d[i] = u;
336: }
337: break;
338: case 6:
339: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
340: u1 = d1[i]; u2 = d2[i];
341: t1 = (u1&0x3f000000); t2 = (u2&0x3f000000); u = t1>t2?t1:t2;
342: t1 = (u1& 0xfc0000); t2 = (u2& 0xfc0000); u |= t1>t2?t1:t2;
343: t1 = (u1& 0x3f000); t2 = (u2& 0x3f000); u |= t1>t2?t1:t2;
344: t1 = (u1& 0xfc0); t2 = (u2& 0xfc0); u |= t1>t2?t1:t2;
345: t1 = (u1& 0x3f); t2 = (u2& 0x3f); u |= t1>t2?t1:t2;
346: d[i] = u;
347: }
348: break;
349: case 8:
350: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
351: u1 = d1[i]; u2 = d2[i];
352: t1 = (u1&0xff000000); t2 = (u2&0xff000000); u = t1>t2?t1:t2;
353: t1 = (u1& 0xff0000); t2 = (u2& 0xff0000); u |= t1>t2?t1:t2;
354: t1 = (u1& 0xff00); t2 = (u2& 0xff00); u |= t1>t2?t1:t2;
355: t1 = (u1& 0xff); t2 = (u2& 0xff); u |= t1>t2?t1:t2;
356: d[i] = u;
357: }
358: break;
359: case 16:
360: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
361: u1 = d1[i]; u2 = d2[i];
362: t1 = (u1&0xffff0000); t2 = (u2&0xffff0000); u = t1>t2?t1:t2;
363: t1 = (u1& 0xffff); t2 = (u2& 0xffff); u |= t1>t2?t1:t2;
364: d[i] = u;
365: }
366: break;
367: case 32:
368: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
369: u1 = d1[i]; u2 = d2[i];
370: d[i] = u1>u2?u1:u2;
371: }
372: break;
373: default:
374: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
375: u1 = d1[i]; u2 = d2[i];
376: for ( j = 0, u = 0; j < nd_epw; j++ ) {
377: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
378: }
379: d[i] = u;
380: }
381: break;
382: }
383: #else
384: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
385: u1 = d1[i]; u2 = d2[i];
386: for ( j = 0, u = 0; j < nd_epw; j++ ) {
387: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
388: }
389: d[i] = u;
390: }
391: #endif
1.163 noro 392: if ( nd_module ) MPOS(d) = MPOS(d1);
1.157 noro 393: TD(d) = ndl_weight(d);
394: if ( nd_blockmask ) ndl_weight_mask(d);
395: }
396:
1.159 noro 397: void ndl_max(UINT *d1,unsigned *d2,UINT *d)
1.157 noro 398: {
399: UINT t1,t2,u,u1,u2;
400: int i,j,l;
1.1 noro 401:
1.157 noro 402: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
403: u1 = d1[i]; u2 = d2[i];
404: for ( j = 0, u = 0; j < nd_epw; j++ ) {
405: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
406: }
407: d[i] = u;
408: }
1.57 noro 409: }
410:
1.61 noro 411: int ndl_weight(UINT *d)
1.1 noro 412: {
1.157 noro 413: UINT t,u;
414: int i,j;
1.1 noro 415:
1.157 noro 416: if ( current_dl_weight_vector )
417: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
418: u = GET_EXP(d,i);
419: t += MUL_WEIGHT(u,i);
420: }
421: else
422: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
423: u = d[i];
424: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
425: t += (u&nd_mask0);
426: }
1.167 noro 427: if ( nd_module && current_module_weight_vector && MPOS(d) )
428: t += current_module_weight_vector[MPOS(d)];
1.157 noro 429: return t;
1.1 noro 430: }
431:
1.61 noro 432: void ndl_weight_mask(UINT *d)
1.43 noro 433: {
1.157 noro 434: UINT t,u;
435: UINT *mask;
436: int i,j,k,l;
437:
438: l = nd_blockmask->n;
439: for ( k = 0; k < l; k++ ) {
440: mask = nd_blockmask->mask[k];
441: if ( current_dl_weight_vector )
442: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
443: u = GET_EXP_MASK(d,i,mask);
444: t += MUL_WEIGHT(u,i);
445: }
446: else
447: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
448: u = d[i]&mask[i];
449: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
450: t += (u&nd_mask0);
451: }
452: d[k+1] = t;
453: }
1.43 noro 454: }
455:
1.61 noro 456: int ndl_lex_compare(UINT *d1,UINT *d2)
1.1 noro 457: {
1.157 noro 458: int i;
1.1 noro 459:
1.157 noro 460: d1 += nd_exporigin;
461: d2 += nd_exporigin;
462: for ( i = nd_exporigin; i < nd_wpd; i++, d1++, d2++ )
463: if ( *d1 > *d2 )
464: return nd_isrlex ? -1 : 1;
465: else if ( *d1 < *d2 )
466: return nd_isrlex ? 1 : -1;
467: return 0;
1.1 noro 468: }
469:
1.61 noro 470: int ndl_block_compare(UINT *d1,UINT *d2)
1.43 noro 471: {
1.157 noro 472: int i,l,j,ord_o,ord_l;
473: struct order_pair *op;
474: UINT t1,t2,m;
475: UINT *mask;
476:
477: l = nd_blockmask->n;
478: op = nd_blockmask->order_pair;
479: for ( j = 0; j < l; j++ ) {
480: mask = nd_blockmask->mask[j];
481: ord_o = op[j].order;
482: if ( ord_o < 2 )
483: if ( (t1=d1[j+1]) > (t2=d2[j+1]) ) return 1;
484: else if ( t1 < t2 ) return -1;
485: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
486: m = mask[i];
487: t1 = d1[i]&m;
488: t2 = d2[i]&m;
489: if ( t1 > t2 )
490: return !ord_o ? -1 : 1;
491: else if ( t1 < t2 )
492: return !ord_o ? 1 : -1;
493: }
494: }
495: return 0;
1.43 noro 496: }
497:
1.96 noro 498: int ndl_matrix_compare(UINT *d1,UINT *d2)
499: {
1.157 noro 500: int i,j,s;
501: int *v;
1.96 noro 502:
1.157 noro 503: for ( j = 0; j < nd_nvar; j++ )
504: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
505: for ( i = 0; i < nd_matrix_len; i++ ) {
506: v = nd_matrix[i];
507: for ( j = 0, s = 0; j < nd_nvar; j++ )
508: s += v[j]*nd_work_vector[j];
509: if ( s > 0 ) return 1;
510: else if ( s < 0 ) return -1;
511: }
512: return 0;
1.96 noro 513: }
514:
1.97 noro 515: int ndl_composite_compare(UINT *d1,UINT *d2)
516: {
1.157 noro 517: int i,j,s,start,end,len,o;
518: int *v;
519: struct sparse_weight *sw;
520:
521: for ( j = 0; j < nd_nvar; j++ )
522: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
523: for ( i = 0; i < nd_worb_len; i++ ) {
524: len = nd_worb[i].length;
525: switch ( nd_worb[i].type ) {
526: case IS_DENSE_WEIGHT:
527: v = nd_worb[i].body.dense_weight;
528: for ( j = 0, s = 0; j < len; j++ )
529: s += v[j]*nd_work_vector[j];
530: if ( s > 0 ) return 1;
531: else if ( s < 0 ) return -1;
532: break;
533: case IS_SPARSE_WEIGHT:
534: sw = nd_worb[i].body.sparse_weight;
535: for ( j = 0, s = 0; j < len; j++ )
536: s += sw[j].value*nd_work_vector[sw[j].pos];
537: if ( s > 0 ) return 1;
538: else if ( s < 0 ) return -1;
539: break;
540: case IS_BLOCK:
541: o = nd_worb[i].body.block.order;
542: start = nd_worb[i].body.block.start;
543: switch ( o ) {
544: case 0:
545: end = start+len;
546: for ( j = start, s = 0; j < end; j++ )
547: s += MUL_WEIGHT(nd_work_vector[j],j);
548: if ( s > 0 ) return 1;
549: else if ( s < 0 ) return -1;
550: for ( j = end-1; j >= start; j-- )
551: if ( nd_work_vector[j] < 0 ) return 1;
552: else if ( nd_work_vector[j] > 0 ) return -1;
553: break;
554: case 1:
555: end = start+len;
556: for ( j = start, s = 0; j < end; j++ )
557: s += MUL_WEIGHT(nd_work_vector[j],j);
558: if ( s > 0 ) return 1;
559: else if ( s < 0 ) return -1;
560: for ( j = start; j < end; j++ )
561: if ( nd_work_vector[j] > 0 ) return 1;
562: else if ( nd_work_vector[j] < 0 ) return -1;
563: break;
564: case 2:
565: for ( j = start; j < end; j++ )
566: if ( nd_work_vector[j] > 0 ) return 1;
567: else if ( nd_work_vector[j] < 0 ) return -1;
568: break;
569: }
570: break;
571: }
572: }
573: return 0;
1.97 noro 574: }
575:
1.58 noro 576: /* TDH -> WW -> TD-> RL */
577:
1.61 noro 578: int ndl_ww_lex_compare(UINT *d1,UINT *d2)
1.58 noro 579: {
1.157 noro 580: int i,m,e1,e2;
1.58 noro 581:
1.157 noro 582: if ( TD(d1) > TD(d2) ) return 1;
583: else if ( TD(d1) < TD(d2) ) return -1;
584: m = nd_nvar>>1;
585: for ( i = 0, e1 = e2 = 0; i < m; i++ ) {
586: e1 += current_weyl_weight_vector[i]*(GET_EXP(d1,m+i)-GET_EXP(d1,i));
587: e2 += current_weyl_weight_vector[i]*(GET_EXP(d2,m+i)-GET_EXP(d2,i));
588: }
589: if ( e1 > e2 ) return 1;
590: else if ( e1 < e2 ) return -1;
591: return ndl_lex_compare(d1,d2);
592: }
593:
594: int ndl_module_grlex_compare(UINT *d1,UINT *d2)
595: {
1.164 noro 596: int i,c;
1.157 noro 597:
1.160 noro 598: if ( nd_ispot ) {
1.174 noro 599: if ( nd_pot_nelim && MPOS(d1)>=nd_pot_nelim+1 && MPOS(d2) >= nd_pot_nelim+1 ) {
600: if ( TD(d1) > TD(d2) ) return 1;
601: else if ( TD(d1) < TD(d2) ) return -1;
602: if ( c = ndl_lex_compare(d1,d2) ) return c;
603: if ( MPOS(d1) < MPOS(d2) ) return 1;
604: else if ( MPOS(d1) > MPOS(d2) ) return -1;
605: return 0;
606: }
1.157 noro 607: if ( MPOS(d1) < MPOS(d2) ) return 1;
608: else if ( MPOS(d1) > MPOS(d2) ) return -1;
609: }
610: if ( TD(d1) > TD(d2) ) return 1;
611: else if ( TD(d1) < TD(d2) ) return -1;
1.167 noro 612: if ( c = ndl_lex_compare(d1,d2) ) return c;
1.160 noro 613: if ( !nd_ispot ) {
1.157 noro 614: if ( MPOS(d1) < MPOS(d2) ) return 1;
615: else if ( MPOS(d1) > MPOS(d2) ) return -1;
616: }
617: return 0;
618: }
619:
620: int ndl_module_glex_compare(UINT *d1,UINT *d2)
621: {
1.164 noro 622: int i,c;
1.157 noro 623:
1.160 noro 624: if ( nd_ispot ) {
1.157 noro 625: if ( MPOS(d1) < MPOS(d2) ) return 1;
626: else if ( MPOS(d1) > MPOS(d2) ) return -1;
627: }
628: if ( TD(d1) > TD(d2) ) return 1;
629: else if ( TD(d1) < TD(d2) ) return -1;
1.167 noro 630: if ( c = ndl_lex_compare(d1,d2) ) return c;
1.160 noro 631: if ( !nd_ispot ) {
1.157 noro 632: if ( MPOS(d1) < MPOS(d2) ) return 1;
633: else if ( MPOS(d1) > MPOS(d2) ) return -1;
634: }
635: return 0;
636: }
637:
638: int ndl_module_lex_compare(UINT *d1,UINT *d2)
639: {
1.164 noro 640: int i,c;
1.157 noro 641:
1.160 noro 642: if ( nd_ispot ) {
1.157 noro 643: if ( MPOS(d1) < MPOS(d2) ) return 1;
644: else if ( MPOS(d1) > MPOS(d2) ) return -1;
645: }
1.167 noro 646: if ( c = ndl_lex_compare(d1,d2) ) return c;
1.160 noro 647: if ( !nd_ispot ) {
1.157 noro 648: if ( MPOS(d1) < MPOS(d2) ) return 1;
649: else if ( MPOS(d1) > MPOS(d2) ) return -1;
650: }
651: return 0;
652: }
653:
654: int ndl_module_block_compare(UINT *d1,UINT *d2)
655: {
656: int i,c;
657:
1.160 noro 658: if ( nd_ispot ) {
1.157 noro 659: if ( MPOS(d1) < MPOS(d2) ) return 1;
660: else if ( MPOS(d1) > MPOS(d2) ) return -1;
661: }
662: if ( c = ndl_block_compare(d1,d2) ) return c;
1.160 noro 663: if ( !nd_ispot ) {
1.157 noro 664: if ( MPOS(d1) < MPOS(d2) ) return 1;
665: else if ( MPOS(d1) > MPOS(d2) ) return -1;
666: }
667: return 0;
668: }
669:
670: int ndl_module_matrix_compare(UINT *d1,UINT *d2)
671: {
672: int i,c;
673:
1.160 noro 674: if ( nd_ispot ) {
1.157 noro 675: if ( MPOS(d1) < MPOS(d2) ) return 1;
676: else if ( MPOS(d1) > MPOS(d2) ) return -1;
677: }
678: if ( c = ndl_matrix_compare(d1,d2) ) return c;
1.160 noro 679: if ( !nd_ispot ) {
1.157 noro 680: if ( MPOS(d1) < MPOS(d2) ) return 1;
681: else if ( MPOS(d1) > MPOS(d2) ) return -1;
682: }
683: return 0;
684: }
685:
686: int ndl_module_composite_compare(UINT *d1,UINT *d2)
687: {
688: int i,c;
689:
1.160 noro 690: if ( nd_ispot ) {
1.157 noro 691: if ( MPOS(d1) > MPOS(d2) ) return 1;
692: else if ( MPOS(d1) < MPOS(d2) ) return -1;
693: }
694: if ( c = ndl_composite_compare(d1,d2) ) return c;
1.160 noro 695: if ( !nd_ispot ) {
1.157 noro 696: if ( MPOS(d1) > MPOS(d2) ) return 1;
697: else if ( MPOS(d1) < MPOS(d2) ) return -1;
698: }
699: return 0;
1.58 noro 700: }
701:
1.61 noro 702: INLINE int ndl_equal(UINT *d1,UINT *d2)
1.1 noro 703: {
1.157 noro 704: int i;
1.1 noro 705:
1.157 noro 706: switch ( nd_wpd ) {
707: case 2:
708: if ( TD(d2) != TD(d1) ) return 0;
709: if ( d2[1] != d1[1] ) return 0;
710: return 1;
711: break;
712: case 3:
713: if ( TD(d2) != TD(d1) ) return 0;
714: if ( d2[1] != d1[1] ) return 0;
715: if ( d2[2] != d1[2] ) return 0;
716: return 1;
717: break;
718: default:
719: for ( i = 0; i < nd_wpd; i++ )
720: if ( *d1++ != *d2++ ) return 0;
721: return 1;
722: break;
723: }
1.1 noro 724: }
725:
1.61 noro 726: INLINE void ndl_copy(UINT *d1,UINT *d2)
1.6 noro 727: {
1.157 noro 728: int i;
1.6 noro 729:
1.157 noro 730: switch ( nd_wpd ) {
731: case 2:
732: TD(d2) = TD(d1);
733: d2[1] = d1[1];
734: break;
735: case 3:
736: TD(d2) = TD(d1);
737: d2[1] = d1[1];
738: d2[2] = d1[2];
739: break;
740: default:
741: for ( i = 0; i < nd_wpd; i++ )
742: d2[i] = d1[i];
743: break;
744: }
1.6 noro 745: }
746:
1.61 noro 747: INLINE void ndl_zero(UINT *d)
748: {
1.157 noro 749: int i;
750: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
1.61 noro 751: }
752:
753: INLINE void ndl_add(UINT *d1,UINT *d2,UINT *d)
1.1 noro 754: {
1.157 noro 755: int i;
1.1 noro 756:
1.162 noro 757: if ( nd_module ) {
758: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
1.167 noro 759: error("ndl_add : invalid operation");
1.162 noro 760: }
1.43 noro 761: #if 1
1.157 noro 762: switch ( nd_wpd ) {
763: case 2:
764: TD(d) = TD(d1)+TD(d2);
765: d[1] = d1[1]+d2[1];
766: break;
767: case 3:
768: TD(d) = TD(d1)+TD(d2);
769: d[1] = d1[1]+d2[1];
770: d[2] = d1[2]+d2[2];
771: break;
772: default:
773: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
774: break;
775: }
1.43 noro 776: #else
1.157 noro 777: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
1.43 noro 778: #endif
1.6 noro 779: }
780:
1.55 noro 781: /* d1 += d2 */
1.61 noro 782: INLINE void ndl_addto(UINT *d1,UINT *d2)
1.55 noro 783: {
1.157 noro 784: int i;
1.55 noro 785:
1.162 noro 786: if ( nd_module ) {
787: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
788: error("ndl_addto : invalid operation");
789: }
1.55 noro 790: #if 1
1.157 noro 791: switch ( nd_wpd ) {
792: case 2:
793: TD(d1) += TD(d2);
794: d1[1] += d2[1];
795: break;
796: case 3:
797: TD(d1) += TD(d2);
798: d1[1] += d2[1];
799: d1[2] += d2[2];
800: break;
801: default:
802: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
803: break;
804: }
1.55 noro 805: #else
1.157 noro 806: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
1.55 noro 807: #endif
808: }
809:
1.61 noro 810: INLINE void ndl_sub(UINT *d1,UINT *d2,UINT *d)
1.6 noro 811: {
1.157 noro 812: int i;
1.6 noro 813:
1.157 noro 814: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]-d2[i];
1.1 noro 815: }
816:
1.61 noro 817: int ndl_disjoint(UINT *d1,UINT *d2)
1.1 noro 818: {
1.157 noro 819: UINT t1,t2,u,u1,u2;
820: int i,j;
1.1 noro 821:
1.157 noro 822: if ( nd_module && (MPOS(d1) == MPOS(d2)) ) return 0;
1.65 noro 823: #if USE_UNROLL
1.157 noro 824: switch ( nd_bpe ) {
825: case 3:
826: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
827: u1 = d1[i]; u2 = d2[i];
828: t1 = u1&0x38000000; t2 = u2&0x38000000; if ( t1&&t2 ) return 0;
829: t1 = u1& 0x7000000; t2 = u2& 0x7000000; if ( t1&&t2 ) return 0;
830: t1 = u1& 0xe00000; t2 = u2& 0xe00000; if ( t1&&t2 ) return 0;
831: t1 = u1& 0x1c0000; t2 = u2& 0x1c0000; if ( t1&&t2 ) return 0;
832: t1 = u1& 0x38000; t2 = u2& 0x38000; if ( t1&&t2 ) return 0;
833: t1 = u1& 0x7000; t2 = u2& 0x7000; if ( t1&&t2 ) return 0;
834: t1 = u1& 0xe00; t2 = u2& 0xe00; if ( t1&&t2 ) return 0;
835: t1 = u1& 0x1c0; t2 = u2& 0x1c0; if ( t1&&t2 ) return 0;
836: t1 = u1& 0x38; t2 = u2& 0x38; if ( t1&&t2 ) return 0;
837: t1 = u1& 0x7; t2 = u2& 0x7; if ( t1&&t2 ) return 0;
838: }
839: return 1;
840: break;
841: case 4:
842: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
843: u1 = d1[i]; u2 = d2[i];
844: t1 = u1&0xf0000000; t2 = u2&0xf0000000; if ( t1&&t2 ) return 0;
845: t1 = u1& 0xf000000; t2 = u2& 0xf000000; if ( t1&&t2 ) return 0;
846: t1 = u1& 0xf00000; t2 = u2& 0xf00000; if ( t1&&t2 ) return 0;
847: t1 = u1& 0xf0000; t2 = u2& 0xf0000; if ( t1&&t2 ) return 0;
848: t1 = u1& 0xf000; t2 = u2& 0xf000; if ( t1&&t2 ) return 0;
849: t1 = u1& 0xf00; t2 = u2& 0xf00; if ( t1&&t2 ) return 0;
850: t1 = u1& 0xf0; t2 = u2& 0xf0; if ( t1&&t2 ) return 0;
851: t1 = u1& 0xf; t2 = u2& 0xf; if ( t1&&t2 ) return 0;
852: }
853: return 1;
854: break;
855: case 6:
856: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
857: u1 = d1[i]; u2 = d2[i];
858: t1 = u1&0x3f000000; t2 = u2&0x3f000000; if ( t1&&t2 ) return 0;
859: t1 = u1& 0xfc0000; t2 = u2& 0xfc0000; if ( t1&&t2 ) return 0;
860: t1 = u1& 0x3f000; t2 = u2& 0x3f000; if ( t1&&t2 ) return 0;
861: t1 = u1& 0xfc0; t2 = u2& 0xfc0; if ( t1&&t2 ) return 0;
862: t1 = u1& 0x3f; t2 = u2& 0x3f; if ( t1&&t2 ) return 0;
863: }
864: return 1;
865: break;
866: case 8:
867: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
868: u1 = d1[i]; u2 = d2[i];
869: t1 = u1&0xff000000; t2 = u2&0xff000000; if ( t1&&t2 ) return 0;
870: t1 = u1& 0xff0000; t2 = u2& 0xff0000; if ( t1&&t2 ) return 0;
871: t1 = u1& 0xff00; t2 = u2& 0xff00; if ( t1&&t2 ) return 0;
872: t1 = u1& 0xff; t2 = u2& 0xff; if ( t1&&t2 ) return 0;
873: }
874: return 1;
875: break;
876: case 16:
877: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
878: u1 = d1[i]; u2 = d2[i];
879: t1 = u1&0xffff0000; t2 = u2&0xffff0000; if ( t1&&t2 ) return 0;
880: t1 = u1& 0xffff; t2 = u2& 0xffff; if ( t1&&t2 ) return 0;
881: }
882: return 1;
883: break;
884: case 32:
885: for ( i = nd_exporigin; i < nd_wpd; i++ )
886: if ( d1[i] && d2[i] ) return 0;
887: return 1;
888: break;
889: default:
890: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
891: u1 = d1[i]; u2 = d2[i];
892: for ( j = 0; j < nd_epw; j++ ) {
893: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
894: u1 >>= nd_bpe; u2 >>= nd_bpe;
895: }
896: }
897: return 1;
898: break;
899: }
1.65 noro 900: #else
1.157 noro 901: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
902: u1 = d1[i]; u2 = d2[i];
903: for ( j = 0; j < nd_epw; j++ ) {
904: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
905: u1 >>= nd_bpe; u2 >>= nd_bpe;
906: }
907: }
908: return 1;
1.65 noro 909: #endif
1.1 noro 910: }
911:
1.114 noro 912: int ndl_check_bound(UINT *d1,UINT *d2)
1.1 noro 913: {
1.157 noro 914: UINT u2;
915: int i,j,ind,k;
1.1 noro 916:
1.157 noro 917: ind = 0;
1.65 noro 918: #if USE_UNROLL
1.157 noro 919: switch ( nd_bpe ) {
920: case 3:
921: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
922: u2 = d2[i];
923: if ( d1[ind++]+((u2>>27)&0x7) >= 0x8 ) return 1;
924: if ( d1[ind++]+((u2>>24)&0x7) >= 0x8 ) return 1;
925: if ( d1[ind++]+((u2>>21)&0x7) >= 0x8 ) return 1;
926: if ( d1[ind++]+((u2>>18)&0x7) >= 0x8 ) return 1;
927: if ( d1[ind++]+((u2>>15)&0x7) >= 0x8 ) return 1;
928: if ( d1[ind++]+((u2>>12)&0x7) >= 0x8 ) return 1;
929: if ( d1[ind++]+((u2>>9)&0x7) >= 0x8 ) return 1;
930: if ( d1[ind++]+((u2>>6)&0x7) >= 0x8 ) return 1;
931: if ( d1[ind++]+((u2>>3)&0x7) >= 0x8 ) return 1;
932: if ( d1[ind++]+(u2&0x7) >= 0x8 ) return 1;
933: }
934: return 0;
935: break;
936: case 4:
937: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
938: u2 = d2[i];
939: if ( d1[ind++]+((u2>>28)&0xf) >= 0x10 ) return 1;
940: if ( d1[ind++]+((u2>>24)&0xf) >= 0x10 ) return 1;
941: if ( d1[ind++]+((u2>>20)&0xf) >= 0x10 ) return 1;
942: if ( d1[ind++]+((u2>>16)&0xf) >= 0x10 ) return 1;
943: if ( d1[ind++]+((u2>>12)&0xf) >= 0x10 ) return 1;
944: if ( d1[ind++]+((u2>>8)&0xf) >= 0x10 ) return 1;
945: if ( d1[ind++]+((u2>>4)&0xf) >= 0x10 ) return 1;
946: if ( d1[ind++]+(u2&0xf) >= 0x10 ) return 1;
947: }
948: return 0;
949: break;
950: case 6:
951: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
952: u2 = d2[i];
953: if ( d1[ind++]+((u2>>24)&0x3f) >= 0x40 ) return 1;
954: if ( d1[ind++]+((u2>>18)&0x3f) >= 0x40 ) return 1;
955: if ( d1[ind++]+((u2>>12)&0x3f) >= 0x40 ) return 1;
956: if ( d1[ind++]+((u2>>6)&0x3f) >= 0x40 ) return 1;
957: if ( d1[ind++]+(u2&0x3f) >= 0x40 ) return 1;
958: }
959: return 0;
960: break;
961: case 8:
962: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
963: u2 = d2[i];
964: if ( d1[ind++]+((u2>>24)&0xff) >= 0x100 ) return 1;
965: if ( d1[ind++]+((u2>>16)&0xff) >= 0x100 ) return 1;
966: if ( d1[ind++]+((u2>>8)&0xff) >= 0x100 ) return 1;
967: if ( d1[ind++]+(u2&0xff) >= 0x100 ) return 1;
968: }
969: return 0;
970: break;
971: case 16:
972: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
973: u2 = d2[i];
974: if ( d1[ind++]+((u2>>16)&0xffff) > 0x10000 ) return 1;
975: if ( d1[ind++]+(u2&0xffff) > 0x10000 ) return 1;
976: }
977: return 0;
978: break;
979: case 32:
980: for ( i = nd_exporigin; i < nd_wpd; i++ )
981: if ( d1[i]+d2[i]<d1[i] ) return 1;
982: return 0;
983: break;
984: default:
985: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
986: u2 = d2[i];
987: k = (nd_epw-1)*nd_bpe;
988: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
989: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
990: }
991: return 0;
992: break;
993: }
1.65 noro 994: #else
1.157 noro 995: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
996: u2 = d2[i];
997: k = (nd_epw-1)*nd_bpe;
998: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
999: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1000: }
1001: return 0;
1.65 noro 1002: #endif
1.1 noro 1003: }
1004:
1.114 noro 1005: int ndl_check_bound2(int index,UINT *d2)
1006: {
1.157 noro 1007: return ndl_check_bound(nd_bound[index],d2);
1.114 noro 1008: }
1009:
1.61 noro 1010: INLINE int ndl_hash_value(UINT *d)
1.1 noro 1011: {
1.157 noro 1012: int i;
1013: int r;
1.1 noro 1014:
1.157 noro 1015: r = 0;
1016: for ( i = 0; i < nd_wpd; i++ )
1017: r = ((r<<16)+d[i])%REDTAB_LEN;
1018: return r;
1.1 noro 1019: }
1020:
1.63 noro 1021: INLINE int ndl_find_reducer(UINT *dg)
1.1 noro 1022: {
1.157 noro 1023: RHist r;
1024: int d,k,i;
1.1 noro 1025:
1.157 noro 1026: d = ndl_hash_value(dg);
1027: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1028: if ( ndl_equal(dg,DL(r)) ) {
1029: if ( k > 0 ) nd_notfirst++;
1030: nd_found++;
1031: return r->index;
1032: }
1033: }
1034: if ( Reverse )
1035: for ( i = nd_psn-1; i >= 0; i-- ) {
1036: r = nd_psh[i];
1037: if ( ndl_reducible(dg,DL(r)) ) {
1038: nd_create++;
1039: nd_append_red(dg,i);
1040: return i;
1041: }
1042: }
1043: else
1044: for ( i = 0; i < nd_psn; i++ ) {
1045: r = nd_psh[i];
1046: if ( ndl_reducible(dg,DL(r)) ) {
1047: nd_create++;
1048: nd_append_red(dg,i);
1049: return i;
1050: }
1051: }
1052: return -1;
1.1 noro 1053: }
1054:
1.63 noro 1055: ND nd_merge(ND p1,ND p2)
1056: {
1.157 noro 1057: int n,c;
1058: int t,can,td1,td2;
1059: ND r;
1060: NM m1,m2,mr0,mr,s;
1061:
1062: if ( !p1 ) return p2;
1063: else if ( !p2 ) return p1;
1064: else {
1065: can = 0;
1066: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1067: c = DL_COMPARE(DL(m1),DL(m2));
1068: switch ( c ) {
1069: case 0:
1070: s = m1; m1 = NEXT(m1);
1071: can++; NEXTNM2(mr0,mr,s);
1072: s = m2; m2 = NEXT(m2); FREENM(s);
1073: break;
1074: case 1:
1075: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1076: break;
1077: case -1:
1078: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1079: break;
1080: }
1081: }
1082: if ( !mr0 )
1083: if ( m1 ) mr0 = m1;
1084: else if ( m2 ) mr0 = m2;
1085: else return 0;
1086: else if ( m1 ) NEXT(mr) = m1;
1087: else if ( m2 ) NEXT(mr) = m2;
1088: else NEXT(mr) = 0;
1089: BDY(p1) = mr0;
1090: SG(p1) = MAX(SG(p1),SG(p2));
1091: LEN(p1) = LEN(p1)+LEN(p2)-can;
1092: FREEND(p2);
1093: return p1;
1094: }
1.63 noro 1095: }
1096:
1.31 noro 1097: ND nd_add(int mod,ND p1,ND p2)
1.1 noro 1098: {
1.157 noro 1099: int n,c;
1100: int t,can,td1,td2;
1101: ND r;
1102: NM m1,m2,mr0,mr,s;
1103:
1104: if ( !p1 ) return p2;
1105: else if ( !p2 ) return p1;
1106: else if ( mod == -1 ) return nd_add_sf(p1,p2);
1107: else if ( !mod ) return nd_add_q(p1,p2);
1108: else {
1109: can = 0;
1110: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1111: c = DL_COMPARE(DL(m1),DL(m2));
1112: switch ( c ) {
1113: case 0:
1114: t = ((CM(m1))+(CM(m2))) - mod;
1115: if ( t < 0 ) t += mod;
1116: s = m1; m1 = NEXT(m1);
1117: if ( t ) {
1118: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1119: } else {
1120: can += 2; FREENM(s);
1121: }
1122: s = m2; m2 = NEXT(m2); FREENM(s);
1123: break;
1124: case 1:
1125: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1126: break;
1127: case -1:
1128: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1129: break;
1130: }
1131: }
1132: if ( !mr0 )
1133: if ( m1 ) mr0 = m1;
1134: else if ( m2 ) mr0 = m2;
1135: else return 0;
1136: else if ( m1 ) NEXT(mr) = m1;
1137: else if ( m2 ) NEXT(mr) = m2;
1138: else NEXT(mr) = 0;
1139: BDY(p1) = mr0;
1140: SG(p1) = MAX(SG(p1),SG(p2));
1141: LEN(p1) = LEN(p1)+LEN(p2)-can;
1142: FREEND(p2);
1143: return p1;
1144: }
1.95 noro 1145: }
1146:
1147: /* XXX on opteron, the inlined manipulation of destructive additon of
1148: * two NM seems to make gcc optimizer get confused, so the part is
1149: * done in a function.
1150: */
1151:
1.113 noro 1152: int nm_destructive_add_q(NM *m1,NM *m2,NM *mr0,NM *mr)
1.95 noro 1153: {
1.157 noro 1154: NM s;
1155: P t;
1156: int can;
1157:
1158: addp(nd_vc,CP(*m1),CP(*m2),&t);
1159: s = *m1; *m1 = NEXT(*m1);
1160: if ( t ) {
1161: can = 1; NEXTNM2(*mr0,*mr,s); CP(*mr) = (t);
1162: } else {
1163: can = 2; FREENM(s);
1164: }
1165: s = *m2; *m2 = NEXT(*m2); FREENM(s);
1166: return can;
1.95 noro 1167: }
1168:
1.113 noro 1169: ND nd_add_q(ND p1,ND p2)
1.95 noro 1170: {
1.157 noro 1171: int n,c,can;
1172: ND r;
1173: NM m1,m2,mr0,mr,s;
1174: P t;
1175:
1176: if ( !p1 ) return p2;
1177: else if ( !p2 ) return p1;
1178: else {
1179: can = 0;
1180: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1181: c = DL_COMPARE(DL(m1),DL(m2));
1182: switch ( c ) {
1183: case 0:
1.95 noro 1184: #if defined(__x86_64__)
1.157 noro 1185: can += nm_destructive_add_q(&m1,&m2,&mr0,&mr);
1.95 noro 1186: #else
1.157 noro 1187: addp(nd_vc,CP(m1),CP(m2),&t);
1188: s = m1; m1 = NEXT(m1);
1189: if ( t ) {
1190: can++; NEXTNM2(mr0,mr,s); CP(mr) = (t);
1191: } else {
1192: can += 2; FREENM(s);
1193: }
1194: s = m2; m2 = NEXT(m2); FREENM(s);
1.95 noro 1195: #endif
1.157 noro 1196: break;
1197: case 1:
1198: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1199: break;
1200: case -1:
1201: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1202: break;
1203: }
1204: }
1205: if ( !mr0 )
1206: if ( m1 ) mr0 = m1;
1207: else if ( m2 ) mr0 = m2;
1208: else return 0;
1209: else if ( m1 ) NEXT(mr) = m1;
1210: else if ( m2 ) NEXT(mr) = m2;
1211: else NEXT(mr) = 0;
1212: BDY(p1) = mr0;
1213: SG(p1) = MAX(SG(p1),SG(p2));
1214: LEN(p1) = LEN(p1)+LEN(p2)-can;
1215: FREEND(p2);
1216: return p1;
1217: }
1.17 noro 1218: }
1219:
1.71 noro 1220: ND nd_add_sf(ND p1,ND p2)
1221: {
1.157 noro 1222: int n,c,can;
1223: ND r;
1224: NM m1,m2,mr0,mr,s;
1225: int t;
1226:
1227: if ( !p1 ) return p2;
1228: else if ( !p2 ) return p1;
1229: else {
1230: can = 0;
1231: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1232: c = DL_COMPARE(DL(m1),DL(m2));
1233: switch ( c ) {
1234: case 0:
1235: t = _addsf(CM(m1),CM(m2));
1236: s = m1; m1 = NEXT(m1);
1237: if ( t ) {
1238: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1239: } else {
1240: can += 2; FREENM(s);
1241: }
1242: s = m2; m2 = NEXT(m2); FREENM(s);
1243: break;
1244: case 1:
1245: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1246: break;
1247: case -1:
1248: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1249: break;
1250: }
1251: }
1252: if ( !mr0 )
1253: if ( m1 ) mr0 = m1;
1254: else if ( m2 ) mr0 = m2;
1255: else return 0;
1256: else if ( m1 ) NEXT(mr) = m1;
1257: else if ( m2 ) NEXT(mr) = m2;
1258: else NEXT(mr) = 0;
1259: BDY(p1) = mr0;
1260: SG(p1) = MAX(SG(p1),SG(p2));
1261: LEN(p1) = LEN(p1)+LEN(p2)-can;
1262: FREEND(p2);
1263: return p1;
1264: }
1.71 noro 1265: }
1266:
1.167 noro 1267: ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp)
1.146 noro 1268: {
1.157 noro 1269: int c,c1,c2;
1270: Q cg,cred,gcd,tq;
1271: P cgp,credp,gcdp;
1272: Obj tr,tr1;
1273:
1.167 noro 1274: if ( mod == -1 ) {
1.157 noro 1275: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1.167 noro 1276: *divp = (Obj)ONE;
1277: } else if ( mod ) {
1.157 noro 1278: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1279: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1.167 noro 1280: *divp = (Obj)ONE;
1.157 noro 1281: } else if ( nd_vc ) {
1282: ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp);
1283: divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp);
1284: chsgnp(cgp,&CP(mul));
1285: nd_mul_c_q(d,credp); nd_mul_c_q(g,credp);
1286: if ( dn ) {
1287: mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr);
1288: reductr(nd_vc,tr,&tr1); dn->r = (R)tr1;
1289: }
1.167 noro 1290: *divp = (Obj)credp;
1.157 noro 1291: } else {
1292: igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred);
1293: chsgnq(cg,&CQ(mul));
1294: nd_mul_c_q(d,(P)cred); nd_mul_c_q(g,(P)cred);
1295: if ( dn ) {
1296: mulq(dn->z,cred,&tq); dn->z = tq;
1297: }
1.167 noro 1298: *divp = (Obj)cred;
1.157 noro 1299: }
1300: return nd_add(mod,g,ndv_mul_nm(mod,mul,p));
1.146 noro 1301: }
1302:
1.1 noro 1303: /* ret=1 : success, ret=0 : overflow */
1.146 noro 1304: int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND *rp)
1.1 noro 1305: {
1.157 noro 1306: NM m,mrd,tail;
1307: NM mul;
1308: int n,sugar,psugar,sugar0,stat,index;
1309: int c,c1,c2,dummy;
1310: RHist h;
1311: NDV p,red;
1.167 noro 1312: Q cg,cred,gcd,tq,qq,iq;
1313: DP dmul;
1314: NODE node;
1315: LIST hist;
1.157 noro 1316: double hmag;
1317: P tp,tp1;
1.167 noro 1318: Obj tr,tr1,div;
1319: union oNDC hg;
1320: P cont;
1.157 noro 1321:
1322: if ( dn ) {
1323: if ( mod )
1324: dn->m = 1;
1325: else if ( nd_vc )
1326: dn->r = (R)ONE;
1327: else
1328: dn->z = ONE;
1329: }
1330: if ( !g ) {
1331: *rp = d;
1332: return 1;
1333: }
1334: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1335:
1336: sugar0 = sugar = SG(g);
1337: n = NV(g);
1338: mul = (NM)ALLOCA(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1339: if ( d )
1340: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1341: for ( ; g; ) {
1342: index = ndl_find_reducer(HDL(g));
1343: if ( index >= 0 ) {
1344: h = nd_psh[index];
1345: ndl_sub(HDL(g),DL(h),DL(mul));
1346: if ( ndl_check_bound2(index,DL(mul)) ) {
1347: nd_free(g); nd_free(d);
1348: return 0;
1349: }
1350: p = nd_demand ? ndv_load(index) : ps[index];
1.167 noro 1351: /* d+g -> div*(d+g)+mul*p */
1352: g = nd_reduce2(mod,d,g,p,mul,dn,&div);
1.172 noro 1353: if ( nd_gentrace ) {
1.167 noro 1354: /* Trace=[div,index,mul,ONE] */
1355: STOQ(index,iq);
1356: nmtodp(mod,mul,&dmul);
1357: node = mknode(4,div,iq,dmul,ONE);
1358: }
1.157 noro 1359: sugar = MAX(sugar,SG(p)+TD(DL(mul)));
1.193 noro 1360: if ( !mod && g && !nd_vc && ((double)(p_mag(HCP(g))) > hmag) ) {
1.167 noro 1361: hg = HCU(g);
1.157 noro 1362: nd_removecont2(d,g);
1.172 noro 1363: if ( dn || nd_gentrace ) {
1.167 noro 1364: /* overwrite cont : Trace=[div,index,mul,cont] */
1365: cont = ndc_div(mod,hg,HCU(g));
1366: if ( dn ) {
1367: if ( nd_vc ) {
1368: divr(nd_vc,(Obj)dn->r,(Obj)cont,&tr);
1369: reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1;
1370: } else divq(dn->z,(Q)cont,&dn->z);
1.157 noro 1371: }
1.172 noro 1372: if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont;
1.157 noro 1373: }
1374: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1375: }
1.167 noro 1376: MKLIST(hist,node);
1377: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1.157 noro 1378: } else if ( !full ) {
1379: *rp = g;
1380: return 1;
1381: } else {
1382: m = BDY(g);
1383: if ( NEXT(m) ) {
1384: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1385: } else {
1386: FREEND(g); g = 0;
1387: }
1388: if ( d ) {
1389: NEXT(tail)=m; tail=m; LEN(d)++;
1390: } else {
1391: MKND(n,m,1,d); tail = BDY(d);
1392: }
1393: }
1394: }
1395: if ( d ) SG(d) = sugar;
1396: *rp = d;
1397: return 1;
1.1 noro 1398: }
1.28 noro 1399:
1.53 noro 1400: int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp)
1.25 noro 1401: {
1.157 noro 1402: int hindex,index;
1403: NDV p;
1404: ND u,d,red;
1405: NODE l;
1406: NM mul,m,mrd,tail;
1407: int sugar,psugar,n,h_reducible;
1408: PGeoBucket bucket;
1409: int c,c1,c2;
1410: Q cg,cred,gcd,zzz;
1411: RHist h;
1412: double hmag,gmag;
1413: int count = 0;
1414: int hcount = 0;
1415:
1416: if ( !g ) {
1417: *rp = 0;
1418: return 1;
1419: }
1420: sugar = SG(g);
1421: n = NV(g);
1422: if ( !mod ) hmag = ((double)p_mag((P)HCQ(g)))*nd_scale;
1423: bucket = create_pbucket();
1424: add_pbucket(mod,bucket,g);
1425: d = 0;
1426: mul = (NM)ALLOCA(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1427: while ( 1 ) {
1428: hindex = mod?head_pbucket(mod,bucket):head_pbucket_q(bucket);
1429: if ( hindex < 0 ) {
1430: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1431: if ( d ) SG(d) = sugar;
1432: *rp = d;
1433: return 1;
1434: }
1435: g = bucket->body[hindex];
1436: index = ndl_find_reducer(HDL(g));
1437: if ( index >= 0 ) {
1438: count++;
1439: if ( !d ) hcount++;
1440: h = nd_psh[index];
1441: ndl_sub(HDL(g),DL(h),DL(mul));
1442: if ( ndl_check_bound2(index,DL(mul)) ) {
1443: nd_free(d);
1444: free_pbucket(bucket);
1445: *rp = 0;
1446: return 0;
1447: }
1448: p = ps[index];
1449: if ( mod == -1 )
1450: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1451: else if ( mod ) {
1452: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1453: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1454: } else {
1455: igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred);
1456: chsgnq(cg,&CQ(mul));
1457: nd_mul_c_q(d,(P)cred);
1458: mulq_pbucket(bucket,cred);
1459: g = bucket->body[hindex];
1460: gmag = (double)p_mag((P)HCQ(g));
1461: }
1462: red = ndv_mul_nm(mod,mul,p);
1463: bucket->body[hindex] = nd_remove_head(g);
1464: red = nd_remove_head(red);
1465: add_pbucket(mod,bucket,red);
1466: psugar = SG(p)+TD(DL(mul));
1467: sugar = MAX(sugar,psugar);
1468: if ( !mod && hmag && (gmag > hmag) ) {
1469: g = normalize_pbucket(mod,bucket);
1470: if ( !g ) {
1471: if ( d ) SG(d) = sugar;
1472: *rp = d;
1473: return 1;
1474: }
1475: nd_removecont2(d,g);
1476: hmag = ((double)p_mag((P)HCQ(g)))*nd_scale;
1477: add_pbucket(mod,bucket,g);
1478: }
1479: } else if ( !full ) {
1480: g = normalize_pbucket(mod,bucket);
1481: if ( g ) SG(g) = sugar;
1482: *rp = g;
1483: return 1;
1484: } else {
1485: m = BDY(g);
1486: if ( NEXT(m) ) {
1487: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1488: } else {
1489: FREEND(g); g = 0;
1490: }
1491: bucket->body[hindex] = g;
1492: NEXT(m) = 0;
1493: if ( d ) {
1494: NEXT(tail)=m; tail=m; LEN(d)++;
1495: } else {
1496: MKND(n,m,1,d); tail = BDY(d);
1497: }
1498: }
1499: }
1.25 noro 1500: }
1.27 noro 1501:
1.61 noro 1502: /* input : list of NDV, cand : list of NDV */
1.28 noro 1503:
1.170 noro 1504: int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand)
1.28 noro 1505: {
1.157 noro 1506: int n,i,stat;
1507: ND nf,d;
1508: NDV r;
1509: NODE t,s;
1510: union oNDC dn;
1.168 noro 1511: Q q;
1512: LIST list;
1.45 noro 1513:
1.172 noro 1514: ndv_setup(m,0,cand,nd_gentrace?1:0,1);
1.157 noro 1515: n = length(cand);
1.28 noro 1516:
1.172 noro 1517: if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; }
1.157 noro 1518: /* membercheck : list is a subset of Id(cand) ? */
1.168 noro 1519: for ( t = input, i = 0; t; t = NEXT(t), i++ ) {
1.45 noro 1520: again:
1.168 noro 1521: nd_tracelist = 0;
1.157 noro 1522: if ( nd_bpe > obpe )
1523: r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos);
1524: else
1525: r = (NDV)BDY(t);
1.171 noro 1526: d = ndvtond(m,r);
1527: stat = nd_nf(m,0,d,nd_ps,0,0,&nf);
1.157 noro 1528: if ( !stat ) {
1529: nd_reconstruct(0,0);
1530: goto again;
1531: } else if ( nf ) return 0;
1.172 noro 1532: if ( nd_gentrace ) {
1.168 noro 1533: nd_tracelist = reverse_node(nd_tracelist);
1534: MKLIST(list,nd_tracelist);
1535: STOQ(i,q); s = mknode(2,q,list); MKLIST(list,s);
1536: MKNODE(s,list,nd_alltracelist);
1537: nd_alltracelist = s; nd_tracelist = 0;
1538: }
1.157 noro 1539: if ( DP_Print ) { printf("."); fflush(stdout); }
1540: }
1541: if ( DP_Print ) { printf("\n"); }
1542: return 1;
1.23 noro 1543: }
1.1 noro 1544:
1545: ND nd_remove_head(ND p)
1546: {
1.157 noro 1547: NM m;
1.1 noro 1548:
1.157 noro 1549: m = BDY(p);
1550: if ( !NEXT(m) ) {
1551: FREEND(p); p = 0;
1552: } else {
1553: BDY(p) = NEXT(m); LEN(p)--;
1554: }
1555: FREENM(m);
1556: return p;
1.1 noro 1557: }
1558:
1.69 noro 1559: ND nd_separate_head(ND p,ND *head)
1560: {
1.157 noro 1561: NM m,m0;
1562: ND r;
1.69 noro 1563:
1.157 noro 1564: m = BDY(p);
1565: if ( !NEXT(m) ) {
1566: *head = p; p = 0;
1567: } else {
1568: m0 = m;
1569: BDY(p) = NEXT(m); LEN(p)--;
1570: NEXT(m0) = 0;
1571: MKND(NV(p),m0,1,r);
1572: *head = r;
1573: }
1574: return p;
1.69 noro 1575: }
1576:
1.1 noro 1577: PGeoBucket create_pbucket()
1578: {
1579: PGeoBucket g;
1.157 noro 1580:
1581: g = CALLOC(1,sizeof(struct oPGeoBucket));
1582: g->m = -1;
1583: return g;
1.1 noro 1584: }
1585:
1.25 noro 1586: void free_pbucket(PGeoBucket b) {
1.157 noro 1587: int i;
1.25 noro 1588:
1.157 noro 1589: for ( i = 0; i <= b->m; i++ )
1590: if ( b->body[i] ) {
1591: nd_free(b->body[i]);
1592: b->body[i] = 0;
1593: }
1.200 noro 1594: GCFREE(b);
1.25 noro 1595: }
1596:
1.63 noro 1597: void add_pbucket_symbolic(PGeoBucket g,ND d)
1598: {
1.157 noro 1599: int l,i,k,m;
1.63 noro 1600:
1.157 noro 1601: if ( !d )
1602: return;
1603: l = LEN(d);
1604: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
1605: /* 2^(k-1) < l <= 2^k (=m) */
1606: d = nd_merge(g->body[k],d);
1607: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
1608: g->body[k] = 0;
1609: d = nd_merge(g->body[k+1],d);
1610: }
1611: g->body[k] = d;
1612: g->m = MAX(g->m,k);
1.63 noro 1613: }
1614:
1.31 noro 1615: void add_pbucket(int mod,PGeoBucket g,ND d)
1.1 noro 1616: {
1.157 noro 1617: int l,i,k,m;
1.1 noro 1618:
1.157 noro 1619: if ( !d )
1620: return;
1621: l = LEN(d);
1622: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
1623: /* 2^(k-1) < l <= 2^k (=m) */
1624: d = nd_add(mod,g->body[k],d);
1625: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
1626: g->body[k] = 0;
1627: d = nd_add(mod,g->body[k+1],d);
1628: }
1629: g->body[k] = d;
1630: g->m = MAX(g->m,k);
1.1 noro 1631: }
1632:
1.113 noro 1633: void mulq_pbucket(PGeoBucket g,Q c)
1.26 noro 1634: {
1.157 noro 1635: int k;
1.26 noro 1636:
1.157 noro 1637: for ( k = 0; k <= g->m; k++ )
1638: nd_mul_c_q(g->body[k],(P)c);
1.26 noro 1639: }
1640:
1.63 noro 1641: NM remove_head_pbucket_symbolic(PGeoBucket g)
1642: {
1.157 noro 1643: int j,i,k,c;
1644: NM head;
1645:
1646: k = g->m;
1647: j = -1;
1648: for ( i = 0; i <= k; i++ ) {
1649: if ( !g->body[i] ) continue;
1650: if ( j < 0 ) j = i;
1651: else {
1652: c = DL_COMPARE(HDL(g->body[i]),HDL(g->body[j]));
1653: if ( c > 0 )
1654: j = i;
1655: else if ( c == 0 )
1656: g->body[i] = nd_remove_head(g->body[i]);
1657: }
1658: }
1659: if ( j < 0 ) return 0;
1660: else {
1661: head = BDY(g->body[j]);
1662: if ( !NEXT(head) ) {
1663: FREEND(g->body[j]);
1664: g->body[j] = 0;
1665: } else {
1666: BDY(g->body[j]) = NEXT(head);
1667: LEN(g->body[j])--;
1668: }
1669: return head;
1670: }
1.63 noro 1671: }
1672:
1.19 noro 1673: int head_pbucket(int mod,PGeoBucket g)
1.1 noro 1674: {
1.157 noro 1675: int j,i,c,k,nv,sum;
1676: UINT *di,*dj;
1677: ND gi,gj;
1678:
1679: k = g->m;
1680: while ( 1 ) {
1681: j = -1;
1682: for ( i = 0; i <= k; i++ ) {
1683: if ( !(gi = g->body[i]) )
1684: continue;
1685: if ( j < 0 ) {
1686: j = i;
1687: gj = g->body[j];
1688: dj = HDL(gj);
1689: sum = HCM(gj);
1690: } else {
1691: c = DL_COMPARE(HDL(gi),dj);
1692: if ( c > 0 ) {
1693: if ( sum ) HCM(gj) = sum;
1694: else g->body[j] = nd_remove_head(gj);
1695: j = i;
1696: gj = g->body[j];
1697: dj = HDL(gj);
1698: sum = HCM(gj);
1699: } else if ( c == 0 ) {
1700: if ( mod == -1 )
1701: sum = _addsf(sum,HCM(gi));
1702: else {
1703: sum = sum+HCM(gi)-mod;
1704: if ( sum < 0 ) sum += mod;
1705: }
1706: g->body[i] = nd_remove_head(gi);
1707: }
1708: }
1709: }
1710: if ( j < 0 ) return -1;
1711: else if ( sum ) {
1712: HCM(gj) = sum;
1713: return j;
1714: } else
1715: g->body[j] = nd_remove_head(gj);
1716: }
1.26 noro 1717: }
1718:
1.113 noro 1719: int head_pbucket_q(PGeoBucket g)
1.26 noro 1720: {
1.157 noro 1721: int j,i,c,k,nv;
1722: Q sum,t;
1723: ND gi,gj;
1724:
1725: k = g->m;
1726: while ( 1 ) {
1727: j = -1;
1728: for ( i = 0; i <= k; i++ ) {
1729: if ( !(gi = g->body[i]) ) continue;
1730: if ( j < 0 ) {
1731: j = i;
1732: gj = g->body[j];
1733: sum = HCQ(gj);
1734: } else {
1735: nv = NV(gi);
1736: c = DL_COMPARE(HDL(gi),HDL(gj));
1737: if ( c > 0 ) {
1738: if ( sum ) HCQ(gj) = sum;
1739: else g->body[j] = nd_remove_head(gj);
1740: j = i;
1741: gj = g->body[j];
1742: sum = HCQ(gj);
1743: } else if ( c == 0 ) {
1744: addq(sum,HCQ(gi),&t);
1745: sum = t;
1746: g->body[i] = nd_remove_head(gi);
1747: }
1748: }
1749: }
1750: if ( j < 0 ) return -1;
1751: else if ( sum ) {
1752: HCQ(gj) = sum;
1753: return j;
1754: } else
1755: g->body[j] = nd_remove_head(gj);
1756: }
1.1 noro 1757: }
1758:
1.25 noro 1759: ND normalize_pbucket(int mod,PGeoBucket g)
1.1 noro 1760: {
1.157 noro 1761: int i;
1762: ND r,t;
1.1 noro 1763:
1.157 noro 1764: r = 0;
1765: for ( i = 0; i <= g->m; i++ ) {
1766: r = nd_add(mod,r,g->body[i]);
1767: g->body[i] = 0;
1768: }
1769: g->m = -1;
1770: return r;
1.1 noro 1771: }
1772:
1.150 noro 1773: #if 0
1774: void register_hcf(NDV p)
1775: {
1.157 noro 1776: DCP dc,t;
1777: P hc,h;
1778: int c;
1779: NODE l,l1,prev;
1780:
1781: hc = p->body->c.p;
1782: if ( !nd_vc || NUM(hc) ) return;
1783: fctrp(nd_vc,hc,&dc);
1784: for ( t = dc; t; t = NEXT(t) ) {
1785: h = t->c;
1786: if ( NUM(h) ) continue;
1787: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
1788: c = compp(nd_vc,h,(P)BDY(l));
1789: if ( c >= 0 ) break;
1790: }
1791: if ( !l || c > 0 ) {
1792: MKNODE(l1,h,l);
1793: if ( !prev )
1794: nd_hcf = l1;
1795: else
1796: NEXT(prev) = l1;
1797: }
1798: }
1.150 noro 1799: }
1800: #else
1801: void register_hcf(NDV p)
1802: {
1.157 noro 1803: DCP dc,t;
1804: P hc,h,q;
1805: Q dmy;
1806: int c;
1807: NODE l,l1,prev;
1808:
1809: hc = p->body->c.p;
1810: if ( NUM(hc) ) return;
1811: ptozp(hc,1,&dmy,&h);
1.150 noro 1812: #if 1
1.157 noro 1813: for ( l = nd_hcf; l; l = NEXT(l) ) {
1814: while ( 1 ) {
1815: if ( divtpz(nd_vc,h,(P)BDY(l),&q) ) h = q;
1816: else break;
1817: }
1818: }
1819: if ( NUM(h) ) return;
1.150 noro 1820: #endif
1.157 noro 1821: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
1822: c = compp(nd_vc,h,(P)BDY(l));
1823: if ( c >= 0 ) break;
1824: }
1825: if ( !l || c > 0 ) {
1826: MKNODE(l1,h,l);
1827: if ( !prev )
1828: nd_hcf = l1;
1829: else
1830: NEXT(prev) = l1;
1831: }
1.150 noro 1832: }
1833: #endif
1834:
1.122 noro 1835: int do_diagonalize(int sugar,int m)
1.92 noro 1836: {
1.157 noro 1837: int i,nh,stat;
1838: NODE r,g,t;
1839: ND h,nf,s,head;
1840: NDV nfv;
1841: Q q,num,den;
1.167 noro 1842: P nm,nmp,dn,mnp,dnp,cont,cont1;
1843: union oNDC hc;
1844: NODE node;
1845: LIST l;
1846: Q iq;
1.157 noro 1847:
1848: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
1.172 noro 1849: if ( nd_gentrace ) {
1.167 noro 1850: /* Trace = [1,index,1,1] */
1851: STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
1852: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
1853: }
1.157 noro 1854: if ( nd_demand )
1855: nfv = ndv_load(i);
1856: else
1857: nfv = nd_ps[i];
1858: s = ndvtond(m,nfv);
1859: s = nd_separate_head(s,&head);
1860: stat = nd_nf(m,head,s,nd_ps,1,0,&nf);
1861: if ( !stat ) return 0;
1862: ndv_free(nfv);
1.167 noro 1863: hc = HCU(nf); nd_removecont(m,nf);
1864: cont = ndc_div(m,hc,HCU(nf));
1.172 noro 1865: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.157 noro 1866: nfv = ndtondv(m,nf);
1867: nd_free(nf);
1868: nd_bound[i] = ndv_compute_bound(nfv);
1869: if ( !m ) register_hcf(nfv);
1870: if ( nd_demand ) {
1871: ndv_save(nfv,i);
1872: ndv_free(nfv);
1873: } else
1874: nd_ps[i] = nfv;
1875: }
1876: return 1;
1.92 noro 1877: }
1878:
1.209 noro 1879: LIST compute_splist()
1880: {
1881: NODE g,tn0,tn,node;
1882: LIST l0;
1883: ND_pairs d,t;
1884: int i;
1885: Q i1,i2;
1886:
1887: g = 0; d = 0;
1888: for ( i = 0; i < nd_psn; i++ ) {
1889: d = update_pairs(d,g,i,0);
1890: g = update_base(g,i);
1891: }
1892: for ( t = d, tn0 = 0; t; t = NEXT(t) ) {
1893: NEXTNODE(tn0,tn);
1894: STOQ(t->i1,i1); STOQ(t->i2,i2);
1895: node = mknode(2,i1,i2); MKLIST(l0,node);
1896: BDY(tn) = l0;
1897: }
1898: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
1899: return l0;
1900: }
1901:
1.27 noro 1902: /* return value = 0 => input is not a GB */
1903:
1.168 noro 1904: NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp)
1.1 noro 1905: {
1.157 noro 1906: int i,nh,sugar,stat;
1907: NODE r,g,t;
1908: ND_pairs d;
1909: ND_pairs l;
1910: ND h,nf,s,head,nf1;
1911: NDV nfv;
1912: Q q,num,den;
1.167 noro 1913: union oNDC dn,hc;
1.157 noro 1914: int diag_count = 0;
1.167 noro 1915: P cont;
1916: LIST list;
1.157 noro 1917:
1918: g = 0; d = 0;
1919: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 1920: d = update_pairs(d,g,i,gensyz);
1.157 noro 1921: g = update_base(g,i);
1922: }
1923: sugar = 0;
1924: while ( d ) {
1.1 noro 1925: again:
1.157 noro 1926: l = nd_minp(d,&d);
1927: if ( SG(l) != sugar ) {
1928: if ( ishomo ) {
1929: diag_count = 0;
1930: stat = do_diagonalize(sugar,m);
1931: if ( !stat ) {
1932: NEXT(l) = d; d = l;
1933: d = nd_reconstruct(0,d);
1934: goto again;
1935: }
1936: }
1937: sugar = SG(l);
1938: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
1939: }
1940: stat = nd_sp(m,0,l,&h);
1941: if ( !stat ) {
1942: NEXT(l) = d; d = l;
1943: d = nd_reconstruct(0,d);
1944: goto again;
1945: }
1.41 noro 1946: #if USE_GEOBUCKET
1.172 noro 1947: stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!Top,&nf)
1.167 noro 1948: :nd_nf(m,0,h,nd_ps,!Top,0,&nf);
1.41 noro 1949: #else
1.157 noro 1950: stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf);
1.41 noro 1951: #endif
1.157 noro 1952: if ( !stat ) {
1953: NEXT(l) = d; d = l;
1954: d = nd_reconstruct(0,d);
1955: goto again;
1956: } else if ( nf ) {
1.168 noro 1957: if ( checkonly || gensyz ) return 0;
1.192 noro 1958: if ( nd_newelim ) {
1959: if ( nd_module ) {
1960: if ( MPOS(HDL(nf)) > 1 ) return 0;
1961: } else if ( !(HDL(nf)[nd_exporigin] & nd_mask[0]) ) return 0;
1962: }
1.157 noro 1963: if ( DP_Print ) { printf("+"); fflush(stdout); }
1.167 noro 1964: hc = HCU(nf);
1.157 noro 1965: nd_removecont(m,nf);
1966: if ( !m && nd_nalg ) {
1967: nd_monic(0,&nf);
1968: nd_removecont(m,nf);
1969: }
1.172 noro 1970: if ( nd_gentrace ) {
1.167 noro 1971: cont = ndc_div(m,hc,HCU(nf));
1972: if ( m || !UNIQ(cont) ) {
1.196 noro 1973: t = mknode(4,NULLP,NULLP,NULLP,cont);
1.167 noro 1974: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
1975: nd_tracelist = t;
1976: }
1977: }
1.157 noro 1978: nfv = ndtondv(m,nf); nd_free(nf);
1.215 ! noro 1979: nh = ndv_newps(m,nfv,0,0);
1.157 noro 1980: if ( !m && (ishomo && ++diag_count == diag_period) ) {
1981: diag_count = 0;
1982: stat = do_diagonalize(sugar,m);
1983: if ( !stat ) {
1984: NEXT(l) = d; d = l;
1985: d = nd_reconstruct(1,d);
1986: goto again;
1987: }
1988: }
1.168 noro 1989: d = update_pairs(d,g,nh,0);
1.157 noro 1990: g = update_base(g,nh);
1991: FREENDP(l);
1992: } else {
1.172 noro 1993: if ( nd_gentrace && gensyz ) {
1.168 noro 1994: nd_tracelist = reverse_node(nd_tracelist);
1995: MKLIST(list,nd_tracelist);
1996: STOQ(-1,q); t = mknode(2,q,list); MKLIST(list,t);
1997: MKNODE(t,list,nd_alltracelist);
1998: nd_alltracelist = t; nd_tracelist = 0;
1999: }
1.157 noro 2000: if ( DP_Print ) { printf("."); fflush(stdout); }
2001: FREENDP(l);
2002: }
2003: }
1.167 noro 2004: conv_ilist(nd_demand,0,g,indp);
1.157 noro 2005: if ( !checkonly && DP_Print ) { printf("nd_gb done.\n"); fflush(stdout); }
2006: return g;
1.1 noro 2007: }
2008:
1.209 noro 2009: /* splist = [[i1,i2],...] */
2010:
2011: int check_splist(int m,NODE splist)
2012: {
2013: NODE t,p;
2014: ND_pairs d,r,l;
2015: int stat;
2016: ND h,nf;
2017:
2018: for ( d = 0, t = splist; t; t = NEXT(t) ) {
2019: p = BDY((LIST)BDY(t));
2020: NEXTND_pairs(d,r);
2021: r->i1 = QTOS((Q)ARG0(p)); r->i2 = QTOS((Q)ARG1(p));
2022: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
2023: SG(r) = TD(LCM(r)); /* XXX */
2024: }
2025: if ( d ) NEXT(r) = 0;
2026:
2027: while ( d ) {
2028: again:
2029: l = nd_minp(d,&d);
2030: stat = nd_sp(m,0,l,&h);
2031: if ( !stat ) {
2032: NEXT(l) = d; d = l;
2033: d = nd_reconstruct(0,d);
2034: goto again;
2035: }
2036: stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf);
2037: if ( !stat ) {
2038: NEXT(l) = d; d = l;
2039: d = nd_reconstruct(0,d);
2040: goto again;
2041: } else if ( nf ) return 0;
2042: if ( DP_Print) { printf("."); fflush(stdout); }
2043: }
2044: if ( DP_Print) { printf("done.\n"); fflush(stdout); }
2045: return 1;
2046: }
2047:
1.214 noro 2048: int check_splist_f4(int m,NODE splist)
2049: {
2050: UINT *s0vect;
2051: PGeoBucket bucket;
2052: NODE p,rp0,t;
2053: ND_pairs d,r,l,ll;
2054: int col,stat;
2055:
2056: for ( d = 0, t = splist; t; t = NEXT(t) ) {
2057: p = BDY((LIST)BDY(t));
2058: NEXTND_pairs(d,r);
2059: r->i1 = QTOS((Q)ARG0(p)); r->i2 = QTOS((Q)ARG1(p));
2060: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
2061: SG(r) = TD(LCM(r)); /* XXX */
2062: }
2063: if ( d ) NEXT(r) = 0;
2064:
2065: while ( d ) {
2066: l = nd_minsugarp(d,&d);
2067: bucket = create_pbucket();
2068: stat = nd_sp_f4(m,0,l,bucket);
2069: if ( !stat ) {
2070: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
2071: NEXT(ll) = d; d = l;
2072: d = nd_reconstruct(0,d);
2073: continue;
2074: }
2075: if ( bucket->m < 0 ) continue;
2076: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
2077: if ( !col ) {
2078: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
2079: NEXT(ll) = d; d = l;
2080: d = nd_reconstruct(0,d);
2081: continue;
2082: }
2083: if ( nd_f4_red(m,l,0,s0vect,col,rp0,0) ) return 0;
2084: }
2085: return 1;
2086: }
2087:
1.122 noro 2088: int do_diagonalize_trace(int sugar,int m)
1.91 noro 2089: {
1.157 noro 2090: int i,nh,stat;
2091: NODE r,g,t;
2092: ND h,nf,nfq,s,head;
2093: NDV nfv,nfqv;
2094: Q q,den,num;
1.167 noro 2095: union oNDC hc;
2096: NODE node;
2097: LIST l;
2098: Q iq;
2099: P cont,cont1;
1.157 noro 2100:
2101: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
1.172 noro 2102: if ( nd_gentrace ) {
1.167 noro 2103: /* Trace = [1,index,1,1] */
2104: STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2105: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2106: }
1.157 noro 2107: /* for nd_ps */
2108: s = ndvtond(m,nd_ps[i]);
2109: s = nd_separate_head(s,&head);
2110: stat = nd_nf_pbucket(m,s,nd_ps,1,&nf);
2111: if ( !stat ) return 0;
2112: nf = nd_add(m,head,nf);
2113: ndv_free(nd_ps[i]);
2114: nd_ps[i] = ndtondv(m,nf);
2115: nd_free(nf);
2116:
2117: /* for nd_ps_trace */
2118: if ( nd_demand )
2119: nfv = ndv_load(i);
2120: else
2121: nfv = nd_ps_trace[i];
2122: s = ndvtond(0,nfv);
2123: s = nd_separate_head(s,&head);
2124: stat = nd_nf(0,head,s,nd_ps_trace,1,0,&nf);
2125: if ( !stat ) return 0;
2126: ndv_free(nfv);
1.167 noro 2127: hc = HCU(nf); nd_removecont(0,nf);
2128: cont = ndc_div(0,hc,HCU(nf));
1.172 noro 2129: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.157 noro 2130: nfv = ndtondv(0,nf);
2131: nd_free(nf);
2132: nd_bound[i] = ndv_compute_bound(nfv);
2133: register_hcf(nfv);
2134: if ( nd_demand ) {
2135: ndv_save(nfv,i);
2136: ndv_free(nfv);
2137: } else
2138: nd_ps_trace[i] = nfv;
2139: }
2140: return 1;
1.91 noro 2141: }
2142:
1.118 noro 2143: static struct oEGT eg_invdalg;
2144: struct oEGT eg_le;
2145:
1.147 noro 2146: void nd_subst_vector(VL vl,P p,NODE subst,P *r)
2147: {
1.157 noro 2148: NODE tn;
2149: P p1;
1.147 noro 2150:
1.157 noro 2151: for ( tn = subst; tn; tn = NEXT(NEXT(tn)) ) {
2152: substp(vl,p,BDY(tn),BDY(NEXT(tn)),&p1); p = p1;
2153: }
2154: *r = p;
1.147 noro 2155: }
2156:
1.167 noro 2157: NODE nd_gb_trace(int m,int ishomo,int **indp)
1.20 noro 2158: {
1.157 noro 2159: int i,nh,sugar,stat;
2160: NODE r,g,t;
2161: ND_pairs d;
2162: ND_pairs l;
2163: ND h,nf,nfq,s,head;
2164: NDV nfv,nfqv;
2165: Q q,den,num;
2166: P hc;
1.167 noro 2167: union oNDC dn,hnfq;
1.157 noro 2168: struct oEGT eg_monic,egm0,egm1;
2169: int diag_count = 0;
1.167 noro 2170: P cont;
2171: LIST list;
1.157 noro 2172:
2173: init_eg(&eg_monic);
2174: init_eg(&eg_invdalg);
2175: init_eg(&eg_le);
2176: g = 0; d = 0;
2177: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 2178: d = update_pairs(d,g,i,0);
1.157 noro 2179: g = update_base(g,i);
2180: }
2181: sugar = 0;
2182: while ( d ) {
1.20 noro 2183: again:
1.157 noro 2184: l = nd_minp(d,&d);
2185: if ( SG(l) != sugar ) {
1.130 noro 2186: #if 1
1.157 noro 2187: if ( ishomo ) {
2188: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2189: stat = do_diagonalize_trace(sugar,m);
2190: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2191: diag_count = 0;
2192: if ( !stat ) {
2193: NEXT(l) = d; d = l;
2194: d = nd_reconstruct(1,d);
2195: goto again;
2196: }
2197: }
1.130 noro 2198: #endif
1.157 noro 2199: sugar = SG(l);
2200: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
2201: }
2202: stat = nd_sp(m,0,l,&h);
2203: if ( !stat ) {
2204: NEXT(l) = d; d = l;
2205: d = nd_reconstruct(1,d);
2206: goto again;
2207: }
1.41 noro 2208: #if USE_GEOBUCKET
1.157 noro 2209: stat = nd_nf_pbucket(m,h,nd_ps,!Top,&nf);
1.41 noro 2210: #else
1.157 noro 2211: stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf);
1.41 noro 2212: #endif
1.157 noro 2213: if ( !stat ) {
2214: NEXT(l) = d; d = l;
2215: d = nd_reconstruct(1,d);
2216: goto again;
2217: } else if ( nf ) {
2218: if ( nd_demand ) {
2219: nfqv = ndv_load(nd_psn);
2220: nfq = ndvtond(0,nfqv);
2221: } else
2222: nfq = 0;
2223: if ( !nfq ) {
2224: if ( !nd_sp(0,1,l,&h) || !nd_nf(0,0,h,nd_ps_trace,!Top,0,&nfq) ) {
2225: NEXT(l) = d; d = l;
2226: d = nd_reconstruct(1,d);
2227: goto again;
2228: }
2229: }
2230: if ( nfq ) {
2231: /* m|HC(nfq) => failure */
2232: if ( nd_vc ) {
2233: nd_subst_vector(nd_vc,HCP(nfq),nd_subst,&hc); q = (Q)hc;
2234: } else
2235: q = HCQ(nfq);
2236: if ( !rem(NM(q),m) ) return 0;
2237:
2238: if ( DP_Print ) { printf("+"); fflush(stdout); }
1.167 noro 2239: hnfq = HCU(nfq);
1.157 noro 2240: if ( nd_nalg ) {
2241: /* m|DN(HC(nf)^(-1)) => failure */
2242: get_eg(&egm0);
2243: if ( !nd_monic(m,&nfq) ) return 0;
2244: get_eg(&egm1); add_eg(&eg_monic,&egm0,&egm1);
2245: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
2246: nfv = ndv_dup(0,nfqv); ndv_mod(m,nfv); nd_free(nf);
2247: } else {
2248: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
2249: nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf);
2250: }
1.172 noro 2251: if ( nd_gentrace ) {
1.167 noro 2252: cont = ndc_div(0,hnfq,HCU(nfqv));
2253: if ( !UNIQ(cont) ) {
1.196 noro 2254: t = mknode(4,NULLP,NULLP,NULLP,cont);
1.167 noro 2255: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
2256: nd_tracelist = t;
2257: }
2258: }
1.215 ! noro 2259: nh = ndv_newps(0,nfv,nfqv,0);
1.157 noro 2260: if ( ishomo && ++diag_count == diag_period ) {
2261: diag_count = 0;
2262: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2263: stat = do_diagonalize_trace(sugar,m);
2264: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2265: if ( !stat ) {
2266: NEXT(l) = d; d = l;
2267: d = nd_reconstruct(1,d);
2268: goto again;
2269: }
2270: }
1.168 noro 2271: d = update_pairs(d,g,nh,0);
1.157 noro 2272: g = update_base(g,nh);
2273: } else {
2274: if ( DP_Print ) { printf("*"); fflush(stdout); }
2275: }
2276: } else {
2277: if ( DP_Print ) { printf("."); fflush(stdout); }
2278: }
2279: FREENDP(l);
2280: }
2281: if ( nd_nalg ) {
2282: print_eg("monic",&eg_monic);
2283: print_eg("invdalg",&eg_invdalg);
2284: print_eg("le",&eg_le);
2285: }
1.167 noro 2286: conv_ilist(nd_demand,1,g,indp);
1.157 noro 2287: if ( DP_Print ) { printf("nd_gb_trace done.\n"); fflush(stdout); }
2288: return g;
1.20 noro 2289: }
2290:
1.23 noro 2291: int ndv_compare(NDV *p1,NDV *p2)
2292: {
1.157 noro 2293: return DL_COMPARE(HDL(*p1),HDL(*p2));
1.23 noro 2294: }
2295:
2296: int ndv_compare_rev(NDV *p1,NDV *p2)
2297: {
1.157 noro 2298: return -DL_COMPARE(HDL(*p1),HDL(*p2));
1.23 noro 2299: }
2300:
1.167 noro 2301: int ndvi_compare(NDVI p1,NDVI p2)
2302: {
2303: return DL_COMPARE(HDL(p1->p),HDL(p2->p));
2304: }
2305:
2306: int ndvi_compare_rev(NDVI p1,NDVI p2)
2307: {
2308: return -DL_COMPARE(HDL(p1->p),HDL(p2->p));
2309: }
2310:
1.61 noro 2311: NODE ndv_reduceall(int m,NODE f)
1.23 noro 2312: {
1.167 noro 2313: int i,j,n,stat;
1.157 noro 2314: ND nf,g,head;
2315: NODE t,a0,a;
2316: union oNDC dn;
2317: Q q,num,den;
1.167 noro 2318: NODE node;
2319: LIST l;
2320: Q iq,jq;
2321: int *perm;
2322: union oNDC hc;
2323: P cont,cont1;
1.23 noro 2324:
1.173 noro 2325: if ( nd_nora ) return f;
1.157 noro 2326: n = length(f);
2327: ndv_setup(m,0,f,0,1);
1.167 noro 2328: perm = (int *)MALLOC(n*sizeof(int));
1.172 noro 2329: if ( nd_gentrace ) {
1.167 noro 2330: for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) )
2331: perm[i] = QTOS((Q)ARG1(BDY((LIST)BDY(t))));
2332: }
1.157 noro 2333: for ( i = 0; i < n; ) {
1.172 noro 2334: if ( nd_gentrace ) {
1.167 noro 2335: /* Trace = [1,index,1,1] */
2336: STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2337: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2338: }
1.157 noro 2339: g = ndvtond(m,nd_ps[i]);
2340: g = nd_separate_head(g,&head);
2341: stat = nd_nf(m,head,g,nd_ps,1,0,&nf);
2342: if ( !stat )
2343: nd_reconstruct(0,0);
2344: else {
2345: if ( DP_Print ) { printf("."); fflush(stdout); }
2346: ndv_free(nd_ps[i]);
1.167 noro 2347: hc = HCU(nf); nd_removecont(m,nf);
1.172 noro 2348: if ( nd_gentrace ) {
1.167 noro 2349: for ( t = nd_tracelist; t; t = NEXT(t) ) {
2350: jq = ARG1(BDY((LIST)BDY(t))); j = QTOS(jq);
2351: STOQ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq;
2352: }
2353: cont = ndc_div(m,hc,HCU(nf));
2354: finalize_tracelist(perm[i],cont);
2355: }
1.157 noro 2356: nd_ps[i] = ndtondv(m,nf); nd_free(nf);
2357: nd_bound[i] = ndv_compute_bound(nd_ps[i]);
2358: i++;
2359: }
2360: }
2361: if ( DP_Print ) { printf("\n"); }
2362: for ( a0 = 0, i = 0; i < n; i++ ) {
2363: NEXTNODE(a0,a);
1.172 noro 2364: if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i];
1.167 noro 2365: else {
2366: for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break;
2367: BDY(a) = (pointer)nd_ps[j];
2368: }
1.157 noro 2369: }
2370: NEXT(a) = 0;
2371: return a0;
1.23 noro 2372: }
2373:
1.168 noro 2374: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz)
1.1 noro 2375: {
1.157 noro 2376: ND_pairs d1,nd,cur,head,prev,remove;
1.1 noro 2377:
1.157 noro 2378: if ( !g ) return d;
1.168 noro 2379: /* for testing */
1.172 noro 2380: if ( gensyz && nd_gensyz == 2 ) {
1.168 noro 2381: d1 = nd_newpairs(g,t);
2382: if ( !d )
2383: return d1;
2384: else {
2385: nd = d;
2386: while ( NEXT(nd) ) nd = NEXT(nd);
2387: NEXT(nd) = d1;
2388: return d;
2389: }
2390: }
1.157 noro 2391: d = crit_B(d,t);
2392: d1 = nd_newpairs(g,t);
2393: d1 = crit_M(d1);
2394: d1 = crit_F(d1);
1.168 noro 2395: if ( gensyz || do_weyl )
1.157 noro 2396: head = d1;
2397: else {
2398: prev = 0; cur = head = d1;
2399: while ( cur ) {
2400: if ( crit_2( cur->i1,cur->i2 ) ) {
2401: remove = cur;
2402: if ( !prev ) head = cur = NEXT(cur);
2403: else cur = NEXT(prev) = NEXT(cur);
2404: FREENDP(remove);
2405: } else {
2406: prev = cur; cur = NEXT(cur);
2407: }
2408: }
2409: }
2410: if ( !d )
2411: return head;
2412: else {
2413: nd = d;
2414: while ( NEXT(nd) ) nd = NEXT(nd);
2415: NEXT(nd) = head;
2416: return d;
2417: }
1.1 noro 2418: }
2419:
1.157 noro 2420:
1.1 noro 2421: ND_pairs nd_newpairs( NODE g, int t )
2422: {
1.157 noro 2423: NODE h;
2424: UINT *dl;
1.187 noro 2425: int ts,s,i,t0,min,max;
1.157 noro 2426: ND_pairs r,r0;
2427:
2428: dl = DL(nd_psh[t]);
2429: ts = SG(nd_psh[t]) - TD(dl);
1.195 noro 2430: if ( nd_module && nd_intersect && (MPOS(dl) > 1) ) return 0;
1.157 noro 2431: for ( r0 = 0, h = g; h; h = NEXT(h) ) {
1.159 noro 2432: if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) )
1.157 noro 2433: continue;
1.187 noro 2434: if ( nd_gbblock ) {
2435: t0 = (long)BDY(h);
2436: for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) {
2437: min = nd_gbblock[i]; max = nd_gbblock[i+1];
2438: if ( t0 >= min && t0 <= max && t >= min && t <= max )
2439: break;
2440: }
1.188 noro 2441: if ( nd_gbblock[i] >= 0 )
1.187 noro 2442: continue;
2443: }
1.157 noro 2444: NEXTND_pairs(r0,r);
1.159 noro 2445: r->i1 = (long)BDY(h);
1.157 noro 2446: r->i2 = t;
2447: ndl_lcm(DL(nd_psh[r->i1]),dl,r->lcm);
2448: s = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
2449: SG(r) = MAX(s,ts) + TD(LCM(r));
2450: }
2451: if ( r0 ) NEXT(r) = 0;
2452: return r0;
1.1 noro 2453: }
2454:
1.157 noro 2455: /* kokokara */
2456:
1.1 noro 2457: ND_pairs crit_B( ND_pairs d, int s )
2458: {
1.157 noro 2459: ND_pairs cur,head,prev,remove;
2460: UINT *t,*tl,*lcm;
2461: int td,tdl;
2462:
2463: if ( !d ) return 0;
2464: t = DL(nd_psh[s]);
2465: prev = 0;
2466: head = cur = d;
2467: lcm = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
2468: while ( cur ) {
2469: tl = cur->lcm;
1.163 noro 2470: if ( ndl_reducible(tl,t) ) {
2471: ndl_lcm(DL(nd_psh[cur->i1]),t,lcm);
1.167 noro 2472: if ( !ndl_equal(lcm,tl) ) {
2473: ndl_lcm(DL(nd_psh[cur->i2]),t,lcm);
2474: if (!ndl_equal(lcm,tl)) {
2475: remove = cur;
2476: if ( !prev ) {
2477: head = cur = NEXT(cur);
2478: } else {
2479: cur = NEXT(prev) = NEXT(cur);
2480: }
2481: FREENDP(remove);
2482: } else {
2483: prev = cur; cur = NEXT(cur);
2484: }
2485: } else {
2486: prev = cur; cur = NEXT(cur);
2487: }
1.157 noro 2488: } else {
2489: prev = cur; cur = NEXT(cur);
2490: }
2491: }
2492: return head;
1.1 noro 2493: }
2494:
2495: ND_pairs crit_M( ND_pairs d1 )
2496: {
1.157 noro 2497: ND_pairs e,d2,d3,dd,p;
2498: UINT *id,*jd;
1.1 noro 2499:
1.157 noro 2500: if ( !d1 ) return d1;
2501: for ( dd = 0, e = d1; e; e = d3 ) {
2502: if ( !(d2 = NEXT(e)) ) {
2503: NEXT(e) = dd;
2504: return e;
2505: }
2506: id = LCM(e);
2507: for ( d3 = 0; d2; d2 = p ) {
2508: p = NEXT(d2);
2509: jd = LCM(d2);
2510: if ( ndl_equal(jd,id) )
2511: ;
2512: else if ( TD(jd) > TD(id) )
2513: if ( ndl_reducible(jd,id) ) continue;
2514: else ;
2515: else if ( ndl_reducible(id,jd) ) goto delit;
2516: NEXT(d2) = d3;
2517: d3 = d2;
2518: }
2519: NEXT(e) = dd;
2520: dd = e;
2521: continue;
2522: /**/
2523: delit: NEXT(d2) = d3;
2524: d3 = d2;
2525: for ( ; p; p = d2 ) {
2526: d2 = NEXT(p);
2527: NEXT(p) = d3;
2528: d3 = p;
2529: }
2530: FREENDP(e);
2531: }
2532: return dd;
1.1 noro 2533: }
2534:
2535: ND_pairs crit_F( ND_pairs d1 )
2536: {
1.157 noro 2537: ND_pairs rest, head,remove;
2538: ND_pairs last, p, r, w;
2539: int s;
2540:
2541: if ( !d1 ) return d1;
2542: for ( head = last = 0, p = d1; NEXT(p); ) {
2543: r = w = equivalent_pairs(p,&rest);
2544: s = SG(r);
2545: w = NEXT(w);
2546: while ( w ) {
2547: if ( crit_2(w->i1,w->i2) ) {
2548: r = w;
2549: w = NEXT(w);
2550: while ( w ) {
2551: remove = w;
2552: w = NEXT(w);
2553: FREENDP(remove);
2554: }
2555: break;
2556: } else if ( SG(w) < s ) {
2557: FREENDP(r);
2558: r = w;
2559: s = SG(r);
2560: w = NEXT(w);
2561: } else {
2562: remove = w;
2563: w = NEXT(w);
2564: FREENDP(remove);
2565: }
2566: }
2567: if ( last ) NEXT(last) = r;
2568: else head = r;
2569: NEXT(last = r) = 0;
2570: p = rest;
2571: if ( !p ) return head;
2572: }
2573: if ( !last ) return p;
2574: NEXT(last) = p;
2575: return head;
1.1 noro 2576: }
2577:
2578: int crit_2( int dp1, int dp2 )
2579: {
1.157 noro 2580: return ndl_disjoint(DL(nd_psh[dp1]),DL(nd_psh[dp2]));
1.1 noro 2581: }
2582:
1.40 noro 2583: ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest )
1.1 noro 2584: {
1.157 noro 2585: ND_pairs w,p,r,s;
2586: UINT *d;
1.1 noro 2587:
1.157 noro 2588: w = d1;
2589: d = LCM(w);
2590: s = NEXT(w);
2591: NEXT(w) = 0;
2592: for ( r = 0; s; s = p ) {
2593: p = NEXT(s);
2594: if ( ndl_equal(d,LCM(s)) ) {
2595: NEXT(s) = w; w = s;
2596: } else {
2597: NEXT(s) = r; r = s;
2598: }
2599: }
2600: *prest = r;
2601: return w;
1.1 noro 2602: }
2603:
2604: NODE update_base(NODE nd,int ndp)
2605: {
1.157 noro 2606: UINT *dl, *dln;
2607: NODE last, p, head;
1.1 noro 2608:
1.157 noro 2609: dl = DL(nd_psh[ndp]);
2610: for ( head = last = 0, p = nd; p; ) {
1.159 noro 2611: dln = DL(nd_psh[(long)BDY(p)]);
1.157 noro 2612: if ( ndl_reducible( dln, dl ) ) {
2613: p = NEXT(p);
2614: if ( last ) NEXT(last) = p;
2615: } else {
2616: if ( !last ) head = p;
2617: p = NEXT(last = p);
2618: }
2619: }
2620: head = append_one(head,ndp);
2621: return head;
1.1 noro 2622: }
2623:
2624: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest )
2625: {
1.157 noro 2626: ND_pairs m,ml,p,l;
2627: UINT *lcm;
2628: int s,td,len,tlen,c,c1;
2629:
2630: if ( !(p = NEXT(m = d)) ) {
2631: *prest = p;
2632: NEXT(m) = 0;
2633: return m;
2634: }
2635: s = SG(m);
2636: if ( !NoSugar ) {
2637: for ( ml = 0, l = m; p; p = NEXT(l = p) )
2638: if ( (SG(p) < s)
2639: || ((SG(p) == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
2640: ml = l; m = p; s = SG(m);
2641: }
2642: } else {
2643: for ( ml = 0, l = m; p; p = NEXT(l = p) )
2644: if ( DL_COMPARE(LCM(p),LCM(m)) < 0 ) {
2645: ml = l; m = p; s = SG(m);
2646: }
2647: }
2648: if ( !ml ) *prest = NEXT(m);
2649: else {
2650: NEXT(ml) = NEXT(m);
2651: *prest = d;
2652: }
2653: NEXT(m) = 0;
2654: return m;
1.1 noro 2655: }
2656:
1.63 noro 2657: ND_pairs nd_minsugarp( ND_pairs d, ND_pairs *prest )
2658: {
1.157 noro 2659: int msugar,i;
2660: ND_pairs t,dm0,dm,dr0,dr;
1.63 noro 2661:
1.157 noro 2662: for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) )
2663: if ( SG(t) < msugar ) msugar = SG(t);
2664: dm0 = 0; dr0 = 0;
2665: for ( i = 0, t = d; t; t = NEXT(t) )
2666: if ( i < nd_f4_nsp && SG(t) == msugar ) {
2667: if ( dm0 ) NEXT(dm) = t;
2668: else dm0 = t;
2669: dm = t;
2670: i++;
2671: } else {
2672: if ( dr0 ) NEXT(dr) = t;
2673: else dr0 = t;
2674: dr = t;
2675: }
2676: NEXT(dm) = 0;
2677: if ( dr0 ) NEXT(dr) = 0;
2678: *prest = dr0;
2679: return dm0;
1.63 noro 2680: }
2681:
1.215 ! noro 2682: int ndv_newps(int m,NDV a,NDV aq,int f4)
1.1 noro 2683: {
1.157 noro 2684: int len;
2685: RHist r;
2686: NDV b;
1.167 noro 2687: NODE tn;
2688: LIST l;
2689: Q iq;
1.157 noro 2690:
2691: if ( nd_psn == nd_pslen ) {
2692: nd_pslen *= 2;
2693: nd_ps = (NDV *)REALLOC((char *)nd_ps,nd_pslen*sizeof(NDV));
1.215 ! noro 2694: nd_ps_gz = (NDV *)REALLOC((char *)nd_ps_gz,nd_pslen*sizeof(NDV));
1.157 noro 2695: nd_ps_trace = (NDV *)REALLOC((char *)nd_ps_trace,nd_pslen*sizeof(NDV));
2696: nd_psh = (RHist *)REALLOC((char *)nd_psh,nd_pslen*sizeof(RHist));
2697: nd_bound = (UINT **)
2698: REALLOC((char *)nd_bound,nd_pslen*sizeof(UINT *));
1.215 ! noro 2699: nd_ps_sym = (NDV *)REALLOC((char *)nd_ps_sym,nd_pslen*sizeof(NDV));
! 2700: nd_ps_trace_sym = (NDV *)REALLOC((char *)nd_ps_trace_sym,nd_pslen*sizeof(NDV));
1.157 noro 2701: }
2702: NEWRHist(r); nd_psh[nd_psn] = r;
2703: nd_ps[nd_psn] = a;
2704: if ( aq ) {
2705: nd_ps_trace[nd_psn] = aq;
1.215 ! noro 2706: nd_ps_gz[nd_psn] = ndvtondvgz(aq);
1.157 noro 2707: register_hcf(aq);
2708: nd_bound[nd_psn] = ndv_compute_bound(aq);
2709: SG(r) = SG(aq); ndl_copy(HDL(aq),DL(r));
2710: } else {
2711: if ( !m ) register_hcf(a);
2712: nd_bound[nd_psn] = ndv_compute_bound(a);
2713: SG(r) = SG(a); ndl_copy(HDL(a),DL(r));
1.215 ! noro 2714: if ( !m ) nd_ps_gz[nd_psn] = ndvtondvgz(a);
1.157 noro 2715: }
2716: if ( nd_demand ) {
2717: if ( aq ) {
2718: ndv_save(nd_ps_trace[nd_psn],nd_psn);
1.215 ! noro 2719: nd_ps_trace_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
1.157 noro 2720: nd_ps_trace[nd_psn] = 0;
2721: } else {
2722: ndv_save(nd_ps[nd_psn],nd_psn);
1.215 ! noro 2723: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps[nd_psn]);
1.157 noro 2724: nd_ps[nd_psn] = 0;
2725: }
2726: }
1.172 noro 2727: if ( nd_gentrace ) {
1.167 noro 2728: /* reverse the tracelist and append it to alltracelist */
2729: nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist);
2730: STOQ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn);
2731: MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0;
2732: }
1.157 noro 2733: return nd_psn++;
1.1 noro 2734: }
2735:
1.167 noro 2736: /* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */
1.177 noro 2737: /* return 1 if success, 0 if failure (HC(a mod p)) */
1.167 noro 2738:
1.177 noro 2739: int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont)
1.1 noro 2740: {
1.157 noro 2741: int i,j,td,len,max;
1.167 noro 2742: NODE s,s0,f0,tn;
1.157 noro 2743: UINT *d;
2744: RHist r;
1.167 noro 2745: NDVI w;
1.157 noro 2746: NDV a,am;
1.167 noro 2747: union oNDC hc;
2748: NODE node;
2749: P hcp;
2750: Q iq,jq,hcq;
2751: LIST l;
1.157 noro 2752:
2753: nd_found = 0; nd_notfirst = 0; nd_create = 0;
1.167 noro 2754: /* initialize the tracelist */
2755: nd_tracelist = 0;
1.157 noro 2756:
2757: for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++;
1.167 noro 2758: w = (NDVI)ALLOCA(nd_psn*sizeof(struct oNDVI));
2759: for ( i = j = 0, s = f; s; s = NEXT(s), j++ )
2760: if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; }
1.157 noro 2761: if ( !dont_sort ) {
2762: /* XXX heuristic */
2763: if ( !nd_ord->id && (nd_ord->ord.simple<2) )
1.167 noro 2764: qsort(w,nd_psn,sizeof(struct oNDVI),
2765: (int (*)(const void *,const void *))ndvi_compare_rev);
1.157 noro 2766: else
1.167 noro 2767: qsort(w,nd_psn,sizeof(struct oNDVI),
2768: (int (*)(const void *,const void *))ndvi_compare);
1.157 noro 2769: }
2770: nd_pslen = 2*nd_psn;
2771: nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.215 ! noro 2772: nd_ps_gz = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.157 noro 2773: nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.215 ! noro 2774: nd_ps_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
! 2775: nd_ps_trace_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.157 noro 2776: nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist));
2777: nd_bound = (UINT **)MALLOC(nd_pslen*sizeof(UINT *));
2778: nd_hcf = 0;
2779:
2780: if ( trace && nd_vc )
2781: makesubst(nd_vc,&nd_subst);
2782: else
2783: nd_subst = 0;
2784:
2785: if ( !nd_red )
2786: nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
2787: for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0;
2788: for ( i = 0; i < nd_psn; i++ ) {
1.167 noro 2789: hc = HCU(w[i].p);
1.157 noro 2790: if ( trace ) {
1.167 noro 2791: a = nd_ps_trace[i] = ndv_dup(0,w[i].p);
1.215 ! noro 2792: nd_ps_gz[i] = ndvtondvgz(a);
1.157 noro 2793: if ( !dont_removecont) ndv_removecont(0,a);
2794: register_hcf(a);
2795: am = nd_ps[i] = ndv_dup(mod,a);
2796: ndv_mod(mod,am);
1.215 ! noro 2797: if ( DL_COMPARE(HDL(am),HDL(a)) )
! 2798: return 0;
1.157 noro 2799: ndv_removecont(mod,am);
2800: } else {
1.167 noro 2801: a = nd_ps[i] = ndv_dup(mod,w[i].p);
1.215 ! noro 2802: if ( !mod ) nd_ps_gz[i] = ndvtondvgz(a);
1.157 noro 2803: if ( mod || !dont_removecont ) ndv_removecont(mod,a);
2804: if ( !mod ) register_hcf(a);
2805: }
1.172 noro 2806: if ( nd_gentrace ) {
1.167 noro 2807: STOQ(i,iq); STOQ(w[i].i,jq); node = mknode(3,iq,jq,ONE);
1.168 noro 2808: if ( !dont_removecont )
2809: ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a));
1.167 noro 2810: MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l;
2811: }
1.157 noro 2812: NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r));
2813: nd_bound[i] = ndv_compute_bound(a);
2814: nd_psh[i] = r;
2815: if ( nd_demand ) {
2816: if ( trace ) {
2817: ndv_save(nd_ps_trace[i],i);
1.215 ! noro 2818: nd_ps_trace_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
1.157 noro 2819: nd_ps_trace[i] = 0;
2820: } else {
2821: ndv_save(nd_ps[i],i);
1.215 ! noro 2822: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps[i]);
1.157 noro 2823: nd_ps[i] = 0;
2824: }
2825: }
2826: }
1.172 noro 2827: if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0;
1.177 noro 2828: return 1;
1.20 noro 2829: }
2830:
1.119 noro 2831: struct order_spec *append_block(struct order_spec *spec,
2832: int nv,int nalg,int ord);
2833:
1.121 noro 2834: extern VECT current_dl_weight_vector_obj;
2835: static VECT prev_weight_vector_obj;
2836:
1.120 noro 2837: void preprocess_algcoef(VL vv,VL av,struct order_spec *ord,LIST f,
1.157 noro 2838: struct order_spec **ord1p,LIST *f1p,NODE *alistp)
1.120 noro 2839: {
1.157 noro 2840: NODE alist,t,s,r0,r,arg;
2841: VL tv;
2842: P poly;
2843: DP d;
2844: Alg alpha,dp;
2845: DAlg inv,da,hc;
2846: MP m;
2847: int i,nvar,nalg,n;
2848: NumberField nf;
2849: LIST f1,f2;
2850: struct order_spec *current_spec;
2851: VECT obj,obj0;
2852: Obj tmp;
2853:
2854: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++);
2855: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++);
2856:
2857: for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) {
2858: NEXTNODE(alist,t); MKV(tv->v,poly);
2859: MKAlg(poly,alpha); BDY(t) = (pointer)alpha;
2860: tv->v = tv->v->priv;
2861: }
2862: NEXT(t) = 0;
2863:
1.167 noro 2864: /* simplification, making polynomials monic */
1.157 noro 2865: setfield_dalg(alist);
2866: obj_algtodalg(f,&f1);
2867: for ( t = BDY(f); t; t = NEXT(t) ) {
2868: initd(ord); ptod(vv,vv,(P)BDY(t),&d);
2869: hc = (DAlg)BDY(d)->c;
2870: if ( NID(hc) == N_DA ) {
2871: invdalg(hc,&inv);
2872: for ( m = BDY(d); m; m = NEXT(m) ) {
2873: muldalg(inv,(DAlg)m->c,&da); m->c = (P)da;
2874: }
2875: }
2876: initd(ord); dtop(vv,vv,d,&poly); BDY(f) = (pointer)poly;
2877: }
2878: obj_dalgtoalg(f1,&f);
2879:
2880: /* append alg vars to the var list */
2881: for ( tv = vv; NEXT(tv); tv = NEXT(tv) );
2882: NEXT(tv) = av;
2883:
2884: /* append a block to ord */
2885: *ord1p = append_block(ord,nvar,nalg,2);
2886:
2887: /* create generator list */
2888: nf = get_numberfield();
2889: for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) {
2890: MKAlg(nf->defpoly[i],dp);
2891: MKNODE(s,dp,t); t = s;
2892: }
2893: MKLIST(f1,t);
2894: *alistp = alist;
2895: algobjtorat(f1,f1p);
2896:
2897: /* creating a new weight vector */
2898: prev_weight_vector_obj = obj0 = current_dl_weight_vector_obj;
2899: n = nvar+nalg+1;
2900: MKVECT(obj,n);
2901: if ( obj0 && obj0->len == nvar )
2902: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = BDY(obj0)[i];
2903: else
2904: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = (pointer)ONE;
2905: for ( i = 0; i < nalg; i++ ) BDY(obj)[i+nvar] = 0;
2906: BDY(obj)[n-1] = (pointer)ONE;
2907: arg = mknode(1,obj);
2908: Pdp_set_weight(arg,&tmp);
1.121 noro 2909: }
2910:
2911: NODE postprocess_algcoef(VL av,NODE alist,NODE r)
2912: {
1.157 noro 2913: NODE s,t,u0,u;
2914: P p;
2915: VL tv;
2916: Obj obj,tmp;
2917: NODE arg;
2918:
2919: u0 = 0;
2920: for ( t = r; t; t = NEXT(t) ) {
2921: p = (P)BDY(t);
2922: for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) {
2923: substr(CO,0,(Obj)p,tv->v,(Obj)BDY(s),&obj); p = (P)obj;
2924: }
2925: if ( OID(p) == O_P || (OID(p) == O_N && NID((Num)p) != N_A) ) {
2926: NEXTNODE(u0,u);
2927: BDY(u) = (pointer)p;
2928: }
2929: }
2930: arg = mknode(1,prev_weight_vector_obj);
2931: Pdp_set_weight(arg,&tmp);
1.121 noro 2932:
1.157 noro 2933: return u0;
1.120 noro 2934: }
2935:
1.199 noro 2936: void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
1.1 noro 2937: {
1.157 noro 2938: VL tv,fv,vv,vc,av;
2939: NODE fd,fd0,r,r0,t,x,s,xx,alist;
2940: int e,max,nvar,i;
2941: NDV b;
1.184 noro 2942: int ishomo,nalg,mrank,trank,wmax,len;
2943: NMV a;
1.157 noro 2944: Alg alpha,dp;
2945: P p,zp;
2946: Q dmy;
2947: LIST f1,f2,zpl;
2948: Obj obj;
2949: NumberField nf;
2950: struct order_spec *ord1;
1.208 noro 2951: NODE tr,tl1,tl2,tl3,tl4,nzlist;
1.170 noro 2952: LIST l1,l2,l3,l4,l5;
1.167 noro 2953: int j;
1.198 noro 2954: Q jq,bpe;
1.167 noro 2955: int *perm;
1.170 noro 2956: EPOS oepos;
1.194 noro 2957: int obpe,oadv,ompos,cbpe;
1.1 noro 2958:
1.174 noro 2959: nd_module = 0;
1.157 noro 2960: if ( !m && Demand ) nd_demand = 1;
2961: else nd_demand = 0;
1.172 noro 2962: parse_nd_option(current_option);
1.78 noro 2963:
1.157 noro 2964: if ( DP_Multiple )
2965: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
1.103 noro 2966: #if 0
1.157 noro 2967: ndv_alloc = 0;
1.103 noro 2968: #endif
1.157 noro 2969: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
2970: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
2971: switch ( ord->id ) {
2972: case 1:
2973: if ( ord->nv != nvar )
2974: error("nd_{gr,f4} : invalid order specification");
2975: break;
2976: default:
2977: break;
2978: }
2979: nd_nalg = 0;
2980: av = 0;
2981: if ( !m ) {
2982: get_algtree((Obj)f,&av);
2983: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
2984: nd_ntrans = nvar;
2985: nd_nalg = nalg;
2986: /* #i -> t#i */
2987: if ( nalg ) {
2988: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
2989: ord = ord1;
2990: f = f1;
2991: }
2992: nvar += nalg;
2993: }
2994: nd_init_ord(ord);
2995: mrank = 0;
1.178 noro 2996: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
1.157 noro 2997: for ( tv = vv; tv; tv = NEXT(tv) ) {
2998: if ( nd_module ) {
2999: s = BDY((LIST)BDY(t));
3000: trank = length(s);
3001: mrank = MAX(mrank,trank);
3002: for ( ; s; s = NEXT(s) ) {
3003: e = getdeg(tv->v,(P)BDY(s));
3004: max = MAX(e,max);
3005: }
3006: } else {
3007: e = getdeg(tv->v,(P)BDY(t));
3008: max = MAX(e,max);
3009: }
3010: }
1.208 noro 3011: nd_setup_parameters(nvar,nd_nzlist?0:max);
1.170 noro 3012: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
1.157 noro 3013: ishomo = 1;
3014: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.167 noro 3015: if ( nd_module ) {
1.172 noro 3016: if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
1.167 noro 3017: else zpl = (LIST)BDY(t);
1.157 noro 3018: b = (pointer)pltondv(CO,vv,zpl);
3019: } else {
1.172 noro 3020: if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
1.167 noro 3021: else zp = (P)BDY(t);
1.157 noro 3022: b = (pointer)ptondv(CO,vv,zp);
1.167 noro 3023: }
1.157 noro 3024: if ( ishomo )
3025: ishomo = ishomo && ndv_ishomo(b);
3026: if ( m ) ndv_mod(m,b);
3027: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
3028: }
3029: if ( fd0 ) NEXT(fd) = 0;
1.184 noro 3030:
3031: if ( !ishomo && homo ) {
3032: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
3033: b = (NDV)BDY(t); len = LEN(b);
3034: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
3035: wmax = MAX(TD(DL(a)),wmax);
3036: }
3037: homogenize_order(ord,nvar,&ord1);
3038: nd_init_ord(ord1);
3039: nd_setup_parameters(nvar+1,wmax);
3040: for ( t = fd0; t; t = NEXT(t) )
3041: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
3042: }
3043:
1.211 noro 3044: ndv_setup(m,0,fd0,(nd_gbblock||nd_splist||nd_check_splist)?1:0,0);
1.172 noro 3045: if ( nd_gentrace ) {
1.167 noro 3046: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
3047: }
1.209 noro 3048: if ( nd_splist ) {
3049: *rp = compute_splist();
3050: return;
3051: }
3052: if ( nd_check_splist ) {
1.214 noro 3053: if ( f4 ) {
3054: if ( check_splist_f4(m,nd_check_splist) ) *rp = (LIST)ONE;
3055: else *rp = 0;
3056: } else {
3057: if ( check_splist(m,nd_check_splist) ) *rp = (LIST)ONE;
3058: else *rp = 0;
3059: }
1.209 noro 3060: return;
3061: }
1.186 noro 3062: x = f4?nd_f4(m,&perm):nd_gb(m,ishomo || homo,0,0,&perm);
1.192 noro 3063: if ( !x ) {
3064: *rp = 0; return;
3065: }
1.184 noro 3066: if ( !ishomo && homo ) {
3067: /* dehomogenization */
3068: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
3069: nd_init_ord(ord);
3070: nd_setup_parameters(nvar,0);
3071: }
1.157 noro 3072: nd_demand = 0;
1.195 noro 3073: if ( nd_module && nd_intersect ) {
3074: for ( j = nd_psn-1, x = 0; j >= 0; j-- )
3075: if ( MPOS(DL(nd_psh[j])) > 1 ) {
3076: MKNODE(xx,(pointer)j,x); x = xx;
3077: }
3078: conv_ilist(nd_demand,0,x,0);
3079: goto FINAL;
3080: }
1.208 noro 3081: if ( nd_gentrace && f4 ) { nzlist = nd_alltracelist; }
1.167 noro 3082: x = ndv_reducebase(x,perm);
1.208 noro 3083: if ( nd_gentrace && !f4 ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
1.157 noro 3084: x = ndv_reduceall(m,x);
1.194 noro 3085: cbpe = nd_bpe;
1.208 noro 3086: if ( nd_gentrace && !f4 ) {
1.170 noro 3087: tl2 = nd_alltracelist; nd_alltracelist = 0;
3088: ndv_check_membership(m,fd0,obpe,oadv,oepos,x);
1.198 noro 3089: tl3 = nd_alltracelist; nd_alltracelist = 0;
3090: if ( nd_gensyz ) {
3091: nd_gb(m,0,1,1,0);
1.170 noro 3092: tl4 = nd_alltracelist; nd_alltracelist = 0;
3093: } else tl4 = 0;
3094: }
1.194 noro 3095: nd_bpe = cbpe;
3096: nd_setup_parameters(nd_nvar,0);
1.195 noro 3097: FINAL:
1.157 noro 3098: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
3099: NEXTNODE(r0,r);
1.194 noro 3100: if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank);
1.199 noro 3101: else if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
3102: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.157 noro 3103: }
3104: if ( r0 ) NEXT(r) = 0;
1.208 noro 3105: if ( !m && nd_nalg )
1.157 noro 3106: r0 = postprocess_algcoef(av,alist,r0);
3107: MKLIST(*rp,r0);
1.172 noro 3108: if ( nd_gentrace ) {
1.208 noro 3109: if ( f4 ) {
3110: STOQ(16,bpe);
3111: tr = mknode(4,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe); MKLIST(*rp,tr);
3112: } else {
3113: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
3114: tl3 = reverse_node(tl3);
3115: /* tl2 = [[i,[[*,j,*,*],...]],...] */
3116: for ( t = tl2; t; t = NEXT(t) ) {
3117: /* s = [i,[*,j,*,*],...] */
3118: s = BDY((LIST)BDY(t));
3119: j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq;
3120: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
3121: j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq);
3122: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
3123: }
3124: }
3125: for ( j = length(x)-1, t = 0; j >= 0; j-- ) {
3126: STOQ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.167 noro 3127: }
1.208 noro 3128: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
3129: MKLIST(l5,tl4);
3130: STOQ(nd_bpe,bpe);
3131: tr = mknode(8,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe); MKLIST(*rp,tr);
3132: }
1.167 noro 3133: }
1.103 noro 3134: #if 0
1.157 noro 3135: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.103 noro 3136: #endif
1.127 noro 3137: }
3138:
3139: void nd_gr_postproc(LIST f,LIST v,int m,struct order_spec *ord,int do_check,LIST *rp)
3140: {
1.157 noro 3141: VL tv,fv,vv,vc,av;
3142: NODE fd,fd0,r,r0,t,x,s,xx,alist;
3143: int e,max,nvar,i;
3144: NDV b;
3145: int ishomo,nalg;
3146: Alg alpha,dp;
3147: P p,zp;
3148: Q dmy;
3149: LIST f1,f2;
3150: Obj obj;
3151: NumberField nf;
3152: struct order_spec *ord1;
1.167 noro 3153: int *perm;
1.157 noro 3154:
1.197 noro 3155: parse_nd_option(current_option);
1.157 noro 3156: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
3157: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3158: switch ( ord->id ) {
3159: case 1:
3160: if ( ord->nv != nvar )
3161: error("nd_check : invalid order specification");
3162: break;
3163: default:
3164: break;
3165: }
3166: nd_nalg = 0;
3167: av = 0;
3168: if ( !m ) {
3169: get_algtree((Obj)f,&av);
3170: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
3171: nd_ntrans = nvar;
3172: nd_nalg = nalg;
3173: /* #i -> t#i */
3174: if ( nalg ) {
3175: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
3176: ord = ord1;
3177: f = f1;
3178: }
3179: nvar += nalg;
3180: }
3181: nd_init_ord(ord);
1.178 noro 3182: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
1.157 noro 3183: for ( tv = vv; tv; tv = NEXT(tv) ) {
3184: e = getdeg(tv->v,(P)BDY(t));
3185: max = MAX(e,max);
3186: }
3187: nd_setup_parameters(nvar,max);
3188: ishomo = 1;
3189: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
3190: ptozp((P)BDY(t),1,&dmy,&zp);
3191: b = (pointer)ptondv(CO,vv,zp);
3192: if ( ishomo )
3193: ishomo = ishomo && ndv_ishomo(b);
3194: if ( m ) ndv_mod(m,b);
3195: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
3196: }
3197: if ( fd0 ) NEXT(fd) = 0;
3198: ndv_setup(m,0,fd0,0,1);
3199: for ( x = 0, i = 0; i < nd_psn; i++ )
3200: x = update_base(x,i);
3201: if ( do_check ) {
1.168 noro 3202: x = nd_gb(m,ishomo,1,0,&perm);
1.157 noro 3203: if ( !x ) {
3204: *rp = 0;
3205: return;
3206: }
3207: } else {
1.175 noro 3208: #if 0
3209: /* bug ? */
1.157 noro 3210: for ( t = x; t; t = NEXT(t) )
1.159 noro 3211: BDY(t) = (pointer)nd_ps[(long)BDY(t)];
1.175 noro 3212: #else
3213: conv_ilist(0,0,x,&perm);
3214: #endif
1.157 noro 3215: }
1.167 noro 3216: x = ndv_reducebase(x,perm);
1.157 noro 3217: x = ndv_reduceall(m,x);
3218: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
3219: NEXTNODE(r0,r);
3220: BDY(r) = ndvtop(m,CO,vv,BDY(t));
3221: }
3222: if ( r0 ) NEXT(r) = 0;
1.208 noro 3223: if ( !m && nd_nalg )
1.157 noro 3224: r0 = postprocess_algcoef(av,alist,r0);
3225: MKLIST(*rp,r0);
1.20 noro 3226: }
3227:
1.198 noro 3228: NDV recompute_trace(NODE trace,NDV *p,int m);
3229: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp);
3230:
3231: NDV recompute_trace(NODE ti,NDV *p,int mod)
3232: {
3233: int c,c1,c2,i;
3234: NM mul,m,tail;
3235: ND d,r,rm;
3236: NODE sj;
3237: NDV red;
3238: Obj mj;
3239: static int afo=0;
3240:
3241: afo++;
3242: mul = (NM)ALLOCA(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
3243: CM(mul) = 1;
3244: tail = 0;
3245: for ( i = 0, d = r = 0; ti; ti = NEXT(ti), i++ ) {
3246: sj = BDY((LIST)BDY(ti));
3247: if ( ARG0(sj) ) {
3248: red = p[QTOS((Q)ARG1(sj))];
3249: mj = (Obj)ARG2(sj);
3250: if ( OID(mj) != O_DP ) ndl_zero(DL(mul));
3251: else dltondl(nd_nvar,BDY((DP)mj)->dl,DL(mul));
3252: rm = ndv_mul_nm(mod,mul,red);
3253: if ( !r ) r = rm;
3254: else {
3255: for ( m = BDY(r); m && !ndl_equal(m->dl,BDY(rm)->dl); m = NEXT(m), LEN(r)-- ) {
3256: if ( d ) {
3257: NEXT(tail) = m; tail = m; LEN(d)++;
3258: } else {
3259: MKND(nd_nvar,m,1,d); tail = BDY(d);
3260: }
3261: }
3262: if ( !m ) return 0; /* failure */
3263: else {
3264: BDY(r) = m;
3265: c1 = invm(HCM(rm),mod); c2 = mod-HCM(r);
3266: DMAR(c1,c2,0,mod,c);
3267: nd_mul_c(mod,rm,c);
3268: r = nd_add(mod,r,rm);
3269: }
3270: }
3271: }
3272: }
3273: if ( tail ) NEXT(tail) = 0;
3274: d = nd_add(mod,d,r);
3275: nd_mul_c(mod,d,invm(HCM(d),mod));
3276: return ndtondv(mod,d);
3277: }
3278:
3279: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp)
3280: {
3281: VL tv,fv,vv,vc,av;
3282: NODE fd,fd0,r,r0,t,x,s,xx,alist;
3283: int e,max,nvar,i;
3284: NDV b;
3285: int ishomo,nalg;
3286: Alg alpha,dp;
3287: P p,zp;
3288: Q dmy;
3289: LIST f1,f2;
3290: Obj obj;
3291: NumberField nf;
3292: struct order_spec *ord1;
3293: NODE permtrace,intred,ind,perm,trace,ti;
3294: int len,n,j;
3295: NDV *db,*pb;
3296:
3297: parse_nd_option(current_option);
3298: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
3299: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3300: switch ( ord->id ) {
3301: case 1:
3302: if ( ord->nv != nvar )
3303: error("nd_check : invalid order specification");
3304: break;
3305: default:
3306: break;
3307: }
3308: nd_init_ord(ord);
3309: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
3310: nd_setup_parameters(nvar,0);
3311:
3312: len = length(BDY(f));
3313: db = (NDV *)MALLOC(len*sizeof(NDV *));
3314: for ( i = 0, t = BDY(f); t; i++, t = NEXT(t) ) {
3315: ptozp((P)BDY(t),1,&dmy,&zp);
3316: b = ptondv(CO,vv,zp);
3317: ndv_mod(m,b);
3318: ndv_mul_c(m,b,invm(HCM(b),m));
3319: db[i] = b;
3320: }
3321:
3322: permtrace = BDY((LIST)ARG2(BDY(tlist)));
3323: intred = BDY((LIST)ARG3(BDY(tlist)));
3324: ind = BDY((LIST)ARG4(BDY(tlist)));
3325: perm = BDY((LIST)ARG0(permtrace));
3326: trace = NEXT(permtrace);
3327:
3328: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
3329: j = QTOS((Q)ARG0(BDY((LIST)BDY(t))));
3330: if ( j > i ) i = j;
3331: }
3332: n = i+1;
3333: pb = (NDV *)MALLOC(n*sizeof(NDV *));
3334: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
3335: ti = BDY((LIST)BDY(t));
3336: pb[QTOS((Q)ARG0(ti))] = db[QTOS((Q)ARG1(ti))];
3337: }
3338: for ( t = trace; t; t = NEXT(t) ) {
3339: ti = BDY((LIST)BDY(t));
3340: pb[QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
3341: if ( !pb[QTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
3342: if ( DP_Print ) {
3343: fprintf(asir_out,"."); fflush(asir_out);
3344: }
3345: }
3346: for ( t = intred; t; t = NEXT(t) ) {
3347: ti = BDY((LIST)BDY(t));
3348: pb[QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
3349: if ( !pb[QTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
3350: if ( DP_Print ) {
3351: fprintf(asir_out,"*"); fflush(asir_out);
3352: }
3353: }
3354: for ( r0 = 0, t = ind; t; t = NEXT(t) ) {
3355: NEXTNODE(r0,r);
3356: b = pb[QTOS((Q)BDY(t))];
3357: ndv_mul_c(m,b,invm(HCM(b),m));
3358: #if 0
3359: BDY(r) = ndvtop(m,CO,vv,pb[QTOS((Q)BDY(t))]);
3360: #else
3361: BDY(r) = ndvtodp(m,pb[QTOS((Q)BDY(t))]);
3362: #endif
3363: }
3364: if ( r0 ) NEXT(r) = 0;
3365: MKLIST(*rp,r0);
3366: if ( DP_Print ) fprintf(asir_out,"\n");
3367: }
3368:
1.133 noro 3369: void nd_gr_trace(LIST f,LIST v,int trace,int homo,int f4,struct order_spec *ord,LIST *rp)
1.20 noro 3370: {
1.157 noro 3371: VL tv,fv,vv,vc,av;
3372: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
3373: int m,nocheck,nvar,mindex,e,max;
3374: NDV c;
3375: NMV a;
3376: P p,zp;
3377: Q dmy;
3378: EPOS oepos;
1.164 noro 3379: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
1.157 noro 3380: Alg alpha,dp;
3381: P poly;
1.158 noro 3382: LIST f1,f2,zpl;
1.157 noro 3383: Obj obj;
3384: NumberField nf;
3385: struct order_spec *ord1;
3386: struct oEGT eg_check,eg0,eg1;
1.168 noro 3387: NODE tr,tl1,tl2,tl3,tl4;
3388: LIST l1,l2,l3,l4,l5;
1.167 noro 3389: int *perm;
1.168 noro 3390: int j,ret;
1.198 noro 3391: Q jq,bpe;
1.157 noro 3392:
1.167 noro 3393: nd_module = 0;
1.172 noro 3394: parse_nd_option(current_option);
1.157 noro 3395: if ( DP_Multiple )
3396: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
3397:
3398: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
3399: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3400: switch ( ord->id ) {
3401: case 1:
3402: if ( ord->nv != nvar )
3403: error("nd_gr_trace : invalid order specification");
3404: break;
3405: default:
3406: break;
3407: }
3408:
3409: get_algtree((Obj)f,&av);
3410: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
3411: nd_ntrans = nvar;
3412: nd_nalg = nalg;
3413: /* #i -> t#i */
3414: if ( nalg ) {
3415: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
3416: ord = ord1;
3417: f = f1;
3418: }
3419: nvar += nalg;
3420:
3421: nocheck = 0;
3422: mindex = 0;
3423:
3424: if ( Demand ) nd_demand = 1;
3425: else nd_demand = 0;
3426:
3427: /* setup modulus */
3428: if ( trace < 0 ) {
3429: trace = -trace;
3430: nocheck = 1;
3431: }
3432: m = trace > 1 ? trace : get_lprime(mindex);
1.158 noro 3433: nd_init_ord(ord);
3434: mrank = 0;
1.178 noro 3435: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
1.157 noro 3436: for ( tv = vv; tv; tv = NEXT(tv) ) {
1.158 noro 3437: if ( nd_module ) {
3438: s = BDY((LIST)BDY(t));
3439: trank = length(s);
3440: mrank = MAX(mrank,trank);
3441: for ( ; s; s = NEXT(s) ) {
3442: e = getdeg(tv->v,(P)BDY(s));
3443: max = MAX(e,max);
3444: }
3445: } else {
3446: e = getdeg(tv->v,(P)BDY(t));
3447: max = MAX(e,max);
3448: }
1.157 noro 3449: }
3450: nd_setup_parameters(nvar,max);
1.164 noro 3451: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
1.157 noro 3452: ishomo = 1;
3453: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.167 noro 3454: if ( nd_module ) {
1.172 noro 3455: if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
1.167 noro 3456: else zpl = (LIST)BDY(t);
1.158 noro 3457: c = (pointer)pltondv(CO,vv,zpl);
3458: } else {
1.172 noro 3459: if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
1.167 noro 3460: else zp = (P)BDY(t);
1.158 noro 3461: c = (pointer)ptondv(CO,vv,zp);
1.167 noro 3462: }
1.157 noro 3463: if ( ishomo )
3464: ishomo = ishomo && ndv_ishomo(c);
3465: if ( c ) {
3466: NEXTNODE(in0,in); BDY(in) = (pointer)c;
3467: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
3468: }
3469: }
3470: if ( in0 ) NEXT(in) = 0;
3471: if ( fd0 ) NEXT(fd) = 0;
3472: if ( !ishomo && homo ) {
3473: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
3474: c = (NDV)BDY(t); len = LEN(c);
3475: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
3476: wmax = MAX(TD(DL(a)),wmax);
3477: }
3478: homogenize_order(ord,nvar,&ord1);
3479: nd_init_ord(ord1);
3480: nd_setup_parameters(nvar+1,wmax);
3481: for ( t = fd0; t; t = NEXT(t) )
1.164 noro 3482: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
1.157 noro 3483: }
3484: while ( 1 ) {
1.183 noro 3485: tl1 = tl2 = tl3 = tl4 = 0;
1.157 noro 3486: if ( Demand )
3487: nd_demand = 1;
1.187 noro 3488: ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0);
1.172 noro 3489: if ( nd_gentrace ) {
1.167 noro 3490: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
3491: }
1.177 noro 3492: if ( ret )
3493: cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm);
3494: if ( !ret || !cand ) {
1.157 noro 3495: /* failure */
3496: if ( trace > 1 ) { *rp = 0; return; }
3497: else m = get_lprime(++mindex);
3498: continue;
3499: }
3500: if ( !ishomo && homo ) {
3501: /* dehomogenization */
3502: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
3503: nd_init_ord(ord);
3504: nd_setup_parameters(nvar,0);
3505: }
3506: nd_demand = 0;
1.167 noro 3507: cand = ndv_reducebase(cand,perm);
1.172 noro 3508: if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
1.157 noro 3509: cand = ndv_reduceall(0,cand);
3510: cbpe = nd_bpe;
1.172 noro 3511: if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; }
1.173 noro 3512: get_eg(&eg0);
1.157 noro 3513: if ( nocheck )
3514: break;
1.170 noro 3515: if ( ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand) ) {
1.172 noro 3516: if ( nd_gentrace ) {
1.168 noro 3517: tl3 = nd_alltracelist; nd_alltracelist = 0;
3518: } else tl3 = 0;
3519: /* gbcheck : cand is a GB of Id(cand) ? */
1.172 noro 3520: ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0;
3521: if ( nd_gentrace && nd_gensyz ) {
1.168 noro 3522: tl4 = nd_alltracelist; nd_alltracelist = 0;
3523: } else tl4 = 0;
3524: }
3525: if ( ret ) break;
1.157 noro 3526: else if ( trace > 1 ) {
3527: /* failure */
3528: *rp = 0; return;
3529: } else {
3530: /* try the next modulus */
3531: m = get_lprime(++mindex);
3532: /* reset the parameters */
3533: if ( !ishomo && homo ) {
3534: nd_init_ord(ord1);
3535: nd_setup_parameters(nvar+1,wmax);
3536: } else {
3537: nd_init_ord(ord);
3538: nd_setup_parameters(nvar,max);
3539: }
3540: }
3541: }
3542: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
3543: if ( DP_Print )
3544: fprintf(asir_out,"check=%fsec\n",eg_check.exectime+eg_check.gctime);
3545: /* dp->p */
3546: nd_bpe = cbpe;
3547: nd_setup_parameters(nd_nvar,0);
1.158 noro 3548: for ( r = cand; r; r = NEXT(r) ) {
1.167 noro 3549: if ( nd_module ) BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank);
1.158 noro 3550: else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r));
3551: }
1.208 noro 3552: if ( nd_nalg )
1.157 noro 3553: cand = postprocess_algcoef(av,alist,cand);
3554: MKLIST(*rp,cand);
1.172 noro 3555: if ( nd_gentrace ) {
1.167 noro 3556: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
1.168 noro 3557: tl3 = reverse_node(tl3);
1.167 noro 3558: /* tl2 = [[i,[[*,j,*,*],...]],...] */
3559: for ( t = tl2; t; t = NEXT(t) ) {
3560: /* s = [i,[*,j,*,*],...] */
3561: s = BDY((LIST)BDY(t));
3562: j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq;
3563: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
3564: j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq);
3565: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
3566: }
3567: }
3568: for ( j = length(cand)-1, t = 0; j >= 0; j-- ) {
3569: STOQ(perm[j],jq); MKNODE(s,jq,t); t = s;
3570: }
1.168 noro 3571: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
3572: MKLIST(l5,tl4);
1.198 noro 3573: STOQ(nd_bpe,bpe);
3574: tr = mknode(8,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe); MKLIST(*rp,tr);
1.167 noro 3575: }
1.157 noro 3576: }
1.52 noro 3577:
1.157 noro 3578: /* XXX : module element is not considered */
1.1 noro 3579:
1.61 noro 3580: void dltondl(int n,DL dl,UINT *r)
1.1 noro 3581: {
1.157 noro 3582: UINT *d;
3583: int i,j,l,s,ord_l;
3584: struct order_pair *op;
3585:
3586: d = dl->d;
3587: for ( i = 0; i < nd_wpd; i++ ) r[i] = 0;
3588: if ( nd_blockmask ) {
3589: l = nd_blockmask->n;
3590: op = nd_blockmask->order_pair;
3591: for ( j = 0, s = 0; j < l; j++ ) {
3592: ord_l = op[j].length;
3593: for ( i = 0; i < ord_l; i++, s++ ) PUT_EXP(r,s,d[s]);
3594: }
3595: TD(r) = ndl_weight(r);
3596: ndl_weight_mask(r);
3597: } else {
3598: for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]);
3599: TD(r) = ndl_weight(r);
3600: }
1.1 noro 3601: }
3602:
1.61 noro 3603: DL ndltodl(int n,UINT *ndl)
1.1 noro 3604: {
1.157 noro 3605: DL dl;
3606: int *d;
3607: int i,j,l,s,ord_l;
3608: struct order_pair *op;
3609:
3610: NEWDL(dl,n);
3611: dl->td = TD(ndl);
3612: d = dl->d;
3613: if ( nd_blockmask ) {
3614: l = nd_blockmask->n;
3615: op = nd_blockmask->order_pair;
3616: for ( j = 0, s = 0; j < l; j++ ) {
3617: ord_l = op[j].length;
3618: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
3619: }
3620: } else {
3621: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
3622: }
3623: return dl;
1.1 noro 3624: }
3625:
1.167 noro 3626: void nmtodp(int mod,NM m,DP *r)
3627: {
3628: DP dp;
3629: MP mr;
3630:
3631: NEWMP(mr);
3632: mr->dl = ndltodl(nd_nvar,DL(m));
3633: mr->c = ndctop(mod,m->c);
3634: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
3635: *r = dp;
3636: }
3637:
1.61 noro 3638: void ndl_print(UINT *dl)
1.1 noro 3639: {
1.157 noro 3640: int n;
3641: int i,j,l,ord_l,s,s0;
3642: struct order_pair *op;
3643:
3644: n = nd_nvar;
3645: printf("<<");
3646: if ( nd_blockmask ) {
3647: l = nd_blockmask->n;
3648: op = nd_blockmask->order_pair;
3649: for ( j = 0, s = s0 = 0; j < l; j++ ) {
3650: ord_l = op[j].length;
3651: for ( i = 0; i < ord_l; i++, s++ )
3652: printf(s==n-1?"%d":"%d,",GET_EXP(dl,s));
3653: }
3654: } else {
3655: for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i));
3656: }
3657: printf(">>");
3658: if ( MPOS(dl) )
3659: printf("*e%d",MPOS(dl));
1.1 noro 3660: }
3661:
3662: void nd_print(ND p)
3663: {
1.157 noro 3664: NM m;
1.1 noro 3665:
1.157 noro 3666: if ( !p )
3667: printf("0\n");
3668: else {
3669: for ( m = BDY(p); m; m = NEXT(m) ) {
3670: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
3671: else printf("+%d*",CM(m));
3672: ndl_print(DL(m));
3673: }
3674: printf("\n");
3675: }
1.1 noro 3676: }
3677:
1.113 noro 3678: void nd_print_q(ND p)
1.16 noro 3679: {
1.157 noro 3680: NM m;
1.16 noro 3681:
1.157 noro 3682: if ( !p )
3683: printf("0\n");
3684: else {
3685: for ( m = BDY(p); m; m = NEXT(m) ) {
3686: printf("+");
3687: printexpr(CO,(Obj)CQ(m));
3688: printf("*");
3689: ndl_print(DL(m));
3690: }
3691: printf("\n");
3692: }
1.16 noro 3693: }
3694:
1.1 noro 3695: void ndp_print(ND_pairs d)
3696: {
1.157 noro 3697: ND_pairs t;
1.1 noro 3698:
1.157 noro 3699: for ( t = d; t; t = NEXT(t) ) printf("%d,%d ",t->i1,t->i2);
3700: printf("\n");
1.1 noro 3701: }
3702:
1.20 noro 3703: void nd_removecont(int mod,ND p)
1.16 noro 3704: {
1.157 noro 3705: int i,n;
3706: Q *w;
3707: Q dvr,t;
3708: NM m;
3709: struct oVECT v;
3710: N q,r;
3711:
3712: if ( mod == -1 ) nd_mul_c(mod,p,_invsf(HCM(p)));
3713: else if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod));
3714: else {
3715: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
3716: w = (Q *)ALLOCA(n*sizeof(Q));
3717: v.len = n;
3718: v.body = (pointer *)w;
3719: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) w[i] = CQ(m);
3720: removecont_array((P *)w,n,1);
3721: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) CQ(m) = w[i];
3722: }
1.16 noro 3723: }
3724:
1.21 noro 3725: void nd_removecont2(ND p1,ND p2)
3726: {
1.157 noro 3727: int i,n1,n2,n;
3728: Q *w;
3729: Q dvr,t;
3730: NM m;
3731: struct oVECT v;
3732: N q,r;
3733:
3734: n1 = nd_length(p1);
3735: n2 = nd_length(p2);
3736: n = n1+n2;
3737: w = (Q *)ALLOCA(n*sizeof(Q));
3738: v.len = n;
3739: v.body = (pointer *)w;
3740: i = 0;
3741: if ( p1 )
3742: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = CQ(m);
3743: if ( p2 )
3744: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CQ(m);
3745: removecont_array((P *)w,n,1);
3746: i = 0;
3747: if ( p1 )
3748: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) CQ(m) = w[i];
3749: if ( p2 )
3750: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CQ(m) = w[i];
1.21 noro 3751: }
3752:
1.20 noro 3753: void ndv_removecont(int mod,NDV p)
1.16 noro 3754: {
1.157 noro 3755: int i,len,all_p;
3756: Q *c;
3757: P *w;
3758: Q dvr,t;
3759: P g,cont,tp;
3760: NMV m;
3761:
3762: if ( mod == -1 )
3763: ndv_mul_c(mod,p,_invsf(HCM(p)));
3764: else if ( mod )
3765: ndv_mul_c(mod,p,invm(HCM(p),mod));
3766: else {
3767: len = p->len;
3768: w = (P *)ALLOCA(len*sizeof(P));
3769: c = (Q *)ALLOCA(len*sizeof(Q));
3770: for ( m = BDY(p), all_p = 1, i = 0; i < len; NMV_ADV(m), i++ ) {
3771: ptozp(CP(m),1,&c[i],&w[i]);
3772: all_p = all_p && !NUM(w[i]);
3773: }
3774: if ( all_p ) {
3775: qltozl(c,len,&dvr); nd_heu_nezgcdnpz(nd_vc,w,len,1,&g);
3776: mulp(nd_vc,(P)dvr,g,&cont);
3777: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
3778: divsp(nd_vc,CP(m),cont,&tp); CP(m) = tp;
3779: }
3780: } else {
3781: sortbynm((Q *)c,len);
3782: qltozl((Q *)c,len,&dvr);
3783: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
3784: divsp(nd_vc,CP(m),(P)dvr,&tp); CP(m) = tp;
3785: }
3786: }
3787: }
1.21 noro 3788: }
3789:
1.157 noro 3790: /* koko */
3791:
1.164 noro 3792: void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos,int ompos)
1.61 noro 3793: {
1.157 noro 3794: int len,i,max;
3795: NMV m,mr0,mr,t;
1.61 noro 3796:
1.157 noro 3797: len = p->len;
1.178 noro 3798: for ( m = BDY(p), i = 0, max = 1; i < len; NMV_OADV(m), i++ )
1.157 noro 3799: max = MAX(max,TD(DL(m)));
3800: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
3801: m = (NMV)((char *)mr0+(len-1)*oadv);
3802: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
3803: t = (NMV)ALLOCA(nmv_adv);
3804: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
1.164 noro 3805: ndl_homogenize(DL(m),DL(t),obpe,oepos,ompos,max);
1.157 noro 3806: CQ(mr) = CQ(m);
3807: ndl_copy(DL(t),DL(mr));
3808: }
3809: NV(p)++;
3810: BDY(p) = mr0;
1.61 noro 3811: }
3812:
1.45 noro 3813: void ndv_dehomogenize(NDV p,struct order_spec *ord)
1.23 noro 3814: {
1.164 noro 3815: int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos;
1.167 noro 3816: int pos;
1.157 noro 3817: Q *w;
3818: Q dvr,t;
3819: NMV m,r;
3820:
3821: len = p->len;
3822: newnvar = nd_nvar-1;
3823: newexporigin = nd_get_exporigin(ord);
1.167 noro 3824: if ( nd_module ) newmpos = newexporigin-1;
1.157 noro 3825: newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin;
3826: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ )
3827: ndl_dehomogenize(DL(m));
3828: if ( newwpd != nd_wpd ) {
3829: newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT));
3830: for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) {
3831: CQ(r) = CQ(m);
1.167 noro 3832: if ( nd_module ) pos = MPOS(DL(m));
1.157 noro 3833: for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j];
3834: adj = nd_exporigin-newexporigin;
3835: for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj];
1.167 noro 3836: if ( nd_module ) {
3837: DL(r)[newmpos] = pos;
3838: }
1.157 noro 3839: }
3840: }
3841: NV(p)--;
1.23 noro 3842: }
3843:
1.150 noro 3844: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr)
3845: {
1.157 noro 3846: int i;
3847: P *tpl,*tpl1;
3848: NODE l;
3849: P h,gcd,t;
3850:
3851: tpl = (P *)ALLOCA(m*sizeof(P));
3852: tpl1 = (P *)ALLOCA(m*sizeof(P));
3853: bcopy(pl,tpl,m*sizeof(P));
3854: gcd = (P)ONE;
3855: for ( l = nd_hcf; l; l = NEXT(l) ) {
3856: h = (P)BDY(l);
3857: while ( 1 ) {
3858: for ( i = 0; i < m; i++ )
3859: if ( !divtpz(vl,tpl[i],h,&tpl1[i]) )
3860: break;
3861: if ( i == m ) {
3862: bcopy(tpl1,tpl,m*sizeof(P));
3863: mulp(vl,gcd,h,&t); gcd = t;
3864: } else
3865: break;
3866: }
3867: }
3868: if ( DP_Print > 2 ){fprintf(asir_out,"[%d]",nmonop(gcd)); fflush(asir_out);}
3869: if ( full ) {
3870: heu_nezgcdnpz(vl,tpl,m,&t);
3871: mulp(vl,gcd,t,pr);
3872: } else
3873: *pr = gcd;
1.150 noro 3874: }
3875:
3876: void removecont_array(P *p,int n,int full)
1.146 noro 3877: {
1.157 noro 3878: int all_p,all_q,i;
3879: Q *c;
3880: P *w;
3881: P t,s;
3882:
3883: for ( all_q = 1, i = 0; i < n; i++ )
3884: all_q = all_q && NUM(p[i]);
3885: if ( all_q ) {
3886: removecont_array_q((Q *)p,n);
3887: } else {
3888: c = (Q *)ALLOCA(n*sizeof(Q));
3889: w = (P *)ALLOCA(n*sizeof(P));
3890: for ( i = 0; i < n; i++ ) {
3891: ptozp(p[i],1,&c[i],&w[i]);
3892: }
3893: removecont_array_q(c,n);
3894: nd_heu_nezgcdnpz(nd_vc,w,n,full,&t);
3895: for ( i = 0; i < n; i++ ) {
3896: divsp(nd_vc,w[i],t,&s); mulp(nd_vc,s,(P)c[i],&p[i]);
3897: }
3898: }
1.146 noro 3899: }
3900:
3901: void removecont_array_q(Q *c,int n)
1.21 noro 3902: {
1.157 noro 3903: struct oVECT v;
3904: Q d0,d1,a,u,u1,gcd;
3905: int i,j;
3906: N qn,rn,gn;
3907: Q *q,*r;
3908:
3909: q = (Q *)ALLOCA(n*sizeof(Q));
3910: r = (Q *)ALLOCA(n*sizeof(Q));
3911: v.id = O_VECT; v.len = n; v.body = (pointer *)c;
3912: igcdv_estimate(&v,&d0);
3913: for ( i = 0; i < n; i++ ) {
3914: divn(NM(c[i]),NM(d0),&qn,&rn);
3915: NTOQ(qn,SGN(c[i])*SGN(d0),q[i]);
3916: NTOQ(rn,SGN(c[i]),r[i]);
3917: }
3918: for ( i = 0; i < n; i++ ) if ( r[i] ) break;
3919: if ( i < n ) {
3920: v.id = O_VECT; v.len = n; v.body = (pointer *)r;
3921: igcdv(&v,&d1);
3922: gcdn(NM(d0),NM(d1),&gn); NTOQ(gn,1,gcd);
3923: divsn(NM(d0),gn,&qn); NTOQ(qn,1,a);
3924: for ( i = 0; i < n; i++ ) {
3925: mulq(a,q[i],&u);
3926: if ( r[i] ) {
3927: divsn(NM(r[i]),gn,&qn); NTOQ(qn,SGN(r[i]),u1);
3928: addq(u,u1,&q[i]);
3929: } else
3930: q[i] = u;
3931: }
3932: }
3933: for ( i = 0; i < n; i++ ) c[i] = q[i];
1.16 noro 3934: }
3935:
1.19 noro 3936: void nd_mul_c(int mod,ND p,int mul)
1.1 noro 3937: {
1.157 noro 3938: NM m;
3939: int c,c1;
1.1 noro 3940:
1.157 noro 3941: if ( !p ) return;
3942: if ( mul == 1 ) return;
3943: if ( mod == -1 )
3944: for ( m = BDY(p); m; m = NEXT(m) )
3945: CM(m) = _mulsf(CM(m),mul);
3946: else
3947: for ( m = BDY(p); m; m = NEXT(m) ) {
3948: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
3949: }
1.1 noro 3950: }
3951:
1.146 noro 3952: void nd_mul_c_q(ND p,P mul)
1.16 noro 3953: {
1.157 noro 3954: NM m;
3955: P c;
1.16 noro 3956:
1.157 noro 3957: if ( !p ) return;
3958: if ( UNIQ(mul) ) return;
3959: for ( m = BDY(p); m; m = NEXT(m) ) {
3960: mulp(nd_vc,CP(m),mul,&c); CP(m) = c;
3961: }
1.16 noro 3962: }
3963:
1.61 noro 3964: void nd_mul_c_p(VL vl,ND p,P mul)
3965: {
1.157 noro 3966: NM m;
3967: P c;
1.61 noro 3968:
1.157 noro 3969: if ( !p ) return;
3970: for ( m = BDY(p); m; m = NEXT(m) ) {
3971: mulp(vl,CP(m),mul,&c); CP(m) = c;
3972: }
1.61 noro 3973: }
3974:
1.1 noro 3975: void nd_free(ND p)
3976: {
1.157 noro 3977: NM t,s;
1.1 noro 3978:
1.157 noro 3979: if ( !p ) return;
3980: t = BDY(p);
3981: while ( t ) {
3982: s = NEXT(t);
3983: FREENM(t);
3984: t = s;
3985: }
3986: FREEND(p);
1.1 noro 3987: }
3988:
1.23 noro 3989: void ndv_free(NDV p)
3990: {
1.200 noro 3991: GCFREE(BDY(p));
1.23 noro 3992: }
3993:
1.61 noro 3994: void nd_append_red(UINT *d,int i)
1.1 noro 3995: {
1.157 noro 3996: RHist m,m0;
3997: int h;
1.1 noro 3998:
1.157 noro 3999: NEWRHist(m);
4000: h = ndl_hash_value(d);
4001: m->index = i;
4002: ndl_copy(d,DL(m));
4003: NEXT(m) = nd_red[h];
4004: nd_red[h] = m;
1.1 noro 4005: }
4006:
1.61 noro 4007: UINT *ndv_compute_bound(NDV p)
1.1 noro 4008: {
1.157 noro 4009: UINT *d1,*d2,*t;
4010: UINT u;
4011: int i,j,k,l,len,ind;
4012: NMV m;
4013:
4014: if ( !p )
4015: return 0;
4016: d1 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
4017: d2 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
4018: len = LEN(p);
4019: m = BDY(p); ndl_copy(DL(m),d1); NMV_ADV(m);
4020: for ( i = 1; i < len; i++, NMV_ADV(m) ) {
1.159 noro 4021: ndl_max(DL(m),d1,d2);
1.157 noro 4022: t = d1; d1 = d2; d2 = t;
4023: }
4024: l = nd_nvar+31;
4025: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
4026: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
4027: u = d1[i];
4028: k = (nd_epw-1)*nd_bpe;
4029: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
4030: t[ind] = (u>>k)&nd_mask0;
4031: }
4032: for ( ; ind < l; ind++ ) t[ind] = 0;
4033: return t;
1.1 noro 4034: }
4035:
1.99 noro 4036: UINT *nd_compute_bound(ND p)
4037: {
1.157 noro 4038: UINT *d1,*d2,*t;
4039: UINT u;
4040: int i,j,k,l,len,ind;
4041: NM m;
4042:
4043: if ( !p )
4044: return 0;
4045: d1 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
4046: d2 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
4047: len = LEN(p);
4048: m = BDY(p); ndl_copy(DL(m),d1); m = NEXT(m);
4049: for ( m = NEXT(m); m; m = NEXT(m) ) {
4050: ndl_lcm(DL(m),d1,d2);
4051: t = d1; d1 = d2; d2 = t;
4052: }
4053: l = nd_nvar+31;
4054: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
4055: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
4056: u = d1[i];
4057: k = (nd_epw-1)*nd_bpe;
4058: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
4059: t[ind] = (u>>k)&nd_mask0;
4060: }
4061: for ( ; ind < l; ind++ ) t[ind] = 0;
4062: return t;
1.99 noro 4063: }
4064:
1.157 noro 4065: /* if nd_module == 1 then d[nd_exporigin-1] indicates the position */
4066: /* of a term. In this case we need additional 1 word. */
4067:
1.48 noro 4068: int nd_get_exporigin(struct order_spec *ord)
4069: {
1.157 noro 4070: switch ( ord->id ) {
4071: case 0: case 2: case 256: case 258:
4072: return 1+nd_module;
4073: case 1: case 257:
4074: /* block order */
4075: /* poly ring d[0]:weight d[1]:w0,...,d[nd_exporigin-1]:w(n-1) */
4076: /* module d[0]:weight d[1]:w0,...,d[nd_exporigin-2]:w(n-1) */
4077: return ord->ord.block.length+1+nd_module;
4078: case 3: case 259:
4079: error("nd_get_exporigin : composite order is not supported yet.");
4080: }
1.48 noro 4081: }
4082:
1.61 noro 4083: void nd_setup_parameters(int nvar,int max) {
1.157 noro 4084: int i,j,n,elen,ord_o,ord_l,l,s,wpd;
4085: struct order_pair *op;
1.48 noro 4086:
1.157 noro 4087: nd_nvar = nvar;
4088: if ( max ) {
4089: /* XXX */
4090: if ( do_weyl ) nd_bpe = 32;
4091: else if ( max < 2 ) nd_bpe = 1;
4092: else if ( max < 4 ) nd_bpe = 2;
4093: else if ( max < 8 ) nd_bpe = 3;
4094: else if ( max < 16 ) nd_bpe = 4;
4095: else if ( max < 32 ) nd_bpe = 5;
4096: else if ( max < 64 ) nd_bpe = 6;
4097: else if ( max < 256 ) nd_bpe = 8;
4098: else if ( max < 1024 ) nd_bpe = 10;
4099: else if ( max < 65536 ) nd_bpe = 16;
4100: else nd_bpe = 32;
4101: }
1.203 noro 4102: if ( !do_weyl && weight_check && (current_dl_weight_vector || nd_matrix) ) {
1.201 noro 4103: UINT t;
1.203 noro 4104: int st;
4105: int *v;
4106: /* t = max(weights) */
4107: t = 0;
4108: if ( current_dl_weight_vector )
4109: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
4110: if ( (st=current_dl_weight_vector[i]) < 0 ) st = -st;
4111: if ( t < st ) t = st;
4112: }
4113: if ( nd_matrix )
4114: for ( i = 0; i < nd_matrix_len; i++ )
4115: for ( j = 0, v = nd_matrix[i]; j < nd_nvar; j++ ) {
4116: if ( (st=v[j]) < 0 ) st = -st;
4117: if ( t < st ) t = st;
4118: }
4119: /* i = bitsize of t */
4120: for ( i = 0; t; t >>=1, i++ );
4121: /* i += bitsize of nd_nvar */
4122: for ( t = nd_nvar; t; t >>=1, i++);
4123: /* nd_bpe+i = bitsize of max(weights)*max(exp)*nd_nvar */
4124: if ( (nd_bpe+i) >= 31 )
4125: error("nd_setup_parameters : too large weight");
4126: }
1.157 noro 4127: nd_epw = (sizeof(UINT)*8)/nd_bpe;
4128: elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0);
4129: nd_exporigin = nd_get_exporigin(nd_ord);
4130: wpd = nd_exporigin+elen;
4131: if ( nd_module )
4132: nd_mpos = nd_exporigin-1;
4133: else
4134: nd_mpos = -1;
4135: if ( wpd != nd_wpd ) {
4136: nd_free_private_storage();
4137: nd_wpd = wpd;
4138: }
4139: if ( nd_bpe < 32 ) {
4140: nd_mask0 = (1<<nd_bpe)-1;
4141: } else {
4142: nd_mask0 = 0xffffffff;
4143: }
4144: bzero(nd_mask,sizeof(nd_mask));
4145: nd_mask1 = 0;
4146: for ( i = 0; i < nd_epw; i++ ) {
4147: nd_mask[nd_epw-i-1] = (nd_mask0<<(i*nd_bpe));
4148: nd_mask1 |= (1<<(nd_bpe-1))<<(i*nd_bpe);
4149: }
4150: nmv_adv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(nd_wpd-1)*sizeof(UINT));
4151: nd_epos = nd_create_epos(nd_ord);
4152: nd_blockmask = nd_create_blockmask(nd_ord);
4153: nd_work_vector = (int *)REALLOC(nd_work_vector,nd_nvar*sizeof(int));
1.1 noro 4154: }
4155:
1.103 noro 4156: ND_pairs nd_reconstruct(int trace,ND_pairs d)
1.1 noro 4157: {
1.157 noro 4158: int i,obpe,oadv,h;
4159: static NM prev_nm_free_list;
4160: static ND_pairs prev_ndp_free_list;
4161: RHist mr0,mr;
4162: RHist r;
4163: RHist *old_red;
4164: ND_pairs s0,s,t;
4165: EPOS oepos;
4166:
4167: obpe = nd_bpe;
4168: oadv = nmv_adv;
4169: oepos = nd_epos;
4170: if ( obpe < 2 ) nd_bpe = 2;
4171: else if ( obpe < 3 ) nd_bpe = 3;
4172: else if ( obpe < 4 ) nd_bpe = 4;
4173: else if ( obpe < 5 ) nd_bpe = 5;
4174: else if ( obpe < 6 ) nd_bpe = 6;
4175: else if ( obpe < 8 ) nd_bpe = 8;
4176: else if ( obpe < 10 ) nd_bpe = 10;
4177: else if ( obpe < 16 ) nd_bpe = 16;
4178: else if ( obpe < 32 ) nd_bpe = 32;
4179: else error("nd_reconstruct : exponent too large");
4180:
4181: nd_setup_parameters(nd_nvar,0);
4182: prev_nm_free_list = _nm_free_list;
4183: prev_ndp_free_list = _ndp_free_list;
4184: _nm_free_list = 0;
4185: _ndp_free_list = 0;
1.215 ! noro 4186: for ( i = nd_psn-1; i >= 0; i-- ) {
! 4187: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
! 4188: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
! 4189: ndv_realloc(nd_ps_gz[i],obpe,oadv,oepos);
! 4190: }
1.157 noro 4191: if ( trace )
1.215 ! noro 4192: for ( i = nd_psn-1; i >= 0; i-- ) {
1.157 noro 4193: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
1.215 ! noro 4194: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
! 4195: }
1.157 noro 4196: s0 = 0;
4197: for ( t = d; t; t = NEXT(t) ) {
4198: NEXTND_pairs(s0,s);
4199: s->i1 = t->i1;
4200: s->i2 = t->i2;
4201: SG(s) = SG(t);
4202: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
4203: }
4204:
4205: old_red = (RHist *)ALLOCA(REDTAB_LEN*sizeof(RHist));
4206: for ( i = 0; i < REDTAB_LEN; i++ ) {
4207: old_red[i] = nd_red[i];
4208: nd_red[i] = 0;
4209: }
4210: for ( i = 0; i < REDTAB_LEN; i++ )
4211: for ( r = old_red[i]; r; r = NEXT(r) ) {
4212: NEWRHist(mr);
4213: mr->index = r->index;
4214: SG(mr) = SG(r);
4215: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
4216: h = ndl_hash_value(DL(mr));
4217: NEXT(mr) = nd_red[h];
4218: nd_red[h] = mr;
4219: }
4220: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
4221: old_red = 0;
4222: for ( i = 0; i < nd_psn; i++ ) {
4223: NEWRHist(r); SG(r) = SG(nd_psh[i]);
4224: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
4225: nd_psh[i] = r;
4226: }
4227: if ( s0 ) NEXT(s) = 0;
4228: prev_nm_free_list = 0;
4229: prev_ndp_free_list = 0;
1.71 noro 4230: #if 0
1.157 noro 4231: GC_gcollect();
1.71 noro 4232: #endif
1.157 noro 4233: return s0;
1.1 noro 4234: }
4235:
1.61 noro 4236: void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos)
1.1 noro 4237: {
1.157 noro 4238: int n,i,ei,oepw,omask0,j,s,ord_l,l;
4239: struct order_pair *op;
1.1 noro 4240:
1.157 noro 4241: n = nd_nvar;
4242: oepw = (sizeof(UINT)*8)/obpe;
4243: omask0 = (1<<obpe)-1;
4244: TD(r) = TD(d);
4245: for ( i = nd_exporigin; i < nd_wpd; i++ ) r[i] = 0;
4246: if ( nd_blockmask ) {
4247: l = nd_blockmask->n;
4248: op = nd_blockmask->order_pair;
4249: for ( i = 1; i < nd_exporigin; i++ )
4250: r[i] = d[i];
4251: for ( j = 0, s = 0; j < l; j++ ) {
4252: ord_l = op[j].length;
4253: for ( i = 0; i < ord_l; i++, s++ ) {
4254: ei = GET_EXP_OLD(d,s);
4255: PUT_EXP(r,s,ei);
4256: }
4257: }
4258: } else {
4259: for ( i = 0; i < n; i++ ) {
4260: ei = GET_EXP_OLD(d,i);
4261: PUT_EXP(r,i,ei);
4262: }
4263: }
4264: if ( nd_module ) MPOS(r) = MPOS(d);
1.1 noro 4265: }
1.3 noro 4266:
1.6 noro 4267: ND nd_copy(ND p)
4268: {
1.157 noro 4269: NM m,mr,mr0;
4270: int c,n;
4271: ND r;
4272:
4273: if ( !p )
4274: return 0;
4275: else {
4276: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
4277: NEXTNM(mr0,mr);
4278: CM(mr) = CM(m);
4279: ndl_copy(DL(m),DL(mr));
4280: }
4281: NEXT(mr) = 0;
4282: MKND(NV(p),mr0,LEN(p),r);
4283: SG(r) = SG(p);
4284: return r;
4285: }
1.6 noro 4286: }
4287:
1.53 noro 4288: int nd_sp(int mod,int trace,ND_pairs p,ND *rp)
1.11 noro 4289: {
1.157 noro 4290: NM m1,m2;
4291: NDV p1,p2;
4292: ND t1,t2;
4293: UINT *lcm;
4294: P gp,tp;
1.167 noro 4295: Q g,t,iq;
1.157 noro 4296: int td;
1.167 noro 4297: LIST hist;
4298: NODE node;
4299: DP d;
1.157 noro 4300:
4301: if ( !mod && nd_demand ) {
4302: p1 = ndv_load(p->i1); p2 = ndv_load(p->i2);
4303: } else {
4304: if ( trace ) {
4305: p1 = nd_ps_trace[p->i1]; p2 = nd_ps_trace[p->i2];
4306: } else {
4307: p1 = nd_ps[p->i1]; p2 = nd_ps[p->i2];
4308: }
4309: }
4310: lcm = LCM(p);
4311: NEWNM(m1); ndl_sub(lcm,HDL(p1),DL(m1));
4312: if ( ndl_check_bound2(p->i1,DL(m1)) ) {
4313: FREENM(m1); return 0;
4314: }
4315: NEWNM(m2); ndl_sub(lcm,HDL(p2),DL(m2));
4316: if ( ndl_check_bound2(p->i2,DL(m2)) ) {
4317: FREENM(m1); FREENM(m2); return 0;
4318: }
4319:
4320: if ( mod == -1 ) {
4321: CM(m1) = HCM(p2); CM(m2) = _chsgnsf(HCM(p1));
4322: } else if ( mod ) {
4323: CM(m1) = HCM(p2); CM(m2) = mod-HCM(p1);
4324: } else if ( nd_vc ) {
4325: ezgcdpz(nd_vc,HCP(p1),HCP(p2),&gp);
4326: divsp(nd_vc,HCP(p2),gp,&CP(m1));
4327: divsp(nd_vc,HCP(p1),gp,&tp); chsgnp(tp,&CP(m2));
4328: } else {
4329: igcd_cofactor(HCQ(p1),HCQ(p2),&g,&t,&CQ(m1)); chsgnq(t,&CQ(m2));
4330: }
4331: t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2);
4332: *rp = nd_add(mod,t1,t2);
1.172 noro 4333: if ( nd_gentrace ) {
1.167 noro 4334: /* nd_tracelist is initialized */
4335: STOQ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE);
4336: MKLIST(hist,node); MKNODE(nd_tracelist,hist,0);
4337: STOQ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE);
4338: MKLIST(hist,node); MKNODE(node,hist,nd_tracelist);
4339: nd_tracelist = node;
4340: }
1.157 noro 4341: FREENM(m1); FREENM(m2);
4342: return 1;
1.11 noro 4343: }
4344:
1.19 noro 4345: void ndv_mul_c(int mod,NDV p,int mul)
1.11 noro 4346: {
1.157 noro 4347: NMV m;
4348: int c,c1,len,i;
1.11 noro 4349:
1.157 noro 4350: if ( !p ) return;
4351: len = LEN(p);
4352: if ( mod == -1 )
4353: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) )
4354: CM(m) = _mulsf(CM(m),mul);
4355: else
4356: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
4357: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
4358: }
1.11 noro 4359: }
4360:
1.113 noro 4361: void ndv_mul_c_q(NDV p,Q mul)
1.16 noro 4362: {
1.157 noro 4363: NMV m;
4364: Q c;
4365: int len,i;
4366:
4367: if ( !p ) return;
4368: len = LEN(p);
4369: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
4370: mulq(CQ(m),mul,&c); CQ(m) = c;
4371: }
1.16 noro 4372: }
4373:
1.55 noro 4374: ND weyl_ndv_mul_nm(int mod,NM m0,NDV p) {
1.157 noro 4375: int n2,i,j,l,n,tlen;
4376: UINT *d0;
4377: NM *tab,*psum;
4378: ND s,r;
4379: NM t;
4380: NMV m1;
4381:
4382: if ( !p ) return 0;
4383: n = NV(p); n2 = n>>1;
4384: d0 = DL(m0);
4385: l = LEN(p);
4386: for ( i = 0, tlen = 1; i < n2; i++ ) tlen *= (GET_EXP(d0,n2+i)+1);
4387: tab = (NM *)ALLOCA(tlen*sizeof(NM));
4388: psum = (NM *)ALLOCA(tlen*sizeof(NM));
4389: for ( i = 0; i < tlen; i++ ) psum[i] = 0;
4390: m1 = (NMV)(((char *)BDY(p))+nmv_adv*(l-1));
4391: for ( i = l-1; i >= 0; i--, NMV_PREV(m1) ) {
4392: /* m0(NM) * m1(NMV) => tab(NM) */
4393: weyl_mul_nm_nmv(n,mod,m0,m1,tab,tlen);
4394: for ( j = 0; j < tlen; j++ ) {
4395: if ( tab[j] ) {
4396: NEXT(tab[j]) = psum[j]; psum[j] = tab[j];
4397: }
4398: }
4399: }
4400: for ( i = tlen-1, r = 0; i >= 0; i-- )
4401: if ( psum[i] ) {
4402: for ( j = 0, t = psum[i]; t; t = NEXT(t), j++ );
4403: MKND(n,psum[i],j,s);
4404: r = nd_add(mod,r,s);
4405: }
4406: if ( r ) SG(r) = SG(p)+TD(d0);
4407: return r;
1.55 noro 4408: }
4409:
1.56 noro 4410: /* product of monomials */
4411: /* XXX block order is not handled correctly */
4412:
1.55 noro 4413: void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *tab,int tlen)
4414: {
1.157 noro 4415: int i,n2,j,s,curlen,homo,h,a,b,k,l,u,min;
4416: UINT *d0,*d1,*d,*dt,*ctab;
4417: Q *ctab_q;
4418: Q q,q1;
4419: UINT c0,c1,c;
4420: NM *p;
4421: NM m,t;
4422: int mpos;
4423:
4424: for ( i = 0; i < tlen; i++ ) tab[i] = 0;
4425: if ( !m0 || !m1 ) return;
4426: d0 = DL(m0); d1 = DL(m1); n2 = n>>1;
1.166 noro 4427: if ( nd_module )
4428: if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation");
4429:
1.157 noro 4430: NEWNM(m); d = DL(m);
4431: if ( mod ) {
4432: c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c;
1.179 noro 4433: } else if ( nd_vc )
4434: mulp(nd_vc,CP(m0),CP(m1),&CP(m));
4435: else
1.157 noro 4436: mulq(CQ(m0),CQ(m1),&CQ(m));
4437: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
4438: homo = n&1 ? 1 : 0;
4439: if ( homo ) {
4440: /* offset of h-degree */
4441: h = GET_EXP(d0,n-1)+GET_EXP(d1,n-1);
4442: PUT_EXP(DL(m),n-1,h);
4443: TD(DL(m)) = h;
4444: if ( nd_blockmask ) ndl_weight_mask(DL(m));
4445: }
4446: tab[0] = m;
4447: NEWNM(m); d = DL(m);
4448: for ( i = 0, curlen = 1; i < n2; i++ ) {
4449: a = GET_EXP(d0,i); b = GET_EXP(d1,n2+i);
4450: k = GET_EXP(d0,n2+i); l = GET_EXP(d1,i);
4451: /* xi^a*(Di^k*xi^l)*Di^b */
4452: a += l; b += k;
4453: s = MUL_WEIGHT(a,i)+MUL_WEIGHT(b,n2+i);
4454: if ( !k || !l ) {
4455: for ( j = 0; j < curlen; j++ )
4456: if ( t = tab[j] ) {
4457: dt = DL(t);
4458: PUT_EXP(dt,i,a); PUT_EXP(dt,n2+i,b); TD(dt) += s;
4459: if ( nd_blockmask ) ndl_weight_mask(dt);
4460: }
4461: curlen *= k+1;
4462: continue;
4463: }
4464: min = MIN(k,l);
4465: if ( mod ) {
4466: ctab = (UINT *)ALLOCA((min+1)*sizeof(UINT));
4467: mkwcm(k,l,mod,ctab);
4468: } else {
4469: ctab_q = (Q *)ALLOCA((min+1)*sizeof(Q));
4470: mkwc(k,l,ctab_q);
4471: }
4472: for ( j = min; j >= 0; j-- ) {
4473: for ( u = 0; u < nd_wpd; u++ ) d[u] = 0;
4474: PUT_EXP(d,i,a-j); PUT_EXP(d,n2+i,b-j);
4475: h = MUL_WEIGHT(a-j,i)+MUL_WEIGHT(b-j,n2+i);
4476: if ( homo ) {
4477: TD(d) = s;
4478: PUT_EXP(d,n-1,s-h);
4479: } else TD(d) = h;
4480: if ( nd_blockmask ) ndl_weight_mask(d);
4481: if ( mod ) c = ctab[j];
4482: else q = ctab_q[j];
4483: p = tab+curlen*j;
4484: if ( j == 0 ) {
4485: for ( u = 0; u < curlen; u++, p++ ) {
4486: if ( tab[u] ) {
4487: ndl_addto(DL(tab[u]),d);
4488: if ( mod ) {
4489: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1;
1.180 noro 4490: } else if ( nd_vc )
4491: mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u]));
4492: else {
1.157 noro 4493: mulq(CQ(tab[u]),q,&q1); CQ(tab[u]) = q1;
4494: }
4495: }
4496: }
4497: } else {
4498: for ( u = 0; u < curlen; u++, p++ ) {
4499: if ( tab[u] ) {
4500: NEWNM(t);
4501: ndl_add(DL(tab[u]),d,DL(t));
4502: if ( mod ) {
4503: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1;
1.181 noro 4504: } else if ( nd_vc )
1.180 noro 4505: mulp(nd_vc,CP(tab[u]),(P)q,&CP(t));
4506: else
1.157 noro 4507: mulq(CQ(tab[u]),q,&CQ(t));
4508: *p = t;
4509: }
4510: }
4511: }
4512: }
4513: curlen *= k+1;
4514: }
4515: FREENM(m);
1.167 noro 4516: if ( nd_module ) {
1.166 noro 4517: mpos = MPOS(d1);
1.167 noro 4518: for ( i = 0; i < tlen; i++ )
4519: if ( tab[i] ) {
4520: d = DL(tab[i]);
4521: MPOS(d) = mpos;
4522: TD(d) = ndl_weight(d);
4523: }
4524: }
1.55 noro 4525: }
4526:
1.63 noro 4527: ND ndv_mul_nm_symbolic(NM m0,NDV p)
4528: {
1.157 noro 4529: NM mr,mr0;
4530: NMV m;
4531: UINT *d,*dt,*dm;
4532: int c,n,td,i,c1,c2,len;
4533: Q q;
4534: ND r;
4535:
4536: if ( !p ) return 0;
4537: else {
4538: n = NV(p); m = BDY(p);
4539: d = DL(m0);
4540: len = LEN(p);
4541: mr0 = 0;
4542: td = TD(d);
4543: c = CM(m0);
4544: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4545: NEXTNM(mr0,mr);
4546: CM(mr) = 1;
4547: ndl_add(DL(m),d,DL(mr));
4548: }
4549: NEXT(mr) = 0;
4550: MKND(NV(p),mr0,len,r);
4551: SG(r) = SG(p) + TD(d);
4552: return r;
4553: }
1.63 noro 4554: }
4555:
1.55 noro 4556: ND ndv_mul_nm(int mod,NM m0,NDV p)
1.9 noro 4557: {
1.157 noro 4558: NM mr,mr0;
4559: NMV m;
4560: UINT *d,*dt,*dm;
4561: int c,n,td,i,c1,c2,len;
4562: P q;
4563: ND r;
4564:
4565: if ( !p ) return 0;
4566: else if ( do_weyl )
4567: if ( mod == -1 )
4568: error("ndv_mul_nm : not implemented (weyl)");
4569: else
4570: return weyl_ndv_mul_nm(mod,m0,p);
4571: else {
4572: n = NV(p); m = BDY(p);
4573: d = DL(m0);
4574: len = LEN(p);
4575: mr0 = 0;
4576: td = TD(d);
4577: if ( mod == -1 ) {
4578: c = CM(m0);
4579: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4580: NEXTNM(mr0,mr);
4581: CM(mr) = _mulsf(CM(m),c);
4582: ndl_add(DL(m),d,DL(mr));
4583: }
4584: } else if ( mod ) {
4585: c = CM(m0);
4586: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4587: NEXTNM(mr0,mr);
4588: c1 = CM(m);
4589: DMAR(c1,c,0,mod,c2);
4590: CM(mr) = c2;
4591: ndl_add(DL(m),d,DL(mr));
4592: }
4593: } else {
4594: q = CP(m0);
4595: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4596: NEXTNM(mr0,mr);
4597: mulp(nd_vc,CP(m),q,&CP(mr));
4598: ndl_add(DL(m),d,DL(mr));
4599: }
4600: }
4601: NEXT(mr) = 0;
4602: MKND(NV(p),mr0,len,r);
4603: SG(r) = SG(p) + TD(d);
4604: return r;
4605: }
1.4 noro 4606: }
4607:
1.104 noro 4608: ND nd_quo(int mod,PGeoBucket bucket,NDV d)
1.99 noro 4609: {
1.157 noro 4610: NM mq0,mq;
4611: NMV tm;
4612: Q q;
4613: int i,nv,sg,c,c1,c2,hindex;
4614: ND p,t,r;
4615: N tnm;
4616:
4617: if ( bucket->m < 0 ) return 0;
4618: else {
4619: nv = NV(d);
4620: mq0 = 0;
4621: tm = (NMV)ALLOCA(nmv_adv);
4622: while ( 1 ) {
4623: hindex = mod?head_pbucket(mod,bucket):head_pbucket_q(bucket);
4624: if ( hindex < 0 ) break;
4625: p = bucket->body[hindex];
4626: NEXTNM(mq0,mq);
4627: ndl_sub(HDL(p),HDL(d),DL(mq));
4628: ndl_copy(DL(mq),DL(tm));
4629: if ( mod ) {
4630: c1 = invm(HCM(d),mod); c2 = HCM(p);
4631: DMAR(c1,c2,0,mod,c); CM(mq) = c;
4632: CM(tm) = mod-c;
4633: } else {
4634: divsn(NM(HCQ(p)),NM(HCQ(d)),&tnm);
4635: NTOQ(tnm,SGN(HCQ(p))*SGN(HCQ(d)),CQ(mq));
4636: chsgnq(CQ(mq),&CQ(tm));
4637: }
4638: t = ndv_mul_nmv_trunc(mod,tm,d,HDL(d));
4639: bucket->body[hindex] = nd_remove_head(p);
4640: t = nd_remove_head(t);
4641: add_pbucket(mod,bucket,t);
4642: }
4643: if ( !mq0 )
4644: r = 0;
4645: else {
4646: NEXT(mq) = 0;
4647: for ( i = 0, mq = mq0; mq; mq = NEXT(mq), i++ );
4648: MKND(nv,mq0,i,r);
4649: /* XXX */
4650: SG(r) = HTD(r);
4651: }
4652: return r;
4653: }
1.99 noro 4654: }
4655:
1.43 noro 4656: void ndv_realloc(NDV p,int obpe,int oadv,EPOS oepos)
1.11 noro 4657: {
1.157 noro 4658: NMV m,mr,mr0,t;
4659: int len,i,k;
1.11 noro 4660:
1.157 noro 4661: if ( !p ) return;
4662: m = BDY(p); len = LEN(p);
4663: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
4664: m = (NMV)((char *)mr0+(len-1)*oadv);
4665: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
4666: t = (NMV)ALLOCA(nmv_adv);
4667: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
4668: CQ(t) = CQ(m);
4669: for ( k = 0; k < nd_wpd; k++ ) DL(t)[k] = 0;
4670: ndl_reconstruct(DL(m),DL(t),obpe,oepos);
4671: CQ(mr) = CQ(t);
4672: ndl_copy(DL(t),DL(mr));
4673: }
4674: BDY(p) = mr0;
1.61 noro 4675: }
4676:
4677: NDV ndv_dup_realloc(NDV p,int obpe,int oadv,EPOS oepos)
4678: {
1.157 noro 4679: NMV m,mr,mr0;
4680: int len,i;
4681: NDV r;
4682:
4683: if ( !p ) return 0;
4684: m = BDY(p); len = LEN(p);
4685: mr0 = mr = (NMV)MALLOC(len*nmv_adv);
4686: for ( i = 0; i < len; i++, NMV_OADV(m), NMV_ADV(mr) ) {
4687: ndl_zero(DL(mr));
4688: ndl_reconstruct(DL(m),DL(mr),obpe,oepos);
4689: CQ(mr) = CQ(m);
4690: }
4691: MKNDV(NV(p),mr0,len,r);
4692: SG(r) = SG(p);
4693: return r;
1.11 noro 4694: }
4695:
1.61 noro 4696: /* duplicate p */
4697:
4698: NDV ndv_dup(int mod,NDV p)
1.3 noro 4699: {
1.157 noro 4700: NDV d;
4701: NMV t,m,m0;
4702: int i,len;
4703:
4704: if ( !p ) return 0;
4705: len = LEN(p);
4706: m0 = m = (NMV)(mod?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
4707: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
4708: ndl_copy(DL(t),DL(m));
4709: CQ(m) = CQ(t);
4710: }
4711: MKNDV(NV(p),m0,len,d);
4712: SG(d) = SG(p);
4713: return d;
1.23 noro 4714: }
4715:
1.215 ! noro 4716: NDV ndvtondvgz(NDV p)
! 4717: {
! 4718: NDV r;
! 4719: int len,i;
! 4720: NMV t;
! 4721:
! 4722: r = ndv_dup(0,p);
! 4723: len = LEN(p);
! 4724: for ( t = BDY(r), i = 0; i < len; i++, NMV_ADV(t) ) CZ(t) = ztogz(CQ(t));
! 4725: return r;
! 4726: }
! 4727:
! 4728: NDV ndvgztondv(NDV p)
! 4729: {
! 4730: NDV r;
! 4731: int len,i;
! 4732: NMV t;
! 4733:
! 4734: r = ndv_dup(0,p);
! 4735: len = LEN(p);
! 4736: for ( t = BDY(r), i = 0; i < len; i++, NMV_ADV(t) ) CQ(t) = gztoz(CZ(t));
! 4737: return r;
! 4738: }
! 4739:
! 4740: NDV ndv_symbolic(int mod,NDV p)
! 4741: {
! 4742: NDV d;
! 4743: NMV t,m,m0;
! 4744: int i,len;
! 4745:
! 4746: if ( !p ) return 0;
! 4747: len = LEN(p);
! 4748: m0 = m = (NMV)(mod?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
! 4749: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
! 4750: ndl_copy(DL(t),DL(m));
! 4751: CQ(m) = ONE;
! 4752: }
! 4753: MKNDV(NV(p),m0,len,d);
! 4754: SG(d) = SG(p);
! 4755: return d;
! 4756: }
! 4757:
1.63 noro 4758: ND nd_dup(ND p)
4759: {
1.157 noro 4760: ND d;
4761: NM t,m,m0;
1.63 noro 4762:
1.157 noro 4763: if ( !p ) return 0;
4764: for ( m0 = 0, t = BDY(p); t; t = NEXT(t) ) {
4765: NEXTNM(m0,m);
4766: ndl_copy(DL(t),DL(m));
4767: CQ(m) = CQ(t);
4768: }
4769: if ( m0 ) NEXT(m) = 0;
4770: MKND(NV(p),m0,LEN(p),d);
4771: SG(d) = SG(p);
4772: return d;
1.63 noro 4773: }
4774:
1.215 ! noro 4775: ND ndtondgz(ND p)
! 4776: {
! 4777: ND r;
! 4778: NM t;
! 4779:
! 4780: r = nd_dup(p);
! 4781: for ( t = BDY(r); t; t = NEXT(t) ) CZ(t) = ztogz(CQ(t));
! 4782: return r;
! 4783: }
! 4784:
! 4785:
! 4786: ND ndgztond(ND p)
! 4787: {
! 4788: ND r;
! 4789: NM t;
! 4790:
! 4791: r = nd_dup(p);
! 4792: for ( t = BDY(r); t; t = NEXT(t) ) CQ(t) = gztoz(CZ(t));
! 4793: return r;
! 4794: }
! 4795:
! 4796:
1.61 noro 4797: /* XXX if p->len == 0 then it represents 0 */
4798:
4799: void ndv_mod(int mod,NDV p)
4800: {
1.157 noro 4801: NMV t,d;
4802: int r,s,u;
4803: int i,len,dlen;
4804: P cp;
4805: Q c;
4806: Obj gfs;
4807:
4808: if ( !p ) return;
4809: len = LEN(p);
4810: dlen = 0;
4811: if ( mod == -1 )
4812: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
4813: simp_ff((Obj)CP(t),&gfs);
4814: r = FTOIF(CONT((GFS)gfs));
4815: CM(d) = r;
4816: ndl_copy(DL(t),DL(d));
4817: NMV_ADV(d);
4818: dlen++;
4819: }
4820: else
4821: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
4822: if ( nd_vc ) {
4823: nd_subst_vector(nd_vc,CP(t),nd_subst,&cp);
4824: c = (Q)cp;
4825: } else
4826: c = CQ(t);
4827: r = rem(NM(c),mod);
4828: if ( r ) {
4829: if ( SGN(c) < 0 )
4830: r = mod-r;
4831: if ( DN(c) ) {
4832: s = rem(DN(c),mod);
4833: if ( !s )
4834: error("ndv_mod : division by 0");
4835: s = invm(s,mod);
4836: DMAR(r,s,0,mod,u); r = u;
4837: }
4838: CM(d) = r;
4839: ndl_copy(DL(t),DL(d));
4840: NMV_ADV(d);
4841: dlen++;
4842: }
4843: }
4844: LEN(p) = dlen;
1.61 noro 4845: }
4846:
4847: NDV ptondv(VL vl,VL dvl,P p)
4848: {
1.157 noro 4849: ND nd;
4850:
4851: nd = ptond(vl,dvl,p);
4852: return ndtondv(0,nd);
4853: }
1.61 noro 4854:
1.157 noro 4855: void pltozpl(LIST l,Q *cont,LIST *pp)
4856: {
4857: NODE nd,nd1;
4858: int n;
4859: P *pl;
4860: Q *cl;
4861: int i;
4862: P dmy;
4863: Q dvr;
4864: LIST r;
4865:
4866: nd = BDY(l); n = length(nd);
4867: pl = (P *)ALLOCA(n*sizeof(P));
4868: cl = (Q *)ALLOCA(n*sizeof(P));
4869: for ( i = 0; i < n; i++, nd = NEXT(nd) )
4870: ptozp((P)BDY(nd),1,&cl[i],&dmy);
4871: qltozl(cl,n,&dvr);
4872: nd = BDY(l);
4873: for ( i = 0; i < n; i++, nd = NEXT(nd) ) {
4874: divsp(CO,(P)BDY(nd),(P)dvr,&pl[i]);
4875: }
4876: nd = 0;
4877: for ( i = n-1; i >= 0; i-- ) {
4878: MKNODE(nd1,pl[i],nd); nd = nd1;
4879: }
4880: MKLIST(r,nd);
4881: *pp = r;
4882: }
4883:
4884: /* (a1,a2,...,an) -> a1*e(1)+...+an*e(n) */
4885:
4886: NDV pltondv(VL vl,VL dvl,LIST p)
4887: {
4888: int i;
4889: NODE t;
4890: ND r,ri;
4891: NM m;
4892:
4893: if ( !nd_module ) error("pltond : module order must be set");
4894: r = 0;
4895: for ( i = 1, t = BDY(p); t; t = NEXT(t), i++ ) {
4896: ri = ptond(vl,dvl,(P)BDY(t));
1.163 noro 4897: if ( ri )
4898: for ( m = BDY(ri); m; m = NEXT(m) ) {
1.167 noro 4899: MPOS(DL(m)) = i;
4900: TD(DL(m)) = ndl_weight(DL(m));
1.163 noro 4901: if ( nd_blockmask ) ndl_weight_mask(DL(m));
4902: }
1.157 noro 4903: r = nd_add(0,r,ri);
4904: }
4905: return ndtondv(0,r);
1.61 noro 4906: }
4907:
4908: ND ptond(VL vl,VL dvl,P p)
1.23 noro 4909: {
1.157 noro 4910: int n,i,j,k,e;
4911: VL tvl;
4912: V v;
4913: DCP dc;
4914: DCP *w;
4915: ND r,s,t,u;
4916: P x;
4917: int c;
4918: UINT *d;
4919: NM m,m0;
4920:
4921: if ( !p )
4922: return 0;
4923: else if ( NUM(p) ) {
4924: NEWNM(m);
4925: ndl_zero(DL(m));
4926: CQ(m) = (Q)p;
4927: NEXT(m) = 0;
4928: MKND(nd_nvar,m,1,r);
4929: SG(r) = 0;
4930: return r;
4931: } else {
4932: for ( dc = DC(p), k = 0; dc; dc = NEXT(dc), k++ );
4933: w = (DCP *)ALLOCA(k*sizeof(DCP));
4934: for ( dc = DC(p), j = 0; j < k; dc = NEXT(dc), j++ ) w[j] = dc;
4935: for ( i = 0, tvl = dvl, v = VR(p);
4936: tvl && tvl->v != v; tvl = NEXT(tvl), i++ );
4937: if ( !tvl ) {
4938: for ( j = k-1, s = 0, MKV(v,x); j >= 0; j-- ) {
4939: t = ptond(vl,dvl,COEF(w[j]));
4940: pwrp(vl,x,DEG(w[j]),&p);
4941: nd_mul_c_p(CO,t,p); s = nd_add(0,s,t);
4942: }
4943: return s;
4944: } else {
4945: NEWNM(m0); d = DL(m0);
4946: for ( j = k-1, s = 0; j >= 0; j-- ) {
4947: ndl_zero(d); e = QTOS(DEG(w[j])); PUT_EXP(d,i,e);
4948: TD(d) = MUL_WEIGHT(e,i);
4949: if ( nd_blockmask) ndl_weight_mask(d);
4950: if ( nd_module ) MPOS(d) = 0;
4951: t = ptond(vl,dvl,COEF(w[j]));
4952: for ( m = BDY(t); m; m = NEXT(m) )
4953: ndl_addto(DL(m),d);
4954: SG(t) += TD(d);
4955: s = nd_add(0,s,t);
4956: }
4957: FREENM(m0);
4958: return s;
4959: }
4960: }
1.61 noro 4961: }
4962:
4963: P ndvtop(int mod,VL vl,VL dvl,NDV p)
4964: {
1.157 noro 4965: VL tvl;
4966: int len,n,j,i,e;
4967: NMV m;
4968: Q q;
4969: P c;
4970: UINT *d;
4971: P s,r,u,t,w;
4972: GFS gfs;
4973:
4974: if ( !p ) return 0;
4975: else {
4976: len = LEN(p);
4977: n = NV(p);
4978: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
4979: for ( j = len-1, s = 0; j >= 0; j--, NMV_PREV(m) ) {
4980: if ( mod == -1 ) {
4981: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
4982: } else if ( mod ) {
4983: STOQ(CM(m),q); c = (P)q;
4984: } else
4985: c = CP(m);
4986: d = DL(m);
4987: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
4988: MKV(tvl->v,r); e = GET_EXP(d,i); STOQ(e,q);
4989: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
4990: }
4991: addp(vl,s,t,&u); s = u;
4992: }
4993: return s;
4994: }
4995: }
4996:
4997: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank)
4998: {
4999: VL tvl;
5000: int len,n,j,i,e;
5001: NMV m;
5002: Q q;
5003: P c;
5004: UINT *d;
5005: P s,r,u,t,w;
5006: GFS gfs;
5007: P *a;
5008: LIST l;
5009: NODE nd,nd1;
5010:
5011: if ( !p ) return 0;
5012: else {
5013: a = (P *)ALLOCA((rank+1)*sizeof(P));
5014: for ( i = 0; i <= rank; i++ ) a[i] = 0;
5015: len = LEN(p);
5016: n = NV(p);
5017: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
5018: for ( j = len-1; j >= 0; j--, NMV_PREV(m) ) {
5019: if ( mod == -1 ) {
5020: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
5021: } else if ( mod ) {
5022: STOQ(CM(m),q); c = (P)q;
5023: } else
5024: c = CP(m);
5025: d = DL(m);
5026: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
5027: MKV(tvl->v,r); e = GET_EXP(d,i); STOQ(e,q);
5028: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
5029: }
5030: addp(vl,a[MPOS(d)],t,&u); a[MPOS(d)] = u;
5031: }
5032: nd = 0;
5033: for ( i = rank; i > 0; i-- ) {
5034: MKNODE(nd1,a[i],nd); nd = nd1;
5035: }
5036: MKLIST(l,nd);
5037: return l;
5038: }
1.3 noro 5039: }
5040:
1.61 noro 5041: NDV ndtondv(int mod,ND p)
1.11 noro 5042: {
1.157 noro 5043: NDV d;
5044: NMV m,m0;
5045: NM t;
5046: int i,len;
5047:
5048: if ( !p ) return 0;
5049: len = LEN(p);
5050: if ( mod )
1.200 noro 5051: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
1.157 noro 5052: else
5053: m0 = m = MALLOC(len*nmv_adv);
1.103 noro 5054: #if 0
1.157 noro 5055: ndv_alloc += nmv_adv*len;
1.103 noro 5056: #endif
1.157 noro 5057: for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, NMV_ADV(m) ) {
5058: ndl_copy(DL(t),DL(m));
5059: CQ(m) = CQ(t);
5060: }
5061: MKNDV(NV(p),m0,len,d);
5062: SG(d) = SG(p);
5063: return d;
1.11 noro 5064: }
5065:
1.61 noro 5066: ND ndvtond(int mod,NDV p)
1.11 noro 5067: {
1.157 noro 5068: ND d;
5069: NM m,m0;
5070: NMV t;
5071: int i,len;
5072:
5073: if ( !p ) return 0;
5074: m0 = 0;
5075: len = p->len;
5076: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
5077: NEXTNM(m0,m);
5078: ndl_copy(DL(t),DL(m));
5079: CQ(m) = CQ(t);
5080: }
5081: NEXT(m) = 0;
5082: MKND(NV(p),m0,len,d);
5083: SG(d) = SG(p);
5084: return d;
1.11 noro 5085: }
5086:
1.198 noro 5087: DP ndvtodp(int mod,NDV p)
5088: {
5089: MP m,m0;
5090: DP d;
5091: NMV t;
5092: int i,len;
5093:
5094: if ( !p ) return 0;
5095: m0 = 0;
5096: len = p->len;
5097: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
5098: NEXTMP(m0,m);
5099: m->dl = ndltodl(nd_nvar,DL(t));
5100: m->c = ndctop(mod,t->c);
5101: }
5102: NEXT(m) = 0;
5103: MKDP(nd_nvar,m0,d);
5104: SG(d) = SG(p);
5105: return d;
5106: }
5107:
1.204 noro 5108: DP ndtodp(int mod,ND p)
5109: {
5110: MP m,m0;
5111: DP d;
5112: NM t;
5113: int i,len;
5114:
5115: if ( !p ) return 0;
5116: m0 = 0;
5117: len = p->len;
5118: for ( t = BDY(p); t; t = NEXT(t) ) {
5119: NEXTMP(m0,m);
5120: m->dl = ndltodl(nd_nvar,DL(t));
5121: m->c = ndctop(mod,t->c);
5122: }
5123: NEXT(m) = 0;
5124: MKDP(nd_nvar,m0,d);
5125: SG(d) = SG(p);
5126: return d;
5127: }
5128:
1.3 noro 5129: void ndv_print(NDV p)
5130: {
1.157 noro 5131: NMV m;
5132: int i,len;
1.3 noro 5133:
1.157 noro 5134: if ( !p ) printf("0\n");
5135: else {
5136: len = LEN(p);
5137: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
5138: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
5139: else printf("+%d*",CM(m));
5140: ndl_print(DL(m));
5141: }
5142: printf("\n");
5143: }
1.16 noro 5144: }
5145:
1.113 noro 5146: void ndv_print_q(NDV p)
1.16 noro 5147: {
1.157 noro 5148: NMV m;
5149: int i,len;
1.16 noro 5150:
1.157 noro 5151: if ( !p ) printf("0\n");
5152: else {
5153: len = LEN(p);
5154: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
5155: printf("+");
5156: printexpr(CO,(Obj)CQ(m));
5157: printf("*");
5158: ndl_print(DL(m));
5159: }
5160: printf("\n");
5161: }
1.25 noro 5162: }
5163:
1.167 noro 5164: NODE ndv_reducebase(NODE x,int *perm)
1.27 noro 5165: {
1.157 noro 5166: int len,i,j;
1.167 noro 5167: NDVI w;
1.157 noro 5168: NODE t,t0;
5169:
5170: len = length(x);
1.167 noro 5171: w = (NDVI)ALLOCA(len*sizeof(struct oNDVI));
5172: for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) {
5173: w[i].p = BDY(t); w[i].i = perm[i];
5174: }
1.157 noro 5175: for ( i = 0; i < len; i++ ) {
5176: for ( j = 0; j < i; j++ ) {
1.167 noro 5177: if ( w[i].p && w[j].p )
5178: if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0;
5179: else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0;
1.157 noro 5180: }
5181: }
1.167 noro 5182: for ( i = j = 0, t0 = 0; i < len; i++ ) {
5183: if ( w[i].p ) {
5184: NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p;
5185: perm[j++] = w[i].i;
5186: }
1.157 noro 5187: }
5188: NEXT(t) = 0; x = t0;
5189: return x;
1.11 noro 5190: }
1.32 noro 5191:
1.43 noro 5192: /* XXX incomplete */
5193:
1.32 noro 5194: void nd_init_ord(struct order_spec *ord)
5195: {
1.157 noro 5196: nd_module = (ord->id >= 256);
1.203 noro 5197: nd_matrix = 0;
5198: nd_matrix_len = 0;
1.157 noro 5199: switch ( ord->id ) {
5200: case 0:
5201: switch ( ord->ord.simple ) {
5202: case 0:
5203: nd_dcomp = 1;
5204: nd_isrlex = 1;
5205: break;
5206: case 1:
5207: nd_dcomp = 1;
5208: nd_isrlex = 0;
5209: break;
5210: case 2:
5211: nd_dcomp = 0;
5212: nd_isrlex = 0;
5213: ndl_compare_function = ndl_lex_compare;
5214: break;
5215: case 11:
5216: /* XXX */
5217: nd_dcomp = 0;
5218: nd_isrlex = 1;
5219: ndl_compare_function = ndl_ww_lex_compare;
5220: break;
5221: default:
5222: error("nd_gr : unsupported order");
5223: }
5224: break;
5225: case 1:
5226: /* block order */
5227: /* XXX */
5228: nd_dcomp = -1;
5229: nd_isrlex = 0;
5230: ndl_compare_function = ndl_block_compare;
5231: break;
5232: case 2:
5233: /* matrix order */
5234: /* XXX */
5235: nd_dcomp = -1;
5236: nd_isrlex = 0;
5237: nd_matrix_len = ord->ord.matrix.row;
5238: nd_matrix = ord->ord.matrix.matrix;
5239: ndl_compare_function = ndl_matrix_compare;
5240: break;
5241: case 3:
5242: /* composite order */
5243: nd_dcomp = -1;
5244: nd_isrlex = 0;
5245: nd_worb_len = ord->ord.composite.length;
5246: nd_worb = ord->ord.composite.w_or_b;
5247: ndl_compare_function = ndl_composite_compare;
5248: break;
5249:
5250: /* module order */
5251: case 256:
1.160 noro 5252: nd_ispot = ord->ispot;
1.174 noro 5253: nd_pot_nelim = ord->pot_nelim;
1.157 noro 5254: nd_dcomp = -1;
5255: switch ( ord->ord.simple ) {
5256: case 0:
1.167 noro 5257: nd_isrlex = 1;
1.157 noro 5258: ndl_compare_function = ndl_module_grlex_compare;
5259: break;
5260: case 1:
1.167 noro 5261: nd_isrlex = 0;
1.157 noro 5262: ndl_compare_function = ndl_module_glex_compare;
5263: break;
5264: case 2:
1.167 noro 5265: nd_isrlex = 0;
1.157 noro 5266: ndl_compare_function = ndl_module_lex_compare;
5267: break;
5268: default:
5269: error("nd_gr : unsupported order");
5270: }
5271: break;
5272: case 257:
5273: /* block order */
1.174 noro 5274: nd_ispot = ord->ispot;
5275: nd_pot_nelim = ord->pot_nelim;
5276: nd_dcomp = -1;
5277: nd_isrlex = 0;
1.157 noro 5278: ndl_compare_function = ndl_module_block_compare;
5279: break;
5280: case 258:
5281: /* matrix order */
1.174 noro 5282: nd_ispot = ord->ispot;
5283: nd_pot_nelim = ord->pot_nelim;
5284: nd_dcomp = -1;
5285: nd_isrlex = 0;
1.157 noro 5286: nd_matrix_len = ord->ord.matrix.row;
5287: nd_matrix = ord->ord.matrix.matrix;
5288: ndl_compare_function = ndl_module_matrix_compare;
5289: break;
5290: case 259:
5291: /* composite order */
1.174 noro 5292: nd_ispot = ord->ispot;
5293: nd_pot_nelim = ord->pot_nelim;
5294: nd_dcomp = -1;
5295: nd_isrlex = 0;
1.157 noro 5296: nd_worb_len = ord->ord.composite.length;
5297: nd_worb = ord->ord.composite.w_or_b;
5298: ndl_compare_function = ndl_module_composite_compare;
5299: break;
5300: }
5301: nd_ord = ord;
1.32 noro 5302: }
5303:
1.43 noro 5304: BlockMask nd_create_blockmask(struct order_spec *ord)
5305: {
1.157 noro 5306: int n,i,j,s,l;
5307: UINT *t;
5308: BlockMask bm;
5309:
5310: /* we only create mask table for block order */
1.164 noro 5311: if ( ord->id != 1 && ord->id != 257 )
1.157 noro 5312: return 0;
5313: n = ord->ord.block.length;
5314: bm = (BlockMask)MALLOC(sizeof(struct oBlockMask));
5315: bm->n = n;
5316: bm->order_pair = ord->ord.block.order_pair;
5317: bm->mask = (UINT **)MALLOC(n*sizeof(UINT *));
5318: for ( i = 0, s = 0; i < n; i++ ) {
5319: bm->mask[i] = t = (UINT *)MALLOC_ATOMIC(nd_wpd*sizeof(UINT));
5320: for ( j = 0; j < nd_wpd; j++ ) t[j] = 0;
5321: l = bm->order_pair[i].length;
5322: for ( j = 0; j < l; j++, s++ ) PUT_EXP(t,s,nd_mask0);
5323: }
5324: return bm;
1.57 noro 5325: }
5326:
5327: EPOS nd_create_epos(struct order_spec *ord)
5328: {
1.157 noro 5329: int i,j,l,s,ord_l,ord_o;
5330: EPOS epos;
5331: struct order_pair *op;
5332:
5333: epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS));
5334: switch ( ord->id ) {
1.164 noro 5335: case 0: case 256:
1.157 noro 5336: if ( nd_isrlex ) {
5337: for ( i = 0; i < nd_nvar; i++ ) {
5338: epos[i].i = nd_exporigin + (nd_nvar-1-i)/nd_epw;
5339: epos[i].s = (nd_epw-((nd_nvar-1-i)%nd_epw)-1)*nd_bpe;
5340: }
5341: } else {
5342: for ( i = 0; i < nd_nvar; i++ ) {
5343: epos[i].i = nd_exporigin + i/nd_epw;
5344: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
5345: }
5346: }
5347: break;
1.164 noro 5348: case 1: case 257:
1.157 noro 5349: /* block order */
5350: l = ord->ord.block.length;
5351: op = ord->ord.block.order_pair;
5352: for ( j = 0, s = 0; j < l; j++ ) {
5353: ord_o = op[j].order;
5354: ord_l = op[j].length;
5355: if ( !ord_o )
5356: for ( i = 0; i < ord_l; i++ ) {
5357: epos[s+i].i = nd_exporigin + (s+ord_l-i-1)/nd_epw;
5358: epos[s+i].s = (nd_epw-((s+ord_l-i-1)%nd_epw)-1)*nd_bpe;
5359: }
5360: else
5361: for ( i = 0; i < ord_l; i++ ) {
5362: epos[s+i].i = nd_exporigin + (s+i)/nd_epw;
5363: epos[s+i].s = (nd_epw-((s+i)%nd_epw)-1)*nd_bpe;
5364: }
5365: s += ord_l;
5366: }
5367: break;
5368: case 2:
5369: /* matrix order */
5370: case 3:
5371: /* composite order */
1.167 noro 5372: default:
1.157 noro 5373: for ( i = 0; i < nd_nvar; i++ ) {
5374: epos[i].i = nd_exporigin + i/nd_epw;
5375: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
5376: }
5377: break;
5378: }
5379: return epos;
1.43 noro 5380: }
1.59 noro 5381:
5382: /* external interface */
5383:
1.191 noro 5384: void nd_nf_p(Obj f,LIST g,LIST v,int m,struct order_spec *ord,Obj *rp)
1.59 noro 5385: {
1.157 noro 5386: NODE t,in0,in;
1.191 noro 5387: ND ndf,nf;
5388: NDV ndvf;
1.157 noro 5389: VL vv,tv;
1.191 noro 5390: int stat,nvar,max,mrank;
1.157 noro 5391: union oNDC dn;
5392: Q cont;
5393: P pp;
1.191 noro 5394: LIST ppl;
1.157 noro 5395:
5396: if ( !f ) {
5397: *rp = 0;
5398: return;
5399: }
5400: pltovl(v,&vv);
5401: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5402:
1.191 noro 5403: /* max=65536 implies nd_bpe=32 */
5404: max = 65536;
1.157 noro 5405:
1.191 noro 5406: nd_module = 0;
5407: /* nd_module will be set if ord is a module ordering */
1.157 noro 5408: nd_init_ord(ord);
5409: nd_setup_parameters(nvar,max);
1.191 noro 5410: if ( nd_module && OID(f) != O_LIST )
5411: error("nd_nf_p : the first argument must be a list");
5412: if ( nd_module ) mrank = length(BDY((LIST)f));
1.157 noro 5413: /* conversion to ndv */
5414: for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) {
5415: NEXTNODE(in0,in);
1.191 noro 5416: if ( nd_module ) {
5417: if ( !BDY(t) || OID(BDY(t)) != O_LIST
5418: || length(BDY((LIST)BDY(t))) != mrank )
5419: error("nd_nf_p : inconsistent basis element");
5420: if ( !m ) pltozpl((LIST)BDY(t),&cont,&ppl);
5421: else ppl = (LIST)BDY(t);
5422: BDY(in) = (pointer)pltondv(CO,vv,ppl);
5423: } else {
5424: if ( !m ) ptozp((P)BDY(t),1,&cont,&pp);
5425: else pp = (P)BDY(t);
5426: BDY(in) = (pointer)ptondv(CO,vv,pp);
5427: }
1.157 noro 5428: if ( m ) ndv_mod(m,(NDV)BDY(in));
5429: }
1.191 noro 5430: if ( in0 ) NEXT(in) = 0;
5431:
5432: if ( nd_module ) ndvf = pltondv(CO,vv,(LIST)f);
5433: else ndvf = ptondv(CO,vv,(P)f);
5434: if ( m ) ndv_mod(m,ndvf);
5435: ndf = (pointer)ndvtond(m,ndvf);
1.157 noro 5436:
5437: /* dont sort, dont removecont */
5438: ndv_setup(m,0,in0,1,1);
5439: nd_scale=2;
1.191 noro 5440: stat = nd_nf(m,0,ndf,nd_ps,1,0,&nf);
5441: if ( !stat )
5442: error("nd_nf_p : exponent too large");
5443: if ( nd_module ) *rp = (Obj)ndvtopl(m,CO,vv,ndtondv(m,nf),mrank);
5444: else *rp = (Obj)ndvtop(m,CO,vv,ndtondv(m,nf));
1.63 noro 5445: }
5446:
5447: int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r)
5448: {
1.157 noro 5449: NM m;
5450: UINT *t,*s;
5451: int i;
5452:
5453: for ( i = 0; i < n; i++ ) r[i] = 0;
5454: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
5455: t = DL(m);
5456: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5457: r[i] = CM(m);
5458: }
5459: for ( i = 0; !r[i]; i++ );
5460: return i;
1.63 noro 5461: }
5462:
1.113 noro 5463: int nd_to_vect_q(UINT *s0,int n,ND d,Q *r)
1.74 noro 5464: {
1.157 noro 5465: NM m;
5466: UINT *t,*s;
5467: int i;
5468:
5469: for ( i = 0; i < n; i++ ) r[i] = 0;
5470: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
5471: t = DL(m);
5472: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5473: r[i] = CQ(m);
5474: }
5475: for ( i = 0; !r[i]; i++ );
5476: return i;
1.74 noro 5477: }
5478:
1.129 noro 5479: Q *nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_pair pair)
5480: {
1.157 noro 5481: NM m;
5482: NMV mr;
5483: UINT *d,*t,*s;
5484: NDV p;
5485: int i,j,len;
5486: Q *r;
5487:
5488: m = pair->mul;
5489: d = DL(m);
5490: p = nd_ps[pair->index];
5491: len = LEN(p);
5492: r = (Q *)CALLOC(n,sizeof(Q));
5493: t = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
5494: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
5495: ndl_add(d,DL(mr),t);
5496: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5497: r[i] = CQ(mr);
5498: }
5499: return r;
1.129 noro 5500: }
5501:
1.210 noro 5502: IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0,int n,int *s0hash,NM_ind_pair pair)
1.64 noro 5503: {
1.157 noro 5504: NM m;
5505: NMV mr;
5506: UINT *d,*t,*s;
5507: NDV p;
5508: unsigned char *ivc;
5509: unsigned short *ivs;
5510: UINT *v,*ivi,*s0v;
1.210 noro 5511: int i,j,len,prev,diff,cdiff,h;
1.157 noro 5512: IndArray r;
1.198 noro 5513: struct oEGT eg0,eg1;
1.157 noro 5514:
5515: m = pair->mul;
5516: d = DL(m);
1.215 ! noro 5517: p = nd_demand?nd_ps_sym[pair->index]:nd_ps[pair->index];
1.157 noro 5518: len = LEN(p);
5519: t = (UINT *)ALLOCA(nd_wpd*sizeof(UINT));
5520: v = (unsigned int *)ALLOCA(len*sizeof(unsigned int));
1.198 noro 5521: get_eg(&eg0);
1.157 noro 5522: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
5523: ndl_add(d,DL(mr),t);
1.210 noro 5524: h = ndl_hash_value(t);
5525: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
1.157 noro 5526: v[j] = i;
5527: }
1.198 noro 5528: get_eg(&eg1); add_eg(&eg_search,&eg0,&eg1);
1.157 noro 5529: r = (IndArray)MALLOC(sizeof(struct oIndArray));
5530: r->head = v[0];
5531: diff = 0;
5532: for ( i = 1; i < len; i++ ) {
5533: cdiff = v[i]-v[i-1]; diff = MAX(cdiff,diff);
5534: }
5535: if ( diff < 256 ) {
5536: r->width = 1;
5537: ivc = (unsigned char *)MALLOC_ATOMIC(len*sizeof(unsigned char));
5538: r->index.c = ivc;
5539: for ( i = 1, ivc[0] = 0; i < len; i++ ) ivc[i] = v[i]-v[i-1];
5540: } else if ( diff < 65536 ) {
5541: r->width = 2;
5542: ivs = (unsigned short *)MALLOC_ATOMIC(len*sizeof(unsigned short));
5543: r->index.s = ivs;
5544: for ( i = 1, ivs[0] = 0; i < len; i++ ) ivs[i] = v[i]-v[i-1];
5545: } else {
5546: r->width = 4;
5547: ivi = (unsigned int *)MALLOC_ATOMIC(len*sizeof(unsigned int));
5548: r->index.i = ivi;
5549: for ( i = 1, ivi[0] = 0; i < len; i++ ) ivi[i] = v[i]-v[i-1];
5550: }
5551: return r;
1.64 noro 5552: }
5553:
1.135 noro 5554: int compress_array(Q *svect,Q *cvect,int n)
5555: {
1.157 noro 5556: int i,j;
1.135 noro 5557:
1.157 noro 5558: for ( i = j = 0; i < n; i++ )
5559: if ( svect[i] ) cvect[j++] = svect[i];
5560: return j;
1.135 noro 5561: }
5562:
5563: void expand_array(Q *svect,Q *cvect,int n)
5564: {
1.157 noro 5565: int i,j;
1.135 noro 5566:
1.157 noro 5567: for ( i = j = 0; j < n; i++ )
5568: if ( svect[i] ) svect[i] = cvect[j++];
1.135 noro 5569: }
5570:
1.133 noro 5571: int ndv_reduce_vect_q(Q *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.107 noro 5572: {
1.157 noro 5573: int i,j,k,len,pos,prev,nz;
5574: Q cs,mcs,c1,c2,cr,gcd,t;
5575: IndArray ivect;
5576: unsigned char *ivc;
5577: unsigned short *ivs;
5578: unsigned int *ivi;
5579: NDV redv;
5580: NMV mr;
5581: NODE rp;
5582: int maxrs;
5583: double hmag;
5584: Q *cvect;
5585:
5586: maxrs = 0;
5587: for ( i = 0; i < col && !svect[i]; i++ );
5588: if ( i == col ) return maxrs;
5589: hmag = p_mag((P)svect[i])*nd_scale;
5590: cvect = (Q *)ALLOCA(col*sizeof(Q));
5591: for ( i = 0; i < nred; i++ ) {
5592: ivect = imat[i];
5593: k = ivect->head;
5594: if ( svect[k] ) {
5595: maxrs = MAX(maxrs,rp0[i]->sugar);
1.215 ! noro 5596: redv = nd_demand?ndv_load(rp0[i]->index)
! 5597: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
1.157 noro 5598: len = LEN(redv); mr = BDY(redv);
5599: igcd_cofactor(svect[k],CQ(mr),&gcd,&cs,&cr);
5600: chsgnq(cs,&mcs);
5601: if ( !UNIQ(cr) ) {
5602: for ( j = 0; j < col; j++ ) {
5603: mulq(svect[j],cr,&c1); svect[j] = c1;
5604: }
5605: }
5606: svect[k] = 0; prev = k;
5607: switch ( ivect->width ) {
5608: case 1:
5609: ivc = ivect->index.c;
5610: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
5611: pos = prev+ivc[j]; prev = pos;
5612: mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t;
5613: }
5614: break;
5615: case 2:
5616: ivs = ivect->index.s;
5617: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
5618: pos = prev+ivs[j]; prev = pos;
5619: mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t;
5620: }
5621: break;
5622: case 4:
5623: ivi = ivect->index.i;
5624: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
5625: pos = prev+ivi[j]; prev = pos;
5626: mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t;
5627: }
5628: break;
5629: }
5630: for ( j = k+1; j < col && !svect[j]; j++ );
5631: if ( j == col ) break;
5632: if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) {
5633: nz = compress_array(svect,cvect,col);
5634: removecont_array((P *)cvect,nz,1);
5635: expand_array(svect,cvect,nz);
5636: hmag = ((double)p_mag((P)svect[j]))*nd_scale;
5637: }
5638: }
5639: }
5640: nz = compress_array(svect,cvect,col);
5641: removecont_array((P *)cvect,nz,1);
5642: expand_array(svect,cvect,nz);
5643: if ( DP_Print ) {
5644: fprintf(asir_out,"-"); fflush(asir_out);
5645: }
5646: return maxrs;
1.107 noro 5647: }
5648:
1.215 ! noro 5649: int ndv_reduce_vect_gz(GZ *gvect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
! 5650: {
! 5651: int i,j,k,l,len,pos,prev,nz;
! 5652: GZ cs,mcs,c1,c2,cr,gcd,t;
! 5653: IndArray ivect;
! 5654: unsigned char *ivc;
! 5655: unsigned short *ivs;
! 5656: unsigned int *ivi;
! 5657: NDV redv;
! 5658: NMV mr;
! 5659: NODE rp;
! 5660: int maxrs;
! 5661: double hmag;
! 5662: struct oVECT v;
! 5663:
! 5664: maxrs = 0;
! 5665: for ( i = 0; i < col && !gvect[i]; i++ );
! 5666: if ( i == col ) return maxrs;
! 5667: hmag = (double)n_bits_gz(gvect[i])*nd_scale;
! 5668: for ( i = 0; i < nred; i++ ) {
! 5669: ivect = imat[i];
! 5670: k = ivect->head;
! 5671: if ( gvect[k] ) {
! 5672: maxrs = MAX(maxrs,rp0[i]->sugar);
! 5673: redv = nd_ps_gz[rp0[i]->index];
! 5674: len = LEN(redv); mr = BDY(redv);
! 5675: gcdgz(gvect[k],CZ(mr),&gcd);
! 5676: divsgz(gvect[k],gcd,&cs);
! 5677: divsgz(CZ(mr),gcd,&cr);
! 5678: chsgngz(cs,&mcs);
! 5679: if ( !UNIGZ(cr) ) {
! 5680: for ( j = 0; j < col; j++ ) {
! 5681: mulgz(gvect[j],cr,&c1); gvect[j] = c1;
! 5682: }
! 5683: }
! 5684: gvect[k] = 0; prev = k;
! 5685: switch ( ivect->width ) {
! 5686: case 1:
! 5687: ivc = ivect->index.c;
! 5688: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
! 5689: pos = prev+ivc[j]; prev = pos;
! 5690: mulgz(CZ(mr),mcs,&c2); addgz(gvect[pos],c2,&t); gvect[pos] = t;
! 5691: }
! 5692: break;
! 5693: case 2:
! 5694: ivs = ivect->index.s;
! 5695: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
! 5696: pos = prev+ivs[j]; prev = pos;
! 5697: mulgz(CZ(mr),mcs,&c2); addgz(gvect[pos],c2,&t); gvect[pos] = t;
! 5698: }
! 5699: break;
! 5700: case 4:
! 5701: ivi = ivect->index.i;
! 5702: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
! 5703: pos = prev+ivi[j]; prev = pos;
! 5704: mulgz(CZ(mr),mcs,&c2); addgz(gvect[pos],c2,&t); gvect[pos] = t;
! 5705: }
! 5706: break;
! 5707: }
! 5708: for ( j = k+1; j < col && !gvect[j]; j++ );
! 5709: if ( j == col ) break;
! 5710: if ( hmag && ((double)n_bits_gz(gvect[j]) > hmag) ) {
! 5711: v.len = col; v.body = (pointer)gvect; gcdvgz(&v,&gcd);
! 5712: #if 1
! 5713: for ( l = 0; l < col; l++ ) { divsgz(gvect[l],gcd,&t); gvect[l] = t; }
! 5714: #endif
! 5715: hmag = (double)n_bits_gz(gvect[j])*nd_scale;
! 5716: }
! 5717: }
! 5718: }
! 5719: for ( j = 0; j < col && !gvect[j]; j++ );
! 5720: if ( j < col ) {
! 5721: v.len = col; v.body = (pointer)gvect; gcdvgz(&v,&gcd);
! 5722: for ( l = 0; l < col; l++ ) { divsgz(gvect[l],gcd,&t); gvect[l] = t; }
! 5723: }
! 5724: if ( DP_Print ) {
! 5725: fprintf(asir_out,"-"); fflush(asir_out);
! 5726: }
! 5727: return maxrs;
! 5728: }
! 5729:
! 5730:
1.76 noro 5731: int ndv_reduce_vect(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.65 noro 5732: {
1.157 noro 5733: int i,j,k,len,pos,prev;
5734: UINT c,c1,c2,c3,up,lo,dmy;
5735: IndArray ivect;
5736: unsigned char *ivc;
5737: unsigned short *ivs;
5738: unsigned int *ivi;
5739: NDV redv;
5740: NMV mr;
5741: NODE rp;
5742: int maxrs;
5743:
5744: maxrs = 0;
5745: for ( i = 0; i < nred; i++ ) {
5746: ivect = imat[i];
5747: k = ivect->head; svect[k] %= m;
5748: if ( c = svect[k] ) {
5749: maxrs = MAX(maxrs,rp0[i]->sugar);
5750: c = m-c; redv = nd_ps[rp0[i]->index];
5751: len = LEN(redv); mr = BDY(redv);
5752: svect[k] = 0; prev = k;
5753: switch ( ivect->width ) {
5754: case 1:
5755: ivc = ivect->index.c;
5756: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
1.215 ! noro 5757: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
! 5758: if ( c1 ) {
! 5759: c2 = svect[pos];
! 5760: DMA(c1,c,c2,up,lo);
! 5761: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
! 5762: } else svect[pos] = lo;
! 5763: }
1.157 noro 5764: }
5765: break;
5766: case 2:
5767: ivs = ivect->index.s;
5768: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
1.215 ! noro 5769: pos = prev+ivs[j]; c1 = CM(mr);
1.157 noro 5770: prev = pos;
1.215 ! noro 5771: if ( c1 ) {
! 5772: c2 = svect[pos];
! 5773: DMA(c1,c,c2,up,lo);
! 5774: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
! 5775: } else svect[pos] = lo;
! 5776: }
1.157 noro 5777: }
5778: break;
5779: case 4:
5780: ivi = ivect->index.i;
5781: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
1.215 ! noro 5782: pos = prev+ivi[j]; c1 = CM(mr);
1.157 noro 5783: prev = pos;
1.215 ! noro 5784: if ( c1 ) {
! 5785: c2 = svect[pos];
! 5786: DMA(c1,c,c2,up,lo);
! 5787: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
! 5788: } else svect[pos] = lo;
! 5789: }
1.157 noro 5790: }
5791: break;
5792: }
5793: }
5794: }
5795: for ( i = 0; i < col; i++ )
5796: if ( svect[i] >= (UINT)m ) svect[i] %= m;
5797: return maxrs;
1.65 noro 5798: }
5799:
1.76 noro 5800: int ndv_reduce_vect_sf(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.72 noro 5801: {
1.157 noro 5802: int i,j,k,len,pos,prev;
5803: UINT c,c1,c2,c3,up,lo,dmy;
5804: IndArray ivect;
5805: unsigned char *ivc;
5806: unsigned short *ivs;
5807: unsigned int *ivi;
5808: NDV redv;
5809: NMV mr;
5810: NODE rp;
5811: int maxrs;
5812:
5813: maxrs = 0;
5814: for ( i = 0; i < nred; i++ ) {
5815: ivect = imat[i];
5816: k = ivect->head; svect[k] %= m;
5817: if ( c = svect[k] ) {
5818: maxrs = MAX(maxrs,rp0[i]->sugar);
5819: c = _chsgnsf(c); redv = nd_ps[rp0[i]->index];
5820: len = LEN(redv); mr = BDY(redv);
5821: svect[k] = 0; prev = k;
5822: switch ( ivect->width ) {
5823: case 1:
5824: ivc = ivect->index.c;
5825: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
5826: pos = prev+ivc[j]; prev = pos;
5827: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
5828: }
5829: break;
5830: case 2:
5831: ivs = ivect->index.s;
5832: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
5833: pos = prev+ivs[j]; prev = pos;
5834: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
5835: }
5836: break;
5837: case 4:
5838: ivi = ivect->index.i;
5839: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
5840: pos = prev+ivi[j]; prev = pos;
5841: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
5842: }
5843: break;
5844: }
5845: }
5846: }
5847: return maxrs;
1.72 noro 5848: }
5849:
1.65 noro 5850: NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhead,UINT *s0vect)
5851: {
1.157 noro 5852: int j,k,len;
5853: UINT *p;
5854: UINT c;
5855: NDV r;
5856: NMV mr0,mr;
5857:
5858: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
5859: if ( !len ) return 0;
5860: else {
1.200 noro 5861: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
1.103 noro 5862: #if 0
1.157 noro 5863: ndv_alloc += nmv_adv*len;
1.103 noro 5864: #endif
1.157 noro 5865: mr = mr0;
5866: p = s0vect;
5867: for ( j = k = 0; j < col; j++, p += nd_wpd )
5868: if ( !rhead[j] ) {
5869: if ( c = vect[k++] ) {
5870: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
5871: }
5872: }
5873: MKNDV(nd_nvar,mr0,len,r);
5874: return r;
5875: }
1.65 noro 5876: }
5877:
1.129 noro 5878: /* for preprocessed vector */
5879:
1.113 noro 5880: NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead,UINT *s0vect)
1.107 noro 5881: {
1.157 noro 5882: int j,k,len;
5883: UINT *p;
5884: Q c;
5885: NDV r;
5886: NMV mr0,mr;
5887:
5888: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
5889: if ( !len ) return 0;
5890: else {
1.200 noro 5891: mr0 = (NMV)MALLOC(nmv_adv*len);
1.107 noro 5892: #if 0
1.157 noro 5893: ndv_alloc += nmv_adv*len;
1.107 noro 5894: #endif
1.157 noro 5895: mr = mr0;
5896: p = s0vect;
5897: for ( j = k = 0; j < col; j++, p += nd_wpd )
5898: if ( !rhead[j] ) {
5899: if ( c = vect[k++] ) {
5900: if ( DN(c) )
5901: error("afo");
5902: ndl_copy(p,DL(mr)); CQ(mr) = c; NMV_ADV(mr);
5903: }
5904: }
5905: MKNDV(nd_nvar,mr0,len,r);
5906: return r;
5907: }
1.107 noro 5908: }
5909:
1.215 ! noro 5910: NDV vect_to_ndv_gz(GZ *vect,int spcol,int col,int *rhead,UINT *s0vect)
! 5911: {
! 5912: int j,k,len;
! 5913: UINT *p;
! 5914: Q c;
! 5915: NDV r;
! 5916: NMV mr0,mr;
! 5917:
! 5918: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
! 5919: if ( !len ) return 0;
! 5920: else {
! 5921: mr0 = (NMV)MALLOC(nmv_adv*len);
! 5922: #if 0
! 5923: ndv_alloc += nmv_adv*len;
! 5924: #endif
! 5925: mr = mr0;
! 5926: p = s0vect;
! 5927: for ( j = k = 0; j < col; j++, p += nd_wpd )
! 5928: if ( !rhead[j] ) {
! 5929: if ( c = vect[k++] ) {
! 5930: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
! 5931: }
! 5932: }
! 5933: MKNDV(nd_nvar,mr0,len,r);
! 5934: return r;
! 5935: }
! 5936: }
! 5937:
1.129 noro 5938: /* for plain vector */
5939:
5940: NDV plain_vect_to_ndv_q(Q *vect,int col,UINT *s0vect)
5941: {
1.157 noro 5942: int j,k,len;
5943: UINT *p;
5944: Q c;
5945: NDV r;
5946: NMV mr0,mr;
5947:
5948: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
5949: if ( !len ) return 0;
5950: else {
1.200 noro 5951: mr0 = (NMV)MALLOC(nmv_adv*len);
1.129 noro 5952: #if 0
1.157 noro 5953: ndv_alloc += nmv_adv*len;
1.129 noro 5954: #endif
1.157 noro 5955: mr = mr0;
5956: p = s0vect;
5957: for ( j = k = 0; j < col; j++, p += nd_wpd, k++ )
5958: if ( c = vect[k] ) {
5959: if ( DN(c) )
5960: error("afo");
5961: ndl_copy(p,DL(mr)); CQ(mr) = c; NMV_ADV(mr);
5962: }
5963: MKNDV(nd_nvar,mr0,len,r);
5964: return r;
5965: }
1.129 noro 5966: }
5967:
1.133 noro 5968: int nd_sp_f4(int m,int trace,ND_pairs l,PGeoBucket bucket)
1.65 noro 5969: {
1.157 noro 5970: ND_pairs t;
5971: NODE sp0,sp;
5972: int stat;
5973: ND spol;
5974:
5975: for ( t = l; t; t = NEXT(t) ) {
5976: stat = nd_sp(m,trace,t,&spol);
5977: if ( !stat ) return 0;
5978: if ( spol ) {
5979: add_pbucket_symbolic(bucket,spol);
5980: }
5981: }
5982: return 1;
1.65 noro 5983: }
5984:
1.133 noro 5985: int nd_symbolic_preproc(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
1.65 noro 5986: {
1.157 noro 5987: NODE rp0,rp;
5988: NM mul,head,s0,s;
5989: int index,col,i,sugar;
5990: RHist h;
5991: UINT *s0v,*p;
5992: NM_ind_pair pair;
5993: ND red;
5994: NDV *ps;
5995:
5996: s0 = 0; rp0 = 0; col = 0;
1.215 ! noro 5997: if ( nd_demand )
! 5998: ps = trace?nd_ps_trace_sym:nd_ps_sym;
! 5999: else
! 6000: ps = trace?nd_ps_trace:nd_ps;
1.157 noro 6001: while ( 1 ) {
6002: head = remove_head_pbucket_symbolic(bucket);
6003: if ( !head ) break;
6004: if ( !s0 ) s0 = head;
6005: else NEXT(s) = head;
6006: s = head;
6007: index = ndl_find_reducer(DL(head));
6008: if ( index >= 0 ) {
6009: h = nd_psh[index];
6010: NEWNM(mul);
6011: ndl_sub(DL(head),DL(h),DL(mul));
6012: if ( ndl_check_bound2(index,DL(mul)) ) return 0;
6013: sugar = TD(DL(mul))+SG(ps[index]);
6014: MKNM_ind_pair(pair,mul,index,sugar);
6015: red = ndv_mul_nm_symbolic(mul,ps[index]);
6016: add_pbucket_symbolic(bucket,nd_remove_head(red));
6017: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
6018: }
6019: col++;
6020: }
6021: if ( rp0 ) NEXT(rp) = 0;
6022: NEXT(s) = 0;
6023: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
6024: for ( i = 0, p = s0v, s = s0; i < col;
6025: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
6026: *s0vect = s0v;
6027: *r = rp0;
6028: return col;
1.65 noro 6029: }
6030:
1.167 noro 6031: NODE nd_f4(int m,int **indp)
1.69 noro 6032: {
1.157 noro 6033: int i,nh,stat,index;
1.208 noro 6034: NODE r,g,tn0,tn,node;
6035: ND_pairs d,l,t,ll0,ll;
6036: LIST l0,l1;
1.157 noro 6037: ND spol,red;
6038: NDV nf,redv;
6039: NM s0,s;
1.208 noro 6040: NODE rp0,srp0,nflist,nzlist;
6041: int nsp,nred,col,rank,len,k,j,a,i1s,i2s;
1.157 noro 6042: UINT c;
6043: UINT **spmat;
6044: UINT *s0vect,*svect,*p,*v;
6045: int *colstat;
6046: IndArray *imat;
6047: int *rhead;
6048: int spcol,sprow;
6049: int sugar;
6050: PGeoBucket bucket;
6051: struct oEGT eg0,eg1,eg_f4;
1.208 noro 6052: Q i1,i2,sugarq;
1.103 noro 6053: #if 0
1.157 noro 6054: ndv_alloc = 0;
1.103 noro 6055: #endif
1.157 noro 6056: g = 0; d = 0;
6057: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 6058: d = update_pairs(d,g,i,0);
1.157 noro 6059: g = update_base(g,i);
6060: }
1.208 noro 6061: nzlist = 0;
1.157 noro 6062: while ( d ) {
6063: get_eg(&eg0);
6064: l = nd_minsugarp(d,&d);
6065: sugar = SG(l);
1.208 noro 6066: if ( nd_nzlist ) {
6067: for ( tn = nd_nzlist; tn; tn = NEXT(tn) ) {
6068: node = BDY((LIST)BDY(tn));
6069: if ( QTOS((Q)ARG0(node)) == sugar ) break;
6070: }
1.209 noro 6071: if ( !tn ) error("nd_f4 : inconsistent non-zero list");
1.208 noro 6072: for ( t = l, ll0 = 0; t; t = NEXT(t) ) {
6073: for ( tn = BDY((LIST)ARG1(node)); tn; tn = NEXT(tn) ) {
6074: i1s = QTOS((Q)ARG0(BDY((LIST)BDY(tn))));
6075: i2s = QTOS((Q)ARG1(BDY((LIST)BDY(tn))));
6076: if ( t->i1 == i1s && t->i2 == i2s ) break;
6077: }
6078: if ( tn ) {
6079: if ( !ll0 ) ll0 = t;
6080: else NEXT(ll) = t;
6081: ll = t;
6082: }
6083: }
6084: if ( ll0 ) NEXT(ll) = 0;
6085: l = ll0;
6086: }
1.157 noro 6087: bucket = create_pbucket();
6088: stat = nd_sp_f4(m,0,l,bucket);
6089: if ( !stat ) {
6090: for ( t = l; NEXT(t); t = NEXT(t) );
6091: NEXT(t) = d; d = l;
6092: d = nd_reconstruct(0,d);
6093: continue;
6094: }
6095: if ( bucket->m < 0 ) continue;
6096: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
6097: if ( !col ) {
6098: for ( t = l; NEXT(t); t = NEXT(t) );
6099: NEXT(t) = d; d = l;
6100: d = nd_reconstruct(0,d);
6101: continue;
6102: }
6103: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
6104: if ( DP_Print )
6105: fprintf(asir_out,"sugar=%d,symb=%fsec,",
6106: sugar,eg_f4.exectime+eg_f4.gctime);
1.210 noro 6107: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,nd_gentrace?&ll:0);
1.157 noro 6108: /* adding new bases */
6109: for ( r = nflist; r; r = NEXT(r) ) {
6110: nf = (NDV)BDY(r);
6111: ndv_removecont(m,nf);
6112: if ( !m && nd_nalg ) {
6113: ND nf1;
6114:
6115: nf1 = ndvtond(m,nf);
6116: nd_monic(0,&nf1);
6117: nd_removecont(m,nf1);
6118: nf = ndtondv(m,nf1);
6119: }
1.215 ! noro 6120: nh = ndv_newps(m,nf,0,1);
1.168 noro 6121: d = update_pairs(d,g,nh,0);
1.157 noro 6122: g = update_base(g,nh);
6123: }
1.208 noro 6124: if ( nd_gentrace ) {
6125: for ( t = ll, tn0 = 0; t; t = NEXT(t) ) {
6126: NEXTNODE(tn0,tn);
6127: STOQ(t->i1,i1); STOQ(t->i2,i2);
6128: node = mknode(2,i1,i2); MKLIST(l0,node);
6129: BDY(tn) = l0;
6130: }
6131: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
6132: STOQ(sugar,sugarq); node = mknode(2,sugarq,l0); MKLIST(l1,node);
6133: MKNODE(node,l1,nzlist); nzlist = node;
6134: }
6135: }
6136: if ( nd_gentrace ) {
6137: MKLIST(l0,reverse_node(nzlist));
6138: MKNODE(nd_alltracelist,l0,0);
1.157 noro 6139: }
1.103 noro 6140: #if 0
1.157 noro 6141: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.103 noro 6142: #endif
1.215 ! noro 6143: conv_ilist(nd_demand,0,g,indp);
1.157 noro 6144: return g;
1.69 noro 6145: }
1.74 noro 6146:
1.167 noro 6147: NODE nd_f4_trace(int m,int **indp)
1.133 noro 6148: {
1.157 noro 6149: int i,nh,stat,index;
6150: NODE r,g;
6151: ND_pairs d,l,l0,t;
6152: ND spol,red;
6153: NDV nf,redv,nfqv,nfv;
6154: NM s0,s;
6155: NODE rp0,srp0,nflist;
6156: int nsp,nred,col,rank,len,k,j,a;
6157: UINT c;
6158: UINT **spmat;
6159: UINT *s0vect,*svect,*p,*v;
6160: int *colstat;
6161: IndArray *imat;
6162: int *rhead;
6163: int spcol,sprow;
6164: int sugar;
6165: PGeoBucket bucket;
6166: struct oEGT eg0,eg1,eg_f4;
6167:
6168: g = 0; d = 0;
6169: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 6170: d = update_pairs(d,g,i,0);
1.157 noro 6171: g = update_base(g,i);
6172: }
6173: while ( d ) {
6174: get_eg(&eg0);
6175: l = nd_minsugarp(d,&d);
6176: sugar = SG(l);
6177: bucket = create_pbucket();
6178: stat = nd_sp_f4(m,0,l,bucket);
6179: if ( !stat ) {
6180: for ( t = l; NEXT(t); t = NEXT(t) );
6181: NEXT(t) = d; d = l;
6182: d = nd_reconstruct(1,d);
6183: continue;
6184: }
6185: if ( bucket->m < 0 ) continue;
6186: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
6187: if ( !col ) {
6188: for ( t = l; NEXT(t); t = NEXT(t) );
6189: NEXT(t) = d; d = l;
6190: d = nd_reconstruct(1,d);
6191: continue;
6192: }
6193: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
6194: if ( DP_Print )
6195: fprintf(asir_out,"sugar=%d,symb=%fsec,",
6196: sugar,eg_f4.exectime+eg_f4.gctime);
6197: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
6198: if ( !l0 ) continue;
6199: l = l0;
6200:
6201: /* over Q */
6202: bucket = create_pbucket();
6203: stat = nd_sp_f4(0,1,l,bucket);
6204: if ( !stat ) {
6205: for ( t = l; NEXT(t); t = NEXT(t) );
6206: NEXT(t) = d; d = l;
6207: d = nd_reconstruct(1,d);
6208: continue;
6209: }
6210: if ( bucket->m < 0 ) continue;
6211: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
6212: if ( !col ) {
6213: for ( t = l; NEXT(t); t = NEXT(t) );
6214: NEXT(t) = d; d = l;
6215: d = nd_reconstruct(1,d);
6216: continue;
6217: }
6218: nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0);
6219: /* adding new bases */
6220: for ( r = nflist; r; r = NEXT(r) ) {
6221: nfqv = (NDV)BDY(r);
6222: ndv_removecont(0,nfqv);
6223: if ( !rem(NM(HCQ(nfqv)),m) ) return 0;
6224: if ( nd_nalg ) {
6225: ND nf1;
6226:
6227: nf1 = ndvtond(m,nfqv);
6228: nd_monic(0,&nf1);
6229: nd_removecont(0,nf1);
6230: nfqv = ndtondv(0,nf1); nd_free(nf1);
6231: }
6232: nfv = ndv_dup(0,nfqv);
6233: ndv_mod(m,nfv);
6234: ndv_removecont(m,nfv);
1.215 ! noro 6235: nh = ndv_newps(0,nfv,nfqv,1);
1.168 noro 6236: d = update_pairs(d,g,nh,0);
1.157 noro 6237: g = update_base(g,nh);
6238: }
6239: }
1.133 noro 6240: #if 0
1.157 noro 6241: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.133 noro 6242: #endif
1.215 ! noro 6243: conv_ilist(nd_demand,1,g,indp);
1.157 noro 6244: return g;
1.133 noro 6245: }
6246:
1.176 noro 6247: NODE nd_f4_pseudo_trace(int m,int **indp)
6248: {
6249: int i,nh,stat,index;
6250: NODE r,g;
6251: ND_pairs d,l,l0,t;
6252: ND spol,red;
6253: NDV nf,redv,nfqv,nfv;
6254: NM s0,s;
6255: NODE rp0,srp0,nflist;
6256: int nsp,nred,col,rank,len,k,j,a;
6257: UINT c;
6258: UINT **spmat;
6259: UINT *s0vect,*svect,*p,*v;
6260: int *colstat;
6261: IndArray *imat;
6262: int *rhead;
6263: int spcol,sprow;
6264: int sugar;
6265: PGeoBucket bucket;
6266: struct oEGT eg0,eg1,eg_f4;
6267:
6268: g = 0; d = 0;
6269: for ( i = 0; i < nd_psn; i++ ) {
6270: d = update_pairs(d,g,i,0);
6271: g = update_base(g,i);
6272: }
6273: while ( d ) {
6274: get_eg(&eg0);
6275: l = nd_minsugarp(d,&d);
6276: sugar = SG(l);
6277: bucket = create_pbucket();
6278: stat = nd_sp_f4(m,0,l,bucket);
6279: if ( !stat ) {
6280: for ( t = l; NEXT(t); t = NEXT(t) );
6281: NEXT(t) = d; d = l;
6282: d = nd_reconstruct(1,d);
6283: continue;
6284: }
6285: if ( bucket->m < 0 ) continue;
6286: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
6287: if ( !col ) {
6288: for ( t = l; NEXT(t); t = NEXT(t) );
6289: NEXT(t) = d; d = l;
6290: d = nd_reconstruct(1,d);
6291: continue;
6292: }
6293: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
6294: if ( DP_Print )
6295: fprintf(asir_out,"sugar=%d,symb=%fsec,",
6296: sugar,eg_f4.exectime+eg_f4.gctime);
6297: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
6298: if ( !l0 ) continue;
6299: l = l0;
6300:
6301: /* over Q */
6302: while ( 1 ) {
6303: bucket = create_pbucket();
6304: stat = nd_sp_f4(0,1,l,bucket);
6305: if ( !stat ) {
6306: for ( t = l; NEXT(t); t = NEXT(t) );
6307: NEXT(t) = d; d = l;
6308: d = nd_reconstruct(1,d);
6309: continue;
6310: }
6311: if ( bucket->m < 0 ) continue;
6312: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
6313: if ( !col ) {
6314: for ( t = l; NEXT(t); t = NEXT(t) );
6315: NEXT(t) = d; d = l;
6316: d = nd_reconstruct(1,d);
6317: continue;
6318: }
6319: nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0);
6320: }
6321:
6322: /* adding new bases */
6323: for ( r = nflist; r; r = NEXT(r) ) {
6324: nfqv = (NDV)BDY(r);
6325: ndv_removecont(0,nfqv);
6326: if ( !rem(NM(HCQ(nfqv)),m) ) return 0;
6327: if ( nd_nalg ) {
6328: ND nf1;
6329:
6330: nf1 = ndvtond(m,nfqv);
6331: nd_monic(0,&nf1);
6332: nd_removecont(0,nf1);
6333: nfqv = ndtondv(0,nf1); nd_free(nf1);
6334: }
6335: nfv = ndv_dup(0,nfqv);
6336: ndv_mod(m,nfv);
6337: ndv_removecont(m,nfv);
1.215 ! noro 6338: nh = ndv_newps(0,nfv,nfqv,1);
1.176 noro 6339: d = update_pairs(d,g,nh,0);
6340: g = update_base(g,nh);
6341: }
6342: }
6343: #if 0
6344: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
6345: #endif
6346: conv_ilist(0,1,g,indp);
6347: return g;
6348: }
6349:
1.133 noro 6350: NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
1.63 noro 6351: {
1.157 noro 6352: IndArray *imat;
6353: int nsp,nred,i;
6354: int *rhead;
6355: NODE r0,rp;
6356: ND_pairs sp;
6357: NM_ind_pair *rvect;
1.210 noro 6358: UINT *s;
6359: int *s0hash;
6360:
1.198 noro 6361: init_eg(&eg_search);
1.157 noro 6362: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
6363: nred = length(rp0);
6364: imat = (IndArray *)ALLOCA(nred*sizeof(IndArray));
6365: rhead = (int *)ALLOCA(col*sizeof(int));
6366: for ( i = 0; i < col; i++ ) rhead[i] = 0;
6367:
6368: /* construction of index arrays */
1.215 ! noro 6369: fprintf(stderr,"%dx%d,",nsp+nred,col);
1.157 noro 6370: rvect = (NM_ind_pair *)ALLOCA(nred*sizeof(NM_ind_pair));
1.210 noro 6371: s0hash = (int *)ALLOCA(col*sizeof(int));
6372: for ( i = 0, s = s0vect; i < col; i++, s += nd_wpd )
6373: s0hash[i] = ndl_hash_value(s);
1.157 noro 6374: for ( rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
6375: rvect[i] = (NM_ind_pair)BDY(rp);
1.210 noro 6376: imat[i] = nm_ind_pair_to_vect_compress(m,s0vect,col,s0hash,rvect[i]);
1.157 noro 6377: rhead[imat[i]->head] = 1;
6378: }
6379: if ( m )
6380: r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
6381: else
1.215 ! noro 6382: r0 = nd_f4_red_gz_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
1.198 noro 6383: print_eg("search",&eg_search);
1.157 noro 6384: return r0;
1.106 noro 6385: }
1.74 noro 6386:
1.106 noro 6387: NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
1.133 noro 6388: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
1.106 noro 6389: {
1.157 noro 6390: int spcol,sprow,a;
6391: int i,j,k,l,rank;
6392: NODE r0,r;
6393: ND_pairs sp;
6394: ND spol;
6395: int **spmat;
6396: UINT *svect,*v;
6397: int *colstat;
6398: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
6399: int maxrs;
6400: int *spsugar;
6401: ND_pairs *spactive;
6402:
6403: spcol = col-nred;
6404: get_eg(&eg0);
6405: /* elimination (1st step) */
6406: spmat = (int **)ALLOCA(nsp*sizeof(UINT *));
6407: svect = (UINT *)ALLOCA(col*sizeof(UINT));
6408: spsugar = (int *)ALLOCA(nsp*sizeof(UINT));
6409: spactive = !nz?0:(ND_pairs *)ALLOCA(nsp*sizeof(ND_pairs));
6410: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
6411: nd_sp(m,0,sp,&spol);
6412: if ( !spol ) continue;
6413: nd_to_vect(m,s0vect,col,spol,svect);
6414: if ( m == -1 )
6415: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
6416: else
6417: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred);
6418: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
6419: if ( i < col ) {
6420: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
6421: for ( j = k = 0; j < col; j++ )
6422: if ( !rhead[j] ) v[k++] = svect[j];
6423: spsugar[sprow] = MAX(maxrs,SG(spol));
6424: if ( nz )
6425: spactive[sprow] = sp;
6426: sprow++;
6427: }
6428: nd_free(spol);
6429: }
6430: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
6431: if ( DP_Print ) {
6432: fprintf(asir_out,"elim1=%fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
6433: fflush(asir_out);
6434: }
6435: /* free index arrays */
1.200 noro 6436: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
1.157 noro 6437:
6438: /* elimination (2nd step) */
6439: colstat = (int *)ALLOCA(spcol*sizeof(int));
6440: if ( m == -1 )
6441: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
6442: else
6443: rank = nd_gauss_elim_mod(spmat,spsugar,spactive,sprow,spcol,m,colstat);
6444: r0 = 0;
6445: for ( i = 0; i < rank; i++ ) {
6446: NEXTNODE(r0,r); BDY(r) =
6447: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
6448: SG((NDV)BDY(r)) = spsugar[i];
1.200 noro 6449: GCFREE(spmat[i]);
1.157 noro 6450: }
6451: if ( r0 ) NEXT(r) = 0;
6452:
1.200 noro 6453: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
1.157 noro 6454: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
6455: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
6456: if ( DP_Print ) {
6457: fprintf(asir_out,"elim2=%fsec\n",eg_f4_2.exectime+eg_f4_2.gctime);
6458: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
6459: nsp,nred,sprow,spcol,rank);
6460: fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime);
6461: }
6462: if ( nz ) {
6463: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
6464: if ( rank > 0 ) {
6465: NEXT(spactive[rank-1]) = 0;
6466: *nz = spactive[0];
6467: } else
6468: *nz = 0;
6469: }
6470: return r0;
1.74 noro 6471: }
6472:
1.133 noro 6473: #if 1
6474: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
1.107 noro 6475: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
6476: {
1.157 noro 6477: int spcol,sprow,a;
6478: int i,j,k,l,rank;
6479: NODE r0,r;
6480: ND_pairs sp;
6481: ND spol;
6482: Q **spmat;
6483: Q *svect,*v;
6484: int *colstat;
6485: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
6486: int maxrs;
6487: int *spsugar;
6488: pointer *w;
6489:
6490: spcol = col-nred;
6491: get_eg(&eg0);
6492: /* elimination (1st step) */
6493: spmat = (Q **)ALLOCA(nsp*sizeof(Q *));
6494: svect = (Q *)ALLOCA(col*sizeof(Q));
6495: spsugar = (int *)ALLOCA(nsp*sizeof(Q));
6496: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
6497: nd_sp(0,trace,sp,&spol);
6498: if ( !spol ) continue;
6499: nd_to_vect_q(s0vect,col,spol,svect);
6500: maxrs = ndv_reduce_vect_q(svect,trace,col,imat,rvect,nred);
6501: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
6502: if ( i < col ) {
6503: spmat[sprow] = v = (Q *)MALLOC(spcol*sizeof(Q));
6504: for ( j = k = 0; j < col; j++ )
6505: if ( !rhead[j] ) v[k++] = svect[j];
6506: spsugar[sprow] = MAX(maxrs,SG(spol));
6507: sprow++;
6508: }
6509: /* nd_free(spol); */
6510: }
6511: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
6512: if ( DP_Print ) {
6513: fprintf(asir_out,"elim1=%fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
6514: fflush(asir_out);
6515: }
6516: /* free index arrays */
1.200 noro 6517: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
1.157 noro 6518:
6519: /* elimination (2nd step) */
6520: colstat = (int *)ALLOCA(spcol*sizeof(int));
6521: rank = nd_gauss_elim_q(spmat,spsugar,sprow,spcol,colstat);
6522: w = (pointer *)ALLOCA(rank*sizeof(pointer));
6523: for ( i = 0; i < rank; i++ ) {
1.213 noro 6524: #if 0
1.157 noro 6525: w[rank-i-1] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
6526: SG((NDV)w[rank-i-1]) = spsugar[i];
1.213 noro 6527: #else
6528: w[i] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
6529: SG((NDV)w[i]) = spsugar[i];
6530: #endif
1.200 noro 6531: /* GCFREE(spmat[i]); */
1.157 noro 6532: }
1.138 noro 6533: #if 0
1.157 noro 6534: qsort(w,rank,sizeof(NDV),
6535: (int (*)(const void *,const void *))ndv_compare);
1.137 noro 6536: #endif
1.157 noro 6537: r0 = 0;
6538: for ( i = 0; i < rank; i++ ) {
6539: NEXTNODE(r0,r); BDY(r) = w[i];
6540: }
6541: if ( r0 ) NEXT(r) = 0;
6542:
1.200 noro 6543: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
1.157 noro 6544: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
6545: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
6546: if ( DP_Print ) {
6547: fprintf(asir_out,"elim2=%fsec\n",eg_f4_2.exectime+eg_f4_2.gctime);
6548: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
6549: nsp,nred,sprow,spcol,rank);
6550: fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime);
6551: }
6552: return r0;
1.107 noro 6553: }
1.215 ! noro 6554:
! 6555: NODE nd_f4_red_gz_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
! 6556: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
! 6557: {
! 6558: int spcol,sprow,a;
! 6559: int i,j,k,l,rank;
! 6560: NODE r0,r;
! 6561: ND_pairs sp;
! 6562: ND spol;
! 6563: GZ **spmat;
! 6564: GZ *svect,*v;
! 6565: int *colstat;
! 6566: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
! 6567: int maxrs;
! 6568: int *spsugar;
! 6569: pointer *w;
! 6570:
! 6571: spcol = col-nred;
! 6572: get_eg(&eg0);
! 6573: /* elimination (1st step) */
! 6574: spmat = (GZ **)ALLOCA(nsp*sizeof(GZ *));
! 6575: svect = (GZ *)ALLOCA(col*sizeof(GZ));
! 6576: spsugar = (int *)ALLOCA(nsp*sizeof(Q));
! 6577: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
! 6578: nd_sp(0,trace,sp,&spol);
! 6579: if ( !spol ) continue;
! 6580: spol = ndtondgz(spol);
! 6581: nd_to_vect_q(s0vect,col,spol,(Q *)svect);
! 6582: maxrs = ndv_reduce_vect_gz(svect,trace,col,imat,rvect,nred);
! 6583: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
! 6584: if ( i < col ) {
! 6585: spmat[sprow] = v = (GZ *)MALLOC(spcol*sizeof(GZ));
! 6586: for ( j = k = 0; j < col; j++ )
! 6587: if ( !rhead[j] ) v[k++] = svect[j];
! 6588: spsugar[sprow] = MAX(maxrs,SG(spol));
! 6589: sprow++;
! 6590: }
! 6591: /* nd_free(spol); */
! 6592: }
! 6593: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
! 6594: if ( DP_Print ) {
! 6595: fprintf(asir_out,"elim1=%fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
! 6596: fflush(asir_out);
! 6597: }
! 6598: /* free index arrays */
! 6599: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
! 6600:
! 6601: /* elimination (2nd step) */
! 6602: colstat = (int *)ALLOCA(spcol*sizeof(int));
! 6603: rank = nd_gauss_elim_gz(spmat,spsugar,sprow,spcol,colstat);
! 6604: w = (pointer *)ALLOCA(rank*sizeof(pointer));
! 6605: for ( i = 0; i < rank; i++ ) {
! 6606: #if 0
! 6607: w[rank-i-1] = (pointer)vect_to_ndv_gz(spmat[i],spcol,col,rhead,s0vect);
! 6608: w[rank-i-1] = ndvgztondv(w[rank-i-1]);
! 6609: SG((NDV)w[rank-i-1]) = spsugar[i];
! 6610: #else
! 6611: w[i] = (pointer)vect_to_ndv_gz((Q *)spmat[i],spcol,col,rhead,s0vect);
! 6612: w[i] = ndvgztondv(w[i]);
! 6613: SG((NDV)w[i]) = spsugar[i];
! 6614: #endif
! 6615: /* GCFREE(spmat[i]); */
! 6616:
! 6617: }
! 6618: #if 0
! 6619: qsort(w,rank,sizeof(NDV),
! 6620: (int (*)(const void *,const void *))ndv_compare);
! 6621: #endif
! 6622: r0 = 0;
! 6623: for ( i = 0; i < rank; i++ ) {
! 6624: NEXTNODE(r0,r); BDY(r) = w[i];
! 6625: }
! 6626: if ( r0 ) NEXT(r) = 0;
! 6627:
! 6628: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
! 6629: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
! 6630: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
! 6631: if ( DP_Print ) {
! 6632: fprintf(asir_out,"elim2=%fsec\n",eg_f4_2.exectime+eg_f4_2.gctime);
! 6633: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
! 6634: nsp,nred,sprow,spcol,rank);
! 6635: fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime);
! 6636: }
! 6637: return r0;
! 6638: }
1.129 noro 6639: #else
6640: void printm(Q **mat,int row,int col)
6641: {
1.157 noro 6642: int i,j;
6643: printf("[");
6644: for ( i = 0; i < row; i++ ) {
6645: for ( j = 0; j < col; j++ ) {
6646: printexpr(CO,mat[i][j]); printf(" ");
6647: }
6648: printf("]\n");
6649: }
1.129 noro 6650: }
6651:
6652: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vect,int col,
6653: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
6654: {
1.157 noro 6655: int row,a;
6656: int i,j,rank;
6657: NODE r0,r;
6658: ND_pairs sp;
6659: ND spol;
6660: Q **mat;
6661: int *colstat;
6662: int *sugar;
6663:
6664: row = nsp+nred;
6665: /* make the matrix */
6666: mat = (Q **)ALLOCA(row*sizeof(Q *));
6667: sugar = (int *)ALLOCA(row*sizeof(int));
6668: for ( row = a = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
6669: nd_sp(0,0,sp,&spol);
6670: if ( !spol ) continue;
6671: mat[row] = (Q *)MALLOC(col*sizeof(Q));
6672: nd_to_vect_q(s0vect,col,spol,mat[row]);
6673: sugar[row] = SG(spol);
6674: row++;
6675: }
6676: for ( i = 0; i < nred; i++, row++ ) {
6677: mat[row] = nm_ind_pair_to_vect(0,s0vect,col,rvect[i]);
6678: sugar[row] = rvect[i]->sugar;
6679: }
6680: /* elimination */
6681: colstat = (int *)ALLOCA(col*sizeof(int));
6682: rank = nd_gauss_elim_q(mat,sugar,row,col,colstat);
6683: r0 = 0;
6684: for ( i = 0; i < rank; i++ ) {
6685: for ( j = 0; j < col; j++ ) if ( mat[i][j] ) break;
6686: if ( j == col ) error("nd_f4_red_q_main : cannot happen");
6687: if ( rhead[j] ) continue;
6688: NEXTNODE(r0,r); BDY(r) =
6689: (pointer)plain_vect_to_ndv_q(mat[i],col,s0vect);
6690: SG((NDV)BDY(r)) = sugar[i];
6691: }
6692: if ( r0 ) NEXT(r) = 0;
6693: printf("\n");
6694: return r0;
1.129 noro 6695: }
6696: #endif
1.107 noro 6697:
1.74 noro 6698: FILE *nd_write,*nd_read;
6699:
6700: void nd_send_int(int a) {
1.157 noro 6701: write_int(nd_write,&a);
1.74 noro 6702: }
6703:
6704: void nd_send_intarray(int *p,int len) {
1.157 noro 6705: write_intarray(nd_write,p,len);
1.74 noro 6706: }
6707:
6708: int nd_recv_int() {
1.157 noro 6709: int a;
1.74 noro 6710:
1.157 noro 6711: read_int(nd_read,&a);
6712: return a;
1.74 noro 6713: }
6714:
6715: void nd_recv_intarray(int *p,int len) {
1.157 noro 6716: read_intarray(nd_read,p,len);
1.74 noro 6717: }
6718:
6719: void nd_send_ndv(NDV p) {
1.157 noro 6720: int len,i;
6721: NMV m;
1.74 noro 6722:
1.157 noro 6723: if ( !p ) nd_send_int(0);
6724: else {
6725: len = LEN(p);
6726: nd_send_int(len);
6727: m = BDY(p);
6728: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6729: nd_send_int(CM(m));
6730: nd_send_intarray(DL(m),nd_wpd);
6731: }
6732: }
1.74 noro 6733: }
6734:
6735: void nd_send_nd(ND p) {
1.157 noro 6736: int len,i;
6737: NM m;
1.74 noro 6738:
1.157 noro 6739: if ( !p ) nd_send_int(0);
6740: else {
6741: len = LEN(p);
6742: nd_send_int(len);
6743: m = BDY(p);
6744: for ( i = 0; i < len; i++, m = NEXT(m) ) {
6745: nd_send_int(CM(m));
6746: nd_send_intarray(DL(m),nd_wpd);
6747: }
6748: }
1.74 noro 6749: }
1.65 noro 6750:
1.74 noro 6751: NDV nd_recv_ndv()
6752: {
1.157 noro 6753: int len,i;
6754: NMV m,m0;
6755: NDV r;
6756:
6757: len = nd_recv_int();
6758: if ( !len ) return 0;
6759: else {
1.200 noro 6760: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
1.103 noro 6761: #if 0
1.157 noro 6762: ndv_alloc += len*nmv_adv;
1.103 noro 6763: #endif
1.157 noro 6764: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6765: CM(m) = nd_recv_int();
6766: nd_recv_intarray(DL(m),nd_wpd);
6767: }
6768: MKNDV(nd_nvar,m0,len,r);
6769: return r;
6770: }
1.74 noro 6771: }
1.65 noro 6772:
1.74 noro 6773: int ox_exec_f4_red(Q proc)
6774: {
1.157 noro 6775: Obj obj;
6776: STRING fname;
6777: NODE arg;
6778: int s;
6779: extern int ox_need_conv,ox_file_io;
6780:
6781: MKSTR(fname,"nd_exec_f4_red");
6782: arg = mknode(2,proc,fname);
6783: Pox_cmo_rpc(arg,&obj);
6784: s = get_ox_server_id(QTOS(proc));
6785: nd_write = iofp[s].out;
6786: nd_read = iofp[s].in;
6787: ox_need_conv = ox_file_io = 0;
6788: return s;
1.74 noro 6789: }
6790:
1.210 noro 6791: #if 0
1.133 noro 6792: NODE nd_f4_red_dist(int m,ND_pairs sp0,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
1.74 noro 6793: {
1.157 noro 6794: int nsp,nred;
6795: int i,rank,s;
6796: NODE rp,r0,r;
6797: ND_pairs sp;
6798: NM_ind_pair pair;
6799: NMV nmv;
6800: NM nm;
6801: NDV nf;
6802: Obj proc,dmy;
6803:
6804: ox_launch_main(0,0,&proc);
6805: s = ox_exec_f4_red((Q)proc);
6806:
6807: nd_send_int(m);
6808: nd_send_int(nd_nvar);
6809: nd_send_int(nd_bpe);
6810: nd_send_int(nd_wpd);
6811: nd_send_int(nmv_adv);
6812:
6813: saveobj(nd_write,dp_current_spec->obj); fflush(nd_write);
6814:
6815: nd_send_int(nd_psn);
6816: for ( i = 0; i < nd_psn; i++ ) nd_send_ndv(nd_ps[i]);
6817:
6818: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
6819: nd_send_int(nsp);
6820: for ( i = 0, sp = sp0; i < nsp; i++, sp = NEXT(sp) ) {
6821: nd_send_int(sp->i1); nd_send_int(sp->i2);
6822: }
6823:
6824: nd_send_int(col); nd_send_intarray(s0vect,col*nd_wpd);
6825:
6826: nred = length(rp0); nd_send_int(nred);
6827: for ( i = 0, rp = rp0; i < nred; i++, rp = NEXT(rp) ) {
6828: pair = (NM_ind_pair)BDY(rp);
6829: nd_send_int(pair->index);
6830: nd_send_intarray(pair->mul->dl,nd_wpd);
6831: }
6832: fflush(nd_write);
6833: rank = nd_recv_int();
6834: fprintf(asir_out,"rank=%d\n",rank);
6835: r0 = 0;
6836: for ( i = 0; i < rank; i++ ) {
6837: nf = nd_recv_ndv();
6838: NEXTNODE(r0,r); BDY(r) = (pointer)nf;
6839: }
6840: Pox_shutdown(mknode(1,proc),&dmy);
6841: return r0;
1.74 noro 6842: }
6843:
6844: /* server side */
6845:
6846: void nd_exec_f4_red_dist()
6847: {
1.157 noro 6848: int m,i,nsp,col,s0size,nred,spcol,j,k;
6849: NM_ind_pair *rp0;
6850: NDV nf;
6851: UINT *s0vect;
6852: IndArray *imat;
6853: int *rhead;
6854: int **spmat;
6855: UINT *svect,*v;
6856: ND_pairs *sp0;
6857: int *colstat;
6858: int a,sprow,rank;
6859: struct order_spec *ord;
6860: Obj ordspec;
6861: ND spol;
6862: int maxrs;
6863: int *spsugar;
6864:
6865: nd_read = iofp[0].in;
6866: nd_write = iofp[0].out;
6867: m = nd_recv_int();
6868: nd_nvar = nd_recv_int();
6869: nd_bpe = nd_recv_int();
6870: nd_wpd = nd_recv_int();
6871: nmv_adv = nd_recv_int();
6872:
6873: loadobj(nd_read,&ordspec);
6874: create_order_spec(0,ordspec,&ord);
6875: nd_init_ord(ord);
6876: nd_setup_parameters(nd_nvar,0);
6877:
6878: nd_psn = nd_recv_int();
6879: nd_ps = (NDV *)MALLOC(nd_psn*sizeof(NDV));
6880: nd_bound = (UINT **)MALLOC(nd_psn*sizeof(UINT *));
6881: for ( i = 0; i < nd_psn; i++ ) {
6882: nd_ps[i] = nd_recv_ndv();
6883: nd_bound[i] = ndv_compute_bound(nd_ps[i]);
6884: }
6885:
6886: nsp = nd_recv_int();
6887: sp0 = (ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
6888: for ( i = 0; i < nsp; i++ ) {
6889: NEWND_pairs(sp0[i]);
6890: sp0[i]->i1 = nd_recv_int(); sp0[i]->i2 = nd_recv_int();
6891: ndl_lcm(HDL(nd_ps[sp0[i]->i1]),HDL(nd_ps[sp0[i]->i2]),LCM(sp0[i]));
6892: }
6893:
6894: col = nd_recv_int();
6895: s0size = col*nd_wpd;
6896: s0vect = (UINT *)MALLOC(s0size*sizeof(UINT));
6897: nd_recv_intarray(s0vect,s0size);
6898:
6899: nred = nd_recv_int();
6900: rp0 = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
6901: for ( i = 0; i < nred; i++ ) {
6902: rp0[i] = (NM_ind_pair)MALLOC(sizeof(struct oNM_ind_pair));
6903: rp0[i]->index = nd_recv_int();
6904: rp0[i]->mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
6905: nd_recv_intarray(rp0[i]->mul->dl,nd_wpd);
6906: }
6907:
6908: spcol = col-nred;
6909: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
6910: rhead = (int *)MALLOC(col*sizeof(int));
6911: for ( i = 0; i < col; i++ ) rhead[i] = 0;
6912:
6913: /* construction of index arrays */
6914: for ( i = 0; i < nred; i++ ) {
6915: imat[i] = nm_ind_pair_to_vect_compress(m,s0vect,col,rp0[i]);
6916: rhead[imat[i]->head] = 1;
6917: }
6918:
6919: /* elimination (1st step) */
6920: spmat = (int **)MALLOC(nsp*sizeof(UINT *));
6921: svect = (UINT *)MALLOC(col*sizeof(UINT));
6922: spsugar = (int *)ALLOCA(nsp*sizeof(UINT));
6923: for ( a = sprow = 0; a < nsp; a++ ) {
6924: nd_sp(m,0,sp0[a],&spol);
6925: if ( !spol ) continue;
6926: nd_to_vect(m,s0vect,col,spol,svect);
6927: if ( m == -1 )
6928: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rp0,nred);
6929: else
6930: maxrs = ndv_reduce_vect(m,svect,col,imat,rp0,nred);
6931: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
6932: if ( i < col ) {
6933: spmat[sprow] = v = (UINT *)MALLOC(spcol*sizeof(UINT));
6934: for ( j = k = 0; j < col; j++ )
6935: if ( !rhead[j] ) v[k++] = svect[j];
6936: spsugar[sprow] = MAX(maxrs,SG(spol));
6937: sprow++;
6938: }
6939: nd_free(spol);
6940: }
6941: /* elimination (2nd step) */
6942: colstat = (int *)ALLOCA(spcol*sizeof(int));
6943: if ( m == -1 )
6944: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
6945: else
6946: rank = nd_gauss_elim_mod(spmat,spsugar,0,sprow,spcol,m,colstat);
6947: nd_send_int(rank);
6948: for ( i = 0; i < rank; i++ ) {
6949: nf = vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
6950: nd_send_ndv(nf);
6951: }
6952: fflush(nd_write);
1.107 noro 6953: }
1.210 noro 6954: #endif
1.107 noro 6955:
1.113 noro 6956: int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int col,int *colstat)
1.107 noro 6957: {
1.176 noro 6958: int i,j,t,c,rank,inv;
1.157 noro 6959: int *ci,*ri;
6960: Q dn;
6961: MAT m,nm;
6962:
6963: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
6964: rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci);
6965: for ( i = 0; i < row; i++ )
6966: for ( j = 0; j < col; j++ )
6967: mat0[i][j] = 0;
6968: c = col-rank;
6969: for ( i = 0; i < rank; i++ ) {
6970: mat0[i][ri[i]] = dn;
6971: for ( j = 0; j < c; j++ )
6972: mat0[i][ci[j]] = (Q)BDY(nm)[i][j];
6973: }
6974: return rank;
1.76 noro 6975: }
6976:
1.215 ! noro 6977: int nd_gauss_elim_gz(GZ **mat0,int *sugar,int row,int col,int *colstat)
! 6978: {
! 6979: int i,j,t,c,rank,inv;
! 6980: int *ci,*ri;
! 6981: GZ *dn;
! 6982: MAT m,nm;
! 6983:
! 6984: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
! 6985: dn = (GZ *)MALLOC(row*sizeof(GZ));
! 6986: rank = gz_generic_gauss_elim2(m,&nm,dn,&ri,&ci);
! 6987: for ( i = 0; i < row; i++ )
! 6988: for ( j = 0; j < col; j++ )
! 6989: mat0[i][j] = 0;
! 6990: c = col-rank;
! 6991: for ( i = 0; i < rank; i++ ) {
! 6992: mat0[i][ri[i]] = dn[i];
! 6993: for ( j = 0; j < c; j++ )
! 6994: mat0[i][ci[j]] = (GZ)BDY(nm)[i][j];
! 6995: }
! 6996: return rank;
! 6997: }
! 6998:
1.133 noro 6999: int nd_gauss_elim_mod(int **mat0,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
1.76 noro 7000: {
1.157 noro 7001: int i,j,k,l,inv,a,rank,s;
7002: unsigned int *t,*pivot,*pk;
7003: unsigned int **mat;
7004: ND_pairs pair;
7005:
7006: mat = (unsigned int **)mat0;
7007: for ( rank = 0, j = 0; j < col; j++ ) {
7008: for ( i = rank; i < row; i++ )
7009: mat[i][j] %= md;
7010: for ( i = rank; i < row; i++ )
7011: if ( mat[i][j] )
7012: break;
7013: if ( i == row ) {
7014: colstat[j] = 0;
7015: continue;
7016: } else
7017: colstat[j] = 1;
7018: if ( i != rank ) {
7019: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
7020: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
7021: if ( spactive ) {
7022: pair = spactive[i]; spactive[i] = spactive[rank];
7023: spactive[rank] = pair;
7024: }
7025: }
7026: pivot = mat[rank];
7027: s = sugar[rank];
7028: inv = invm(pivot[j],md);
7029: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
7030: if ( *pk ) {
7031: if ( *pk >= (unsigned int)md )
7032: *pk %= md;
7033: DMAR(*pk,inv,0,md,*pk)
7034: }
7035: for ( i = rank+1; i < row; i++ ) {
7036: t = mat[i];
7037: if ( a = t[j] ) {
7038: sugar[i] = MAX(sugar[i],s);
7039: red_by_vect(md,t+j,pivot+j,md-a,col-j);
7040: }
7041: }
7042: rank++;
7043: }
7044: for ( j = col-1, l = rank-1; j >= 0; j-- )
7045: if ( colstat[j] ) {
7046: pivot = mat[l];
7047: s = sugar[l];
7048: for ( i = 0; i < l; i++ ) {
7049: t = mat[i];
7050: t[j] %= md;
7051: if ( a = t[j] ) {
7052: sugar[i] = MAX(sugar[i],s);
7053: red_by_vect(md,t+j,pivot+j,md-a,col-j);
7054: }
7055: }
7056: l--;
7057: }
7058: for ( j = 0, l = 0; l < rank; j++ )
7059: if ( colstat[j] ) {
7060: t = mat[l];
7061: for ( k = j; k < col; k++ )
7062: if ( t[k] >= (unsigned int)md )
7063: t[k] %= md;
7064: l++;
7065: }
7066: return rank;
1.76 noro 7067: }
7068:
7069: int nd_gauss_elim_sf(int **mat0,int *sugar,int row,int col,int md,int *colstat)
7070: {
1.157 noro 7071: int i,j,k,l,inv,a,rank,s;
7072: unsigned int *t,*pivot,*pk;
7073: unsigned int **mat;
7074:
7075: mat = (unsigned int **)mat0;
7076: for ( rank = 0, j = 0; j < col; j++ ) {
7077: for ( i = rank; i < row; i++ )
7078: if ( mat[i][j] )
7079: break;
7080: if ( i == row ) {
7081: colstat[j] = 0;
7082: continue;
7083: } else
7084: colstat[j] = 1;
7085: if ( i != rank ) {
7086: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
7087: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
7088: }
7089: pivot = mat[rank];
7090: s = sugar[rank];
7091: inv = _invsf(pivot[j]);
7092: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
7093: if ( *pk )
7094: *pk = _mulsf(*pk,inv);
7095: for ( i = rank+1; i < row; i++ ) {
7096: t = mat[i];
7097: if ( a = t[j] ) {
7098: sugar[i] = MAX(sugar[i],s);
7099: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
7100: }
7101: }
7102: rank++;
7103: }
7104: for ( j = col-1, l = rank-1; j >= 0; j-- )
7105: if ( colstat[j] ) {
7106: pivot = mat[l];
7107: s = sugar[l];
7108: for ( i = 0; i < l; i++ ) {
7109: t = mat[i];
7110: if ( a = t[j] ) {
7111: sugar[i] = MAX(sugar[i],s);
7112: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
7113: }
7114: }
7115: l--;
7116: }
7117: return rank;
1.77 noro 7118: }
7119:
7120: int ndv_ishomo(NDV p)
7121: {
1.157 noro 7122: NMV m;
7123: int len,h;
1.77 noro 7124:
1.157 noro 7125: if ( !p ) return 1;
7126: len = LEN(p);
7127: m = BDY(p);
7128: h = TD(DL(m));
7129: NMV_ADV(m);
7130: for ( len--; len; len--, NMV_ADV(m) )
7131: if ( TD(DL(m)) != h ) return 0;
7132: return 1;
1.77 noro 7133: }
7134:
7135: void ndv_save(NDV p,int index)
7136: {
1.157 noro 7137: FILE *s;
7138: char name[BUFSIZ];
7139: short id;
7140: int nv,sugar,len,n,i,td,e,j;
7141: NMV m;
7142: unsigned int *dl;
7143: int mpos;
7144:
7145: sprintf(name,"%s/%d",Demand,index);
7146: s = fopen(name,"w");
7147: savevl(s,0);
7148: if ( !p ) {
7149: saveobj(s,0);
7150: return;
7151: }
7152: id = O_DP;
7153: nv = NV(p);
7154: sugar = SG(p);
7155: len = LEN(p);
7156: write_short(s,&id); write_int(s,&nv); write_int(s,&sugar);
7157: write_int(s,&len);
7158:
7159: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7160: saveobj(s,(Obj)CQ(m));
7161: dl = DL(m);
7162: td = TD(dl);
7163: write_int(s,&td);
7164: for ( j = 0; j < nv; j++ ) {
7165: e = GET_EXP(dl,j);
7166: write_int(s,&e);
7167: }
7168: if ( nd_module ) {
7169: mpos = MPOS(dl); write_int(s,&mpos);
7170: }
7171: }
7172: fclose(s);
1.77 noro 7173: }
7174:
1.206 noro 7175: void nd_save_mod(ND p,int index)
7176: {
7177: FILE *s;
7178: char name[BUFSIZ];
7179: int nv,sugar,len,c;
7180: NM m;
7181:
7182: sprintf(name,"%s/%d",Demand,index);
7183: s = fopen(name,"w");
7184: if ( !p ) {
7185: len = 0;
7186: write_int(s,&len);
7187: fclose(s);
7188: return;
7189: }
7190: nv = NV(p);
7191: sugar = SG(p);
7192: len = LEN(p);
7193: write_int(s,&nv); write_int(s,&sugar); write_int(s,&len);
7194: for ( m = BDY(p); m; m = NEXT(m) ) {
7195: c = CM(m); write_int(s,&c);
7196: write_intarray(s,DL(m),nd_wpd);
7197: }
7198: fclose(s);
7199: }
7200:
1.77 noro 7201: NDV ndv_load(int index)
7202: {
1.157 noro 7203: FILE *s;
7204: char name[BUFSIZ];
7205: short id;
7206: int nv,sugar,len,n,i,td,e,j;
7207: NDV d;
7208: NMV m0,m;
7209: unsigned int *dl;
7210: Obj obj;
7211: int mpos;
7212:
7213: sprintf(name,"%s/%d",Demand,index);
7214: s = fopen(name,"r");
7215: if ( !s ) return 0;
7216:
7217: skipvl(s);
7218: read_short(s,&id);
7219: if ( !id ) return 0;
7220: read_int(s,&nv);
7221: read_int(s,&sugar);
7222: read_int(s,&len);
7223:
7224: m0 = m = MALLOC(len*nmv_adv);
7225: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7226: loadobj(s,&obj); CQ(m) = (Q)obj;
7227: dl = DL(m);
7228: ndl_zero(dl);
7229: read_int(s,&td); TD(dl) = td;
7230: for ( j = 0; j < nv; j++ ) {
7231: read_int(s,&e);
7232: PUT_EXP(dl,j,e);
7233: }
7234: if ( nd_module ) {
7235: read_int(s,&mpos); MPOS(dl) = mpos;
7236: }
7237: if ( nd_blockmask ) ndl_weight_mask(dl);
7238: }
7239: fclose(s);
7240: MKNDV(nv,m0,len,d);
7241: SG(d) = sugar;
7242: return d;
1.99 noro 7243: }
7244:
1.206 noro 7245: ND nd_load_mod(int index)
7246: {
7247: FILE *s;
7248: char name[BUFSIZ];
7249: int nv,sugar,len,i,c;
7250: ND d;
7251: NM m0,m;
7252:
7253: sprintf(name,"%s/%d",Demand,index);
7254: s = fopen(name,"r");
7255: /* if the file does not exist, it means p[index]=0 */
7256: if ( !s ) return 0;
7257:
7258: read_int(s,&nv);
7259: if ( !nv ) { fclose(s); return 0; }
7260:
7261: read_int(s,&sugar);
7262: read_int(s,&len);
7263: for ( m0 = 0, i = 0; i < len; i++ ) {
7264: NEXTNM(m0,m);
7265: read_int(s,&c); CM(m) = c;
7266: read_intarray(s,DL(m),nd_wpd);
7267: }
7268: NEXT(m) = 0;
7269: MKND(nv,m0,len,d);
7270: SG(d) = sugar;
7271: fclose(s);
7272: return d;
7273: }
7274:
1.102 noro 7275: void nd_det(int mod,MAT f,P *rp)
1.99 noro 7276: {
1.157 noro 7277: VL fv,tv;
7278: int n,i,j,max,e,nvar,sgn,k0,l0,len0,len,k,l,a;
7279: pointer **m;
7280: Q mone;
7281: P **w;
7282: P mp,r;
7283: NDV **dm;
7284: NDV *t,*mi,*mj;
7285: NDV d,s,mij,mjj;
7286: ND u;
7287: NMV nmv;
7288: UINT *bound;
7289: PGeoBucket bucket;
7290: struct order_spec *ord;
7291: Q dq,dt,ds;
7292: N gn,qn,dn0,nm,dn;
7293:
7294: create_order_spec(0,0,&ord);
7295: nd_init_ord(ord);
7296: get_vars((Obj)f,&fv);
7297: if ( f->row != f->col )
7298: error("nd_det : non-square matrix");
7299: n = f->row;
7300: m = f->body;
7301: for ( nvar = 0, tv = fv; tv; tv = NEXT(tv), nvar++ );
7302:
7303: if ( !nvar ) {
7304: if ( !mod )
7305: detp(CO,(P **)m,n,rp);
7306: else {
7307: w = (P **)almat_pointer(n,n);
7308: for ( i = 0; i < n; i++ )
7309: for ( j = 0; j < n; j++ )
7310: ptomp(mod,(P)m[i][j],&w[i][j]);
7311: detmp(CO,mod,w,n,&mp);
7312: mptop(mp,rp);
7313: }
7314: return;
7315: }
7316:
7317: if ( !mod ) {
7318: w = (P **)almat_pointer(n,n);
7319: dq = ONE;
7320: for ( i = 0; i < n; i++ ) {
7321: dn0 = ONEN;
7322: for ( j = 0; j < n; j++ ) {
7323: if ( !m[i][j] ) continue;
7324: lgp(m[i][j],&nm,&dn);
7325: gcdn(dn0,dn,&gn); divsn(dn0,gn,&qn); muln(qn,dn,&dn0);
7326: }
7327: if ( !UNIN(dn0) ) {
7328: NTOQ(dn0,1,ds);
7329: for ( j = 0; j < n; j++ )
7330: mulp(CO,(P)m[i][j],(P)ds,&w[i][j]);
7331: mulq(dq,ds,&dt); dq = dt;
7332: } else
7333: for ( j = 0; j < n; j++ )
7334: w[i][j] = (P)m[i][j];
7335: }
7336: m = (pointer **)w;
7337: }
7338:
1.178 noro 7339: for ( i = 0, max = 1; i < n; i++ )
1.157 noro 7340: for ( j = 0; j < n; j++ )
7341: for ( tv = fv; tv; tv = NEXT(tv) ) {
7342: e = getdeg(tv->v,(P)m[i][j]);
7343: max = MAX(e,max);
7344: }
7345: nd_setup_parameters(nvar,max);
7346: dm = (NDV **)almat_pointer(n,n);
1.178 noro 7347: for ( i = 0, max = 1; i < n; i++ )
1.157 noro 7348: for ( j = 0; j < n; j++ ) {
7349: dm[i][j] = ptondv(CO,fv,m[i][j]);
7350: if ( mod ) ndv_mod(mod,dm[i][j]);
7351: if ( dm[i][j] && !LEN(dm[i][j]) ) dm[i][j] = 0;
7352: }
7353: d = ptondv(CO,fv,(P)ONE);
7354: if ( mod ) ndv_mod(mod,d);
7355: chsgnq(ONE,&mone);
7356: for ( j = 0, sgn = 1; j < n; j++ ) {
7357: if ( DP_Print ) fprintf(stderr,".",j);
7358: for ( i = j; i < n && !dm[i][j]; i++ );
7359: if ( i == n ) {
7360: *rp = 0;
7361: return;
7362: }
7363: k0 = i; l0 = j; len0 = LEN(dm[k0][l0]);
7364: for ( k = j; k < n; k++ )
7365: for ( l = j; l < n; l++ )
7366: if ( dm[k][l] && LEN(dm[k][l]) < len0 ) {
7367: k0 = k; l0 = l; len0 = LEN(dm[k][l]);
7368: }
7369: if ( k0 != j ) {
7370: t = dm[j]; dm[j] = dm[k0]; dm[k0] = t;
7371: sgn = -sgn;
7372: }
7373: if ( l0 != j ) {
7374: for ( k = j; k < n; k++ ) {
7375: s = dm[k][j]; dm[k][j] = dm[k][l0]; dm[k][l0] = s;
7376: }
7377: sgn = -sgn;
7378: }
7379: bound = nd_det_compute_bound(dm,n,j);
7380: for ( k = 0; k < nd_nvar; k++ )
7381: if ( bound[k]*2 > nd_mask0 ) break;
7382: if ( k < nd_nvar )
7383: nd_det_reconstruct(dm,n,j,d);
7384:
7385: for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) {
7386: /* if ( DP_Print ) fprintf(stderr," i=%d\n ",i); */
7387: mi = dm[i]; mij = mi[j];
7388: if ( mod )
7389: ndv_mul_c(mod,mij,mod-1);
7390: else
7391: ndv_mul_c_q(mij,mone);
7392: for ( k = j+1; k < n; k++ ) {
7393: /* if ( DP_Print ) fprintf(stderr,"k=%d ",k); */
7394: bucket = create_pbucket();
7395: if ( mi[k] ) {
7396: nmv = BDY(mjj); len = LEN(mjj);
7397: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
7398: u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d)));
7399: add_pbucket(mod,bucket,u);
7400: }
7401: }
7402: if ( mj[k] && mij ) {
7403: nmv = BDY(mij); len = LEN(mij);
7404: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
7405: u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d)));
7406: add_pbucket(mod,bucket,u);
7407: }
7408: }
7409: u = nd_quo(mod,bucket,d);
7410: mi[k] = ndtondv(mod,u);
7411: }
7412: /* if ( DP_Print ) fprintf(stderr,"\n",k); */
7413: }
7414: d = mjj;
7415: }
7416: if ( DP_Print ) fprintf(stderr,"\n",k);
7417: if ( sgn < 0 )
7418: if ( mod )
7419: ndv_mul_c(mod,d,mod-1);
7420: else
7421: ndv_mul_c_q(d,mone);
7422: r = ndvtop(mod,CO,fv,d);
7423: if ( !mod && !UNIQ(dq) )
7424: divsp(CO,r,(P)dq,rp);
7425: else
7426: *rp = r;
1.99 noro 7427: }
7428:
1.102 noro 7429: ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d)
1.99 noro 7430: {
1.157 noro 7431: NM mr,mr0;
7432: NM tnm;
7433: NMV m;
7434: UINT *d0,*dt,*dm;
7435: int c,n,td,i,c1,c2,len;
7436: Q q;
7437: ND r;
7438:
7439: if ( !p ) return 0;
7440: else {
7441: n = NV(p); m = BDY(p); len = LEN(p);
7442: d0 = DL(m0);
7443: td = TD(d);
7444: mr0 = 0;
7445: NEWNM(tnm);
7446: if ( mod ) {
7447: c = CM(m0);
7448: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7449: ndl_add(DL(m),d0,DL(tnm));
7450: if ( ndl_reducible(DL(tnm),d) ) {
7451: NEXTNM(mr0,mr);
7452: c1 = CM(m); DMAR(c1,c,0,mod,c2); CM(mr) = c2;
7453: ndl_copy(DL(tnm),DL(mr));
7454: }
7455: }
7456: } else {
7457: q = CQ(m0);
7458: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7459: ndl_add(DL(m),d0,DL(tnm));
7460: if ( ndl_reducible(DL(tnm),d) ) {
7461: NEXTNM(mr0,mr);
7462: mulq(CQ(m),q,&CQ(mr));
7463: ndl_copy(DL(tnm),DL(mr));
7464: }
7465: }
7466: }
7467: if ( !mr0 )
7468: return 0;
7469: else {
7470: NEXT(mr) = 0;
7471: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
7472: MKND(NV(p),mr0,len,r);
7473: SG(r) = SG(p) + TD(d0);
7474: return r;
7475: }
7476: }
1.114 noro 7477: }
7478:
7479: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d)
7480: {
1.157 noro 7481: int i,obpe,oadv,h,k,l;
7482: static NM prev_nm_free_list;
7483: EPOS oepos;
7484:
7485: obpe = nd_bpe;
7486: oadv = nmv_adv;
7487: oepos = nd_epos;
7488: if ( obpe < 2 ) nd_bpe = 2;
7489: else if ( obpe < 3 ) nd_bpe = 3;
7490: else if ( obpe < 4 ) nd_bpe = 4;
7491: else if ( obpe < 5 ) nd_bpe = 5;
7492: else if ( obpe < 6 ) nd_bpe = 6;
7493: else if ( obpe < 8 ) nd_bpe = 8;
7494: else if ( obpe < 10 ) nd_bpe = 10;
7495: else if ( obpe < 16 ) nd_bpe = 16;
7496: else if ( obpe < 32 ) nd_bpe = 32;
7497: else error("nd_det_reconstruct : exponent too large");
7498:
7499: nd_setup_parameters(nd_nvar,0);
7500: prev_nm_free_list = _nm_free_list;
7501: _nm_free_list = 0;
7502: for ( k = j; k < n; k++ )
7503: for (l = j; l < n; l++ )
7504: ndv_realloc(dm[k][l],obpe,oadv,oepos);
7505: ndv_realloc(d,obpe,oadv,oepos);
7506: prev_nm_free_list = 0;
1.114 noro 7507: #if 0
1.157 noro 7508: GC_gcollect();
1.114 noro 7509: #endif
7510: }
7511:
1.153 noro 7512: /* returns a UINT array containing degree bounds */
7513:
1.114 noro 7514: UINT *nd_det_compute_bound(NDV **dm,int n,int j)
7515: {
1.157 noro 7516: UINT *d0,*d1,*d,*t,*r;
7517: int k,l,i;
1.114 noro 7518:
1.157 noro 7519: d0 = (UINT *)MALLOC(nd_nvar*sizeof(UINT));
7520: for ( k = 0; k < nd_nvar; k++ ) d0[k] = 0;
7521: for ( k = j; k < n; k++ )
7522: for ( l = j; l < n; l++ )
7523: if ( dm[k][l] ) {
7524: d = ndv_compute_bound(dm[k][l]);
7525: for ( i = 0; i < nd_nvar; i++ )
7526: d0[i] = MAX(d0[i],d[i]);
7527: }
7528: return d0;
1.117 noro 7529: }
7530:
7531: DL nd_separate_d(UINT *d,UINT *trans)
7532: {
1.157 noro 7533: int n,td,i,e,j;
7534: DL a;
1.117 noro 7535:
1.157 noro 7536: ndl_zero(trans);
7537: td = 0;
7538: for ( i = 0; i < nd_ntrans; i++ ) {
7539: e = GET_EXP(d,i);
7540: PUT_EXP(trans,i,e);
7541: td += MUL_WEIGHT(e,i);
7542: }
7543: if ( nd_ntrans+nd_nalg < nd_nvar ) {
7544: /* homogenized */
7545: i = nd_nvar-1;
7546: e = GET_EXP(d,i);
7547: PUT_EXP(trans,i,e);
7548: td += MUL_WEIGHT(e,i);
7549: }
7550: TD(trans) = td;
7551: if ( nd_blockmask) ndl_weight_mask(trans);
7552: NEWDL(a,nd_nalg);
7553: td = 0;
7554: for ( i = 0; i < nd_nalg; i++ ) {
7555: j = nd_ntrans+i;
7556: e = GET_EXP(d,j);
7557: a->d[i] = e;
7558: td += e;
7559: }
7560: a->td = td;
7561: return a;
1.117 noro 7562: }
7563:
1.118 noro 7564: int nd_monic(int mod,ND *p)
1.117 noro 7565: {
1.157 noro 7566: UINT *trans,*t;
7567: DL alg;
7568: MP mp0,mp;
7569: NM m,m0,m1,ma0,ma,mb,mr0,mr;
7570: ND r;
7571: DL dl;
7572: DP nm;
7573: NDV ndv;
7574: DAlg inv,cd;
7575: ND s,c;
7576: Q l,mul;
7577: N ln;
7578: int n,ntrans,i,e,td,is_lc,len;
7579: NumberField nf;
7580: struct oEGT eg0,eg1;
7581:
7582: if ( !(nf = get_numberfield()) )
7583: error("nd_monic : current_numberfield is not set");
7584:
7585: /* Q coef -> DAlg coef */
7586: NEWNM(ma0); ma = ma0;
7587: m = BDY(*p);
7588: is_lc = 1;
7589: while ( 1 ) {
7590: NEWMP(mp0); mp = mp0;
7591: mp->c = (P)CQ(m);
7592: mp->dl = nd_separate_d(DL(m),DL(ma));
7593: NEWNM(mb);
7594: for ( m = NEXT(m); m; m = NEXT(m) ) {
7595: alg = nd_separate_d(DL(m),DL(mb));
7596: if ( !ndl_equal(DL(ma),DL(mb)) )
7597: break;
7598: NEXTMP(mp0,mp); mp->c = (P)CQ(m); mp->dl = alg;
7599: }
7600: NEXT(mp) = 0;
7601: MKDP(nd_nalg,mp0,nm);
7602: MKDAlg(nm,ONE,cd);
7603: if ( is_lc == 1 ) {
7604: /* if the lc is a rational number, we have nothing to do */
7605: if ( !mp0->dl->td )
7606: return 1;
7607:
7608: get_eg(&eg0);
7609: invdalg(cd,&inv);
7610: get_eg(&eg1); add_eg(&eg_invdalg,&eg0,&eg1);
7611: /* check the validity of inv */
7612: if ( mod && !rem(NM(inv->dn),mod) )
7613: return 0;
7614: CA(ma) = nf->one;
7615: is_lc = 0;
7616: ln = ONEN;
7617: } else {
7618: muldalg(cd,inv,&CA(ma));
7619: lcmn(ln,NM(CA(ma)->dn),&ln);
7620: }
7621: if ( m ) {
7622: NEXT(ma) = mb; ma = mb;
7623: } else {
7624: NEXT(ma) = 0;
7625: break;
7626: }
7627: }
7628: /* l = lcm(denoms) */
7629: NTOQ(ln,1,l);
7630: for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) {
7631: divq(l,CA(m)->dn,&mul);
7632: for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) {
7633: NEXTNM(mr0,mr);
7634: mulq((Q)mp->c,mul,&CQ(mr));
7635: dl = mp->dl;
7636: td = TD(DL(m));
7637: ndl_copy(DL(m),DL(mr));
7638: for ( i = 0; i < nd_nalg; i++ ) {
7639: e = dl->d[i];
7640: PUT_EXP(DL(mr),i+nd_ntrans,e);
7641: td += MUL_WEIGHT(e,i+nd_ntrans);
7642: }
1.163 noro 7643: if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m));
1.157 noro 7644: TD(DL(mr)) = td;
7645: if ( nd_blockmask) ndl_weight_mask(DL(mr));
7646: }
7647: }
7648: NEXT(mr) = 0;
7649: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
7650: MKND(NV(*p),mr0,len,r);
7651: /* XXX */
7652: SG(r) = SG(*p);
7653: nd_free(*p);
7654: *p = r;
7655: return 1;
1.59 noro 7656: }
1.167 noro 7657:
7658: NODE reverse_node(NODE n)
7659: {
7660: NODE t,t1;
7661:
7662: for ( t = 0; n; n = NEXT(n) ) {
7663: MKNODE(t1,BDY(n),t); t = t1;
7664: }
7665: return t;
7666: }
7667:
7668: P ndc_div(int mod,union oNDC a,union oNDC b)
7669: {
7670: union oNDC c;
7671: int inv,t;
7672:
7673: if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m));
7674: else if ( mod ) {
7675: inv = invm(b.m,mod);
7676: DMAR(a.m,inv,0,mod,t); c.m = t;
7677: } else if ( nd_vc )
7678: divsp(nd_vc,a.p,b.p,&c.p);
7679: else
7680: divq(a.z,b.z,&c.z);
7681: return ndctop(mod,c);
7682: }
7683:
7684: P ndctop(int mod,union oNDC c)
7685: {
7686: Q q;
7687: int e;
7688: GFS gfs;
7689:
7690: if ( mod == -1 ) {
7691: e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs;
7692: } else if ( mod ) {
7693: STOQ(c.m,q); return (P)q;
7694: } else
7695: return (P)c.p;
7696: }
7697:
7698: /* [0,0,0,cont] = p -> p/cont */
7699:
7700: void finalize_tracelist(int i,P cont)
7701: {
7702: LIST l;
7703: NODE node;
7704: Q iq;
7705:
7706: if ( !UNIQ(cont) ) {
1.196 noro 7707: node = mknode(4,NULLP,NULLP,NULLP,cont);
1.167 noro 7708: MKLIST(l,node); MKNODE(node,l,nd_tracelist);
7709: nd_tracelist = node;
7710: }
7711: STOQ(i,iq);
7712: nd_tracelist = reverse_node(nd_tracelist);
7713: MKLIST(l,nd_tracelist);
7714: node = mknode(2,iq,l); MKLIST(l,node);
7715: MKNODE(node,l,nd_alltracelist); MKLIST(l,node);
7716: nd_alltracelist = node; nd_tracelist = 0;
7717: }
7718:
7719: void conv_ilist(int demand,int trace,NODE g,int **indp)
7720: {
7721: int n,i,j;
7722: int *ind;
7723: NODE t;
7724:
7725: n = length(g);
7726: ind = (int *)MALLOC(n*sizeof(int));
7727: for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) {
7728: j = (long)BDY(t); ind[i] = j;
7729: BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j]));
7730: }
7731: if ( indp ) *indp = ind;
7732: }
1.172 noro 7733:
7734: void parse_nd_option(NODE opt)
7735: {
1.187 noro 7736: NODE t,p,u;
7737: int i,s;
1.172 noro 7738: char *key;
7739: Obj value;
7740:
1.187 noro 7741: nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_gbblock = 0;
1.208 noro 7742: nd_newelim = 0; nd_intersect = 0; nd_nzlist = 0;
1.209 noro 7743: nd_splist = 0; nd_check_splist = 0;
1.172 noro 7744: for ( t = opt; t; t = NEXT(t) ) {
7745: p = BDY((LIST)BDY(t));
7746: key = BDY((STRING)BDY(p));
7747: value = (Obj)BDY(NEXT(p));
7748: if ( !strcmp(key,"gentrace") )
7749: nd_gentrace = value?1:0;
7750: else if ( !strcmp(key,"gensyz") )
7751: nd_gensyz = value?1:0;
1.173 noro 7752: else if ( !strcmp(key,"nora") )
7753: nd_nora = value?1:0;
1.187 noro 7754: else if ( !strcmp(key,"gbblock") ) {
7755: if ( !value || OID(value) != O_LIST )
7756: error("nd_* : invalid value for gbblock option");
7757: u = BDY((LIST)value);
1.189 noro 7758: nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int));
1.187 noro 7759: for ( i = 0; u; u = NEXT(u) ) {
7760: p = BDY((LIST)BDY(u));
7761: s = nd_gbblock[i++] = QTOS((Q)BDY(p));
7762: nd_gbblock[i++] = s+QTOS((Q)BDY(NEXT(p)))-1;
7763: }
7764: nd_gbblock[i] = -1;
1.192 noro 7765: } else if ( !strcmp(key,"newelim") )
7766: nd_newelim = value?1:0;
1.195 noro 7767: else if ( !strcmp(key,"intersect") )
7768: nd_intersect = value?1:0;
1.208 noro 7769: else if ( !strcmp(key,"trace") ) {
7770: u = BDY((LIST)value);
7771: nd_nzlist = BDY((LIST)ARG2(u));
7772: nd_bpe = QTOS((Q)ARG3(u));
1.209 noro 7773: } else if ( !strcmp(key,"splist") )
7774: nd_splist = value?1:0;
7775: else if ( !strcmp(key,"check_splist") ) {
7776: nd_check_splist = BDY((LIST)value);
1.208 noro 7777: }
1.172 noro 7778: }
7779: }
1.204 noro 7780:
7781: ND mdptond(DP d);
7782: ND nd_mul_nm(int mod,NM m0,ND p);
1.207 noro 7783: ND *btog(NODE ti,ND **p,int nb,int mod);
7784: ND btog_one(NODE ti,ND *p,int nb,int mod);
1.204 noro 7785: MAT nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,MAT *rp);
1.205 noro 7786: VECT nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos,MAT *rp);
1.204 noro 7787:
7788: /* d:monomial */
7789: ND mdptond(DP d)
7790: {
7791: NM m;
7792: ND r;
7793:
7794: if ( OID(d) == 1 )
7795: r = ptond(CO,CO,(P)d);
7796: else {
7797: NEWNM(m);
7798: dltondl(NV(d),BDY(d)->dl,DL(m));
7799: CQ(m) = (Q)BDY(d)->c;
7800: NEXT(m) = 0;
7801: MKND(NV(d),m,1,r);
7802: }
7803: return r;
7804: }
7805:
7806: ND nd_mul_nm(int mod,NM m0,ND p)
7807: {
7808: UINT *d0;
7809: int c0,c1,c;
7810: NM tm,mr,mr0;
7811: ND r;
7812:
7813: if ( !p ) return 0;
7814: d0 = DL(m0);
7815: c0 = CM(m0);
7816: mr0 = 0;
7817: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
7818: NEXTNM(mr0,mr);
7819: c = CM(tm); DMAR(c0,c,0,mod,c1); CM(mr) = c1;
7820: ndl_add(d0,DL(tm),DL(mr));
7821: }
7822: NEXT(mr) = 0;
7823: MKND(NV(p),mr0,LEN(p),r);
7824: return r;
7825: }
7826:
1.207 noro 7827: ND *btog(NODE ti,ND **p,int nb,int mod)
1.204 noro 7828: {
7829: PGeoBucket *r;
7830: int i,ci;
7831: NODE t,s;
7832: ND m,tp;
7833: ND *pi,*rd;
7834: P c;
7835:
7836: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
7837: for ( i = 0; i < nb; i++ )
7838: r[i] = create_pbucket();
7839: for ( t = ti; t; t = NEXT(t) ) {
7840: s = BDY((LIST)BDY(t));
7841: if ( ARG0(s) ) {
7842: m = mdptond((DP)ARG2(s));
7843: ptomp(mod,(P)HCQ(m),&c);
7844: if ( ci = ((MQ)c)->cont ) {
7845: HCM(m) = ci;
7846: pi = p[QTOS((Q)ARG1(s))];
7847: for ( i = 0; i < nb; i++ ) {
7848: tp = nd_mul_nm(mod,BDY(m),pi[i]);
7849: add_pbucket(mod,r[i],tp);
7850: }
7851: }
7852: ci = 1;
7853: } else {
7854: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
7855: ci = invm(ci,mod);
7856: }
7857: }
7858: rd = (ND *)MALLOC(nb*sizeof(ND));
7859: for ( i = 0; i < nb; i++ )
7860: rd[i] = normalize_pbucket(mod,r[i]);
7861: if ( ci != 1 )
7862: for ( i = 0; i < nb; i++ ) nd_mul_c(mod,rd[i],ci);
7863: return rd;
7864: }
7865:
1.207 noro 7866: ND btog_one(NODE ti,ND *p,int nb,int mod)
1.205 noro 7867: {
7868: PGeoBucket r;
1.206 noro 7869: int i,ci,j;
1.205 noro 7870: NODE t,s;
7871: ND m,tp;
7872: ND pi,rd;
7873: P c;
7874:
7875: r = create_pbucket();
7876: for ( t = ti; t; t = NEXT(t) ) {
7877: s = BDY((LIST)BDY(t));
7878: if ( ARG0(s) ) {
7879: m = mdptond((DP)ARG2(s));
7880: ptomp(mod,(P)HCQ(m),&c);
7881: if ( ci = ((MQ)c)->cont ) {
7882: HCM(m) = ci;
1.206 noro 7883: pi = p[j=QTOS((Q)ARG1(s))];
7884: if ( !pi ) {
7885: pi = nd_load_mod(j);
7886: tp = nd_mul_nm(mod,BDY(m),pi);
7887: nd_free(pi);
7888: add_pbucket(mod,r,tp);
7889: } else {
7890: tp = nd_mul_nm(mod,BDY(m),pi);
7891: add_pbucket(mod,r,tp);
7892: }
1.205 noro 7893: }
7894: ci = 1;
7895: } else {
7896: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
7897: ci = invm(ci,mod);
7898: }
7899: }
7900: rd = normalize_pbucket(mod,r);
1.206 noro 7901: free_pbucket(r);
1.205 noro 7902: if ( ci != 1 ) nd_mul_c(mod,rd,ci);
7903: return rd;
7904: }
1.204 noro 7905:
7906: MAT nd_btog(LIST f,LIST v,int mod,struct order_spec *ord,LIST tlist,MAT *rp)
7907: {
7908: int i,j,n,m,nb,pi0,pi1,nvar;
7909: VL fv,tv,vv;
7910: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
7911: ND **p;
7912: ND *c;
7913: ND u;
7914: P inv;
7915: MAT mat;
7916:
7917: parse_nd_option(current_option);
7918: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
7919: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
7920: switch ( ord->id ) {
7921: case 1:
7922: if ( ord->nv != nvar )
7923: error("nd_check : invalid order specification");
7924: break;
7925: default:
7926: break;
7927: }
7928: nd_init_ord(ord);
7929: #if 0
7930: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
7931: #else
7932: nd_bpe = 32;
7933: #endif
7934: nd_setup_parameters(nvar,0);
7935: permtrace = BDY((LIST)ARG2(BDY(tlist)));
7936: intred = BDY((LIST)ARG3(BDY(tlist)));
7937: ind = BDY((LIST)ARG4(BDY(tlist)));
7938: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
7939: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
7940: j = QTOS((Q)BDY(BDY((LIST)BDY(t))));
7941: if ( j > i ) i = j;
7942: }
7943: n = i+1;
7944: nb = length(BDY(f));
7945: p = (ND **)MALLOC(n*sizeof(ND *));
7946: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
7947: pi = BDY((LIST)BDY(t));
7948: pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi));
7949: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
7950: ptomp(mod,(P)ARG2(pi),&inv);
7951: u = ptond(CO,vv,(P)ONE);
7952: HCM(u) = ((MQ)inv)->cont;
7953: c[pi1] = u;
7954: }
7955: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
7956: printf("%d ",i); fflush(stdout);
7957: ti = BDY((LIST)BDY(t));
1.207 noro 7958: p[j=QTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.204 noro 7959: if ( j == 441 )
7960: printf("afo");
7961: }
7962: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
7963: printf("%d ",i); fflush(stdout);
7964: ti = BDY((LIST)BDY(t));
1.207 noro 7965: p[j=QTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.204 noro 7966: if ( j == 441 )
7967: printf("afo");
7968: }
7969: m = length(ind);
7970: MKMAT(mat,nb,m);
7971: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
7972: for ( i = 0, c = p[QTOS((Q)BDY(t))]; i < nb; i++ )
7973: BDY(mat)[i][j] = ndtodp(mod,c[i]);
7974: return mat;
7975: }
7976:
1.205 noro 7977: VECT nd_btog_one(LIST f,LIST v,int mod,struct order_spec *ord,
7978: LIST tlist,int pos,MAT *rp)
7979: {
7980: int i,j,n,m,nb,pi0,pi1,nvar;
7981: VL fv,tv,vv;
7982: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
7983: ND *p;
7984: ND *c;
7985: ND u;
7986: P inv;
7987: VECT vect;
7988:
7989: parse_nd_option(current_option);
7990: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
7991: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
7992: switch ( ord->id ) {
7993: case 1:
7994: if ( ord->nv != nvar )
7995: error("nd_check : invalid order specification");
7996: break;
7997: default:
7998: break;
7999: }
8000: nd_init_ord(ord);
8001: #if 0
8002: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
8003: #else
8004: nd_bpe = 32;
8005: #endif
8006: nd_setup_parameters(nvar,0);
8007: permtrace = BDY((LIST)ARG2(BDY(tlist)));
8008: intred = BDY((LIST)ARG3(BDY(tlist)));
8009: ind = BDY((LIST)ARG4(BDY(tlist)));
8010: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
8011: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
8012: j = QTOS((Q)BDY(BDY((LIST)BDY(t))));
8013: if ( j > i ) i = j;
8014: }
8015: n = i+1;
8016: nb = length(BDY(f));
8017: p = (ND *)MALLOC(n*sizeof(ND *));
8018: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
8019: pi = BDY((LIST)BDY(t));
8020: pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi));
8021: if ( pi1 == pos ) {
8022: ptomp(mod,(P)ARG2(pi),&inv);
8023: u = ptond(CO,vv,(P)ONE);
8024: HCM(u) = ((MQ)inv)->cont;
8025: p[pi0] = u;
8026: }
8027: }
8028: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
8029: printf("%d ",i); fflush(stdout);
8030: ti = BDY((LIST)BDY(t));
1.207 noro 8031: p[j=QTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.206 noro 8032: if ( Demand ) {
8033: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
8034: }
1.205 noro 8035: }
8036: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
8037: printf("%d ",i); fflush(stdout);
8038: ti = BDY((LIST)BDY(t));
1.207 noro 8039: p[j=QTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.206 noro 8040: if ( Demand ) {
8041: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
8042: }
1.205 noro 8043: }
8044: m = length(ind);
8045: MKVECT(vect,m);
1.206 noro 8046: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) {
8047: u = p[QTOS((Q)BDY(t))];
8048: if ( !u ) {
8049: u = nd_load_mod(QTOS((Q)BDY(t)));
8050: BDY(vect)[j] = ndtodp(mod,u);
8051: nd_free(u);
8052: } else
8053: BDY(vect)[j] = ndtodp(mod,u);
8054: }
1.205 noro 8055: return vect;
8056: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>