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