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