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