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