Annotation of OpenXM_contrib2/asir2000/engine/nd.c, Revision 1.249
1.249 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.248 2019/03/03 05:21:16 noro Exp $ */
1.2 noro 2:
1.94 noro 3: #include "nd.h"
1.63 noro 4:
1.198 noro 5: struct oEGT eg_search;
6:
1.131 noro 7: int diag_period = 6;
1.202 noro 8: int weight_check = 1;
1.61 noro 9: int (*ndl_compare_function)(UINT *a1,UINT *a2);
1.94 noro 10: int nd_dcomp;
1.220 noro 11: int nd_rref2;
1.94 noro 12: NM _nm_free_list;
13: ND _nd_free_list;
14: ND_pairs _ndp_free_list;
1.150 noro 15: NODE nd_hcf;
1.32 noro 16:
1.219 noro 17: Obj nd_top_weight;
18:
1.146 noro 19: static NODE nd_subst;
20: static VL nd_vc;
1.121 noro 21: static int nd_ntrans;
1.117 noro 22: static int nd_nalg;
1.103 noro 23: #if 0
1.74 noro 24: static int ndv_alloc;
1.103 noro 25: #endif
1.87 noro 26: #if 1
1.69 noro 27: static int nd_f4_nsp=0x7fffffff;
1.87 noro 28: #else
29: static int nd_f4_nsp=50;
30: #endif
1.42 noro 31: static double nd_scale=2;
1.61 noro 32: static UINT **nd_bound;
1.42 noro 33: static struct order_spec *nd_ord;
34: static EPOS nd_epos;
1.43 noro 35: static BlockMask nd_blockmask;
1.42 noro 36: static int nd_nvar;
37: static int nd_isrlex;
38: static int nd_epw,nd_bpe,nd_wpd,nd_exporigin;
1.61 noro 39: static UINT nd_mask[32];
40: static UINT nd_mask0,nd_mask1;
1.42 noro 41:
1.20 noro 42: static NDV *nd_ps;
1.215 noro 43: static NDV *nd_ps_gz;
1.53 noro 44: static NDV *nd_ps_trace;
1.215 noro 45: static NDV *nd_ps_sym;
46: static NDV *nd_ps_trace_sym;
1.42 noro 47: static RHist *nd_psh;
48: static int nd_psn,nd_pslen;
49: static RHist *nd_red;
1.96 noro 50: static int *nd_work_vector;
51: static int **nd_matrix;
52: static int nd_matrix_len;
1.97 noro 53: static struct weight_or_block *nd_worb;
54: static int nd_worb_len;
1.42 noro 55: static int nd_found,nd_create,nd_notfirst;
56: static int nmv_adv;
1.77 noro 57: static int nd_demand;
1.174 noro 58: static int nd_module,nd_ispot,nd_mpos,nd_pot_nelim;
1.224 noro 59: static int nd_module_rank,nd_poly_weight_len;
60: static int *nd_poly_weight,*nd_module_weight;
1.167 noro 61: static NODE nd_tracelist;
62: static NODE nd_alltracelist;
1.234 noro 63: static int nd_gentrace,nd_gensyz,nd_nora,nd_newelim,nd_intersect,nd_lf;
1.187 noro 64: static int *nd_gbblock;
1.209 noro 65: static NODE nd_nzlist,nd_check_splist;
66: static int nd_splist;
1.231 noro 67: static int *nd_sugarweight;
1.241 noro 68: static int nd_f4red,nd_rank0,nd_last_nonzero;
1.1 noro 69:
1.119 noro 70: NumberField get_numberfield();
1.114 noro 71: UINT *nd_det_compute_bound(NDV **dm,int n,int j);
72: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d);
1.152 ohara 73: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr);
1.118 noro 74: int nd_monic(int m,ND *p);
1.129 noro 75: NDV plain_vect_to_ndv_q(Q *mat,int col,UINT *s0vect);
1.157 noro 76: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank);
77: NDV pltondv(VL vl,VL dvl,LIST p);
78: void pltozpl(LIST l,Q *cont,LIST *pp);
1.159 noro 79: void ndl_max(UINT *d1,unsigned *d2,UINT *d);
1.167 noro 80: void nmtodp(int mod,NM m,DP *r);
81: NODE reverse_node(NODE n);
82: P ndc_div(int mod,union oNDC a,union oNDC b);
83: P ndctop(int mod,union oNDC c);
84: void finalize_tracelist(int i,P cont);
85: void conv_ilist(int demand,int trace,NODE g,int **indp);
1.172 noro 86: void parse_nd_option(NODE opt);
1.198 noro 87: void dltondl(int n,DL dl,UINT *r);
88: DP ndvtodp(int mod,NDV p);
1.204 noro 89: DP ndtodp(int mod,ND p);
1.215 noro 90: NDV ndvtondvgz(NDV p);
91: NDV ndvgztondv(NDV p);
92: ND ndtondgz(ND p);
93: ND ndgztond(ND p);
1.114 noro 94:
1.221 ohara 95: void Pdp_set_weight(NODE,VECT *);
96: void Pox_cmo_rpc(NODE,Obj *);
97:
1.232 noro 98: ND nd_add_lf(ND p1,ND p2);
99: void nd_mul_c_lf(ND p,GZ mul);
100: void ndv_mul_c_lf(NDV p,GZ mul);
1.239 noro 101: NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
102: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz);
1.240 noro 103: NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
1.239 noro 104: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz);
1.234 noro 105: NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
1.232 noro 106: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred);
107: int nd_gauss_elim_lf(mpz_t **mat0,int *sugar,int row,int col,int *colstat);
1.234 noro 108: NODE nd_f4_lf_trace_main(int m,int **indp);
109: void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp);
1.249 ! noro 110: void addlf(Z a,Z b,Z *c);
! 111: void sublf(Z a,Z b,Z *c);
! 112: void mullf(Z a,Z b,Z *c);
! 113: void divlf(Z a,Z b,Z *c);
! 114: void chsgnlf(Z a,Z *c);
! 115: int cmplf(Z a,Z b);
! 116: void simplf(Z a,Z *b);
! 117: void simplf_force(Z a,Z *b);
! 118: void setmod_lf(Z p);
! 119: void lmtolf(LM f,Z *b);
! 120: void invgz(GZ n1,GZ *nq);
1.234 noro 121:
1.232 noro 122: extern int lf_lazy;
123: extern GZ current_mod_lf;
124:
1.228 noro 125: extern int Denominator,DP_Multiple,MaxDeg;
1.149 noro 126:
1.220 noro 127: #define BLEN (8*sizeof(unsigned long))
128:
129: typedef struct matrix {
130: int row,col;
131: unsigned long **a;
132: } *matrix;
133:
134:
1.1 noro 135: void nd_free_private_storage()
136: {
1.157 noro 137: _nm_free_list = 0;
138: _ndp_free_list = 0;
1.71 noro 139: #if 0
1.157 noro 140: GC_gcollect();
1.71 noro 141: #endif
1.1 noro 142: }
143:
144: void _NM_alloc()
145: {
1.157 noro 146: NM p;
147: int i;
1.1 noro 148:
1.157 noro 149: for ( i = 0; i < 1024; i++ ) {
1.200 noro 150: p = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1.157 noro 151: p->next = _nm_free_list; _nm_free_list = p;
152: }
1.1 noro 153: }
154:
1.220 noro 155: matrix alloc_matrix(int row,int col)
156: {
157: unsigned long **a;
158: int i,len,blen;
159: matrix mat;
160:
161: mat = (matrix)MALLOC(sizeof(struct matrix));
162: mat->row = row;
163: mat->col = col;
164: mat->a = a = (unsigned long **)MALLOC(row*sizeof(unsigned long *));
165: return mat;
166: }
167:
168:
1.1 noro 169: void _ND_alloc()
170: {
1.157 noro 171: ND p;
172: int i;
1.1 noro 173:
1.157 noro 174: for ( i = 0; i < 1024; i++ ) {
1.200 noro 175: p = (ND)MALLOC(sizeof(struct oND));
1.157 noro 176: p->body = (NM)_nd_free_list; _nd_free_list = p;
177: }
1.1 noro 178: }
179:
180: void _NDP_alloc()
181: {
1.157 noro 182: ND_pairs p;
183: int i;
1.1 noro 184:
1.157 noro 185: for ( i = 0; i < 1024; i++ ) {
1.200 noro 186: p = (ND_pairs)MALLOC(sizeof(struct oND_pairs)
1.157 noro 187: +(nd_wpd-1)*sizeof(UINT));
188: p->next = _ndp_free_list; _ndp_free_list = p;
189: }
1.1 noro 190: }
191:
1.30 noro 192: INLINE int nd_length(ND p)
1.1 noro 193: {
1.157 noro 194: NM m;
195: int i;
1.1 noro 196:
1.157 noro 197: if ( !p )
198: return 0;
199: else {
200: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
201: return i;
202: }
1.1 noro 203: }
204:
1.230 noro 205: extern int dp_negative_weight;
206:
1.61 noro 207: INLINE int ndl_reducible(UINT *d1,UINT *d2)
1.1 noro 208: {
1.157 noro 209: UINT u1,u2;
210: int i,j;
1.1 noro 211:
1.157 noro 212: if ( nd_module && (MPOS(d1) != MPOS(d2)) ) return 0;
213:
1.230 noro 214: if ( !dp_negative_weight && TD(d1) < TD(d2) ) return 0;
1.65 noro 215: #if USE_UNROLL
1.157 noro 216: switch ( nd_bpe ) {
217: case 3:
218: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
219: u1 = d1[i]; u2 = d2[i];
220: if ( (u1&0x38000000) < (u2&0x38000000) ) return 0;
221: if ( (u1& 0x7000000) < (u2& 0x7000000) ) return 0;
222: if ( (u1& 0xe00000) < (u2& 0xe00000) ) return 0;
223: if ( (u1& 0x1c0000) < (u2& 0x1c0000) ) return 0;
224: if ( (u1& 0x38000) < (u2& 0x38000) ) return 0;
225: if ( (u1& 0x7000) < (u2& 0x7000) ) return 0;
226: if ( (u1& 0xe00) < (u2& 0xe00) ) return 0;
227: if ( (u1& 0x1c0) < (u2& 0x1c0) ) return 0;
228: if ( (u1& 0x38) < (u2& 0x38) ) return 0;
229: if ( (u1& 0x7) < (u2& 0x7) ) return 0;
230: }
231: return 1;
232: break;
233: case 4:
234: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
235: u1 = d1[i]; u2 = d2[i];
236: if ( (u1&0xf0000000) < (u2&0xf0000000) ) return 0;
237: if ( (u1& 0xf000000) < (u2& 0xf000000) ) return 0;
238: if ( (u1& 0xf00000) < (u2& 0xf00000) ) return 0;
239: if ( (u1& 0xf0000) < (u2& 0xf0000) ) return 0;
240: if ( (u1& 0xf000) < (u2& 0xf000) ) return 0;
241: if ( (u1& 0xf00) < (u2& 0xf00) ) return 0;
242: if ( (u1& 0xf0) < (u2& 0xf0) ) return 0;
243: if ( (u1& 0xf) < (u2& 0xf) ) return 0;
244: }
245: return 1;
246: break;
247: case 6:
248: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
249: u1 = d1[i]; u2 = d2[i];
250: if ( (u1&0x3f000000) < (u2&0x3f000000) ) return 0;
251: if ( (u1& 0xfc0000) < (u2& 0xfc0000) ) return 0;
252: if ( (u1& 0x3f000) < (u2& 0x3f000) ) return 0;
253: if ( (u1& 0xfc0) < (u2& 0xfc0) ) return 0;
254: if ( (u1& 0x3f) < (u2& 0x3f) ) return 0;
255: }
256: return 1;
257: break;
258: case 8:
259: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
260: u1 = d1[i]; u2 = d2[i];
261: if ( (u1&0xff000000) < (u2&0xff000000) ) return 0;
262: if ( (u1& 0xff0000) < (u2& 0xff0000) ) return 0;
263: if ( (u1& 0xff00) < (u2& 0xff00) ) return 0;
264: if ( (u1& 0xff) < (u2& 0xff) ) return 0;
265: }
266: return 1;
267: break;
268: case 16:
269: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
270: u1 = d1[i]; u2 = d2[i];
271: if ( (u1&0xffff0000) < (u2&0xffff0000) ) return 0;
272: if ( (u1& 0xffff) < (u2& 0xffff) ) return 0;
273: }
274: return 1;
275: break;
276: case 32:
277: for ( i = nd_exporigin; i < nd_wpd; i++ )
278: if ( d1[i] < d2[i] ) return 0;
279: return 1;
280: break;
281: default:
282: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
283: u1 = d1[i]; u2 = d2[i];
284: for ( j = 0; j < nd_epw; j++ )
285: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
286: }
287: return 1;
288: }
1.65 noro 289: #else
1.157 noro 290: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
291: u1 = d1[i]; u2 = d2[i];
292: for ( j = 0; j < nd_epw; j++ )
293: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
294: }
295: return 1;
1.65 noro 296: #endif
1.1 noro 297: }
298:
1.61 noro 299: /*
300: * If the current order is a block order,
301: * then the last block is length 1 and contains
302: * the homo variable. Otherwise, the original
303: * order is either 0 or 2.
304: */
305:
1.164 noro 306: void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepos,int ompos,int weight)
1.23 noro 307: {
1.157 noro 308: int w,i,e,n,omask0;
1.61 noro 309:
1.157 noro 310: omask0 = obpe==32?0xffffffff:((1<<obpe)-1);
311: n = nd_nvar-1;
312: ndl_zero(r);
313: for ( i = 0; i < n; i++ ) {
314: e = GET_EXP_OLD(d,i);
315: PUT_EXP(r,i,e);
316: }
317: w = TD(d);
318: PUT_EXP(r,nd_nvar-1,weight-w);
1.164 noro 319: if ( nd_module ) MPOS(r) = d[ompos];
1.157 noro 320: TD(r) = weight;
321: if ( nd_blockmask ) ndl_weight_mask(r);
1.61 noro 322: }
323:
324: void ndl_dehomogenize(UINT *d)
325: {
1.157 noro 326: UINT mask;
327: UINT h;
328: int i,bits;
329:
330: if ( nd_blockmask ) {
331: h = GET_EXP(d,nd_nvar-1);
332: XOR_EXP(d,nd_nvar-1,h);
333: TD(d) -= h;
334: ndl_weight_mask(d);
335: } else {
336: if ( nd_isrlex ) {
337: if ( nd_bpe == 32 ) {
338: h = d[nd_exporigin];
339: for ( i = nd_exporigin+1; i < nd_wpd; i++ )
340: d[i-1] = d[i];
341: d[i-1] = 0;
342: TD(d) -= h;
343: } else {
344: bits = nd_epw*nd_bpe;
345: mask = bits==32?0xffffffff:((1<<(nd_epw*nd_bpe))-1);
346: h = (d[nd_exporigin]>>((nd_epw-1)*nd_bpe))&nd_mask0;
347: for ( i = nd_exporigin; i < nd_wpd; i++ )
348: d[i] = ((d[i]<<nd_bpe)&mask)
349: |(i+1<nd_wpd?((d[i+1]>>((nd_epw-1)*nd_bpe))&nd_mask0):0);
350: TD(d) -= h;
351: }
352: } else {
353: h = GET_EXP(d,nd_nvar-1);
354: XOR_EXP(d,nd_nvar-1,h);
355: TD(d) -= h;
356: }
357: }
1.23 noro 358: }
359:
1.61 noro 360: void ndl_lcm(UINT *d1,unsigned *d2,UINT *d)
1.1 noro 361: {
1.157 noro 362: UINT t1,t2,u,u1,u2;
363: int i,j,l;
364:
365: if ( nd_module && (MPOS(d1) != MPOS(d2)) )
366: error("ndl_lcm : inconsistent monomials");
367: #if USE_UNROLL
368: switch ( nd_bpe ) {
369: case 3:
370: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
371: u1 = d1[i]; u2 = d2[i];
372: t1 = (u1&0x38000000); t2 = (u2&0x38000000); u = t1>t2?t1:t2;
373: t1 = (u1& 0x7000000); t2 = (u2& 0x7000000); u |= t1>t2?t1:t2;
374: t1 = (u1& 0xe00000); t2 = (u2& 0xe00000); u |= t1>t2?t1:t2;
375: t1 = (u1& 0x1c0000); t2 = (u2& 0x1c0000); u |= t1>t2?t1:t2;
376: t1 = (u1& 0x38000); t2 = (u2& 0x38000); u |= t1>t2?t1:t2;
377: t1 = (u1& 0x7000); t2 = (u2& 0x7000); u |= t1>t2?t1:t2;
378: t1 = (u1& 0xe00); t2 = (u2& 0xe00); u |= t1>t2?t1:t2;
379: t1 = (u1& 0x1c0); t2 = (u2& 0x1c0); u |= t1>t2?t1:t2;
380: t1 = (u1& 0x38); t2 = (u2& 0x38); u |= t1>t2?t1:t2;
381: t1 = (u1& 0x7); t2 = (u2& 0x7); u |= t1>t2?t1:t2;
382: d[i] = u;
383: }
384: break;
385: case 4:
386: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
387: u1 = d1[i]; u2 = d2[i];
388: t1 = (u1&0xf0000000); t2 = (u2&0xf0000000); u = t1>t2?t1:t2;
389: t1 = (u1& 0xf000000); t2 = (u2& 0xf000000); u |= t1>t2?t1:t2;
390: t1 = (u1& 0xf00000); t2 = (u2& 0xf00000); u |= t1>t2?t1:t2;
391: t1 = (u1& 0xf0000); t2 = (u2& 0xf0000); u |= t1>t2?t1:t2;
392: t1 = (u1& 0xf000); t2 = (u2& 0xf000); u |= t1>t2?t1:t2;
393: t1 = (u1& 0xf00); t2 = (u2& 0xf00); u |= t1>t2?t1:t2;
394: t1 = (u1& 0xf0); t2 = (u2& 0xf0); u |= t1>t2?t1:t2;
395: t1 = (u1& 0xf); t2 = (u2& 0xf); u |= t1>t2?t1:t2;
396: d[i] = u;
397: }
398: break;
399: case 6:
400: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
401: u1 = d1[i]; u2 = d2[i];
402: t1 = (u1&0x3f000000); t2 = (u2&0x3f000000); u = t1>t2?t1:t2;
403: t1 = (u1& 0xfc0000); t2 = (u2& 0xfc0000); u |= t1>t2?t1:t2;
404: t1 = (u1& 0x3f000); t2 = (u2& 0x3f000); u |= t1>t2?t1:t2;
405: t1 = (u1& 0xfc0); t2 = (u2& 0xfc0); u |= t1>t2?t1:t2;
406: t1 = (u1& 0x3f); t2 = (u2& 0x3f); u |= t1>t2?t1:t2;
407: d[i] = u;
408: }
409: break;
410: case 8:
411: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
412: u1 = d1[i]; u2 = d2[i];
413: t1 = (u1&0xff000000); t2 = (u2&0xff000000); u = t1>t2?t1:t2;
414: t1 = (u1& 0xff0000); t2 = (u2& 0xff0000); u |= t1>t2?t1:t2;
415: t1 = (u1& 0xff00); t2 = (u2& 0xff00); u |= t1>t2?t1:t2;
416: t1 = (u1& 0xff); t2 = (u2& 0xff); u |= t1>t2?t1:t2;
417: d[i] = u;
418: }
419: break;
420: case 16:
421: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
422: u1 = d1[i]; u2 = d2[i];
423: t1 = (u1&0xffff0000); t2 = (u2&0xffff0000); u = t1>t2?t1:t2;
424: t1 = (u1& 0xffff); t2 = (u2& 0xffff); u |= t1>t2?t1:t2;
425: d[i] = u;
426: }
427: break;
428: case 32:
429: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
430: u1 = d1[i]; u2 = d2[i];
431: d[i] = u1>u2?u1:u2;
432: }
433: break;
434: default:
435: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
436: u1 = d1[i]; u2 = d2[i];
437: for ( j = 0, u = 0; j < nd_epw; j++ ) {
438: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
439: }
440: d[i] = u;
441: }
442: break;
443: }
444: #else
445: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
446: u1 = d1[i]; u2 = d2[i];
447: for ( j = 0, u = 0; j < nd_epw; j++ ) {
448: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
449: }
450: d[i] = u;
451: }
452: #endif
1.163 noro 453: if ( nd_module ) MPOS(d) = MPOS(d1);
1.157 noro 454: TD(d) = ndl_weight(d);
455: if ( nd_blockmask ) ndl_weight_mask(d);
456: }
457:
1.159 noro 458: void ndl_max(UINT *d1,unsigned *d2,UINT *d)
1.157 noro 459: {
460: UINT t1,t2,u,u1,u2;
461: int i,j,l;
1.1 noro 462:
1.157 noro 463: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
464: u1 = d1[i]; u2 = d2[i];
465: for ( j = 0, u = 0; j < nd_epw; j++ ) {
466: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
467: }
468: d[i] = u;
469: }
1.57 noro 470: }
471:
1.61 noro 472: int ndl_weight(UINT *d)
1.1 noro 473: {
1.157 noro 474: UINT t,u;
475: int i,j;
1.1 noro 476:
1.157 noro 477: if ( current_dl_weight_vector )
478: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
479: u = GET_EXP(d,i);
480: t += MUL_WEIGHT(u,i);
481: }
482: else
483: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
484: u = d[i];
485: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
486: t += (u&nd_mask0);
487: }
1.167 noro 488: if ( nd_module && current_module_weight_vector && MPOS(d) )
489: t += current_module_weight_vector[MPOS(d)];
1.157 noro 490: return t;
1.1 noro 491: }
492:
1.231 noro 493: /* for sugarweight */
494:
495: int ndl_weight2(UINT *d)
496: {
497: int t,u;
498: int i,j;
499:
500: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
501: u = GET_EXP(d,i);
502: t += nd_sugarweight[i]*u;
503: }
504: if ( nd_module && current_module_weight_vector && MPOS(d) )
505: t += current_module_weight_vector[MPOS(d)];
506: return t;
507: }
508:
1.61 noro 509: void ndl_weight_mask(UINT *d)
1.43 noro 510: {
1.157 noro 511: UINT t,u;
512: UINT *mask;
513: int i,j,k,l;
514:
515: l = nd_blockmask->n;
516: for ( k = 0; k < l; k++ ) {
517: mask = nd_blockmask->mask[k];
518: if ( current_dl_weight_vector )
519: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
520: u = GET_EXP_MASK(d,i,mask);
521: t += MUL_WEIGHT(u,i);
522: }
523: else
524: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
525: u = d[i]&mask[i];
526: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
527: t += (u&nd_mask0);
528: }
529: d[k+1] = t;
530: }
1.43 noro 531: }
532:
1.61 noro 533: int ndl_lex_compare(UINT *d1,UINT *d2)
1.1 noro 534: {
1.157 noro 535: int i;
1.1 noro 536:
1.157 noro 537: d1 += nd_exporigin;
538: d2 += nd_exporigin;
539: for ( i = nd_exporigin; i < nd_wpd; i++, d1++, d2++ )
540: if ( *d1 > *d2 )
541: return nd_isrlex ? -1 : 1;
542: else if ( *d1 < *d2 )
543: return nd_isrlex ? 1 : -1;
544: return 0;
1.1 noro 545: }
546:
1.61 noro 547: int ndl_block_compare(UINT *d1,UINT *d2)
1.43 noro 548: {
1.157 noro 549: int i,l,j,ord_o,ord_l;
550: struct order_pair *op;
551: UINT t1,t2,m;
552: UINT *mask;
553:
554: l = nd_blockmask->n;
555: op = nd_blockmask->order_pair;
556: for ( j = 0; j < l; j++ ) {
557: mask = nd_blockmask->mask[j];
558: ord_o = op[j].order;
559: if ( ord_o < 2 )
560: if ( (t1=d1[j+1]) > (t2=d2[j+1]) ) return 1;
561: else if ( t1 < t2 ) return -1;
562: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
563: m = mask[i];
564: t1 = d1[i]&m;
565: t2 = d2[i]&m;
566: if ( t1 > t2 )
567: return !ord_o ? -1 : 1;
568: else if ( t1 < t2 )
569: return !ord_o ? 1 : -1;
570: }
571: }
572: return 0;
1.43 noro 573: }
574:
1.96 noro 575: int ndl_matrix_compare(UINT *d1,UINT *d2)
576: {
1.219 noro 577: int i,j,s,row;
1.157 noro 578: int *v;
1.245 noro 579: Q **mat;
1.219 noro 580: Q *w;
581: Q t,t1,t2;
1.96 noro 582:
1.157 noro 583: for ( j = 0; j < nd_nvar; j++ )
584: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
1.245 noro 585: if ( nd_top_weight ) {
586: if ( OID(nd_top_weight) == O_VECT ) {
587: mat = (Q **)&BDY((VECT)nd_top_weight);
588: row = 1;
589: } else {
590: mat = (Q **)BDY((MAT)nd_top_weight);
591: row = ((MAT)nd_top_weight)->row;
592: }
593: for ( i = 0; i < row; i++ ) {
594: w = (Q *)mat[i];
595: for ( j = 0, t = 0; j < nd_nvar; j++ ) {
596: STOQ(nd_work_vector[j],t1);
597: mulq(w[j],t1,&t2);
598: addq(t,t2,&t1);
599: t = t1;
600: }
601: if ( t ) {
602: s = SGN(t);
603: if ( s > 0 ) return 1;
604: else if ( s < 0 ) return -1;
605: }
606: }
607: }
1.157 noro 608: for ( i = 0; i < nd_matrix_len; i++ ) {
609: v = nd_matrix[i];
610: for ( j = 0, s = 0; j < nd_nvar; j++ )
611: s += v[j]*nd_work_vector[j];
612: if ( s > 0 ) return 1;
613: else if ( s < 0 ) return -1;
614: }
1.245 noro 615: if ( !ndl_equal(d1,d2) )
616: error("afo");
1.157 noro 617: return 0;
1.96 noro 618: }
619:
1.97 noro 620: int ndl_composite_compare(UINT *d1,UINT *d2)
621: {
1.157 noro 622: int i,j,s,start,end,len,o;
623: int *v;
624: struct sparse_weight *sw;
625:
626: for ( j = 0; j < nd_nvar; j++ )
627: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
628: for ( i = 0; i < nd_worb_len; i++ ) {
629: len = nd_worb[i].length;
630: switch ( nd_worb[i].type ) {
631: case IS_DENSE_WEIGHT:
632: v = nd_worb[i].body.dense_weight;
633: for ( j = 0, s = 0; j < len; j++ )
634: s += v[j]*nd_work_vector[j];
635: if ( s > 0 ) return 1;
636: else if ( s < 0 ) return -1;
637: break;
638: case IS_SPARSE_WEIGHT:
639: sw = nd_worb[i].body.sparse_weight;
640: for ( j = 0, s = 0; j < len; j++ )
641: s += sw[j].value*nd_work_vector[sw[j].pos];
642: if ( s > 0 ) return 1;
643: else if ( s < 0 ) return -1;
644: break;
645: case IS_BLOCK:
646: o = nd_worb[i].body.block.order;
647: start = nd_worb[i].body.block.start;
648: switch ( o ) {
649: case 0:
650: end = start+len;
651: for ( j = start, s = 0; j < end; j++ )
652: s += MUL_WEIGHT(nd_work_vector[j],j);
653: if ( s > 0 ) return 1;
654: else if ( s < 0 ) return -1;
655: for ( j = end-1; j >= start; j-- )
656: if ( nd_work_vector[j] < 0 ) return 1;
657: else if ( nd_work_vector[j] > 0 ) return -1;
658: break;
659: case 1:
660: end = start+len;
661: for ( j = start, s = 0; j < end; j++ )
662: s += MUL_WEIGHT(nd_work_vector[j],j);
663: if ( s > 0 ) return 1;
664: else if ( s < 0 ) return -1;
665: for ( j = start; j < end; j++ )
666: if ( nd_work_vector[j] > 0 ) return 1;
667: else if ( nd_work_vector[j] < 0 ) return -1;
668: break;
669: case 2:
1.236 noro 670: end = start+len;
1.157 noro 671: for ( j = start; j < end; j++ )
672: if ( nd_work_vector[j] > 0 ) return 1;
673: else if ( nd_work_vector[j] < 0 ) return -1;
674: break;
675: }
676: break;
677: }
678: }
679: return 0;
1.97 noro 680: }
681:
1.58 noro 682: /* TDH -> WW -> TD-> RL */
683:
1.61 noro 684: int ndl_ww_lex_compare(UINT *d1,UINT *d2)
1.58 noro 685: {
1.157 noro 686: int i,m,e1,e2;
1.58 noro 687:
1.157 noro 688: if ( TD(d1) > TD(d2) ) return 1;
689: else if ( TD(d1) < TD(d2) ) return -1;
690: m = nd_nvar>>1;
691: for ( i = 0, e1 = e2 = 0; i < m; i++ ) {
692: e1 += current_weyl_weight_vector[i]*(GET_EXP(d1,m+i)-GET_EXP(d1,i));
693: e2 += current_weyl_weight_vector[i]*(GET_EXP(d2,m+i)-GET_EXP(d2,i));
694: }
695: if ( e1 > e2 ) return 1;
696: else if ( e1 < e2 ) return -1;
697: return ndl_lex_compare(d1,d2);
698: }
699:
1.224 noro 700: int ndl_module_weight_compare(UINT *d1,UINT *d2)
701: {
702: int s,j;
703:
704: if ( nd_nvar != nd_poly_weight_len )
705: error("invalid module weight : the length of polynomial weight != the number of variables");
706: s = 0;
707: for ( j = 0; j < nd_nvar; j++ )
708: s += (GET_EXP(d1,j)-GET_EXP(d2,j))*nd_poly_weight[j];
1.226 noro 709: if ( MPOS(d1) >= 1 && MPOS(d2) >= 1 ) {
710: s += nd_module_weight[MPOS(d1)-1]-nd_module_weight[MPOS(d2)-1];
711: }
1.224 noro 712: if ( s > 0 ) return 1;
713: else if ( s < 0 ) return -1;
714: else return 0;
715: }
716:
1.157 noro 717: int ndl_module_grlex_compare(UINT *d1,UINT *d2)
718: {
1.164 noro 719: int i,c;
1.157 noro 720:
1.224 noro 721: if ( nd_module_rank && (c = ndl_module_weight_compare(d1,d2)) ) return c;
1.160 noro 722: if ( nd_ispot ) {
1.245 noro 723: if ( nd_pot_nelim && MPOS(d1)>=nd_pot_nelim+1 && MPOS(d2) >= nd_pot_nelim+1 ) {
1.174 noro 724: if ( TD(d1) > TD(d2) ) return 1;
725: else if ( TD(d1) < TD(d2) ) return -1;
726: if ( c = ndl_lex_compare(d1,d2) ) return c;
727: if ( MPOS(d1) < MPOS(d2) ) return 1;
728: else if ( MPOS(d1) > MPOS(d2) ) return -1;
729: return 0;
1.245 noro 730: }
1.157 noro 731: if ( MPOS(d1) < MPOS(d2) ) return 1;
732: else if ( MPOS(d1) > MPOS(d2) ) return -1;
733: }
734: if ( TD(d1) > TD(d2) ) return 1;
735: else if ( TD(d1) < TD(d2) ) return -1;
1.167 noro 736: if ( c = ndl_lex_compare(d1,d2) ) return c;
1.160 noro 737: if ( !nd_ispot ) {
1.157 noro 738: if ( MPOS(d1) < MPOS(d2) ) return 1;
739: else if ( MPOS(d1) > MPOS(d2) ) return -1;
740: }
741: return 0;
742: }
743:
744: int ndl_module_glex_compare(UINT *d1,UINT *d2)
745: {
1.164 noro 746: int i,c;
1.157 noro 747:
1.224 noro 748: if ( nd_module_rank && (c = ndl_module_weight_compare(d1,d2)) ) return c;
1.160 noro 749: if ( nd_ispot ) {
1.157 noro 750: if ( MPOS(d1) < MPOS(d2) ) return 1;
751: else if ( MPOS(d1) > MPOS(d2) ) return -1;
752: }
753: if ( TD(d1) > TD(d2) ) return 1;
754: else if ( TD(d1) < TD(d2) ) return -1;
1.167 noro 755: if ( c = ndl_lex_compare(d1,d2) ) return c;
1.160 noro 756: if ( !nd_ispot ) {
1.157 noro 757: if ( MPOS(d1) < MPOS(d2) ) return 1;
758: else if ( MPOS(d1) > MPOS(d2) ) return -1;
759: }
760: return 0;
761: }
762:
763: int ndl_module_lex_compare(UINT *d1,UINT *d2)
764: {
1.164 noro 765: int i,c;
1.157 noro 766:
1.224 noro 767: if ( nd_module_rank && (c = ndl_module_weight_compare(d1,d2)) ) return c;
1.160 noro 768: if ( nd_ispot ) {
1.157 noro 769: if ( MPOS(d1) < MPOS(d2) ) return 1;
770: else if ( MPOS(d1) > MPOS(d2) ) return -1;
771: }
1.167 noro 772: if ( c = ndl_lex_compare(d1,d2) ) return c;
1.160 noro 773: if ( !nd_ispot ) {
1.157 noro 774: if ( MPOS(d1) < MPOS(d2) ) return 1;
775: else if ( MPOS(d1) > MPOS(d2) ) return -1;
776: }
777: return 0;
778: }
779:
780: int ndl_module_block_compare(UINT *d1,UINT *d2)
781: {
782: int i,c;
783:
1.224 noro 784: if ( nd_module_rank && (c = ndl_module_weight_compare(d1,d2)) ) return c;
1.160 noro 785: if ( nd_ispot ) {
1.157 noro 786: if ( MPOS(d1) < MPOS(d2) ) return 1;
787: else if ( MPOS(d1) > MPOS(d2) ) return -1;
788: }
789: if ( c = ndl_block_compare(d1,d2) ) return c;
1.160 noro 790: if ( !nd_ispot ) {
1.157 noro 791: if ( MPOS(d1) < MPOS(d2) ) return 1;
792: else if ( MPOS(d1) > MPOS(d2) ) return -1;
793: }
794: return 0;
795: }
796:
797: int ndl_module_matrix_compare(UINT *d1,UINT *d2)
798: {
799: int i,c;
800:
1.224 noro 801: if ( nd_module_rank && (c = ndl_module_weight_compare(d1,d2)) ) return c;
1.160 noro 802: if ( nd_ispot ) {
1.157 noro 803: if ( MPOS(d1) < MPOS(d2) ) return 1;
804: else if ( MPOS(d1) > MPOS(d2) ) return -1;
805: }
806: if ( c = ndl_matrix_compare(d1,d2) ) return c;
1.160 noro 807: if ( !nd_ispot ) {
1.157 noro 808: if ( MPOS(d1) < MPOS(d2) ) return 1;
809: else if ( MPOS(d1) > MPOS(d2) ) return -1;
810: }
811: return 0;
812: }
813:
814: int ndl_module_composite_compare(UINT *d1,UINT *d2)
815: {
816: int i,c;
817:
1.224 noro 818: if ( nd_module_rank && (c = ndl_module_weight_compare(d1,d2)) ) return c;
1.160 noro 819: if ( nd_ispot ) {
1.157 noro 820: if ( MPOS(d1) > MPOS(d2) ) return 1;
821: else if ( MPOS(d1) < MPOS(d2) ) return -1;
822: }
823: if ( c = ndl_composite_compare(d1,d2) ) return c;
1.160 noro 824: if ( !nd_ispot ) {
1.157 noro 825: if ( MPOS(d1) > MPOS(d2) ) return 1;
826: else if ( MPOS(d1) < MPOS(d2) ) return -1;
827: }
828: return 0;
1.58 noro 829: }
830:
1.61 noro 831: INLINE int ndl_equal(UINT *d1,UINT *d2)
1.1 noro 832: {
1.157 noro 833: int i;
1.1 noro 834:
1.157 noro 835: switch ( nd_wpd ) {
836: case 2:
837: if ( TD(d2) != TD(d1) ) return 0;
838: if ( d2[1] != d1[1] ) return 0;
839: return 1;
840: break;
841: case 3:
842: if ( TD(d2) != TD(d1) ) return 0;
843: if ( d2[1] != d1[1] ) return 0;
844: if ( d2[2] != d1[2] ) return 0;
845: return 1;
846: break;
847: default:
848: for ( i = 0; i < nd_wpd; i++ )
849: if ( *d1++ != *d2++ ) return 0;
850: return 1;
851: break;
852: }
1.1 noro 853: }
854:
1.61 noro 855: INLINE void ndl_copy(UINT *d1,UINT *d2)
1.6 noro 856: {
1.157 noro 857: int i;
1.6 noro 858:
1.157 noro 859: switch ( nd_wpd ) {
860: case 2:
861: TD(d2) = TD(d1);
862: d2[1] = d1[1];
863: break;
864: case 3:
865: TD(d2) = TD(d1);
866: d2[1] = d1[1];
867: d2[2] = d1[2];
868: break;
869: default:
870: for ( i = 0; i < nd_wpd; i++ )
871: d2[i] = d1[i];
872: break;
873: }
1.6 noro 874: }
875:
1.61 noro 876: INLINE void ndl_zero(UINT *d)
877: {
1.157 noro 878: int i;
879: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
1.61 noro 880: }
881:
882: INLINE void ndl_add(UINT *d1,UINT *d2,UINT *d)
1.1 noro 883: {
1.157 noro 884: int i;
1.1 noro 885:
1.162 noro 886: if ( nd_module ) {
887: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
1.167 noro 888: error("ndl_add : invalid operation");
1.162 noro 889: }
1.43 noro 890: #if 1
1.157 noro 891: switch ( nd_wpd ) {
892: case 2:
893: TD(d) = TD(d1)+TD(d2);
894: d[1] = d1[1]+d2[1];
895: break;
896: case 3:
897: TD(d) = TD(d1)+TD(d2);
898: d[1] = d1[1]+d2[1];
899: d[2] = d1[2]+d2[2];
900: break;
901: default:
902: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
903: break;
904: }
1.43 noro 905: #else
1.157 noro 906: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
1.43 noro 907: #endif
1.6 noro 908: }
909:
1.55 noro 910: /* d1 += d2 */
1.61 noro 911: INLINE void ndl_addto(UINT *d1,UINT *d2)
1.55 noro 912: {
1.157 noro 913: int i;
1.55 noro 914:
1.162 noro 915: if ( nd_module ) {
916: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
917: error("ndl_addto : invalid operation");
918: }
1.55 noro 919: #if 1
1.157 noro 920: switch ( nd_wpd ) {
921: case 2:
922: TD(d1) += TD(d2);
923: d1[1] += d2[1];
924: break;
925: case 3:
926: TD(d1) += TD(d2);
927: d1[1] += d2[1];
928: d1[2] += d2[2];
929: break;
930: default:
931: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
932: break;
933: }
1.55 noro 934: #else
1.157 noro 935: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
1.55 noro 936: #endif
937: }
938:
1.61 noro 939: INLINE void ndl_sub(UINT *d1,UINT *d2,UINT *d)
1.6 noro 940: {
1.157 noro 941: int i;
1.6 noro 942:
1.157 noro 943: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]-d2[i];
1.1 noro 944: }
945:
1.61 noro 946: int ndl_disjoint(UINT *d1,UINT *d2)
1.1 noro 947: {
1.157 noro 948: UINT t1,t2,u,u1,u2;
949: int i,j;
1.1 noro 950:
1.157 noro 951: if ( nd_module && (MPOS(d1) == MPOS(d2)) ) return 0;
1.65 noro 952: #if USE_UNROLL
1.157 noro 953: switch ( nd_bpe ) {
954: case 3:
955: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
956: u1 = d1[i]; u2 = d2[i];
957: t1 = u1&0x38000000; t2 = u2&0x38000000; if ( t1&&t2 ) return 0;
958: t1 = u1& 0x7000000; t2 = u2& 0x7000000; if ( t1&&t2 ) return 0;
959: t1 = u1& 0xe00000; t2 = u2& 0xe00000; if ( t1&&t2 ) return 0;
960: t1 = u1& 0x1c0000; t2 = u2& 0x1c0000; if ( t1&&t2 ) return 0;
961: t1 = u1& 0x38000; t2 = u2& 0x38000; if ( t1&&t2 ) return 0;
962: t1 = u1& 0x7000; t2 = u2& 0x7000; if ( t1&&t2 ) return 0;
963: t1 = u1& 0xe00; t2 = u2& 0xe00; if ( t1&&t2 ) return 0;
964: t1 = u1& 0x1c0; t2 = u2& 0x1c0; if ( t1&&t2 ) return 0;
965: t1 = u1& 0x38; t2 = u2& 0x38; if ( t1&&t2 ) return 0;
966: t1 = u1& 0x7; t2 = u2& 0x7; if ( t1&&t2 ) return 0;
967: }
968: return 1;
969: break;
970: case 4:
971: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
972: u1 = d1[i]; u2 = d2[i];
973: t1 = u1&0xf0000000; t2 = u2&0xf0000000; if ( t1&&t2 ) return 0;
974: t1 = u1& 0xf000000; t2 = u2& 0xf000000; if ( t1&&t2 ) return 0;
975: t1 = u1& 0xf00000; t2 = u2& 0xf00000; if ( t1&&t2 ) return 0;
976: t1 = u1& 0xf0000; t2 = u2& 0xf0000; if ( t1&&t2 ) return 0;
977: t1 = u1& 0xf000; t2 = u2& 0xf000; if ( t1&&t2 ) return 0;
978: t1 = u1& 0xf00; t2 = u2& 0xf00; if ( t1&&t2 ) return 0;
979: t1 = u1& 0xf0; t2 = u2& 0xf0; if ( t1&&t2 ) return 0;
980: t1 = u1& 0xf; t2 = u2& 0xf; if ( t1&&t2 ) return 0;
981: }
982: return 1;
983: break;
984: case 6:
985: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
986: u1 = d1[i]; u2 = d2[i];
987: t1 = u1&0x3f000000; t2 = u2&0x3f000000; if ( t1&&t2 ) return 0;
988: t1 = u1& 0xfc0000; t2 = u2& 0xfc0000; if ( t1&&t2 ) return 0;
989: t1 = u1& 0x3f000; t2 = u2& 0x3f000; if ( t1&&t2 ) return 0;
990: t1 = u1& 0xfc0; t2 = u2& 0xfc0; if ( t1&&t2 ) return 0;
991: t1 = u1& 0x3f; t2 = u2& 0x3f; if ( t1&&t2 ) return 0;
992: }
993: return 1;
994: break;
995: case 8:
996: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
997: u1 = d1[i]; u2 = d2[i];
998: t1 = u1&0xff000000; t2 = u2&0xff000000; if ( t1&&t2 ) return 0;
999: t1 = u1& 0xff0000; t2 = u2& 0xff0000; if ( t1&&t2 ) return 0;
1000: t1 = u1& 0xff00; t2 = u2& 0xff00; if ( t1&&t2 ) return 0;
1001: t1 = u1& 0xff; t2 = u2& 0xff; if ( t1&&t2 ) return 0;
1002: }
1003: return 1;
1004: break;
1005: case 16:
1006: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1007: u1 = d1[i]; u2 = d2[i];
1008: t1 = u1&0xffff0000; t2 = u2&0xffff0000; if ( t1&&t2 ) return 0;
1009: t1 = u1& 0xffff; t2 = u2& 0xffff; if ( t1&&t2 ) return 0;
1010: }
1011: return 1;
1012: break;
1013: case 32:
1014: for ( i = nd_exporigin; i < nd_wpd; i++ )
1015: if ( d1[i] && d2[i] ) return 0;
1016: return 1;
1017: break;
1018: default:
1019: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1020: u1 = d1[i]; u2 = d2[i];
1021: for ( j = 0; j < nd_epw; j++ ) {
1022: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
1023: u1 >>= nd_bpe; u2 >>= nd_bpe;
1024: }
1025: }
1026: return 1;
1027: break;
1028: }
1.65 noro 1029: #else
1.157 noro 1030: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1031: u1 = d1[i]; u2 = d2[i];
1032: for ( j = 0; j < nd_epw; j++ ) {
1033: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
1034: u1 >>= nd_bpe; u2 >>= nd_bpe;
1035: }
1036: }
1037: return 1;
1.65 noro 1038: #endif
1.1 noro 1039: }
1040:
1.114 noro 1041: int ndl_check_bound(UINT *d1,UINT *d2)
1.1 noro 1042: {
1.157 noro 1043: UINT u2;
1044: int i,j,ind,k;
1.1 noro 1045:
1.157 noro 1046: ind = 0;
1.65 noro 1047: #if USE_UNROLL
1.157 noro 1048: switch ( nd_bpe ) {
1049: case 3:
1050: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1051: u2 = d2[i];
1052: if ( d1[ind++]+((u2>>27)&0x7) >= 0x8 ) return 1;
1053: if ( d1[ind++]+((u2>>24)&0x7) >= 0x8 ) return 1;
1054: if ( d1[ind++]+((u2>>21)&0x7) >= 0x8 ) return 1;
1055: if ( d1[ind++]+((u2>>18)&0x7) >= 0x8 ) return 1;
1056: if ( d1[ind++]+((u2>>15)&0x7) >= 0x8 ) return 1;
1057: if ( d1[ind++]+((u2>>12)&0x7) >= 0x8 ) return 1;
1058: if ( d1[ind++]+((u2>>9)&0x7) >= 0x8 ) return 1;
1059: if ( d1[ind++]+((u2>>6)&0x7) >= 0x8 ) return 1;
1060: if ( d1[ind++]+((u2>>3)&0x7) >= 0x8 ) return 1;
1061: if ( d1[ind++]+(u2&0x7) >= 0x8 ) return 1;
1062: }
1063: return 0;
1064: break;
1065: case 4:
1066: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1067: u2 = d2[i];
1068: if ( d1[ind++]+((u2>>28)&0xf) >= 0x10 ) return 1;
1069: if ( d1[ind++]+((u2>>24)&0xf) >= 0x10 ) return 1;
1070: if ( d1[ind++]+((u2>>20)&0xf) >= 0x10 ) return 1;
1071: if ( d1[ind++]+((u2>>16)&0xf) >= 0x10 ) return 1;
1072: if ( d1[ind++]+((u2>>12)&0xf) >= 0x10 ) return 1;
1073: if ( d1[ind++]+((u2>>8)&0xf) >= 0x10 ) return 1;
1074: if ( d1[ind++]+((u2>>4)&0xf) >= 0x10 ) return 1;
1075: if ( d1[ind++]+(u2&0xf) >= 0x10 ) return 1;
1076: }
1077: return 0;
1078: break;
1079: case 6:
1080: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1081: u2 = d2[i];
1082: if ( d1[ind++]+((u2>>24)&0x3f) >= 0x40 ) return 1;
1083: if ( d1[ind++]+((u2>>18)&0x3f) >= 0x40 ) return 1;
1084: if ( d1[ind++]+((u2>>12)&0x3f) >= 0x40 ) return 1;
1085: if ( d1[ind++]+((u2>>6)&0x3f) >= 0x40 ) return 1;
1086: if ( d1[ind++]+(u2&0x3f) >= 0x40 ) return 1;
1087: }
1088: return 0;
1089: break;
1090: case 8:
1091: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1092: u2 = d2[i];
1093: if ( d1[ind++]+((u2>>24)&0xff) >= 0x100 ) return 1;
1094: if ( d1[ind++]+((u2>>16)&0xff) >= 0x100 ) return 1;
1095: if ( d1[ind++]+((u2>>8)&0xff) >= 0x100 ) return 1;
1096: if ( d1[ind++]+(u2&0xff) >= 0x100 ) return 1;
1097: }
1098: return 0;
1099: break;
1100: case 16:
1101: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1102: u2 = d2[i];
1103: if ( d1[ind++]+((u2>>16)&0xffff) > 0x10000 ) return 1;
1104: if ( d1[ind++]+(u2&0xffff) > 0x10000 ) return 1;
1105: }
1106: return 0;
1107: break;
1108: case 32:
1109: for ( i = nd_exporigin; i < nd_wpd; i++ )
1110: if ( d1[i]+d2[i]<d1[i] ) return 1;
1111: return 0;
1112: break;
1113: default:
1114: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1115: u2 = d2[i];
1116: k = (nd_epw-1)*nd_bpe;
1117: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
1118: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1119: }
1120: return 0;
1121: break;
1122: }
1.65 noro 1123: #else
1.157 noro 1124: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1125: u2 = d2[i];
1126: k = (nd_epw-1)*nd_bpe;
1127: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
1128: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1129: }
1130: return 0;
1.65 noro 1131: #endif
1.1 noro 1132: }
1133:
1.114 noro 1134: int ndl_check_bound2(int index,UINT *d2)
1135: {
1.157 noro 1136: return ndl_check_bound(nd_bound[index],d2);
1.114 noro 1137: }
1138:
1.61 noro 1139: INLINE int ndl_hash_value(UINT *d)
1.1 noro 1140: {
1.157 noro 1141: int i;
1142: int r;
1.1 noro 1143:
1.157 noro 1144: r = 0;
1145: for ( i = 0; i < nd_wpd; i++ )
1146: r = ((r<<16)+d[i])%REDTAB_LEN;
1147: return r;
1.1 noro 1148: }
1149:
1.63 noro 1150: INLINE int ndl_find_reducer(UINT *dg)
1.1 noro 1151: {
1.157 noro 1152: RHist r;
1153: int d,k,i;
1.1 noro 1154:
1.157 noro 1155: d = ndl_hash_value(dg);
1156: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1157: if ( ndl_equal(dg,DL(r)) ) {
1158: if ( k > 0 ) nd_notfirst++;
1159: nd_found++;
1160: return r->index;
1161: }
1162: }
1163: if ( Reverse )
1164: for ( i = nd_psn-1; i >= 0; i-- ) {
1165: r = nd_psh[i];
1166: if ( ndl_reducible(dg,DL(r)) ) {
1167: nd_create++;
1168: nd_append_red(dg,i);
1169: return i;
1170: }
1171: }
1172: else
1173: for ( i = 0; i < nd_psn; i++ ) {
1174: r = nd_psh[i];
1175: if ( ndl_reducible(dg,DL(r)) ) {
1176: nd_create++;
1177: nd_append_red(dg,i);
1178: return i;
1179: }
1180: }
1181: return -1;
1.1 noro 1182: }
1183:
1.63 noro 1184: ND nd_merge(ND p1,ND p2)
1185: {
1.157 noro 1186: int n,c;
1187: int t,can,td1,td2;
1188: ND r;
1189: NM m1,m2,mr0,mr,s;
1190:
1191: if ( !p1 ) return p2;
1192: else if ( !p2 ) return p1;
1193: else {
1194: can = 0;
1195: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1196: c = DL_COMPARE(DL(m1),DL(m2));
1197: switch ( c ) {
1198: case 0:
1199: s = m1; m1 = NEXT(m1);
1200: can++; NEXTNM2(mr0,mr,s);
1201: s = m2; m2 = NEXT(m2); FREENM(s);
1202: break;
1203: case 1:
1204: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1205: break;
1206: case -1:
1207: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1208: break;
1209: }
1210: }
1211: if ( !mr0 )
1212: if ( m1 ) mr0 = m1;
1213: else if ( m2 ) mr0 = m2;
1214: else return 0;
1215: else if ( m1 ) NEXT(mr) = m1;
1216: else if ( m2 ) NEXT(mr) = m2;
1217: else NEXT(mr) = 0;
1218: BDY(p1) = mr0;
1219: SG(p1) = MAX(SG(p1),SG(p2));
1220: LEN(p1) = LEN(p1)+LEN(p2)-can;
1221: FREEND(p2);
1222: return p1;
1223: }
1.63 noro 1224: }
1225:
1.31 noro 1226: ND nd_add(int mod,ND p1,ND p2)
1.1 noro 1227: {
1.157 noro 1228: int n,c;
1229: int t,can,td1,td2;
1230: ND r;
1231: NM m1,m2,mr0,mr,s;
1232:
1233: if ( !p1 ) return p2;
1234: else if ( !p2 ) return p1;
1235: else if ( mod == -1 ) return nd_add_sf(p1,p2);
1.232 noro 1236: else if ( mod == -2 ) return nd_add_lf(p1,p2);
1.157 noro 1237: else if ( !mod ) return nd_add_q(p1,p2);
1238: else {
1239: can = 0;
1240: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1241: c = DL_COMPARE(DL(m1),DL(m2));
1242: switch ( c ) {
1243: case 0:
1244: t = ((CM(m1))+(CM(m2))) - mod;
1245: if ( t < 0 ) t += mod;
1246: s = m1; m1 = NEXT(m1);
1247: if ( t ) {
1248: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1249: } else {
1250: can += 2; FREENM(s);
1251: }
1252: s = m2; m2 = NEXT(m2); FREENM(s);
1253: break;
1254: case 1:
1255: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1256: break;
1257: case -1:
1258: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1259: break;
1260: }
1261: }
1262: if ( !mr0 )
1263: if ( m1 ) mr0 = m1;
1264: else if ( m2 ) mr0 = m2;
1265: else return 0;
1266: else if ( m1 ) NEXT(mr) = m1;
1267: else if ( m2 ) NEXT(mr) = m2;
1268: else NEXT(mr) = 0;
1269: BDY(p1) = mr0;
1270: SG(p1) = MAX(SG(p1),SG(p2));
1271: LEN(p1) = LEN(p1)+LEN(p2)-can;
1272: FREEND(p2);
1273: return p1;
1274: }
1.95 noro 1275: }
1276:
1277: /* XXX on opteron, the inlined manipulation of destructive additon of
1278: * two NM seems to make gcc optimizer get confused, so the part is
1279: * done in a function.
1280: */
1281:
1.113 noro 1282: int nm_destructive_add_q(NM *m1,NM *m2,NM *mr0,NM *mr)
1.95 noro 1283: {
1.157 noro 1284: NM s;
1285: P t;
1286: int can;
1287:
1288: addp(nd_vc,CP(*m1),CP(*m2),&t);
1289: s = *m1; *m1 = NEXT(*m1);
1290: if ( t ) {
1291: can = 1; NEXTNM2(*mr0,*mr,s); CP(*mr) = (t);
1292: } else {
1293: can = 2; FREENM(s);
1294: }
1295: s = *m2; *m2 = NEXT(*m2); FREENM(s);
1296: return can;
1.95 noro 1297: }
1298:
1.113 noro 1299: ND nd_add_q(ND p1,ND p2)
1.95 noro 1300: {
1.157 noro 1301: int n,c,can;
1302: ND r;
1303: NM m1,m2,mr0,mr,s;
1304: P t;
1305:
1306: if ( !p1 ) return p2;
1307: else if ( !p2 ) return p1;
1308: else {
1309: can = 0;
1310: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1311: c = DL_COMPARE(DL(m1),DL(m2));
1312: switch ( c ) {
1313: case 0:
1.95 noro 1314: #if defined(__x86_64__)
1.157 noro 1315: can += nm_destructive_add_q(&m1,&m2,&mr0,&mr);
1.95 noro 1316: #else
1.157 noro 1317: addp(nd_vc,CP(m1),CP(m2),&t);
1318: s = m1; m1 = NEXT(m1);
1319: if ( t ) {
1320: can++; NEXTNM2(mr0,mr,s); CP(mr) = (t);
1321: } else {
1322: can += 2; FREENM(s);
1323: }
1324: s = m2; m2 = NEXT(m2); FREENM(s);
1.95 noro 1325: #endif
1.157 noro 1326: break;
1327: case 1:
1328: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1329: break;
1330: case -1:
1331: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1332: break;
1333: }
1334: }
1335: if ( !mr0 )
1336: if ( m1 ) mr0 = m1;
1337: else if ( m2 ) mr0 = m2;
1338: else return 0;
1339: else if ( m1 ) NEXT(mr) = m1;
1340: else if ( m2 ) NEXT(mr) = m2;
1341: else NEXT(mr) = 0;
1342: BDY(p1) = mr0;
1343: SG(p1) = MAX(SG(p1),SG(p2));
1344: LEN(p1) = LEN(p1)+LEN(p2)-can;
1345: FREEND(p2);
1346: return p1;
1347: }
1.17 noro 1348: }
1349:
1.71 noro 1350: ND nd_add_sf(ND p1,ND p2)
1351: {
1.157 noro 1352: int n,c,can;
1353: ND r;
1354: NM m1,m2,mr0,mr,s;
1355: int t;
1356:
1357: if ( !p1 ) return p2;
1358: else if ( !p2 ) return p1;
1359: else {
1360: can = 0;
1361: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1362: c = DL_COMPARE(DL(m1),DL(m2));
1363: switch ( c ) {
1364: case 0:
1365: t = _addsf(CM(m1),CM(m2));
1366: s = m1; m1 = NEXT(m1);
1367: if ( t ) {
1368: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1369: } else {
1370: can += 2; FREENM(s);
1371: }
1372: s = m2; m2 = NEXT(m2); FREENM(s);
1373: break;
1374: case 1:
1375: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1376: break;
1377: case -1:
1378: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1379: break;
1380: }
1381: }
1382: if ( !mr0 )
1383: if ( m1 ) mr0 = m1;
1384: else if ( m2 ) mr0 = m2;
1385: else return 0;
1386: else if ( m1 ) NEXT(mr) = m1;
1387: else if ( m2 ) NEXT(mr) = m2;
1388: else NEXT(mr) = 0;
1389: BDY(p1) = mr0;
1390: SG(p1) = MAX(SG(p1),SG(p2));
1391: LEN(p1) = LEN(p1)+LEN(p2)-can;
1392: FREEND(p2);
1393: return p1;
1394: }
1.71 noro 1395: }
1396:
1.232 noro 1397:
1.167 noro 1398: ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp)
1.146 noro 1399: {
1.157 noro 1400: int c,c1,c2;
1401: Q cg,cred,gcd,tq;
1402: P cgp,credp,gcdp;
1403: Obj tr,tr1;
1404:
1.167 noro 1405: if ( mod == -1 ) {
1.157 noro 1406: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1.167 noro 1407: *divp = (Obj)ONE;
1.232 noro 1408: } else if ( mod == -2 ) {
1409: GZ inv,t;
1410: divlf(ONEGZ,HCZ(p),&inv);
1411: chsgnlf(HCZ(g),&t);
1412: mullf(inv,t,&CZ(mul));
1413: *divp = (Obj)ONE;
1.167 noro 1414: } else if ( mod ) {
1.157 noro 1415: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1416: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1.167 noro 1417: *divp = (Obj)ONE;
1.157 noro 1418: } else if ( nd_vc ) {
1419: ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp);
1420: divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp);
1421: chsgnp(cgp,&CP(mul));
1422: nd_mul_c_q(d,credp); nd_mul_c_q(g,credp);
1423: if ( dn ) {
1424: mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr);
1425: reductr(nd_vc,tr,&tr1); dn->r = (R)tr1;
1426: }
1.167 noro 1427: *divp = (Obj)credp;
1.157 noro 1428: } else {
1429: igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred);
1430: chsgnq(cg,&CQ(mul));
1431: nd_mul_c_q(d,(P)cred); nd_mul_c_q(g,(P)cred);
1432: if ( dn ) {
1433: mulq(dn->z,cred,&tq); dn->z = tq;
1434: }
1.167 noro 1435: *divp = (Obj)cred;
1.157 noro 1436: }
1437: return nd_add(mod,g,ndv_mul_nm(mod,mul,p));
1.146 noro 1438: }
1439:
1.1 noro 1440: /* ret=1 : success, ret=0 : overflow */
1.146 noro 1441: int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND *rp)
1.1 noro 1442: {
1.157 noro 1443: NM m,mrd,tail;
1444: NM mul;
1445: int n,sugar,psugar,sugar0,stat,index;
1446: int c,c1,c2,dummy;
1447: RHist h;
1448: NDV p,red;
1.167 noro 1449: Q cg,cred,gcd,tq,qq,iq;
1450: DP dmul;
1451: NODE node;
1452: LIST hist;
1.157 noro 1453: double hmag;
1454: P tp,tp1;
1.167 noro 1455: Obj tr,tr1,div;
1456: union oNDC hg;
1457: P cont;
1.157 noro 1458:
1459: if ( dn ) {
1460: if ( mod )
1461: dn->m = 1;
1462: else if ( nd_vc )
1463: dn->r = (R)ONE;
1464: else
1465: dn->z = ONE;
1466: }
1467: if ( !g ) {
1468: *rp = d;
1469: return 1;
1470: }
1471: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1472:
1473: sugar0 = sugar = SG(g);
1474: n = NV(g);
1.235 noro 1475: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1.157 noro 1476: if ( d )
1477: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1478: for ( ; g; ) {
1479: index = ndl_find_reducer(HDL(g));
1480: if ( index >= 0 ) {
1481: h = nd_psh[index];
1482: ndl_sub(HDL(g),DL(h),DL(mul));
1483: if ( ndl_check_bound2(index,DL(mul)) ) {
1484: nd_free(g); nd_free(d);
1485: return 0;
1486: }
1487: p = nd_demand ? ndv_load(index) : ps[index];
1.167 noro 1488: /* d+g -> div*(d+g)+mul*p */
1489: g = nd_reduce2(mod,d,g,p,mul,dn,&div);
1.172 noro 1490: if ( nd_gentrace ) {
1.167 noro 1491: /* Trace=[div,index,mul,ONE] */
1492: STOQ(index,iq);
1493: nmtodp(mod,mul,&dmul);
1494: node = mknode(4,div,iq,dmul,ONE);
1495: }
1.157 noro 1496: sugar = MAX(sugar,SG(p)+TD(DL(mul)));
1.193 noro 1497: if ( !mod && g && !nd_vc && ((double)(p_mag(HCP(g))) > hmag) ) {
1.167 noro 1498: hg = HCU(g);
1.157 noro 1499: nd_removecont2(d,g);
1.172 noro 1500: if ( dn || nd_gentrace ) {
1.167 noro 1501: /* overwrite cont : Trace=[div,index,mul,cont] */
1502: cont = ndc_div(mod,hg,HCU(g));
1503: if ( dn ) {
1504: if ( nd_vc ) {
1505: divr(nd_vc,(Obj)dn->r,(Obj)cont,&tr);
1506: reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1;
1507: } else divq(dn->z,(Q)cont,&dn->z);
1.157 noro 1508: }
1.172 noro 1509: if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont;
1.157 noro 1510: }
1511: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1512: }
1.167 noro 1513: MKLIST(hist,node);
1514: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1.157 noro 1515: } else if ( !full ) {
1516: *rp = g;
1517: return 1;
1518: } else {
1519: m = BDY(g);
1520: if ( NEXT(m) ) {
1521: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1522: } else {
1523: FREEND(g); g = 0;
1524: }
1525: if ( d ) {
1526: NEXT(tail)=m; tail=m; LEN(d)++;
1527: } else {
1528: MKND(n,m,1,d); tail = BDY(d);
1529: }
1530: }
1531: }
1532: if ( d ) SG(d) = sugar;
1533: *rp = d;
1534: return 1;
1.1 noro 1535: }
1.28 noro 1536:
1.53 noro 1537: int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp)
1.25 noro 1538: {
1.157 noro 1539: int hindex,index;
1540: NDV p;
1541: ND u,d,red;
1542: NODE l;
1543: NM mul,m,mrd,tail;
1544: int sugar,psugar,n,h_reducible;
1545: PGeoBucket bucket;
1546: int c,c1,c2;
1547: Q cg,cred,gcd,zzz;
1548: RHist h;
1549: double hmag,gmag;
1550: int count = 0;
1551: int hcount = 0;
1552:
1553: if ( !g ) {
1554: *rp = 0;
1555: return 1;
1556: }
1557: sugar = SG(g);
1558: n = NV(g);
1559: if ( !mod ) hmag = ((double)p_mag((P)HCQ(g)))*nd_scale;
1560: bucket = create_pbucket();
1561: add_pbucket(mod,bucket,g);
1562: d = 0;
1.235 noro 1563: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1.157 noro 1564: while ( 1 ) {
1.232 noro 1565: if ( mod > 0 || mod == -1 )
1566: hindex = head_pbucket(mod,bucket);
1567: else if ( mod == -2 )
1568: hindex = head_pbucket_lf(bucket);
1569: else
1570: hindex = head_pbucket_q(bucket);
1.157 noro 1571: if ( hindex < 0 ) {
1572: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1573: if ( d ) SG(d) = sugar;
1574: *rp = d;
1575: return 1;
1576: }
1577: g = bucket->body[hindex];
1578: index = ndl_find_reducer(HDL(g));
1579: if ( index >= 0 ) {
1580: count++;
1581: if ( !d ) hcount++;
1582: h = nd_psh[index];
1583: ndl_sub(HDL(g),DL(h),DL(mul));
1584: if ( ndl_check_bound2(index,DL(mul)) ) {
1585: nd_free(d);
1586: free_pbucket(bucket);
1587: *rp = 0;
1588: return 0;
1589: }
1590: p = ps[index];
1591: if ( mod == -1 )
1592: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1.232 noro 1593: else if ( mod == -2 ) {
1594: GZ inv,t;
1595: divlf(ONEGZ,HCZ(p),&inv);
1596: chsgnlf(HCZ(g),&t);
1597: mullf(inv,t,&CZ(mul));
1598: } else if ( mod ) {
1.157 noro 1599: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1600: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1601: } else {
1602: igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred);
1603: chsgnq(cg,&CQ(mul));
1604: nd_mul_c_q(d,(P)cred);
1605: mulq_pbucket(bucket,cred);
1606: g = bucket->body[hindex];
1607: gmag = (double)p_mag((P)HCQ(g));
1608: }
1609: red = ndv_mul_nm(mod,mul,p);
1610: bucket->body[hindex] = nd_remove_head(g);
1611: red = nd_remove_head(red);
1612: add_pbucket(mod,bucket,red);
1613: psugar = SG(p)+TD(DL(mul));
1614: sugar = MAX(sugar,psugar);
1615: if ( !mod && hmag && (gmag > hmag) ) {
1616: g = normalize_pbucket(mod,bucket);
1617: if ( !g ) {
1618: if ( d ) SG(d) = sugar;
1619: *rp = d;
1620: return 1;
1621: }
1622: nd_removecont2(d,g);
1623: hmag = ((double)p_mag((P)HCQ(g)))*nd_scale;
1624: add_pbucket(mod,bucket,g);
1625: }
1626: } else if ( !full ) {
1627: g = normalize_pbucket(mod,bucket);
1628: if ( g ) SG(g) = sugar;
1629: *rp = g;
1630: return 1;
1631: } else {
1632: m = BDY(g);
1633: if ( NEXT(m) ) {
1634: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1635: } else {
1636: FREEND(g); g = 0;
1637: }
1638: bucket->body[hindex] = g;
1639: NEXT(m) = 0;
1640: if ( d ) {
1641: NEXT(tail)=m; tail=m; LEN(d)++;
1642: } else {
1643: MKND(n,m,1,d); tail = BDY(d);
1644: }
1645: }
1646: }
1.25 noro 1647: }
1.27 noro 1648:
1.61 noro 1649: /* input : list of NDV, cand : list of NDV */
1.28 noro 1650:
1.170 noro 1651: int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand)
1.28 noro 1652: {
1.157 noro 1653: int n,i,stat;
1654: ND nf,d;
1655: NDV r;
1656: NODE t,s;
1657: union oNDC dn;
1.168 noro 1658: Q q;
1659: LIST list;
1.45 noro 1660:
1.172 noro 1661: ndv_setup(m,0,cand,nd_gentrace?1:0,1);
1.157 noro 1662: n = length(cand);
1.28 noro 1663:
1.245 noro 1664: if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; }
1.157 noro 1665: /* membercheck : list is a subset of Id(cand) ? */
1.168 noro 1666: for ( t = input, i = 0; t; t = NEXT(t), i++ ) {
1.45 noro 1667: again:
1.245 noro 1668: nd_tracelist = 0;
1.157 noro 1669: if ( nd_bpe > obpe )
1670: r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos);
1671: else
1672: r = (NDV)BDY(t);
1.247 noro 1673: #if 0
1674: // moved to nd_f4_lf_trace()
1.246 noro 1675: if ( m == -2 ) ndv_mod(m,r);
1.247 noro 1676: #endif
1.171 noro 1677: d = ndvtond(m,r);
1678: stat = nd_nf(m,0,d,nd_ps,0,0,&nf);
1.157 noro 1679: if ( !stat ) {
1680: nd_reconstruct(0,0);
1681: goto again;
1682: } else if ( nf ) return 0;
1.245 noro 1683: if ( nd_gentrace ) {
1684: nd_tracelist = reverse_node(nd_tracelist);
1685: MKLIST(list,nd_tracelist);
1686: STOQ(i,q); s = mknode(2,q,list); MKLIST(list,s);
1687: MKNODE(s,list,nd_alltracelist);
1688: nd_alltracelist = s; nd_tracelist = 0;
1689: }
1.157 noro 1690: if ( DP_Print ) { printf("."); fflush(stdout); }
1691: }
1692: if ( DP_Print ) { printf("\n"); }
1693: return 1;
1.23 noro 1694: }
1.1 noro 1695:
1696: ND nd_remove_head(ND p)
1697: {
1.157 noro 1698: NM m;
1.1 noro 1699:
1.157 noro 1700: m = BDY(p);
1701: if ( !NEXT(m) ) {
1702: FREEND(p); p = 0;
1703: } else {
1704: BDY(p) = NEXT(m); LEN(p)--;
1705: }
1706: FREENM(m);
1707: return p;
1.1 noro 1708: }
1709:
1.69 noro 1710: ND nd_separate_head(ND p,ND *head)
1711: {
1.157 noro 1712: NM m,m0;
1713: ND r;
1.69 noro 1714:
1.157 noro 1715: m = BDY(p);
1716: if ( !NEXT(m) ) {
1717: *head = p; p = 0;
1718: } else {
1719: m0 = m;
1720: BDY(p) = NEXT(m); LEN(p)--;
1721: NEXT(m0) = 0;
1722: MKND(NV(p),m0,1,r);
1723: *head = r;
1724: }
1725: return p;
1.69 noro 1726: }
1727:
1.1 noro 1728: PGeoBucket create_pbucket()
1729: {
1730: PGeoBucket g;
1.157 noro 1731:
1732: g = CALLOC(1,sizeof(struct oPGeoBucket));
1733: g->m = -1;
1734: return g;
1.1 noro 1735: }
1736:
1.25 noro 1737: void free_pbucket(PGeoBucket b) {
1.157 noro 1738: int i;
1.25 noro 1739:
1.157 noro 1740: for ( i = 0; i <= b->m; i++ )
1741: if ( b->body[i] ) {
1742: nd_free(b->body[i]);
1743: b->body[i] = 0;
1744: }
1.200 noro 1745: GCFREE(b);
1.25 noro 1746: }
1747:
1.63 noro 1748: void add_pbucket_symbolic(PGeoBucket g,ND d)
1749: {
1.157 noro 1750: int l,i,k,m;
1.63 noro 1751:
1.157 noro 1752: if ( !d )
1753: return;
1754: l = LEN(d);
1755: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
1756: /* 2^(k-1) < l <= 2^k (=m) */
1757: d = nd_merge(g->body[k],d);
1758: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
1759: g->body[k] = 0;
1760: d = nd_merge(g->body[k+1],d);
1761: }
1762: g->body[k] = d;
1763: g->m = MAX(g->m,k);
1.63 noro 1764: }
1765:
1.31 noro 1766: void add_pbucket(int mod,PGeoBucket g,ND d)
1.1 noro 1767: {
1.157 noro 1768: int l,i,k,m;
1.1 noro 1769:
1.157 noro 1770: if ( !d )
1771: return;
1772: l = LEN(d);
1773: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
1774: /* 2^(k-1) < l <= 2^k (=m) */
1775: d = nd_add(mod,g->body[k],d);
1776: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
1777: g->body[k] = 0;
1778: d = nd_add(mod,g->body[k+1],d);
1779: }
1780: g->body[k] = d;
1781: g->m = MAX(g->m,k);
1.1 noro 1782: }
1783:
1.113 noro 1784: void mulq_pbucket(PGeoBucket g,Q c)
1.26 noro 1785: {
1.157 noro 1786: int k;
1.26 noro 1787:
1.157 noro 1788: for ( k = 0; k <= g->m; k++ )
1789: nd_mul_c_q(g->body[k],(P)c);
1.26 noro 1790: }
1791:
1.63 noro 1792: NM remove_head_pbucket_symbolic(PGeoBucket g)
1793: {
1.157 noro 1794: int j,i,k,c;
1795: NM head;
1796:
1797: k = g->m;
1798: j = -1;
1799: for ( i = 0; i <= k; i++ ) {
1800: if ( !g->body[i] ) continue;
1801: if ( j < 0 ) j = i;
1802: else {
1803: c = DL_COMPARE(HDL(g->body[i]),HDL(g->body[j]));
1804: if ( c > 0 )
1805: j = i;
1806: else if ( c == 0 )
1807: g->body[i] = nd_remove_head(g->body[i]);
1808: }
1809: }
1810: if ( j < 0 ) return 0;
1811: else {
1812: head = BDY(g->body[j]);
1813: if ( !NEXT(head) ) {
1814: FREEND(g->body[j]);
1815: g->body[j] = 0;
1816: } else {
1817: BDY(g->body[j]) = NEXT(head);
1818: LEN(g->body[j])--;
1819: }
1820: return head;
1821: }
1.63 noro 1822: }
1823:
1.19 noro 1824: int head_pbucket(int mod,PGeoBucket g)
1.1 noro 1825: {
1.157 noro 1826: int j,i,c,k,nv,sum;
1827: UINT *di,*dj;
1828: ND gi,gj;
1829:
1830: k = g->m;
1831: while ( 1 ) {
1832: j = -1;
1833: for ( i = 0; i <= k; i++ ) {
1834: if ( !(gi = g->body[i]) )
1835: continue;
1836: if ( j < 0 ) {
1837: j = i;
1838: gj = g->body[j];
1839: dj = HDL(gj);
1840: sum = HCM(gj);
1841: } else {
1842: c = DL_COMPARE(HDL(gi),dj);
1843: if ( c > 0 ) {
1844: if ( sum ) HCM(gj) = sum;
1845: else g->body[j] = nd_remove_head(gj);
1846: j = i;
1847: gj = g->body[j];
1848: dj = HDL(gj);
1849: sum = HCM(gj);
1850: } else if ( c == 0 ) {
1851: if ( mod == -1 )
1852: sum = _addsf(sum,HCM(gi));
1853: else {
1854: sum = sum+HCM(gi)-mod;
1855: if ( sum < 0 ) sum += mod;
1856: }
1857: g->body[i] = nd_remove_head(gi);
1858: }
1859: }
1860: }
1861: if ( j < 0 ) return -1;
1862: else if ( sum ) {
1863: HCM(gj) = sum;
1864: return j;
1865: } else
1866: g->body[j] = nd_remove_head(gj);
1867: }
1.26 noro 1868: }
1869:
1.113 noro 1870: int head_pbucket_q(PGeoBucket g)
1.26 noro 1871: {
1.157 noro 1872: int j,i,c,k,nv;
1873: Q sum,t;
1874: ND gi,gj;
1875:
1876: k = g->m;
1877: while ( 1 ) {
1878: j = -1;
1879: for ( i = 0; i <= k; i++ ) {
1880: if ( !(gi = g->body[i]) ) continue;
1881: if ( j < 0 ) {
1882: j = i;
1883: gj = g->body[j];
1884: sum = HCQ(gj);
1885: } else {
1886: nv = NV(gi);
1887: c = DL_COMPARE(HDL(gi),HDL(gj));
1888: if ( c > 0 ) {
1889: if ( sum ) HCQ(gj) = sum;
1890: else g->body[j] = nd_remove_head(gj);
1891: j = i;
1892: gj = g->body[j];
1893: sum = HCQ(gj);
1894: } else if ( c == 0 ) {
1895: addq(sum,HCQ(gi),&t);
1896: sum = t;
1897: g->body[i] = nd_remove_head(gi);
1898: }
1899: }
1900: }
1901: if ( j < 0 ) return -1;
1902: else if ( sum ) {
1903: HCQ(gj) = sum;
1904: return j;
1905: } else
1906: g->body[j] = nd_remove_head(gj);
1907: }
1.1 noro 1908: }
1909:
1.232 noro 1910: int head_pbucket_lf(PGeoBucket g)
1911: {
1912: int j,i,c,k,nv;
1913: GZ sum,t;
1914: ND gi,gj;
1915:
1916: k = g->m;
1917: while ( 1 ) {
1918: j = -1;
1919: for ( i = 0; i <= k; i++ ) {
1920: if ( !(gi = g->body[i]) ) continue;
1921: if ( j < 0 ) {
1922: j = i;
1923: gj = g->body[j];
1924: sum = HCZ(gj);
1925: } else {
1926: nv = NV(gi);
1927: c = DL_COMPARE(HDL(gi),HDL(gj));
1928: if ( c > 0 ) {
1929: if ( sum ) HCZ(gj) = sum;
1930: else g->body[j] = nd_remove_head(gj);
1931: j = i;
1932: gj = g->body[j];
1933: sum = HCZ(gj);
1934: } else if ( c == 0 ) {
1935: addlf(sum,HCZ(gi),&t);
1936: sum = t;
1937: g->body[i] = nd_remove_head(gi);
1938: }
1939: }
1940: }
1941: if ( j < 0 ) return -1;
1942: else if ( sum ) {
1943: HCZ(gj) = sum;
1944: return j;
1945: } else
1946: g->body[j] = nd_remove_head(gj);
1947: }
1948: }
1949:
1.25 noro 1950: ND normalize_pbucket(int mod,PGeoBucket g)
1.1 noro 1951: {
1.157 noro 1952: int i;
1953: ND r,t;
1.1 noro 1954:
1.157 noro 1955: r = 0;
1956: for ( i = 0; i <= g->m; i++ ) {
1957: r = nd_add(mod,r,g->body[i]);
1958: g->body[i] = 0;
1959: }
1960: g->m = -1;
1961: return r;
1.1 noro 1962: }
1963:
1.150 noro 1964: #if 0
1965: void register_hcf(NDV p)
1966: {
1.157 noro 1967: DCP dc,t;
1968: P hc,h;
1969: int c;
1970: NODE l,l1,prev;
1971:
1972: hc = p->body->c.p;
1973: if ( !nd_vc || NUM(hc) ) return;
1974: fctrp(nd_vc,hc,&dc);
1975: for ( t = dc; t; t = NEXT(t) ) {
1976: h = t->c;
1977: if ( NUM(h) ) continue;
1978: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
1979: c = compp(nd_vc,h,(P)BDY(l));
1980: if ( c >= 0 ) break;
1981: }
1982: if ( !l || c > 0 ) {
1983: MKNODE(l1,h,l);
1984: if ( !prev )
1985: nd_hcf = l1;
1986: else
1987: NEXT(prev) = l1;
1988: }
1989: }
1.150 noro 1990: }
1991: #else
1992: void register_hcf(NDV p)
1993: {
1.157 noro 1994: DCP dc,t;
1995: P hc,h,q;
1996: Q dmy;
1997: int c;
1998: NODE l,l1,prev;
1999:
2000: hc = p->body->c.p;
2001: if ( NUM(hc) ) return;
2002: ptozp(hc,1,&dmy,&h);
1.150 noro 2003: #if 1
1.157 noro 2004: for ( l = nd_hcf; l; l = NEXT(l) ) {
2005: while ( 1 ) {
2006: if ( divtpz(nd_vc,h,(P)BDY(l),&q) ) h = q;
2007: else break;
2008: }
2009: }
2010: if ( NUM(h) ) return;
1.150 noro 2011: #endif
1.157 noro 2012: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2013: c = compp(nd_vc,h,(P)BDY(l));
2014: if ( c >= 0 ) break;
2015: }
2016: if ( !l || c > 0 ) {
2017: MKNODE(l1,h,l);
2018: if ( !prev )
2019: nd_hcf = l1;
2020: else
2021: NEXT(prev) = l1;
2022: }
1.150 noro 2023: }
2024: #endif
2025:
1.122 noro 2026: int do_diagonalize(int sugar,int m)
1.92 noro 2027: {
1.157 noro 2028: int i,nh,stat;
2029: NODE r,g,t;
2030: ND h,nf,s,head;
2031: NDV nfv;
2032: Q q,num,den;
1.167 noro 2033: P nm,nmp,dn,mnp,dnp,cont,cont1;
2034: union oNDC hc;
2035: NODE node;
2036: LIST l;
2037: Q iq;
1.157 noro 2038:
2039: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
1.172 noro 2040: if ( nd_gentrace ) {
1.167 noro 2041: /* Trace = [1,index,1,1] */
2042: STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2043: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2044: }
1.157 noro 2045: if ( nd_demand )
2046: nfv = ndv_load(i);
2047: else
2048: nfv = nd_ps[i];
2049: s = ndvtond(m,nfv);
2050: s = nd_separate_head(s,&head);
2051: stat = nd_nf(m,head,s,nd_ps,1,0,&nf);
2052: if ( !stat ) return 0;
2053: ndv_free(nfv);
1.167 noro 2054: hc = HCU(nf); nd_removecont(m,nf);
2055: cont = ndc_div(m,hc,HCU(nf));
1.245 noro 2056: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.157 noro 2057: nfv = ndtondv(m,nf);
2058: nd_free(nf);
2059: nd_bound[i] = ndv_compute_bound(nfv);
2060: if ( !m ) register_hcf(nfv);
2061: if ( nd_demand ) {
2062: ndv_save(nfv,i);
2063: ndv_free(nfv);
2064: } else
2065: nd_ps[i] = nfv;
2066: }
2067: return 1;
1.92 noro 2068: }
2069:
1.209 noro 2070: LIST compute_splist()
2071: {
1.245 noro 2072: NODE g,tn0,tn,node;
2073: LIST l0;
2074: ND_pairs d,t;
2075: int i;
2076: Q i1,i2;
1.209 noro 2077:
2078: g = 0; d = 0;
2079: for ( i = 0; i < nd_psn; i++ ) {
2080: d = update_pairs(d,g,i,0);
2081: g = update_base(g,i);
2082: }
1.245 noro 2083: for ( t = d, tn0 = 0; t; t = NEXT(t) ) {
2084: NEXTNODE(tn0,tn);
1.209 noro 2085: STOQ(t->i1,i1); STOQ(t->i2,i2);
2086: node = mknode(2,i1,i2); MKLIST(l0,node);
1.245 noro 2087: BDY(tn) = l0;
2088: }
2089: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
2090: return l0;
1.209 noro 2091: }
2092:
1.27 noro 2093: /* return value = 0 => input is not a GB */
2094:
1.168 noro 2095: NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp)
1.1 noro 2096: {
1.157 noro 2097: int i,nh,sugar,stat;
2098: NODE r,g,t;
2099: ND_pairs d;
2100: ND_pairs l;
2101: ND h,nf,s,head,nf1;
2102: NDV nfv;
2103: Q q,num,den;
1.167 noro 2104: union oNDC dn,hc;
1.157 noro 2105: int diag_count = 0;
1.167 noro 2106: P cont;
2107: LIST list;
1.157 noro 2108:
2109: g = 0; d = 0;
2110: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 2111: d = update_pairs(d,g,i,gensyz);
1.157 noro 2112: g = update_base(g,i);
2113: }
2114: sugar = 0;
2115: while ( d ) {
1.1 noro 2116: again:
1.157 noro 2117: l = nd_minp(d,&d);
1.228 noro 2118: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
1.157 noro 2119: if ( SG(l) != sugar ) {
2120: if ( ishomo ) {
2121: diag_count = 0;
2122: stat = do_diagonalize(sugar,m);
2123: if ( !stat ) {
2124: NEXT(l) = d; d = l;
2125: d = nd_reconstruct(0,d);
2126: goto again;
2127: }
2128: }
2129: sugar = SG(l);
2130: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
2131: }
2132: stat = nd_sp(m,0,l,&h);
2133: if ( !stat ) {
2134: NEXT(l) = d; d = l;
2135: d = nd_reconstruct(0,d);
2136: goto again;
2137: }
1.41 noro 2138: #if USE_GEOBUCKET
1.172 noro 2139: stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!Top,&nf)
1.167 noro 2140: :nd_nf(m,0,h,nd_ps,!Top,0,&nf);
1.41 noro 2141: #else
1.157 noro 2142: stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf);
1.41 noro 2143: #endif
1.157 noro 2144: if ( !stat ) {
2145: NEXT(l) = d; d = l;
2146: d = nd_reconstruct(0,d);
2147: goto again;
2148: } else if ( nf ) {
1.168 noro 2149: if ( checkonly || gensyz ) return 0;
1.245 noro 2150: if ( nd_newelim ) {
2151: if ( nd_module ) {
2152: if ( MPOS(HDL(nf)) > 1 ) return 0;
2153: } else if ( !(HDL(nf)[nd_exporigin] & nd_mask[0]) ) return 0;
2154: }
1.157 noro 2155: if ( DP_Print ) { printf("+"); fflush(stdout); }
1.167 noro 2156: hc = HCU(nf);
1.157 noro 2157: nd_removecont(m,nf);
2158: if ( !m && nd_nalg ) {
2159: nd_monic(0,&nf);
2160: nd_removecont(m,nf);
2161: }
1.172 noro 2162: if ( nd_gentrace ) {
1.245 noro 2163: cont = ndc_div(m,hc,HCU(nf));
2164: if ( m || !UNIQ(cont) ) {
1.196 noro 2165: t = mknode(4,NULLP,NULLP,NULLP,cont);
1.167 noro 2166: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
1.245 noro 2167: nd_tracelist = t;
2168: }
1.167 noro 2169: }
1.157 noro 2170: nfv = ndtondv(m,nf); nd_free(nf);
1.215 noro 2171: nh = ndv_newps(m,nfv,0,0);
1.157 noro 2172: if ( !m && (ishomo && ++diag_count == diag_period) ) {
2173: diag_count = 0;
2174: stat = do_diagonalize(sugar,m);
2175: if ( !stat ) {
2176: NEXT(l) = d; d = l;
2177: d = nd_reconstruct(1,d);
2178: goto again;
2179: }
2180: }
1.168 noro 2181: d = update_pairs(d,g,nh,0);
1.157 noro 2182: g = update_base(g,nh);
2183: FREENDP(l);
2184: } else {
1.245 noro 2185: if ( nd_gentrace && gensyz ) {
1.168 noro 2186: nd_tracelist = reverse_node(nd_tracelist);
1.245 noro 2187: MKLIST(list,nd_tracelist);
1.168 noro 2188: STOQ(-1,q); t = mknode(2,q,list); MKLIST(list,t);
2189: MKNODE(t,list,nd_alltracelist);
1.245 noro 2190: nd_alltracelist = t; nd_tracelist = 0;
2191: }
1.157 noro 2192: if ( DP_Print ) { printf("."); fflush(stdout); }
2193: FREENDP(l);
2194: }
2195: }
1.245 noro 2196: conv_ilist(nd_demand,0,g,indp);
1.157 noro 2197: if ( !checkonly && DP_Print ) { printf("nd_gb done.\n"); fflush(stdout); }
2198: return g;
1.1 noro 2199: }
2200:
1.209 noro 2201: /* splist = [[i1,i2],...] */
2202:
2203: int check_splist(int m,NODE splist)
2204: {
1.245 noro 2205: NODE t,p;
2206: ND_pairs d,r,l;
2207: int stat;
2208: ND h,nf;
1.209 noro 2209:
1.245 noro 2210: for ( d = 0, t = splist; t; t = NEXT(t) ) {
2211: p = BDY((LIST)BDY(t));
1.209 noro 2212: NEXTND_pairs(d,r);
2213: r->i1 = QTOS((Q)ARG0(p)); r->i2 = QTOS((Q)ARG1(p));
2214: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.245 noro 2215: SG(r) = TD(LCM(r)); /* XXX */
2216: }
2217: if ( d ) NEXT(r) = 0;
1.209 noro 2218:
2219: while ( d ) {
2220: again:
2221: l = nd_minp(d,&d);
2222: stat = nd_sp(m,0,l,&h);
2223: if ( !stat ) {
2224: NEXT(l) = d; d = l;
2225: d = nd_reconstruct(0,d);
2226: goto again;
2227: }
2228: stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf);
2229: if ( !stat ) {
2230: NEXT(l) = d; d = l;
2231: d = nd_reconstruct(0,d);
2232: goto again;
2233: } else if ( nf ) return 0;
1.245 noro 2234: if ( DP_Print) { printf("."); fflush(stdout); }
1.209 noro 2235: }
1.245 noro 2236: if ( DP_Print) { printf("done.\n"); fflush(stdout); }
2237: return 1;
1.209 noro 2238: }
2239:
1.214 noro 2240: int check_splist_f4(int m,NODE splist)
2241: {
1.245 noro 2242: UINT *s0vect;
1.214 noro 2243: PGeoBucket bucket;
1.245 noro 2244: NODE p,rp0,t;
2245: ND_pairs d,r,l,ll;
2246: int col,stat;
1.214 noro 2247:
1.245 noro 2248: for ( d = 0, t = splist; t; t = NEXT(t) ) {
2249: p = BDY((LIST)BDY(t));
1.214 noro 2250: NEXTND_pairs(d,r);
2251: r->i1 = QTOS((Q)ARG0(p)); r->i2 = QTOS((Q)ARG1(p));
2252: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.245 noro 2253: SG(r) = TD(LCM(r)); /* XXX */
2254: }
2255: if ( d ) NEXT(r) = 0;
1.214 noro 2256:
2257: while ( d ) {
2258: l = nd_minsugarp(d,&d);
2259: bucket = create_pbucket();
2260: stat = nd_sp_f4(m,0,l,bucket);
2261: if ( !stat ) {
2262: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
2263: NEXT(ll) = d; d = l;
2264: d = nd_reconstruct(0,d);
2265: continue;
2266: }
2267: if ( bucket->m < 0 ) continue;
2268: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
2269: if ( !col ) {
2270: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
2271: NEXT(ll) = d; d = l;
2272: d = nd_reconstruct(0,d);
2273: continue;
2274: }
2275: if ( nd_f4_red(m,l,0,s0vect,col,rp0,0) ) return 0;
2276: }
2277: return 1;
2278: }
2279:
1.122 noro 2280: int do_diagonalize_trace(int sugar,int m)
1.91 noro 2281: {
1.157 noro 2282: int i,nh,stat;
2283: NODE r,g,t;
2284: ND h,nf,nfq,s,head;
2285: NDV nfv,nfqv;
2286: Q q,den,num;
1.167 noro 2287: union oNDC hc;
2288: NODE node;
2289: LIST l;
2290: Q iq;
2291: P cont,cont1;
1.157 noro 2292:
2293: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
1.172 noro 2294: if ( nd_gentrace ) {
1.167 noro 2295: /* Trace = [1,index,1,1] */
2296: STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2297: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2298: }
1.157 noro 2299: /* for nd_ps */
2300: s = ndvtond(m,nd_ps[i]);
2301: s = nd_separate_head(s,&head);
2302: stat = nd_nf_pbucket(m,s,nd_ps,1,&nf);
2303: if ( !stat ) return 0;
2304: nf = nd_add(m,head,nf);
2305: ndv_free(nd_ps[i]);
2306: nd_ps[i] = ndtondv(m,nf);
2307: nd_free(nf);
2308:
2309: /* for nd_ps_trace */
2310: if ( nd_demand )
2311: nfv = ndv_load(i);
2312: else
2313: nfv = nd_ps_trace[i];
2314: s = ndvtond(0,nfv);
2315: s = nd_separate_head(s,&head);
2316: stat = nd_nf(0,head,s,nd_ps_trace,1,0,&nf);
2317: if ( !stat ) return 0;
2318: ndv_free(nfv);
1.167 noro 2319: hc = HCU(nf); nd_removecont(0,nf);
1.245 noro 2320: cont = ndc_div(0,hc,HCU(nf));
1.172 noro 2321: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.157 noro 2322: nfv = ndtondv(0,nf);
2323: nd_free(nf);
2324: nd_bound[i] = ndv_compute_bound(nfv);
2325: register_hcf(nfv);
2326: if ( nd_demand ) {
2327: ndv_save(nfv,i);
2328: ndv_free(nfv);
2329: } else
2330: nd_ps_trace[i] = nfv;
2331: }
2332: return 1;
1.91 noro 2333: }
2334:
1.118 noro 2335: static struct oEGT eg_invdalg;
2336: struct oEGT eg_le;
2337:
1.147 noro 2338: void nd_subst_vector(VL vl,P p,NODE subst,P *r)
2339: {
1.157 noro 2340: NODE tn;
2341: P p1;
1.147 noro 2342:
1.157 noro 2343: for ( tn = subst; tn; tn = NEXT(NEXT(tn)) ) {
2344: substp(vl,p,BDY(tn),BDY(NEXT(tn)),&p1); p = p1;
2345: }
2346: *r = p;
1.147 noro 2347: }
2348:
1.167 noro 2349: NODE nd_gb_trace(int m,int ishomo,int **indp)
1.20 noro 2350: {
1.157 noro 2351: int i,nh,sugar,stat;
2352: NODE r,g,t;
2353: ND_pairs d;
2354: ND_pairs l;
2355: ND h,nf,nfq,s,head;
2356: NDV nfv,nfqv;
2357: Q q,den,num;
2358: P hc;
1.167 noro 2359: union oNDC dn,hnfq;
1.157 noro 2360: struct oEGT eg_monic,egm0,egm1;
2361: int diag_count = 0;
1.167 noro 2362: P cont;
2363: LIST list;
1.157 noro 2364:
2365: init_eg(&eg_monic);
2366: init_eg(&eg_invdalg);
2367: init_eg(&eg_le);
2368: g = 0; d = 0;
2369: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 2370: d = update_pairs(d,g,i,0);
1.157 noro 2371: g = update_base(g,i);
2372: }
2373: sugar = 0;
2374: while ( d ) {
1.20 noro 2375: again:
1.157 noro 2376: l = nd_minp(d,&d);
1.228 noro 2377: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
1.157 noro 2378: if ( SG(l) != sugar ) {
1.130 noro 2379: #if 1
1.157 noro 2380: if ( ishomo ) {
2381: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2382: stat = do_diagonalize_trace(sugar,m);
2383: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2384: diag_count = 0;
2385: if ( !stat ) {
2386: NEXT(l) = d; d = l;
2387: d = nd_reconstruct(1,d);
2388: goto again;
2389: }
2390: }
1.130 noro 2391: #endif
1.157 noro 2392: sugar = SG(l);
2393: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
2394: }
2395: stat = nd_sp(m,0,l,&h);
2396: if ( !stat ) {
2397: NEXT(l) = d; d = l;
2398: d = nd_reconstruct(1,d);
2399: goto again;
2400: }
1.41 noro 2401: #if USE_GEOBUCKET
1.157 noro 2402: stat = nd_nf_pbucket(m,h,nd_ps,!Top,&nf);
1.41 noro 2403: #else
1.157 noro 2404: stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf);
1.41 noro 2405: #endif
1.157 noro 2406: if ( !stat ) {
2407: NEXT(l) = d; d = l;
2408: d = nd_reconstruct(1,d);
2409: goto again;
2410: } else if ( nf ) {
2411: if ( nd_demand ) {
2412: nfqv = ndv_load(nd_psn);
2413: nfq = ndvtond(0,nfqv);
2414: } else
2415: nfq = 0;
2416: if ( !nfq ) {
2417: if ( !nd_sp(0,1,l,&h) || !nd_nf(0,0,h,nd_ps_trace,!Top,0,&nfq) ) {
2418: NEXT(l) = d; d = l;
2419: d = nd_reconstruct(1,d);
2420: goto again;
2421: }
2422: }
2423: if ( nfq ) {
2424: /* m|HC(nfq) => failure */
2425: if ( nd_vc ) {
2426: nd_subst_vector(nd_vc,HCP(nfq),nd_subst,&hc); q = (Q)hc;
2427: } else
2428: q = HCQ(nfq);
2429: if ( !rem(NM(q),m) ) return 0;
2430:
2431: if ( DP_Print ) { printf("+"); fflush(stdout); }
1.167 noro 2432: hnfq = HCU(nfq);
1.157 noro 2433: if ( nd_nalg ) {
2434: /* m|DN(HC(nf)^(-1)) => failure */
2435: get_eg(&egm0);
2436: if ( !nd_monic(m,&nfq) ) return 0;
2437: get_eg(&egm1); add_eg(&eg_monic,&egm0,&egm1);
2438: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
2439: nfv = ndv_dup(0,nfqv); ndv_mod(m,nfv); nd_free(nf);
2440: } else {
2441: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
2442: nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf);
2443: }
1.172 noro 2444: if ( nd_gentrace ) {
1.245 noro 2445: cont = ndc_div(0,hnfq,HCU(nfqv));
2446: if ( !UNIQ(cont) ) {
1.196 noro 2447: t = mknode(4,NULLP,NULLP,NULLP,cont);
1.167 noro 2448: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
1.245 noro 2449: nd_tracelist = t;
2450: }
1.167 noro 2451: }
1.215 noro 2452: nh = ndv_newps(0,nfv,nfqv,0);
1.157 noro 2453: if ( ishomo && ++diag_count == diag_period ) {
2454: diag_count = 0;
2455: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2456: stat = do_diagonalize_trace(sugar,m);
2457: if ( DP_Print > 2 ) fprintf(asir_out,"|");
2458: if ( !stat ) {
2459: NEXT(l) = d; d = l;
2460: d = nd_reconstruct(1,d);
2461: goto again;
2462: }
2463: }
1.168 noro 2464: d = update_pairs(d,g,nh,0);
1.157 noro 2465: g = update_base(g,nh);
2466: } else {
2467: if ( DP_Print ) { printf("*"); fflush(stdout); }
2468: }
2469: } else {
2470: if ( DP_Print ) { printf("."); fflush(stdout); }
2471: }
2472: FREENDP(l);
2473: }
2474: if ( nd_nalg ) {
1.227 noro 2475: if ( DP_Print ) {
2476: print_eg("monic",&eg_monic);
2477: print_eg("invdalg",&eg_invdalg);
2478: print_eg("le",&eg_le);
2479: }
1.157 noro 2480: }
1.245 noro 2481: conv_ilist(nd_demand,1,g,indp);
1.157 noro 2482: if ( DP_Print ) { printf("nd_gb_trace done.\n"); fflush(stdout); }
2483: return g;
1.20 noro 2484: }
2485:
1.23 noro 2486: int ndv_compare(NDV *p1,NDV *p2)
2487: {
1.157 noro 2488: return DL_COMPARE(HDL(*p1),HDL(*p2));
1.23 noro 2489: }
2490:
2491: int ndv_compare_rev(NDV *p1,NDV *p2)
2492: {
1.157 noro 2493: return -DL_COMPARE(HDL(*p1),HDL(*p2));
1.23 noro 2494: }
2495:
1.167 noro 2496: int ndvi_compare(NDVI p1,NDVI p2)
2497: {
2498: return DL_COMPARE(HDL(p1->p),HDL(p2->p));
2499: }
2500:
2501: int ndvi_compare_rev(NDVI p1,NDVI p2)
2502: {
2503: return -DL_COMPARE(HDL(p1->p),HDL(p2->p));
2504: }
2505:
1.61 noro 2506: NODE ndv_reduceall(int m,NODE f)
1.23 noro 2507: {
1.167 noro 2508: int i,j,n,stat;
1.157 noro 2509: ND nf,g,head;
2510: NODE t,a0,a;
2511: union oNDC dn;
2512: Q q,num,den;
1.167 noro 2513: NODE node;
1.245 noro 2514: LIST l;
2515: Q iq,jq;
1.167 noro 2516: int *perm;
2517: union oNDC hc;
2518: P cont,cont1;
1.23 noro 2519:
1.173 noro 2520: if ( nd_nora ) return f;
1.157 noro 2521: n = length(f);
2522: ndv_setup(m,0,f,0,1);
1.245 noro 2523: perm = (int *)MALLOC(n*sizeof(int));
2524: if ( nd_gentrace ) {
2525: for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) )
2526: perm[i] = QTOS((Q)ARG1(BDY((LIST)BDY(t))));
2527: }
1.157 noro 2528: for ( i = 0; i < n; ) {
1.172 noro 2529: if ( nd_gentrace ) {
1.167 noro 2530: /* Trace = [1,index,1,1] */
2531: STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2532: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2533: }
1.157 noro 2534: g = ndvtond(m,nd_ps[i]);
2535: g = nd_separate_head(g,&head);
2536: stat = nd_nf(m,head,g,nd_ps,1,0,&nf);
2537: if ( !stat )
2538: nd_reconstruct(0,0);
2539: else {
2540: if ( DP_Print ) { printf("."); fflush(stdout); }
2541: ndv_free(nd_ps[i]);
1.167 noro 2542: hc = HCU(nf); nd_removecont(m,nf);
1.172 noro 2543: if ( nd_gentrace ) {
1.245 noro 2544: for ( t = nd_tracelist; t; t = NEXT(t) ) {
1.167 noro 2545: jq = ARG1(BDY((LIST)BDY(t))); j = QTOS(jq);
2546: STOQ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq;
2547: }
2548: cont = ndc_div(m,hc,HCU(nf));
2549: finalize_tracelist(perm[i],cont);
2550: }
1.157 noro 2551: nd_ps[i] = ndtondv(m,nf); nd_free(nf);
2552: nd_bound[i] = ndv_compute_bound(nd_ps[i]);
2553: i++;
2554: }
2555: }
2556: if ( DP_Print ) { printf("\n"); }
2557: for ( a0 = 0, i = 0; i < n; i++ ) {
2558: NEXTNODE(a0,a);
1.245 noro 2559: if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i];
2560: else {
2561: for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break;
2562: BDY(a) = (pointer)nd_ps[j];
2563: }
1.157 noro 2564: }
2565: NEXT(a) = 0;
2566: return a0;
1.23 noro 2567: }
2568:
1.168 noro 2569: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz)
1.1 noro 2570: {
1.157 noro 2571: ND_pairs d1,nd,cur,head,prev,remove;
1.1 noro 2572:
1.157 noro 2573: if ( !g ) return d;
1.245 noro 2574: /* for testing */
2575: if ( gensyz && nd_gensyz == 2 ) {
2576: d1 = nd_newpairs(g,t);
2577: if ( !d )
2578: return d1;
2579: else {
2580: nd = d;
2581: while ( NEXT(nd) ) nd = NEXT(nd);
2582: NEXT(nd) = d1;
2583: return d;
2584: }
2585: }
1.157 noro 2586: d = crit_B(d,t);
2587: d1 = nd_newpairs(g,t);
2588: d1 = crit_M(d1);
2589: d1 = crit_F(d1);
1.168 noro 2590: if ( gensyz || do_weyl )
1.157 noro 2591: head = d1;
2592: else {
2593: prev = 0; cur = head = d1;
2594: while ( cur ) {
2595: if ( crit_2( cur->i1,cur->i2 ) ) {
2596: remove = cur;
2597: if ( !prev ) head = cur = NEXT(cur);
2598: else cur = NEXT(prev) = NEXT(cur);
2599: FREENDP(remove);
2600: } else {
2601: prev = cur; cur = NEXT(cur);
2602: }
2603: }
2604: }
2605: if ( !d )
2606: return head;
2607: else {
2608: nd = d;
2609: while ( NEXT(nd) ) nd = NEXT(nd);
2610: NEXT(nd) = head;
2611: return d;
2612: }
1.1 noro 2613: }
2614:
1.157 noro 2615:
1.1 noro 2616: ND_pairs nd_newpairs( NODE g, int t )
2617: {
1.157 noro 2618: NODE h;
2619: UINT *dl;
1.187 noro 2620: int ts,s,i,t0,min,max;
1.157 noro 2621: ND_pairs r,r0;
2622:
2623: dl = DL(nd_psh[t]);
2624: ts = SG(nd_psh[t]) - TD(dl);
1.245 noro 2625: if ( nd_module && nd_intersect && (MPOS(dl) > 1) ) return 0;
1.157 noro 2626: for ( r0 = 0, h = g; h; h = NEXT(h) ) {
1.159 noro 2627: if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) )
1.157 noro 2628: continue;
1.245 noro 2629: if ( nd_gbblock ) {
2630: t0 = (long)BDY(h);
2631: for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) {
2632: min = nd_gbblock[i]; max = nd_gbblock[i+1];
2633: if ( t0 >= min && t0 <= max && t >= min && t <= max )
2634: break;
2635: }
2636: if ( nd_gbblock[i] >= 0 )
2637: continue;
2638: }
1.157 noro 2639: NEXTND_pairs(r0,r);
1.159 noro 2640: r->i1 = (long)BDY(h);
1.157 noro 2641: r->i2 = t;
2642: ndl_lcm(DL(nd_psh[r->i1]),dl,r->lcm);
2643: s = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
2644: SG(r) = MAX(s,ts) + TD(LCM(r));
1.231 noro 2645: /* experimental */
2646: if ( nd_sugarweight )
2647: r->sugar2 = ndl_weight2(r->lcm);
1.157 noro 2648: }
2649: if ( r0 ) NEXT(r) = 0;
2650: return r0;
1.1 noro 2651: }
2652:
1.231 noro 2653: /* ipair = [i1,i2],[i1,i2],... */
2654: ND_pairs nd_ipairtospair(NODE ipair)
2655: {
2656: int s1,s2;
2657: NODE tn,t;
2658: ND_pairs r,r0;
2659:
2660: for ( r0 = 0, t = ipair; t; t = NEXT(t) ) {
2661: NEXTND_pairs(r0,r);
2662: tn = BDY((LIST)BDY(t));
2663: r->i1 = QTOS((Q)ARG0(tn));
2664: r->i2 = QTOS((Q)ARG1(tn));
2665: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
2666: s1 = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
2667: s2 = SG(nd_psh[r->i2])-TD(DL(nd_psh[r->i2]));
2668: SG(r) = MAX(s1,s2) + TD(LCM(r));
2669: /* experimental */
2670: if ( nd_sugarweight )
2671: r->sugar2 = ndl_weight2(r->lcm);
2672: }
2673: if ( r0 ) NEXT(r) = 0;
2674: return r0;
2675: }
2676:
1.157 noro 2677: /* kokokara */
2678:
1.1 noro 2679: ND_pairs crit_B( ND_pairs d, int s )
2680: {
1.157 noro 2681: ND_pairs cur,head,prev,remove;
2682: UINT *t,*tl,*lcm;
2683: int td,tdl;
2684:
2685: if ( !d ) return 0;
2686: t = DL(nd_psh[s]);
2687: prev = 0;
2688: head = cur = d;
1.235 noro 2689: lcm = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
1.157 noro 2690: while ( cur ) {
2691: tl = cur->lcm;
1.163 noro 2692: if ( ndl_reducible(tl,t) ) {
2693: ndl_lcm(DL(nd_psh[cur->i1]),t,lcm);
1.167 noro 2694: if ( !ndl_equal(lcm,tl) ) {
2695: ndl_lcm(DL(nd_psh[cur->i2]),t,lcm);
2696: if (!ndl_equal(lcm,tl)) {
2697: remove = cur;
2698: if ( !prev ) {
2699: head = cur = NEXT(cur);
2700: } else {
2701: cur = NEXT(prev) = NEXT(cur);
2702: }
2703: FREENDP(remove);
2704: } else {
2705: prev = cur; cur = NEXT(cur);
2706: }
2707: } else {
2708: prev = cur; cur = NEXT(cur);
2709: }
1.157 noro 2710: } else {
2711: prev = cur; cur = NEXT(cur);
2712: }
2713: }
2714: return head;
1.1 noro 2715: }
2716:
2717: ND_pairs crit_M( ND_pairs d1 )
2718: {
1.157 noro 2719: ND_pairs e,d2,d3,dd,p;
2720: UINT *id,*jd;
1.1 noro 2721:
1.157 noro 2722: if ( !d1 ) return d1;
2723: for ( dd = 0, e = d1; e; e = d3 ) {
2724: if ( !(d2 = NEXT(e)) ) {
2725: NEXT(e) = dd;
2726: return e;
2727: }
2728: id = LCM(e);
2729: for ( d3 = 0; d2; d2 = p ) {
2730: p = NEXT(d2);
2731: jd = LCM(d2);
2732: if ( ndl_equal(jd,id) )
2733: ;
2734: else if ( TD(jd) > TD(id) )
2735: if ( ndl_reducible(jd,id) ) continue;
2736: else ;
2737: else if ( ndl_reducible(id,jd) ) goto delit;
2738: NEXT(d2) = d3;
2739: d3 = d2;
2740: }
2741: NEXT(e) = dd;
2742: dd = e;
2743: continue;
2744: /**/
2745: delit: NEXT(d2) = d3;
2746: d3 = d2;
2747: for ( ; p; p = d2 ) {
2748: d2 = NEXT(p);
2749: NEXT(p) = d3;
2750: d3 = p;
2751: }
2752: FREENDP(e);
2753: }
2754: return dd;
1.1 noro 2755: }
2756:
2757: ND_pairs crit_F( ND_pairs d1 )
2758: {
1.157 noro 2759: ND_pairs rest, head,remove;
2760: ND_pairs last, p, r, w;
2761: int s;
2762:
2763: if ( !d1 ) return d1;
2764: for ( head = last = 0, p = d1; NEXT(p); ) {
2765: r = w = equivalent_pairs(p,&rest);
2766: s = SG(r);
2767: w = NEXT(w);
2768: while ( w ) {
2769: if ( crit_2(w->i1,w->i2) ) {
2770: r = w;
2771: w = NEXT(w);
2772: while ( w ) {
2773: remove = w;
2774: w = NEXT(w);
2775: FREENDP(remove);
2776: }
2777: break;
2778: } else if ( SG(w) < s ) {
2779: FREENDP(r);
2780: r = w;
2781: s = SG(r);
2782: w = NEXT(w);
2783: } else {
2784: remove = w;
2785: w = NEXT(w);
2786: FREENDP(remove);
2787: }
2788: }
2789: if ( last ) NEXT(last) = r;
2790: else head = r;
2791: NEXT(last = r) = 0;
2792: p = rest;
2793: if ( !p ) return head;
2794: }
2795: if ( !last ) return p;
2796: NEXT(last) = p;
2797: return head;
1.1 noro 2798: }
2799:
2800: int crit_2( int dp1, int dp2 )
2801: {
1.157 noro 2802: return ndl_disjoint(DL(nd_psh[dp1]),DL(nd_psh[dp2]));
1.1 noro 2803: }
2804:
1.40 noro 2805: ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest )
1.1 noro 2806: {
1.157 noro 2807: ND_pairs w,p,r,s;
2808: UINT *d;
1.1 noro 2809:
1.157 noro 2810: w = d1;
2811: d = LCM(w);
2812: s = NEXT(w);
2813: NEXT(w) = 0;
2814: for ( r = 0; s; s = p ) {
2815: p = NEXT(s);
2816: if ( ndl_equal(d,LCM(s)) ) {
2817: NEXT(s) = w; w = s;
2818: } else {
2819: NEXT(s) = r; r = s;
2820: }
2821: }
2822: *prest = r;
2823: return w;
1.1 noro 2824: }
2825:
2826: NODE update_base(NODE nd,int ndp)
2827: {
1.157 noro 2828: UINT *dl, *dln;
2829: NODE last, p, head;
1.1 noro 2830:
1.157 noro 2831: dl = DL(nd_psh[ndp]);
2832: for ( head = last = 0, p = nd; p; ) {
1.159 noro 2833: dln = DL(nd_psh[(long)BDY(p)]);
1.157 noro 2834: if ( ndl_reducible( dln, dl ) ) {
2835: p = NEXT(p);
2836: if ( last ) NEXT(last) = p;
2837: } else {
2838: if ( !last ) head = p;
2839: p = NEXT(last = p);
2840: }
2841: }
2842: head = append_one(head,ndp);
2843: return head;
1.1 noro 2844: }
2845:
2846: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest )
2847: {
1.157 noro 2848: ND_pairs m,ml,p,l;
2849: UINT *lcm;
2850: int s,td,len,tlen,c,c1;
2851:
2852: if ( !(p = NEXT(m = d)) ) {
2853: *prest = p;
2854: NEXT(m) = 0;
2855: return m;
2856: }
2857: if ( !NoSugar ) {
1.231 noro 2858: if ( nd_sugarweight ) {
2859: s = m->sugar2;
2860: for ( ml = 0, l = m; p; p = NEXT(l = p) )
2861: if ( (p->sugar2 < s)
2862: || ((p->sugar2 == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
2863: ml = l; m = p; s = m->sugar2;
2864: }
2865: } else {
2866: s = SG(m);
2867: for ( ml = 0, l = m; p; p = NEXT(l = p) )
2868: if ( (SG(p) < s)
2869: || ((SG(p) == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
2870: ml = l; m = p; s = SG(m);
2871: }
2872: }
1.157 noro 2873: } else {
2874: for ( ml = 0, l = m; p; p = NEXT(l = p) )
2875: if ( DL_COMPARE(LCM(p),LCM(m)) < 0 ) {
2876: ml = l; m = p; s = SG(m);
2877: }
2878: }
2879: if ( !ml ) *prest = NEXT(m);
2880: else {
2881: NEXT(ml) = NEXT(m);
2882: *prest = d;
2883: }
2884: NEXT(m) = 0;
2885: return m;
1.1 noro 2886: }
2887:
1.63 noro 2888: ND_pairs nd_minsugarp( ND_pairs d, ND_pairs *prest )
2889: {
1.157 noro 2890: int msugar,i;
2891: ND_pairs t,dm0,dm,dr0,dr;
1.63 noro 2892:
1.231 noro 2893: if ( nd_sugarweight ) {
2894: for ( msugar = d->sugar2, t = NEXT(d); t; t = NEXT(t) )
2895: if ( t->sugar2 < msugar ) msugar = t->sugar2;
2896: dm0 = 0; dr0 = 0;
2897: for ( i = 0, t = d; t; t = NEXT(t) )
2898: if ( i < nd_f4_nsp && t->sugar2 == msugar ) {
2899: if ( dm0 ) NEXT(dm) = t;
2900: else dm0 = t;
2901: dm = t;
2902: i++;
2903: } else {
2904: if ( dr0 ) NEXT(dr) = t;
2905: else dr0 = t;
2906: dr = t;
2907: }
2908: } else {
2909: for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) )
2910: if ( SG(t) < msugar ) msugar = SG(t);
2911: dm0 = 0; dr0 = 0;
2912: for ( i = 0, t = d; t; t = NEXT(t) )
2913: if ( i < nd_f4_nsp && SG(t) == msugar ) {
2914: if ( dm0 ) NEXT(dm) = t;
2915: else dm0 = t;
2916: dm = t;
2917: i++;
2918: } else {
2919: if ( dr0 ) NEXT(dr) = t;
2920: else dr0 = t;
2921: dr = t;
2922: }
2923: }
1.157 noro 2924: NEXT(dm) = 0;
2925: if ( dr0 ) NEXT(dr) = 0;
2926: *prest = dr0;
2927: return dm0;
1.63 noro 2928: }
2929:
1.239 noro 2930: int nd_tdeg(NDV c)
2931: {
2932: int wmax = 0;
2933: int i,len;
2934: NMV a;
2935:
2936: len = LEN(c);
2937: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
2938: wmax = MAX(TD(DL(a)),wmax);
2939: return wmax;
2940: }
2941:
1.215 noro 2942: int ndv_newps(int m,NDV a,NDV aq,int f4)
1.1 noro 2943: {
1.157 noro 2944: int len;
2945: RHist r;
2946: NDV b;
1.167 noro 2947: NODE tn;
2948: LIST l;
2949: Q iq;
1.157 noro 2950:
2951: if ( nd_psn == nd_pslen ) {
2952: nd_pslen *= 2;
2953: nd_ps = (NDV *)REALLOC((char *)nd_ps,nd_pslen*sizeof(NDV));
1.215 noro 2954: nd_ps_gz = (NDV *)REALLOC((char *)nd_ps_gz,nd_pslen*sizeof(NDV));
1.157 noro 2955: nd_ps_trace = (NDV *)REALLOC((char *)nd_ps_trace,nd_pslen*sizeof(NDV));
2956: nd_psh = (RHist *)REALLOC((char *)nd_psh,nd_pslen*sizeof(RHist));
2957: nd_bound = (UINT **)
2958: REALLOC((char *)nd_bound,nd_pslen*sizeof(UINT *));
1.215 noro 2959: nd_ps_sym = (NDV *)REALLOC((char *)nd_ps_sym,nd_pslen*sizeof(NDV));
2960: nd_ps_trace_sym = (NDV *)REALLOC((char *)nd_ps_trace_sym,nd_pslen*sizeof(NDV));
1.157 noro 2961: }
2962: NEWRHist(r); nd_psh[nd_psn] = r;
2963: nd_ps[nd_psn] = a;
2964: if ( aq ) {
2965: nd_ps_trace[nd_psn] = aq;
1.234 noro 2966: if ( !m ) {
1.245 noro 2967: if ( !nd_vc ) nd_ps_gz[nd_psn] = ndvtondvgz(aq);
1.234 noro 2968: register_hcf(aq);
2969: } else if ( m == -2 ) {
2970: /* do nothing */
2971: } else
2972: error("ndv_newps : invalud modulus");
1.157 noro 2973: nd_bound[nd_psn] = ndv_compute_bound(aq);
1.239 noro 2974: #if 1
2975: SG(r) = SG(aq);
2976: #else
2977: SG(r) = nd_tdeg(aq);
2978: #endif
2979: ndl_copy(HDL(aq),DL(r));
1.157 noro 2980: } else {
2981: if ( !m ) register_hcf(a);
2982: nd_bound[nd_psn] = ndv_compute_bound(a);
1.239 noro 2983: #if 1
2984: SG(r) = SG(a);
2985: #else
2986: SG(r) = nd_tdeg(a);
2987: #endif
2988: ndl_copy(HDL(a),DL(r));
1.245 noro 2989: if ( !m && !nd_vc ) nd_ps_gz[nd_psn] = ndvtondvgz(a);
1.157 noro 2990: }
2991: if ( nd_demand ) {
2992: if ( aq ) {
2993: ndv_save(nd_ps_trace[nd_psn],nd_psn);
1.235 noro 2994: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
1.215 noro 2995: nd_ps_trace_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
1.157 noro 2996: nd_ps_trace[nd_psn] = 0;
2997: } else {
2998: ndv_save(nd_ps[nd_psn],nd_psn);
1.215 noro 2999: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps[nd_psn]);
1.157 noro 3000: nd_ps[nd_psn] = 0;
3001: }
3002: }
1.172 noro 3003: if ( nd_gentrace ) {
1.167 noro 3004: /* reverse the tracelist and append it to alltracelist */
3005: nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist);
3006: STOQ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn);
3007: MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0;
3008: }
1.157 noro 3009: return nd_psn++;
1.1 noro 3010: }
3011:
1.167 noro 3012: /* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */
1.177 noro 3013: /* return 1 if success, 0 if failure (HC(a mod p)) */
1.167 noro 3014:
1.177 noro 3015: int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont)
1.1 noro 3016: {
1.157 noro 3017: int i,j,td,len,max;
1.167 noro 3018: NODE s,s0,f0,tn;
1.157 noro 3019: UINT *d;
3020: RHist r;
1.167 noro 3021: NDVI w;
1.157 noro 3022: NDV a,am;
1.167 noro 3023: union oNDC hc;
3024: NODE node;
3025: P hcp;
3026: Q iq,jq,hcq;
3027: LIST l;
1.157 noro 3028:
3029: nd_found = 0; nd_notfirst = 0; nd_create = 0;
1.167 noro 3030: /* initialize the tracelist */
3031: nd_tracelist = 0;
1.157 noro 3032:
3033: for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++;
1.235 noro 3034: w = (NDVI)MALLOC(nd_psn*sizeof(struct oNDVI));
1.167 noro 3035: for ( i = j = 0, s = f; s; s = NEXT(s), j++ )
3036: if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; }
1.157 noro 3037: if ( !dont_sort ) {
3038: /* XXX heuristic */
3039: if ( !nd_ord->id && (nd_ord->ord.simple<2) )
1.167 noro 3040: qsort(w,nd_psn,sizeof(struct oNDVI),
3041: (int (*)(const void *,const void *))ndvi_compare_rev);
1.157 noro 3042: else
1.167 noro 3043: qsort(w,nd_psn,sizeof(struct oNDVI),
3044: (int (*)(const void *,const void *))ndvi_compare);
1.157 noro 3045: }
3046: nd_pslen = 2*nd_psn;
3047: nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.215 noro 3048: nd_ps_gz = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.157 noro 3049: nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.215 noro 3050: nd_ps_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
3051: nd_ps_trace_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1.157 noro 3052: nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist));
3053: nd_bound = (UINT **)MALLOC(nd_pslen*sizeof(UINT *));
3054: nd_hcf = 0;
3055:
3056: if ( trace && nd_vc )
3057: makesubst(nd_vc,&nd_subst);
3058: else
3059: nd_subst = 0;
3060:
3061: if ( !nd_red )
3062: nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
3063: for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0;
3064: for ( i = 0; i < nd_psn; i++ ) {
1.167 noro 3065: hc = HCU(w[i].p);
1.157 noro 3066: if ( trace ) {
1.234 noro 3067: if ( mod == -2 ) {
3068: /* over a large finite field */
3069: /* trace = small modulus */
3070: a = nd_ps_trace[i] = ndv_dup(-2,w[i].p);
3071: ndv_mod(-2,a);
3072: if ( !dont_removecont) ndv_removecont(-2,a);
3073: am = nd_ps[i] = ndv_dup(trace,w[i].p);
3074: ndv_mod(trace,am);
1.245 noro 3075: if ( DL_COMPARE(HDL(am),HDL(a)) )
3076: return 0;
1.234 noro 3077: ndv_removecont(trace,am);
3078: } else {
3079: a = nd_ps_trace[i] = ndv_dup(0,w[i].p);
1.245 noro 3080: if ( !nd_vc ) nd_ps_gz[i] = ndvtondvgz(a);
1.234 noro 3081: if ( !dont_removecont) ndv_removecont(0,a);
3082: register_hcf(a);
3083: am = nd_ps[i] = ndv_dup(mod,a);
3084: ndv_mod(mod,am);
1.245 noro 3085: if ( DL_COMPARE(HDL(am),HDL(a)) )
3086: return 0;
1.234 noro 3087: ndv_removecont(mod,am);
3088: }
1.157 noro 3089: } else {
1.167 noro 3090: a = nd_ps[i] = ndv_dup(mod,w[i].p);
1.245 noro 3091: if ( !mod && !nd_vc ) nd_ps_gz[i] = ndvtondvgz(a);
1.157 noro 3092: if ( mod || !dont_removecont ) ndv_removecont(mod,a);
3093: if ( !mod ) register_hcf(a);
3094: }
1.172 noro 3095: if ( nd_gentrace ) {
1.167 noro 3096: STOQ(i,iq); STOQ(w[i].i,jq); node = mknode(3,iq,jq,ONE);
1.245 noro 3097: if ( !dont_removecont )
1.168 noro 3098: ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a));
1.167 noro 3099: MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l;
3100: }
1.157 noro 3101: NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r));
3102: nd_bound[i] = ndv_compute_bound(a);
3103: nd_psh[i] = r;
3104: if ( nd_demand ) {
3105: if ( trace ) {
3106: ndv_save(nd_ps_trace[i],i);
1.235 noro 3107: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
1.215 noro 3108: nd_ps_trace_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
1.157 noro 3109: nd_ps_trace[i] = 0;
3110: } else {
3111: ndv_save(nd_ps[i],i);
1.215 noro 3112: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps[i]);
1.157 noro 3113: nd_ps[i] = 0;
3114: }
3115: }
3116: }
1.172 noro 3117: if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0;
1.177 noro 3118: return 1;
1.20 noro 3119: }
3120:
1.119 noro 3121: struct order_spec *append_block(struct order_spec *spec,
3122: int nv,int nalg,int ord);
3123:
1.121 noro 3124: extern VECT current_dl_weight_vector_obj;
3125: static VECT prev_weight_vector_obj;
3126:
1.120 noro 3127: void preprocess_algcoef(VL vv,VL av,struct order_spec *ord,LIST f,
1.157 noro 3128: struct order_spec **ord1p,LIST *f1p,NODE *alistp)
1.120 noro 3129: {
1.157 noro 3130: NODE alist,t,s,r0,r,arg;
3131: VL tv;
3132: P poly;
3133: DP d;
3134: Alg alpha,dp;
3135: DAlg inv,da,hc;
3136: MP m;
3137: int i,nvar,nalg,n;
3138: NumberField nf;
3139: LIST f1,f2;
3140: struct order_spec *current_spec;
3141: VECT obj,obj0;
1.232 noro 3142: VECT tmp;
1.157 noro 3143:
3144: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++);
3145: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++);
3146:
3147: for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) {
3148: NEXTNODE(alist,t); MKV(tv->v,poly);
3149: MKAlg(poly,alpha); BDY(t) = (pointer)alpha;
3150: tv->v = tv->v->priv;
3151: }
3152: NEXT(t) = 0;
3153:
1.167 noro 3154: /* simplification, making polynomials monic */
1.157 noro 3155: setfield_dalg(alist);
1.232 noro 3156: obj_algtodalg((Obj)f,(Obj *)&f1);
1.157 noro 3157: for ( t = BDY(f); t; t = NEXT(t) ) {
3158: initd(ord); ptod(vv,vv,(P)BDY(t),&d);
3159: hc = (DAlg)BDY(d)->c;
3160: if ( NID(hc) == N_DA ) {
3161: invdalg(hc,&inv);
3162: for ( m = BDY(d); m; m = NEXT(m) ) {
1.238 noro 3163: muldalg(inv,(DAlg)m->c,&da); m->c = (Obj)da;
1.157 noro 3164: }
3165: }
1.238 noro 3166: initd(ord); dtop(vv,vv,d,(Obj *)&poly); BDY(f) = (pointer)poly;
1.157 noro 3167: }
1.232 noro 3168: obj_dalgtoalg((Obj)f1,(Obj *)&f);
1.157 noro 3169:
3170: /* append alg vars to the var list */
3171: for ( tv = vv; NEXT(tv); tv = NEXT(tv) );
3172: NEXT(tv) = av;
3173:
3174: /* append a block to ord */
3175: *ord1p = append_block(ord,nvar,nalg,2);
3176:
3177: /* create generator list */
3178: nf = get_numberfield();
3179: for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) {
3180: MKAlg(nf->defpoly[i],dp);
3181: MKNODE(s,dp,t); t = s;
3182: }
3183: MKLIST(f1,t);
3184: *alistp = alist;
1.232 noro 3185: algobjtorat((Obj)f1,(Obj *)f1p);
1.157 noro 3186:
3187: /* creating a new weight vector */
3188: prev_weight_vector_obj = obj0 = current_dl_weight_vector_obj;
3189: n = nvar+nalg+1;
3190: MKVECT(obj,n);
3191: if ( obj0 && obj0->len == nvar )
3192: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = BDY(obj0)[i];
3193: else
3194: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = (pointer)ONE;
3195: for ( i = 0; i < nalg; i++ ) BDY(obj)[i+nvar] = 0;
3196: BDY(obj)[n-1] = (pointer)ONE;
3197: arg = mknode(1,obj);
3198: Pdp_set_weight(arg,&tmp);
1.121 noro 3199: }
3200:
3201: NODE postprocess_algcoef(VL av,NODE alist,NODE r)
3202: {
1.157 noro 3203: NODE s,t,u0,u;
3204: P p;
3205: VL tv;
1.232 noro 3206: Obj obj;
3207: VECT tmp;
1.157 noro 3208: NODE arg;
3209:
3210: u0 = 0;
3211: for ( t = r; t; t = NEXT(t) ) {
3212: p = (P)BDY(t);
3213: for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) {
3214: substr(CO,0,(Obj)p,tv->v,(Obj)BDY(s),&obj); p = (P)obj;
3215: }
3216: if ( OID(p) == O_P || (OID(p) == O_N && NID((Num)p) != N_A) ) {
3217: NEXTNODE(u0,u);
3218: BDY(u) = (pointer)p;
3219: }
3220: }
3221: arg = mknode(1,prev_weight_vector_obj);
3222: Pdp_set_weight(arg,&tmp);
1.121 noro 3223:
1.157 noro 3224: return u0;
1.120 noro 3225: }
3226:
1.199 noro 3227: void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
1.1 noro 3228: {
1.157 noro 3229: VL tv,fv,vv,vc,av;
3230: NODE fd,fd0,r,r0,t,x,s,xx,alist;
3231: int e,max,nvar,i;
3232: NDV b;
1.184 noro 3233: int ishomo,nalg,mrank,trank,wmax,len;
1.245 noro 3234: NMV a;
1.157 noro 3235: Alg alpha,dp;
3236: P p,zp;
3237: Q dmy;
3238: LIST f1,f2,zpl;
3239: Obj obj;
3240: NumberField nf;
3241: struct order_spec *ord1;
1.208 noro 3242: NODE tr,tl1,tl2,tl3,tl4,nzlist;
1.170 noro 3243: LIST l1,l2,l3,l4,l5;
1.245 noro 3244: int j;
3245: Q jq,bpe,last_nonzero;
1.167 noro 3246: int *perm;
1.170 noro 3247: EPOS oepos;
1.194 noro 3248: int obpe,oadv,ompos,cbpe;
1.1 noro 3249:
1.174 noro 3250: nd_module = 0;
1.157 noro 3251: if ( !m && Demand ) nd_demand = 1;
3252: else nd_demand = 0;
1.172 noro 3253: parse_nd_option(current_option);
1.78 noro 3254:
1.157 noro 3255: if ( DP_Multiple )
3256: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
1.103 noro 3257: #if 0
1.157 noro 3258: ndv_alloc = 0;
1.103 noro 3259: #endif
1.157 noro 3260: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.229 noro 3261: if ( m && nd_vc )
3262: error("nd_{gr,f4} : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
1.157 noro 3263: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3264: switch ( ord->id ) {
3265: case 1:
3266: if ( ord->nv != nvar )
3267: error("nd_{gr,f4} : invalid order specification");
3268: break;
3269: default:
3270: break;
3271: }
3272: nd_nalg = 0;
3273: av = 0;
3274: if ( !m ) {
3275: get_algtree((Obj)f,&av);
3276: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
3277: nd_ntrans = nvar;
3278: nd_nalg = nalg;
3279: /* #i -> t#i */
3280: if ( nalg ) {
3281: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
3282: ord = ord1;
3283: f = f1;
3284: }
3285: nvar += nalg;
3286: }
3287: nd_init_ord(ord);
3288: mrank = 0;
1.178 noro 3289: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
1.157 noro 3290: for ( tv = vv; tv; tv = NEXT(tv) ) {
3291: if ( nd_module ) {
3292: s = BDY((LIST)BDY(t));
3293: trank = length(s);
3294: mrank = MAX(mrank,trank);
3295: for ( ; s; s = NEXT(s) ) {
3296: e = getdeg(tv->v,(P)BDY(s));
3297: max = MAX(e,max);
3298: }
3299: } else {
3300: e = getdeg(tv->v,(P)BDY(t));
3301: max = MAX(e,max);
3302: }
3303: }
1.208 noro 3304: nd_setup_parameters(nvar,nd_nzlist?0:max);
1.170 noro 3305: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
1.157 noro 3306: ishomo = 1;
3307: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.167 noro 3308: if ( nd_module ) {
1.245 noro 3309: if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
3310: else zpl = (LIST)BDY(t);
1.157 noro 3311: b = (pointer)pltondv(CO,vv,zpl);
3312: } else {
1.245 noro 3313: if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
3314: else zp = (P)BDY(t);
1.157 noro 3315: b = (pointer)ptondv(CO,vv,zp);
1.167 noro 3316: }
1.157 noro 3317: if ( ishomo )
3318: ishomo = ishomo && ndv_ishomo(b);
3319: if ( m ) ndv_mod(m,b);
3320: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
3321: }
3322: if ( fd0 ) NEXT(fd) = 0;
1.184 noro 3323:
1.245 noro 3324: if ( !ishomo && homo ) {
1.184 noro 3325: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
3326: b = (NDV)BDY(t); len = LEN(b);
3327: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
3328: wmax = MAX(TD(DL(a)),wmax);
3329: }
3330: homogenize_order(ord,nvar,&ord1);
3331: nd_init_ord(ord1);
1.243 noro 3332: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
1.184 noro 3333: for ( t = fd0; t; t = NEXT(t) )
3334: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
3335: }
3336:
1.211 noro 3337: ndv_setup(m,0,fd0,(nd_gbblock||nd_splist||nd_check_splist)?1:0,0);
1.172 noro 3338: if ( nd_gentrace ) {
1.167 noro 3339: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
3340: }
1.245 noro 3341: if ( nd_splist ) {
3342: *rp = compute_splist();
3343: return;
3344: }
3345: if ( nd_check_splist ) {
1.214 noro 3346: if ( f4 ) {
3347: if ( check_splist_f4(m,nd_check_splist) ) *rp = (LIST)ONE;
3348: else *rp = 0;
3349: } else {
3350: if ( check_splist(m,nd_check_splist) ) *rp = (LIST)ONE;
3351: else *rp = 0;
3352: }
1.245 noro 3353: return;
3354: }
1.234 noro 3355: x = f4?nd_f4(m,0,&perm):nd_gb(m,ishomo || homo,0,0,&perm);
1.245 noro 3356: if ( !x ) {
3357: *rp = 0; return;
3358: }
3359: if ( !ishomo && homo ) {
3360: /* dehomogenization */
3361: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
3362: nd_init_ord(ord);
3363: nd_setup_parameters(nvar,0);
3364: }
1.157 noro 3365: nd_demand = 0;
1.245 noro 3366: if ( nd_module && nd_intersect ) {
3367: for ( j = nd_psn-1, x = 0; j >= 0; j-- )
3368: if ( MPOS(DL(nd_psh[j])) > 1 ) {
3369: MKNODE(xx,(pointer)j,x); x = xx;
3370: }
3371: conv_ilist(nd_demand,0,x,0);
3372: goto FINAL;
3373: }
1.208 noro 3374: if ( nd_gentrace && f4 ) { nzlist = nd_alltracelist; }
1.167 noro 3375: x = ndv_reducebase(x,perm);
1.208 noro 3376: if ( nd_gentrace && !f4 ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
1.157 noro 3377: x = ndv_reduceall(m,x);
1.194 noro 3378: cbpe = nd_bpe;
1.208 noro 3379: if ( nd_gentrace && !f4 ) {
1.170 noro 3380: tl2 = nd_alltracelist; nd_alltracelist = 0;
3381: ndv_check_membership(m,fd0,obpe,oadv,oepos,x);
1.198 noro 3382: tl3 = nd_alltracelist; nd_alltracelist = 0;
3383: if ( nd_gensyz ) {
1.245 noro 3384: nd_gb(m,0,1,1,0);
1.170 noro 3385: tl4 = nd_alltracelist; nd_alltracelist = 0;
3386: } else tl4 = 0;
3387: }
1.194 noro 3388: nd_bpe = cbpe;
3389: nd_setup_parameters(nd_nvar,0);
1.195 noro 3390: FINAL:
1.157 noro 3391: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
3392: NEXTNODE(r0,r);
1.194 noro 3393: if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank);
1.199 noro 3394: else if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
1.245 noro 3395: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.157 noro 3396: }
3397: if ( r0 ) NEXT(r) = 0;
1.208 noro 3398: if ( !m && nd_nalg )
1.157 noro 3399: r0 = postprocess_algcoef(av,alist,r0);
3400: MKLIST(*rp,r0);
1.172 noro 3401: if ( nd_gentrace ) {
1.245 noro 3402: if ( f4 ) {
1.208 noro 3403: STOQ(16,bpe);
1.241 noro 3404: STOQ(nd_last_nonzero,last_nonzero);
3405: tr = mknode(5,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe,last_nonzero); MKLIST(*rp,tr);
3406:
1.208 noro 3407: } else {
3408: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
3409: tl3 = reverse_node(tl3);
3410: /* tl2 = [[i,[[*,j,*,*],...]],...] */
3411: for ( t = tl2; t; t = NEXT(t) ) {
3412: /* s = [i,[*,j,*,*],...] */
3413: s = BDY((LIST)BDY(t));
3414: j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq;
3415: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
3416: j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq);
3417: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
3418: }
3419: }
3420: for ( j = length(x)-1, t = 0; j >= 0; j-- ) {
3421: STOQ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.167 noro 3422: }
1.208 noro 3423: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
3424: MKLIST(l5,tl4);
3425: STOQ(nd_bpe,bpe);
3426: tr = mknode(8,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe); MKLIST(*rp,tr);
3427: }
1.167 noro 3428: }
1.103 noro 3429: #if 0
1.157 noro 3430: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.103 noro 3431: #endif
1.127 noro 3432: }
3433:
3434: void nd_gr_postproc(LIST f,LIST v,int m,struct order_spec *ord,int do_check,LIST *rp)
3435: {
1.157 noro 3436: VL tv,fv,vv,vc,av;
3437: NODE fd,fd0,r,r0,t,x,s,xx,alist;
3438: int e,max,nvar,i;
3439: NDV b;
3440: int ishomo,nalg;
3441: Alg alpha,dp;
3442: P p,zp;
3443: Q dmy;
3444: LIST f1,f2;
3445: Obj obj;
3446: NumberField nf;
3447: struct order_spec *ord1;
1.167 noro 3448: int *perm;
1.157 noro 3449:
1.197 noro 3450: parse_nd_option(current_option);
1.157 noro 3451: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
3452: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3453: switch ( ord->id ) {
3454: case 1:
3455: if ( ord->nv != nvar )
3456: error("nd_check : invalid order specification");
3457: break;
3458: default:
3459: break;
3460: }
3461: nd_nalg = 0;
3462: av = 0;
3463: if ( !m ) {
3464: get_algtree((Obj)f,&av);
3465: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
3466: nd_ntrans = nvar;
3467: nd_nalg = nalg;
3468: /* #i -> t#i */
3469: if ( nalg ) {
3470: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
3471: ord = ord1;
3472: f = f1;
3473: }
3474: nvar += nalg;
3475: }
3476: nd_init_ord(ord);
1.178 noro 3477: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
1.157 noro 3478: for ( tv = vv; tv; tv = NEXT(tv) ) {
3479: e = getdeg(tv->v,(P)BDY(t));
3480: max = MAX(e,max);
3481: }
3482: nd_setup_parameters(nvar,max);
3483: ishomo = 1;
3484: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
3485: ptozp((P)BDY(t),1,&dmy,&zp);
3486: b = (pointer)ptondv(CO,vv,zp);
3487: if ( ishomo )
3488: ishomo = ishomo && ndv_ishomo(b);
3489: if ( m ) ndv_mod(m,b);
3490: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
3491: }
3492: if ( fd0 ) NEXT(fd) = 0;
3493: ndv_setup(m,0,fd0,0,1);
3494: for ( x = 0, i = 0; i < nd_psn; i++ )
3495: x = update_base(x,i);
3496: if ( do_check ) {
1.168 noro 3497: x = nd_gb(m,ishomo,1,0,&perm);
1.157 noro 3498: if ( !x ) {
3499: *rp = 0;
3500: return;
3501: }
3502: } else {
1.175 noro 3503: #if 0
1.245 noro 3504: /* bug ? */
1.157 noro 3505: for ( t = x; t; t = NEXT(t) )
1.159 noro 3506: BDY(t) = (pointer)nd_ps[(long)BDY(t)];
1.175 noro 3507: #else
1.245 noro 3508: conv_ilist(0,0,x,&perm);
1.175 noro 3509: #endif
1.157 noro 3510: }
1.167 noro 3511: x = ndv_reducebase(x,perm);
1.157 noro 3512: x = ndv_reduceall(m,x);
3513: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
3514: NEXTNODE(r0,r);
3515: BDY(r) = ndvtop(m,CO,vv,BDY(t));
3516: }
3517: if ( r0 ) NEXT(r) = 0;
1.208 noro 3518: if ( !m && nd_nalg )
1.157 noro 3519: r0 = postprocess_algcoef(av,alist,r0);
3520: MKLIST(*rp,r0);
1.20 noro 3521: }
3522:
1.198 noro 3523: NDV recompute_trace(NODE trace,NDV *p,int m);
3524: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp);
3525:
3526: NDV recompute_trace(NODE ti,NDV *p,int mod)
3527: {
1.245 noro 3528: int c,c1,c2,i;
3529: NM mul,m,tail;
3530: ND d,r,rm;
3531: NODE sj;
3532: NDV red;
3533: Obj mj;
3534: static int afo=0;
3535:
3536: afo++;
3537: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
3538: CM(mul) = 1;
3539: tail = 0;
3540: for ( i = 0, d = r = 0; ti; ti = NEXT(ti), i++ ) {
3541: sj = BDY((LIST)BDY(ti));
3542: if ( ARG0(sj) ) {
3543: red = p[QTOS((Q)ARG1(sj))];
3544: mj = (Obj)ARG2(sj);
3545: if ( OID(mj) != O_DP ) ndl_zero(DL(mul));
3546: else dltondl(nd_nvar,BDY((DP)mj)->dl,DL(mul));
3547: rm = ndv_mul_nm(mod,mul,red);
3548: if ( !r ) r = rm;
3549: else {
3550: for ( m = BDY(r); m && !ndl_equal(m->dl,BDY(rm)->dl); m = NEXT(m), LEN(r)-- ) {
3551: if ( d ) {
3552: NEXT(tail) = m; tail = m; LEN(d)++;
3553: } else {
3554: MKND(nd_nvar,m,1,d); tail = BDY(d);
3555: }
3556: }
3557: if ( !m ) return 0; /* failure */
1.232 noro 3558: else {
1.245 noro 3559: BDY(r) = m;
1.232 noro 3560: if ( mod > 0 || mod == -1 ) {
1.245 noro 3561: c1 = invm(HCM(rm),mod); c2 = mod-HCM(r);
3562: DMAR(c1,c2,0,mod,c);
3563: nd_mul_c(mod,rm,c);
1.232 noro 3564: } else {
3565: GZ t,u;
3566:
3567: chsgnlf(HCZ(r),&t);
3568: divlf(t,HCZ(rm),&u);
3569: nd_mul_c_lf(rm,u);
3570: }
1.245 noro 3571: r = nd_add(mod,r,rm);
3572: }
1.232 noro 3573: }
1.245 noro 3574: }
3575: }
3576: if ( tail ) NEXT(tail) = 0;
3577: d = nd_add(mod,d,r);
3578: nd_mul_c(mod,d,invm(HCM(d),mod));
3579: return ndtondv(mod,d);
1.198 noro 3580: }
3581:
3582: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp)
3583: {
3584: VL tv,fv,vv,vc,av;
3585: NODE fd,fd0,r,r0,t,x,s,xx,alist;
3586: int e,max,nvar,i;
3587: NDV b;
3588: int ishomo,nalg;
3589: Alg alpha,dp;
3590: P p,zp;
3591: Q dmy;
3592: LIST f1,f2;
3593: Obj obj;
3594: NumberField nf;
3595: struct order_spec *ord1;
1.245 noro 3596: NODE permtrace,intred,ind,perm,trace,ti;
3597: int len,n,j;
3598: NDV *db,*pb;
1.198 noro 3599:
3600: parse_nd_option(current_option);
3601: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
3602: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3603: switch ( ord->id ) {
3604: case 1:
3605: if ( ord->nv != nvar )
3606: error("nd_check : invalid order specification");
3607: break;
3608: default:
3609: break;
3610: }
3611: nd_init_ord(ord);
1.245 noro 3612: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
1.198 noro 3613: nd_setup_parameters(nvar,0);
3614:
1.245 noro 3615: len = length(BDY(f));
3616: db = (NDV *)MALLOC(len*sizeof(NDV *));
3617: for ( i = 0, t = BDY(f); t; i++, t = NEXT(t) ) {
3618: ptozp((P)BDY(t),1,&dmy,&zp);
3619: b = ptondv(CO,vv,zp);
1.198 noro 3620: ndv_mod(m,b);
1.245 noro 3621: ndv_mul_c(m,b,invm(HCM(b),m));
3622: db[i] = b;
1.198 noro 3623: }
3624:
1.245 noro 3625: permtrace = BDY((LIST)ARG2(BDY(tlist)));
3626: intred = BDY((LIST)ARG3(BDY(tlist)));
3627: ind = BDY((LIST)ARG4(BDY(tlist)));
3628: perm = BDY((LIST)ARG0(permtrace));
3629: trace = NEXT(permtrace);
3630:
3631: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
3632: j = QTOS((Q)ARG0(BDY((LIST)BDY(t))));
3633: if ( j > i ) i = j;
3634: }
3635: n = i+1;
3636: pb = (NDV *)MALLOC(n*sizeof(NDV *));
3637: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
3638: ti = BDY((LIST)BDY(t));
3639: pb[QTOS((Q)ARG0(ti))] = db[QTOS((Q)ARG1(ti))];
3640: }
3641: for ( t = trace; t; t = NEXT(t) ) {
3642: ti = BDY((LIST)BDY(t));
3643: pb[QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
3644: if ( !pb[QTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
3645: if ( DP_Print ) {
3646: fprintf(asir_out,"."); fflush(asir_out);
3647: }
3648: }
3649: for ( t = intred; t; t = NEXT(t) ) {
3650: ti = BDY((LIST)BDY(t));
3651: pb[QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
3652: if ( !pb[QTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
3653: if ( DP_Print ) {
3654: fprintf(asir_out,"*"); fflush(asir_out);
3655: }
3656: }
1.198 noro 3657: for ( r0 = 0, t = ind; t; t = NEXT(t) ) {
3658: NEXTNODE(r0,r);
1.245 noro 3659: b = pb[QTOS((Q)BDY(t))];
1.198 noro 3660: ndv_mul_c(m,b,invm(HCM(b),m));
3661: #if 0
3662: BDY(r) = ndvtop(m,CO,vv,pb[QTOS((Q)BDY(t))]);
3663: #else
3664: BDY(r) = ndvtodp(m,pb[QTOS((Q)BDY(t))]);
3665: #endif
3666: }
3667: if ( r0 ) NEXT(r) = 0;
3668: MKLIST(*rp,r0);
3669: if ( DP_Print ) fprintf(asir_out,"\n");
3670: }
3671:
1.133 noro 3672: void nd_gr_trace(LIST f,LIST v,int trace,int homo,int f4,struct order_spec *ord,LIST *rp)
1.20 noro 3673: {
1.157 noro 3674: VL tv,fv,vv,vc,av;
3675: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
3676: int m,nocheck,nvar,mindex,e,max;
3677: NDV c;
3678: NMV a;
3679: P p,zp;
3680: Q dmy;
3681: EPOS oepos;
1.164 noro 3682: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
1.157 noro 3683: Alg alpha,dp;
3684: P poly;
1.158 noro 3685: LIST f1,f2,zpl;
1.157 noro 3686: Obj obj;
3687: NumberField nf;
3688: struct order_spec *ord1;
3689: struct oEGT eg_check,eg0,eg1;
1.168 noro 3690: NODE tr,tl1,tl2,tl3,tl4;
3691: LIST l1,l2,l3,l4,l5;
1.167 noro 3692: int *perm;
1.168 noro 3693: int j,ret;
1.198 noro 3694: Q jq,bpe;
1.157 noro 3695:
1.167 noro 3696: nd_module = 0;
1.235 noro 3697: nd_lf = 0;
1.172 noro 3698: parse_nd_option(current_option);
1.234 noro 3699: if ( nd_lf ) {
3700: if ( f4 )
3701: nd_f4_lf_trace(f,v,trace,homo,ord,rp);
3702: else
3703: error("nd_gr_trace is not implemented yet over a large finite field");
3704: return;
3705: }
1.157 noro 3706: if ( DP_Multiple )
3707: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
3708:
3709: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
3710: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
3711: switch ( ord->id ) {
3712: case 1:
3713: if ( ord->nv != nvar )
3714: error("nd_gr_trace : invalid order specification");
3715: break;
3716: default:
3717: break;
3718: }
3719:
3720: get_algtree((Obj)f,&av);
3721: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
3722: nd_ntrans = nvar;
3723: nd_nalg = nalg;
3724: /* #i -> t#i */
3725: if ( nalg ) {
3726: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
3727: ord = ord1;
3728: f = f1;
3729: }
3730: nvar += nalg;
3731:
3732: nocheck = 0;
3733: mindex = 0;
3734:
3735: if ( Demand ) nd_demand = 1;
3736: else nd_demand = 0;
3737:
3738: /* setup modulus */
3739: if ( trace < 0 ) {
3740: trace = -trace;
3741: nocheck = 1;
3742: }
3743: m = trace > 1 ? trace : get_lprime(mindex);
1.158 noro 3744: nd_init_ord(ord);
3745: mrank = 0;
1.178 noro 3746: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
1.157 noro 3747: for ( tv = vv; tv; tv = NEXT(tv) ) {
1.158 noro 3748: if ( nd_module ) {
3749: s = BDY((LIST)BDY(t));
3750: trank = length(s);
3751: mrank = MAX(mrank,trank);
3752: for ( ; s; s = NEXT(s) ) {
3753: e = getdeg(tv->v,(P)BDY(s));
3754: max = MAX(e,max);
3755: }
3756: } else {
3757: e = getdeg(tv->v,(P)BDY(t));
3758: max = MAX(e,max);
3759: }
1.157 noro 3760: }
3761: nd_setup_parameters(nvar,max);
1.164 noro 3762: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
1.157 noro 3763: ishomo = 1;
3764: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.167 noro 3765: if ( nd_module ) {
1.245 noro 3766: if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
3767: else zpl = (LIST)BDY(t);
1.158 noro 3768: c = (pointer)pltondv(CO,vv,zpl);
3769: } else {
1.245 noro 3770: if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
3771: else zp = (P)BDY(t);
1.158 noro 3772: c = (pointer)ptondv(CO,vv,zp);
1.167 noro 3773: }
1.157 noro 3774: if ( ishomo )
3775: ishomo = ishomo && ndv_ishomo(c);
3776: if ( c ) {
3777: NEXTNODE(in0,in); BDY(in) = (pointer)c;
3778: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
3779: }
3780: }
3781: if ( in0 ) NEXT(in) = 0;
3782: if ( fd0 ) NEXT(fd) = 0;
3783: if ( !ishomo && homo ) {
3784: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
3785: c = (NDV)BDY(t); len = LEN(c);
3786: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
3787: wmax = MAX(TD(DL(a)),wmax);
3788: }
3789: homogenize_order(ord,nvar,&ord1);
3790: nd_init_ord(ord1);
3791: nd_setup_parameters(nvar+1,wmax);
3792: for ( t = fd0; t; t = NEXT(t) )
1.164 noro 3793: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
1.157 noro 3794: }
1.228 noro 3795: if ( MaxDeg > 0 ) nocheck = 1;
1.157 noro 3796: while ( 1 ) {
1.245 noro 3797: tl1 = tl2 = tl3 = tl4 = 0;
1.157 noro 3798: if ( Demand )
3799: nd_demand = 1;
1.187 noro 3800: ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0);
1.172 noro 3801: if ( nd_gentrace ) {
1.167 noro 3802: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
3803: }
1.177 noro 3804: if ( ret )
3805: cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm);
3806: if ( !ret || !cand ) {
1.157 noro 3807: /* failure */
3808: if ( trace > 1 ) { *rp = 0; return; }
3809: else m = get_lprime(++mindex);
3810: continue;
3811: }
3812: if ( !ishomo && homo ) {
3813: /* dehomogenization */
3814: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
3815: nd_init_ord(ord);
3816: nd_setup_parameters(nvar,0);
3817: }
3818: nd_demand = 0;
1.167 noro 3819: cand = ndv_reducebase(cand,perm);
1.172 noro 3820: if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
1.157 noro 3821: cand = ndv_reduceall(0,cand);
3822: cbpe = nd_bpe;
1.172 noro 3823: if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; }
1.173 noro 3824: get_eg(&eg0);
1.157 noro 3825: if ( nocheck )
3826: break;
1.170 noro 3827: if ( ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand) ) {
1.172 noro 3828: if ( nd_gentrace ) {
1.245 noro 3829: tl3 = nd_alltracelist; nd_alltracelist = 0;
3830: } else tl3 = 0;
1.168 noro 3831: /* gbcheck : cand is a GB of Id(cand) ? */
1.234 noro 3832: if ( nd_vc || nd_gentrace || nd_gensyz )
3833: ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0;
3834: else
3835: ret = nd_f4(0,1,0)!=0;
1.172 noro 3836: if ( nd_gentrace && nd_gensyz ) {
1.245 noro 3837: tl4 = nd_alltracelist; nd_alltracelist = 0;
3838: } else tl4 = 0;
3839: }
3840: if ( ret ) break;
1.157 noro 3841: else if ( trace > 1 ) {
3842: /* failure */
3843: *rp = 0; return;
3844: } else {
3845: /* try the next modulus */
3846: m = get_lprime(++mindex);
3847: /* reset the parameters */
3848: if ( !ishomo && homo ) {
3849: nd_init_ord(ord1);
3850: nd_setup_parameters(nvar+1,wmax);
3851: } else {
3852: nd_init_ord(ord);
3853: nd_setup_parameters(nvar,max);
3854: }
3855: }
3856: }
3857: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
3858: if ( DP_Print )
1.241 noro 3859: fprintf(asir_out,"check=%.3fsec,",eg_check.exectime+eg_check.gctime);
1.157 noro 3860: /* dp->p */
3861: nd_bpe = cbpe;
3862: nd_setup_parameters(nd_nvar,0);
1.158 noro 3863: for ( r = cand; r; r = NEXT(r) ) {
1.167 noro 3864: if ( nd_module ) BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank);
1.158 noro 3865: else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r));
3866: }
1.208 noro 3867: if ( nd_nalg )
1.157 noro 3868: cand = postprocess_algcoef(av,alist,cand);
3869: MKLIST(*rp,cand);
1.172 noro 3870: if ( nd_gentrace ) {
1.167 noro 3871: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
1.245 noro 3872: tl3 = reverse_node(tl3);
3873: /* tl2 = [[i,[[*,j,*,*],...]],...] */
1.167 noro 3874: for ( t = tl2; t; t = NEXT(t) ) {
1.245 noro 3875: /* s = [i,[*,j,*,*],...] */
1.167 noro 3876: s = BDY((LIST)BDY(t));
3877: j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq;
1.245 noro 3878: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.167 noro 3879: j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq);
1.245 noro 3880: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
1.167 noro 3881: }
1.245 noro 3882: }
3883: for ( j = length(cand)-1, t = 0; j >= 0; j-- ) {
3884: STOQ(perm[j],jq); MKNODE(s,jq,t); t = s;
3885: }
1.168 noro 3886: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
1.245 noro 3887: MKLIST(l5,tl4);
3888: STOQ(nd_bpe,bpe);
1.198 noro 3889: tr = mknode(8,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe); MKLIST(*rp,tr);
1.167 noro 3890: }
1.157 noro 3891: }
1.52 noro 3892:
1.157 noro 3893: /* XXX : module element is not considered */
1.1 noro 3894:
1.61 noro 3895: void dltondl(int n,DL dl,UINT *r)
1.1 noro 3896: {
1.157 noro 3897: UINT *d;
3898: int i,j,l,s,ord_l;
3899: struct order_pair *op;
3900:
3901: d = dl->d;
3902: for ( i = 0; i < nd_wpd; i++ ) r[i] = 0;
3903: if ( nd_blockmask ) {
3904: l = nd_blockmask->n;
3905: op = nd_blockmask->order_pair;
3906: for ( j = 0, s = 0; j < l; j++ ) {
3907: ord_l = op[j].length;
3908: for ( i = 0; i < ord_l; i++, s++ ) PUT_EXP(r,s,d[s]);
3909: }
3910: TD(r) = ndl_weight(r);
3911: ndl_weight_mask(r);
3912: } else {
3913: for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]);
3914: TD(r) = ndl_weight(r);
3915: }
1.1 noro 3916: }
3917:
1.61 noro 3918: DL ndltodl(int n,UINT *ndl)
1.1 noro 3919: {
1.157 noro 3920: DL dl;
3921: int *d;
3922: int i,j,l,s,ord_l;
3923: struct order_pair *op;
3924:
3925: NEWDL(dl,n);
3926: dl->td = TD(ndl);
3927: d = dl->d;
3928: if ( nd_blockmask ) {
3929: l = nd_blockmask->n;
3930: op = nd_blockmask->order_pair;
3931: for ( j = 0, s = 0; j < l; j++ ) {
3932: ord_l = op[j].length;
3933: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
3934: }
3935: } else {
3936: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
3937: }
3938: return dl;
1.1 noro 3939: }
3940:
1.167 noro 3941: void nmtodp(int mod,NM m,DP *r)
3942: {
3943: DP dp;
3944: MP mr;
3945:
3946: NEWMP(mr);
3947: mr->dl = ndltodl(nd_nvar,DL(m));
1.238 noro 3948: mr->c = (Obj)ndctop(mod,m->c);
1.167 noro 3949: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
3950: *r = dp;
3951: }
3952:
1.61 noro 3953: void ndl_print(UINT *dl)
1.1 noro 3954: {
1.157 noro 3955: int n;
3956: int i,j,l,ord_l,s,s0;
3957: struct order_pair *op;
3958:
3959: n = nd_nvar;
3960: printf("<<");
3961: if ( nd_blockmask ) {
3962: l = nd_blockmask->n;
3963: op = nd_blockmask->order_pair;
3964: for ( j = 0, s = s0 = 0; j < l; j++ ) {
3965: ord_l = op[j].length;
3966: for ( i = 0; i < ord_l; i++, s++ )
3967: printf(s==n-1?"%d":"%d,",GET_EXP(dl,s));
3968: }
3969: } else {
3970: for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i));
3971: }
3972: printf(">>");
1.236 noro 3973: if ( nd_module && MPOS(dl) )
1.157 noro 3974: printf("*e%d",MPOS(dl));
1.1 noro 3975: }
3976:
3977: void nd_print(ND p)
3978: {
1.157 noro 3979: NM m;
1.1 noro 3980:
1.157 noro 3981: if ( !p )
3982: printf("0\n");
3983: else {
3984: for ( m = BDY(p); m; m = NEXT(m) ) {
3985: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
3986: else printf("+%d*",CM(m));
3987: ndl_print(DL(m));
3988: }
3989: printf("\n");
3990: }
1.1 noro 3991: }
3992:
1.113 noro 3993: void nd_print_q(ND p)
1.16 noro 3994: {
1.157 noro 3995: NM m;
1.16 noro 3996:
1.157 noro 3997: if ( !p )
3998: printf("0\n");
3999: else {
4000: for ( m = BDY(p); m; m = NEXT(m) ) {
4001: printf("+");
4002: printexpr(CO,(Obj)CQ(m));
4003: printf("*");
4004: ndl_print(DL(m));
4005: }
4006: printf("\n");
4007: }
1.16 noro 4008: }
4009:
1.1 noro 4010: void ndp_print(ND_pairs d)
4011: {
1.157 noro 4012: ND_pairs t;
1.1 noro 4013:
1.157 noro 4014: for ( t = d; t; t = NEXT(t) ) printf("%d,%d ",t->i1,t->i2);
4015: printf("\n");
1.1 noro 4016: }
4017:
1.20 noro 4018: void nd_removecont(int mod,ND p)
1.16 noro 4019: {
1.157 noro 4020: int i,n;
4021: Q *w;
4022: Q dvr,t;
4023: NM m;
4024: struct oVECT v;
4025: N q,r;
4026:
4027: if ( mod == -1 ) nd_mul_c(mod,p,_invsf(HCM(p)));
1.232 noro 4028: else if ( mod == -2 ) {
4029: GZ inv;
4030: divlf(ONEGZ,HCZ(p),&inv);
4031: nd_mul_c_lf(p,inv);
4032: } else if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod));
1.157 noro 4033: else {
4034: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
1.235 noro 4035: w = (Q *)MALLOC(n*sizeof(Q));
1.157 noro 4036: v.len = n;
4037: v.body = (pointer *)w;
4038: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) w[i] = CQ(m);
4039: removecont_array((P *)w,n,1);
4040: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) CQ(m) = w[i];
4041: }
1.16 noro 4042: }
4043:
1.21 noro 4044: void nd_removecont2(ND p1,ND p2)
4045: {
1.157 noro 4046: int i,n1,n2,n;
4047: Q *w;
4048: Q dvr,t;
4049: NM m;
4050: struct oVECT v;
4051: N q,r;
4052:
4053: n1 = nd_length(p1);
4054: n2 = nd_length(p2);
4055: n = n1+n2;
1.235 noro 4056: w = (Q *)MALLOC(n*sizeof(Q));
1.157 noro 4057: v.len = n;
4058: v.body = (pointer *)w;
4059: i = 0;
4060: if ( p1 )
4061: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = CQ(m);
4062: if ( p2 )
4063: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CQ(m);
4064: removecont_array((P *)w,n,1);
4065: i = 0;
4066: if ( p1 )
4067: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) CQ(m) = w[i];
4068: if ( p2 )
4069: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CQ(m) = w[i];
1.21 noro 4070: }
4071:
1.20 noro 4072: void ndv_removecont(int mod,NDV p)
1.16 noro 4073: {
1.157 noro 4074: int i,len,all_p;
4075: Q *c;
4076: P *w;
4077: Q dvr,t;
4078: P g,cont,tp;
4079: NMV m;
4080:
4081: if ( mod == -1 )
4082: ndv_mul_c(mod,p,_invsf(HCM(p)));
1.232 noro 4083: else if ( mod == -2 ) {
4084: GZ inv;
4085: divlf(ONEGZ,HCZ(p),&inv);
4086: ndv_mul_c_lf(p,inv);
4087: } else if ( mod )
1.157 noro 4088: ndv_mul_c(mod,p,invm(HCM(p),mod));
4089: else {
4090: len = p->len;
1.235 noro 4091: w = (P *)MALLOC(len*sizeof(P));
4092: c = (Q *)MALLOC(len*sizeof(Q));
1.157 noro 4093: for ( m = BDY(p), all_p = 1, i = 0; i < len; NMV_ADV(m), i++ ) {
4094: ptozp(CP(m),1,&c[i],&w[i]);
4095: all_p = all_p && !NUM(w[i]);
4096: }
4097: if ( all_p ) {
4098: qltozl(c,len,&dvr); nd_heu_nezgcdnpz(nd_vc,w,len,1,&g);
4099: mulp(nd_vc,(P)dvr,g,&cont);
4100: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
4101: divsp(nd_vc,CP(m),cont,&tp); CP(m) = tp;
4102: }
4103: } else {
4104: sortbynm((Q *)c,len);
4105: qltozl((Q *)c,len,&dvr);
4106: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
4107: divsp(nd_vc,CP(m),(P)dvr,&tp); CP(m) = tp;
4108: }
4109: }
4110: }
1.21 noro 4111: }
4112:
1.157 noro 4113: /* koko */
4114:
1.164 noro 4115: void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos,int ompos)
1.61 noro 4116: {
1.157 noro 4117: int len,i,max;
4118: NMV m,mr0,mr,t;
1.61 noro 4119:
1.157 noro 4120: len = p->len;
1.248 noro 4121: for ( m = BDY(p), i = 0, max = 0; i < len; NMV_OADV(m), i++ )
1.157 noro 4122: max = MAX(max,TD(DL(m)));
4123: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
4124: m = (NMV)((char *)mr0+(len-1)*oadv);
4125: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
1.235 noro 4126: t = (NMV)MALLOC(nmv_adv);
1.157 noro 4127: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
1.164 noro 4128: ndl_homogenize(DL(m),DL(t),obpe,oepos,ompos,max);
1.157 noro 4129: CQ(mr) = CQ(m);
4130: ndl_copy(DL(t),DL(mr));
4131: }
4132: NV(p)++;
4133: BDY(p) = mr0;
1.61 noro 4134: }
4135:
1.45 noro 4136: void ndv_dehomogenize(NDV p,struct order_spec *ord)
1.23 noro 4137: {
1.164 noro 4138: int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos;
1.167 noro 4139: int pos;
1.157 noro 4140: Q *w;
4141: Q dvr,t;
4142: NMV m,r;
4143:
4144: len = p->len;
4145: newnvar = nd_nvar-1;
4146: newexporigin = nd_get_exporigin(ord);
1.167 noro 4147: if ( nd_module ) newmpos = newexporigin-1;
1.157 noro 4148: newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin;
4149: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ )
4150: ndl_dehomogenize(DL(m));
4151: if ( newwpd != nd_wpd ) {
4152: newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT));
4153: for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) {
4154: CQ(r) = CQ(m);
1.167 noro 4155: if ( nd_module ) pos = MPOS(DL(m));
1.157 noro 4156: for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j];
4157: adj = nd_exporigin-newexporigin;
4158: for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj];
1.167 noro 4159: if ( nd_module ) {
4160: DL(r)[newmpos] = pos;
4161: }
1.157 noro 4162: }
4163: }
4164: NV(p)--;
1.23 noro 4165: }
4166:
1.150 noro 4167: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr)
4168: {
1.157 noro 4169: int i;
4170: P *tpl,*tpl1;
4171: NODE l;
4172: P h,gcd,t;
4173:
1.235 noro 4174: tpl = (P *)MALLOC(m*sizeof(P));
4175: tpl1 = (P *)MALLOC(m*sizeof(P));
1.157 noro 4176: bcopy(pl,tpl,m*sizeof(P));
4177: gcd = (P)ONE;
4178: for ( l = nd_hcf; l; l = NEXT(l) ) {
4179: h = (P)BDY(l);
4180: while ( 1 ) {
4181: for ( i = 0; i < m; i++ )
4182: if ( !divtpz(vl,tpl[i],h,&tpl1[i]) )
4183: break;
4184: if ( i == m ) {
4185: bcopy(tpl1,tpl,m*sizeof(P));
4186: mulp(vl,gcd,h,&t); gcd = t;
4187: } else
4188: break;
4189: }
4190: }
4191: if ( DP_Print > 2 ){fprintf(asir_out,"[%d]",nmonop(gcd)); fflush(asir_out);}
4192: if ( full ) {
4193: heu_nezgcdnpz(vl,tpl,m,&t);
4194: mulp(vl,gcd,t,pr);
4195: } else
4196: *pr = gcd;
1.150 noro 4197: }
4198:
4199: void removecont_array(P *p,int n,int full)
1.146 noro 4200: {
1.157 noro 4201: int all_p,all_q,i;
4202: Q *c;
4203: P *w;
4204: P t,s;
4205:
4206: for ( all_q = 1, i = 0; i < n; i++ )
4207: all_q = all_q && NUM(p[i]);
4208: if ( all_q ) {
4209: removecont_array_q((Q *)p,n);
4210: } else {
1.235 noro 4211: c = (Q *)MALLOC(n*sizeof(Q));
4212: w = (P *)MALLOC(n*sizeof(P));
1.157 noro 4213: for ( i = 0; i < n; i++ ) {
4214: ptozp(p[i],1,&c[i],&w[i]);
4215: }
4216: removecont_array_q(c,n);
4217: nd_heu_nezgcdnpz(nd_vc,w,n,full,&t);
4218: for ( i = 0; i < n; i++ ) {
4219: divsp(nd_vc,w[i],t,&s); mulp(nd_vc,s,(P)c[i],&p[i]);
4220: }
4221: }
1.146 noro 4222: }
4223:
4224: void removecont_array_q(Q *c,int n)
1.21 noro 4225: {
1.157 noro 4226: struct oVECT v;
4227: Q d0,d1,a,u,u1,gcd;
4228: int i,j;
4229: N qn,rn,gn;
4230: Q *q,*r;
4231:
1.235 noro 4232: q = (Q *)MALLOC(n*sizeof(Q));
4233: r = (Q *)MALLOC(n*sizeof(Q));
1.157 noro 4234: v.id = O_VECT; v.len = n; v.body = (pointer *)c;
4235: igcdv_estimate(&v,&d0);
4236: for ( i = 0; i < n; i++ ) {
4237: divn(NM(c[i]),NM(d0),&qn,&rn);
4238: NTOQ(qn,SGN(c[i])*SGN(d0),q[i]);
4239: NTOQ(rn,SGN(c[i]),r[i]);
4240: }
4241: for ( i = 0; i < n; i++ ) if ( r[i] ) break;
4242: if ( i < n ) {
4243: v.id = O_VECT; v.len = n; v.body = (pointer *)r;
4244: igcdv(&v,&d1);
4245: gcdn(NM(d0),NM(d1),&gn); NTOQ(gn,1,gcd);
4246: divsn(NM(d0),gn,&qn); NTOQ(qn,1,a);
4247: for ( i = 0; i < n; i++ ) {
4248: mulq(a,q[i],&u);
4249: if ( r[i] ) {
4250: divsn(NM(r[i]),gn,&qn); NTOQ(qn,SGN(r[i]),u1);
4251: addq(u,u1,&q[i]);
4252: } else
4253: q[i] = u;
4254: }
4255: }
4256: for ( i = 0; i < n; i++ ) c[i] = q[i];
1.16 noro 4257: }
4258:
1.19 noro 4259: void nd_mul_c(int mod,ND p,int mul)
1.1 noro 4260: {
1.157 noro 4261: NM m;
4262: int c,c1;
1.1 noro 4263:
1.157 noro 4264: if ( !p ) return;
4265: if ( mul == 1 ) return;
4266: if ( mod == -1 )
4267: for ( m = BDY(p); m; m = NEXT(m) )
4268: CM(m) = _mulsf(CM(m),mul);
4269: else
4270: for ( m = BDY(p); m; m = NEXT(m) ) {
4271: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
4272: }
1.1 noro 4273: }
4274:
1.232 noro 4275: void nd_mul_c_lf(ND p,GZ mul)
4276: {
4277: NM m;
4278: GZ c;
4279:
4280: if ( !p ) return;
4281: if ( UNIGZ(mul) ) return;
4282: for ( m = BDY(p); m; m = NEXT(m) ) {
4283: mullf(CZ(m),mul,&c); CZ(m) = c;
4284: }
4285: }
4286:
1.146 noro 4287: void nd_mul_c_q(ND p,P mul)
1.16 noro 4288: {
1.157 noro 4289: NM m;
4290: P c;
1.16 noro 4291:
1.157 noro 4292: if ( !p ) return;
4293: if ( UNIQ(mul) ) return;
4294: for ( m = BDY(p); m; m = NEXT(m) ) {
4295: mulp(nd_vc,CP(m),mul,&c); CP(m) = c;
4296: }
1.16 noro 4297: }
4298:
1.61 noro 4299: void nd_mul_c_p(VL vl,ND p,P mul)
4300: {
1.157 noro 4301: NM m;
4302: P c;
1.61 noro 4303:
1.157 noro 4304: if ( !p ) return;
4305: for ( m = BDY(p); m; m = NEXT(m) ) {
4306: mulp(vl,CP(m),mul,&c); CP(m) = c;
4307: }
1.61 noro 4308: }
4309:
1.1 noro 4310: void nd_free(ND p)
4311: {
1.157 noro 4312: NM t,s;
1.1 noro 4313:
1.157 noro 4314: if ( !p ) return;
4315: t = BDY(p);
4316: while ( t ) {
4317: s = NEXT(t);
4318: FREENM(t);
4319: t = s;
4320: }
4321: FREEND(p);
1.1 noro 4322: }
4323:
1.23 noro 4324: void ndv_free(NDV p)
4325: {
1.200 noro 4326: GCFREE(BDY(p));
1.23 noro 4327: }
4328:
1.61 noro 4329: void nd_append_red(UINT *d,int i)
1.1 noro 4330: {
1.157 noro 4331: RHist m,m0;
4332: int h;
1.1 noro 4333:
1.157 noro 4334: NEWRHist(m);
4335: h = ndl_hash_value(d);
4336: m->index = i;
4337: ndl_copy(d,DL(m));
4338: NEXT(m) = nd_red[h];
4339: nd_red[h] = m;
1.1 noro 4340: }
4341:
1.61 noro 4342: UINT *ndv_compute_bound(NDV p)
1.1 noro 4343: {
1.157 noro 4344: UINT *d1,*d2,*t;
4345: UINT u;
4346: int i,j,k,l,len,ind;
4347: NMV m;
4348:
4349: if ( !p )
4350: return 0;
1.235 noro 4351: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
4352: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
1.157 noro 4353: len = LEN(p);
4354: m = BDY(p); ndl_copy(DL(m),d1); NMV_ADV(m);
4355: for ( i = 1; i < len; i++, NMV_ADV(m) ) {
1.159 noro 4356: ndl_max(DL(m),d1,d2);
1.157 noro 4357: t = d1; d1 = d2; d2 = t;
4358: }
4359: l = nd_nvar+31;
4360: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
4361: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
4362: u = d1[i];
4363: k = (nd_epw-1)*nd_bpe;
4364: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
4365: t[ind] = (u>>k)&nd_mask0;
4366: }
4367: for ( ; ind < l; ind++ ) t[ind] = 0;
4368: return t;
1.1 noro 4369: }
4370:
1.99 noro 4371: UINT *nd_compute_bound(ND p)
4372: {
1.157 noro 4373: UINT *d1,*d2,*t;
4374: UINT u;
4375: int i,j,k,l,len,ind;
4376: NM m;
4377:
4378: if ( !p )
4379: return 0;
1.235 noro 4380: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
4381: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
1.157 noro 4382: len = LEN(p);
4383: m = BDY(p); ndl_copy(DL(m),d1); m = NEXT(m);
4384: for ( m = NEXT(m); m; m = NEXT(m) ) {
4385: ndl_lcm(DL(m),d1,d2);
4386: t = d1; d1 = d2; d2 = t;
4387: }
4388: l = nd_nvar+31;
4389: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
4390: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
4391: u = d1[i];
4392: k = (nd_epw-1)*nd_bpe;
4393: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
4394: t[ind] = (u>>k)&nd_mask0;
4395: }
4396: for ( ; ind < l; ind++ ) t[ind] = 0;
4397: return t;
1.99 noro 4398: }
4399:
1.157 noro 4400: /* if nd_module == 1 then d[nd_exporigin-1] indicates the position */
4401: /* of a term. In this case we need additional 1 word. */
4402:
1.48 noro 4403: int nd_get_exporigin(struct order_spec *ord)
4404: {
1.157 noro 4405: switch ( ord->id ) {
4406: case 0: case 2: case 256: case 258:
4407: return 1+nd_module;
4408: case 1: case 257:
4409: /* block order */
4410: /* poly ring d[0]:weight d[1]:w0,...,d[nd_exporigin-1]:w(n-1) */
4411: /* module d[0]:weight d[1]:w0,...,d[nd_exporigin-2]:w(n-1) */
4412: return ord->ord.block.length+1+nd_module;
4413: case 3: case 259:
1.236 noro 4414: #if 0
1.157 noro 4415: error("nd_get_exporigin : composite order is not supported yet.");
1.236 noro 4416: #else
4417: return 1+nd_module;
4418: #endif
1.157 noro 4419: }
1.48 noro 4420: }
4421:
1.61 noro 4422: void nd_setup_parameters(int nvar,int max) {
1.157 noro 4423: int i,j,n,elen,ord_o,ord_l,l,s,wpd;
4424: struct order_pair *op;
1.48 noro 4425:
1.157 noro 4426: nd_nvar = nvar;
4427: if ( max ) {
4428: /* XXX */
4429: if ( do_weyl ) nd_bpe = 32;
4430: else if ( max < 2 ) nd_bpe = 1;
4431: else if ( max < 4 ) nd_bpe = 2;
4432: else if ( max < 8 ) nd_bpe = 3;
4433: else if ( max < 16 ) nd_bpe = 4;
4434: else if ( max < 32 ) nd_bpe = 5;
4435: else if ( max < 64 ) nd_bpe = 6;
4436: else if ( max < 256 ) nd_bpe = 8;
4437: else if ( max < 1024 ) nd_bpe = 10;
4438: else if ( max < 65536 ) nd_bpe = 16;
4439: else nd_bpe = 32;
4440: }
1.203 noro 4441: if ( !do_weyl && weight_check && (current_dl_weight_vector || nd_matrix) ) {
1.201 noro 4442: UINT t;
1.245 noro 4443: int st;
1.203 noro 4444: int *v;
1.245 noro 4445: /* t = max(weights) */
1.203 noro 4446: t = 0;
4447: if ( current_dl_weight_vector )
4448: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
4449: if ( (st=current_dl_weight_vector[i]) < 0 ) st = -st;
4450: if ( t < st ) t = st;
4451: }
4452: if ( nd_matrix )
4453: for ( i = 0; i < nd_matrix_len; i++ )
4454: for ( j = 0, v = nd_matrix[i]; j < nd_nvar; j++ ) {
4455: if ( (st=v[j]) < 0 ) st = -st;
4456: if ( t < st ) t = st;
1.245 noro 4457: }
1.203 noro 4458: /* i = bitsize of t */
4459: for ( i = 0; t; t >>=1, i++ );
4460: /* i += bitsize of nd_nvar */
4461: for ( t = nd_nvar; t; t >>=1, i++);
4462: /* nd_bpe+i = bitsize of max(weights)*max(exp)*nd_nvar */
4463: if ( (nd_bpe+i) >= 31 )
4464: error("nd_setup_parameters : too large weight");
4465: }
1.157 noro 4466: nd_epw = (sizeof(UINT)*8)/nd_bpe;
4467: elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0);
4468: nd_exporigin = nd_get_exporigin(nd_ord);
4469: wpd = nd_exporigin+elen;
4470: if ( nd_module )
4471: nd_mpos = nd_exporigin-1;
4472: else
4473: nd_mpos = -1;
4474: if ( wpd != nd_wpd ) {
4475: nd_free_private_storage();
4476: nd_wpd = wpd;
4477: }
4478: if ( nd_bpe < 32 ) {
4479: nd_mask0 = (1<<nd_bpe)-1;
4480: } else {
4481: nd_mask0 = 0xffffffff;
4482: }
4483: bzero(nd_mask,sizeof(nd_mask));
4484: nd_mask1 = 0;
4485: for ( i = 0; i < nd_epw; i++ ) {
4486: nd_mask[nd_epw-i-1] = (nd_mask0<<(i*nd_bpe));
4487: nd_mask1 |= (1<<(nd_bpe-1))<<(i*nd_bpe);
4488: }
4489: nmv_adv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(nd_wpd-1)*sizeof(UINT));
4490: nd_epos = nd_create_epos(nd_ord);
4491: nd_blockmask = nd_create_blockmask(nd_ord);
4492: nd_work_vector = (int *)REALLOC(nd_work_vector,nd_nvar*sizeof(int));
1.1 noro 4493: }
4494:
1.103 noro 4495: ND_pairs nd_reconstruct(int trace,ND_pairs d)
1.1 noro 4496: {
1.157 noro 4497: int i,obpe,oadv,h;
4498: static NM prev_nm_free_list;
4499: static ND_pairs prev_ndp_free_list;
4500: RHist mr0,mr;
4501: RHist r;
4502: RHist *old_red;
4503: ND_pairs s0,s,t;
4504: EPOS oepos;
4505:
4506: obpe = nd_bpe;
4507: oadv = nmv_adv;
4508: oepos = nd_epos;
4509: if ( obpe < 2 ) nd_bpe = 2;
4510: else if ( obpe < 3 ) nd_bpe = 3;
4511: else if ( obpe < 4 ) nd_bpe = 4;
4512: else if ( obpe < 5 ) nd_bpe = 5;
4513: else if ( obpe < 6 ) nd_bpe = 6;
4514: else if ( obpe < 8 ) nd_bpe = 8;
4515: else if ( obpe < 10 ) nd_bpe = 10;
4516: else if ( obpe < 16 ) nd_bpe = 16;
4517: else if ( obpe < 32 ) nd_bpe = 32;
4518: else error("nd_reconstruct : exponent too large");
4519:
4520: nd_setup_parameters(nd_nvar,0);
4521: prev_nm_free_list = _nm_free_list;
4522: prev_ndp_free_list = _ndp_free_list;
4523: _nm_free_list = 0;
4524: _ndp_free_list = 0;
1.215 noro 4525: for ( i = nd_psn-1; i >= 0; i-- ) {
4526: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
4527: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
4528: ndv_realloc(nd_ps_gz[i],obpe,oadv,oepos);
4529: }
1.157 noro 4530: if ( trace )
1.215 noro 4531: for ( i = nd_psn-1; i >= 0; i-- ) {
1.157 noro 4532: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
1.215 noro 4533: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
4534: }
1.157 noro 4535: s0 = 0;
4536: for ( t = d; t; t = NEXT(t) ) {
4537: NEXTND_pairs(s0,s);
4538: s->i1 = t->i1;
4539: s->i2 = t->i2;
4540: SG(s) = SG(t);
4541: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
4542: }
4543:
1.235 noro 4544: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
1.157 noro 4545: for ( i = 0; i < REDTAB_LEN; i++ ) {
4546: old_red[i] = nd_red[i];
4547: nd_red[i] = 0;
4548: }
4549: for ( i = 0; i < REDTAB_LEN; i++ )
4550: for ( r = old_red[i]; r; r = NEXT(r) ) {
4551: NEWRHist(mr);
4552: mr->index = r->index;
4553: SG(mr) = SG(r);
4554: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
4555: h = ndl_hash_value(DL(mr));
4556: NEXT(mr) = nd_red[h];
4557: nd_red[h] = mr;
4558: }
4559: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
4560: old_red = 0;
4561: for ( i = 0; i < nd_psn; i++ ) {
4562: NEWRHist(r); SG(r) = SG(nd_psh[i]);
4563: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
4564: nd_psh[i] = r;
4565: }
4566: if ( s0 ) NEXT(s) = 0;
4567: prev_nm_free_list = 0;
4568: prev_ndp_free_list = 0;
1.71 noro 4569: #if 0
1.157 noro 4570: GC_gcollect();
1.71 noro 4571: #endif
1.157 noro 4572: return s0;
1.1 noro 4573: }
4574:
1.61 noro 4575: void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos)
1.1 noro 4576: {
1.157 noro 4577: int n,i,ei,oepw,omask0,j,s,ord_l,l;
4578: struct order_pair *op;
1.1 noro 4579:
1.157 noro 4580: n = nd_nvar;
4581: oepw = (sizeof(UINT)*8)/obpe;
4582: omask0 = (1<<obpe)-1;
4583: TD(r) = TD(d);
4584: for ( i = nd_exporigin; i < nd_wpd; i++ ) r[i] = 0;
4585: if ( nd_blockmask ) {
4586: l = nd_blockmask->n;
4587: op = nd_blockmask->order_pair;
4588: for ( i = 1; i < nd_exporigin; i++ )
4589: r[i] = d[i];
4590: for ( j = 0, s = 0; j < l; j++ ) {
4591: ord_l = op[j].length;
4592: for ( i = 0; i < ord_l; i++, s++ ) {
4593: ei = GET_EXP_OLD(d,s);
4594: PUT_EXP(r,s,ei);
4595: }
4596: }
4597: } else {
4598: for ( i = 0; i < n; i++ ) {
4599: ei = GET_EXP_OLD(d,i);
4600: PUT_EXP(r,i,ei);
4601: }
4602: }
4603: if ( nd_module ) MPOS(r) = MPOS(d);
1.1 noro 4604: }
1.3 noro 4605:
1.6 noro 4606: ND nd_copy(ND p)
4607: {
1.157 noro 4608: NM m,mr,mr0;
4609: int c,n;
4610: ND r;
4611:
4612: if ( !p )
4613: return 0;
4614: else {
4615: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
4616: NEXTNM(mr0,mr);
4617: CM(mr) = CM(m);
4618: ndl_copy(DL(m),DL(mr));
4619: }
4620: NEXT(mr) = 0;
4621: MKND(NV(p),mr0,LEN(p),r);
4622: SG(r) = SG(p);
4623: return r;
4624: }
1.6 noro 4625: }
4626:
1.53 noro 4627: int nd_sp(int mod,int trace,ND_pairs p,ND *rp)
1.11 noro 4628: {
1.157 noro 4629: NM m1,m2;
4630: NDV p1,p2;
4631: ND t1,t2;
4632: UINT *lcm;
4633: P gp,tp;
1.167 noro 4634: Q g,t,iq;
1.157 noro 4635: int td;
1.167 noro 4636: LIST hist;
4637: NODE node;
4638: DP d;
1.157 noro 4639:
4640: if ( !mod && nd_demand ) {
4641: p1 = ndv_load(p->i1); p2 = ndv_load(p->i2);
4642: } else {
4643: if ( trace ) {
4644: p1 = nd_ps_trace[p->i1]; p2 = nd_ps_trace[p->i2];
4645: } else {
4646: p1 = nd_ps[p->i1]; p2 = nd_ps[p->i2];
4647: }
4648: }
4649: lcm = LCM(p);
4650: NEWNM(m1); ndl_sub(lcm,HDL(p1),DL(m1));
4651: if ( ndl_check_bound2(p->i1,DL(m1)) ) {
4652: FREENM(m1); return 0;
4653: }
4654: NEWNM(m2); ndl_sub(lcm,HDL(p2),DL(m2));
4655: if ( ndl_check_bound2(p->i2,DL(m2)) ) {
4656: FREENM(m1); FREENM(m2); return 0;
4657: }
4658:
4659: if ( mod == -1 ) {
4660: CM(m1) = HCM(p2); CM(m2) = _chsgnsf(HCM(p1));
1.232 noro 4661: } else if ( mod > 0 ) {
1.157 noro 4662: CM(m1) = HCM(p2); CM(m2) = mod-HCM(p1);
1.232 noro 4663: } else if ( mod == -2 ) {
4664: CZ(m1) = HCZ(p2); chsgnlf(HCZ(p1),&CZ(m2));
1.157 noro 4665: } else if ( nd_vc ) {
4666: ezgcdpz(nd_vc,HCP(p1),HCP(p2),&gp);
4667: divsp(nd_vc,HCP(p2),gp,&CP(m1));
4668: divsp(nd_vc,HCP(p1),gp,&tp); chsgnp(tp,&CP(m2));
4669: } else {
4670: igcd_cofactor(HCQ(p1),HCQ(p2),&g,&t,&CQ(m1)); chsgnq(t,&CQ(m2));
4671: }
4672: t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2);
4673: *rp = nd_add(mod,t1,t2);
1.172 noro 4674: if ( nd_gentrace ) {
1.167 noro 4675: /* nd_tracelist is initialized */
4676: STOQ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE);
4677: MKLIST(hist,node); MKNODE(nd_tracelist,hist,0);
4678: STOQ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE);
4679: MKLIST(hist,node); MKNODE(node,hist,nd_tracelist);
4680: nd_tracelist = node;
4681: }
1.157 noro 4682: FREENM(m1); FREENM(m2);
4683: return 1;
1.11 noro 4684: }
4685:
1.19 noro 4686: void ndv_mul_c(int mod,NDV p,int mul)
1.11 noro 4687: {
1.157 noro 4688: NMV m;
4689: int c,c1,len,i;
1.11 noro 4690:
1.157 noro 4691: if ( !p ) return;
4692: len = LEN(p);
4693: if ( mod == -1 )
4694: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) )
4695: CM(m) = _mulsf(CM(m),mul);
4696: else
4697: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
4698: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
4699: }
1.11 noro 4700: }
4701:
1.232 noro 4702: void ndv_mul_c_lf(NDV p,GZ mul)
4703: {
4704: NMV m;
4705: GZ c;
4706: int len,i;
4707:
4708: if ( !p ) return;
4709: len = LEN(p);
4710: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
4711: mullf(CZ(m),mul,&c); CZ(m) = c;
4712: }
4713: }
4714:
1.113 noro 4715: void ndv_mul_c_q(NDV p,Q mul)
1.16 noro 4716: {
1.157 noro 4717: NMV m;
4718: Q c;
4719: int len,i;
4720:
4721: if ( !p ) return;
4722: len = LEN(p);
4723: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
4724: mulq(CQ(m),mul,&c); CQ(m) = c;
4725: }
1.16 noro 4726: }
4727:
1.55 noro 4728: ND weyl_ndv_mul_nm(int mod,NM m0,NDV p) {
1.157 noro 4729: int n2,i,j,l,n,tlen;
4730: UINT *d0;
4731: NM *tab,*psum;
4732: ND s,r;
4733: NM t;
4734: NMV m1;
4735:
4736: if ( !p ) return 0;
4737: n = NV(p); n2 = n>>1;
4738: d0 = DL(m0);
4739: l = LEN(p);
4740: for ( i = 0, tlen = 1; i < n2; i++ ) tlen *= (GET_EXP(d0,n2+i)+1);
1.235 noro 4741: tab = (NM *)MALLOC(tlen*sizeof(NM));
4742: psum = (NM *)MALLOC(tlen*sizeof(NM));
1.157 noro 4743: for ( i = 0; i < tlen; i++ ) psum[i] = 0;
4744: m1 = (NMV)(((char *)BDY(p))+nmv_adv*(l-1));
4745: for ( i = l-1; i >= 0; i--, NMV_PREV(m1) ) {
4746: /* m0(NM) * m1(NMV) => tab(NM) */
4747: weyl_mul_nm_nmv(n,mod,m0,m1,tab,tlen);
4748: for ( j = 0; j < tlen; j++ ) {
4749: if ( tab[j] ) {
4750: NEXT(tab[j]) = psum[j]; psum[j] = tab[j];
4751: }
4752: }
4753: }
4754: for ( i = tlen-1, r = 0; i >= 0; i-- )
4755: if ( psum[i] ) {
4756: for ( j = 0, t = psum[i]; t; t = NEXT(t), j++ );
4757: MKND(n,psum[i],j,s);
4758: r = nd_add(mod,r,s);
4759: }
4760: if ( r ) SG(r) = SG(p)+TD(d0);
4761: return r;
1.55 noro 4762: }
4763:
1.56 noro 4764: /* product of monomials */
4765: /* XXX block order is not handled correctly */
4766:
1.55 noro 4767: void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *tab,int tlen)
4768: {
1.157 noro 4769: int i,n2,j,s,curlen,homo,h,a,b,k,l,u,min;
4770: UINT *d0,*d1,*d,*dt,*ctab;
4771: Q *ctab_q;
4772: Q q,q1;
4773: UINT c0,c1,c;
4774: NM *p;
4775: NM m,t;
4776: int mpos;
4777:
4778: for ( i = 0; i < tlen; i++ ) tab[i] = 0;
4779: if ( !m0 || !m1 ) return;
4780: d0 = DL(m0); d1 = DL(m1); n2 = n>>1;
1.166 noro 4781: if ( nd_module )
4782: if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation");
4783:
1.157 noro 4784: NEWNM(m); d = DL(m);
4785: if ( mod ) {
4786: c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c;
1.179 noro 4787: } else if ( nd_vc )
4788: mulp(nd_vc,CP(m0),CP(m1),&CP(m));
1.245 noro 4789: else
1.157 noro 4790: mulq(CQ(m0),CQ(m1),&CQ(m));
4791: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
4792: homo = n&1 ? 1 : 0;
4793: if ( homo ) {
4794: /* offset of h-degree */
4795: h = GET_EXP(d0,n-1)+GET_EXP(d1,n-1);
4796: PUT_EXP(DL(m),n-1,h);
4797: TD(DL(m)) = h;
4798: if ( nd_blockmask ) ndl_weight_mask(DL(m));
4799: }
4800: tab[0] = m;
4801: NEWNM(m); d = DL(m);
4802: for ( i = 0, curlen = 1; i < n2; i++ ) {
4803: a = GET_EXP(d0,i); b = GET_EXP(d1,n2+i);
4804: k = GET_EXP(d0,n2+i); l = GET_EXP(d1,i);
4805: /* xi^a*(Di^k*xi^l)*Di^b */
4806: a += l; b += k;
4807: s = MUL_WEIGHT(a,i)+MUL_WEIGHT(b,n2+i);
4808: if ( !k || !l ) {
4809: for ( j = 0; j < curlen; j++ )
4810: if ( t = tab[j] ) {
4811: dt = DL(t);
4812: PUT_EXP(dt,i,a); PUT_EXP(dt,n2+i,b); TD(dt) += s;
4813: if ( nd_blockmask ) ndl_weight_mask(dt);
4814: }
4815: curlen *= k+1;
4816: continue;
4817: }
4818: min = MIN(k,l);
4819: if ( mod ) {
1.235 noro 4820: ctab = (UINT *)MALLOC((min+1)*sizeof(UINT));
1.157 noro 4821: mkwcm(k,l,mod,ctab);
4822: } else {
1.235 noro 4823: ctab_q = (Q *)MALLOC((min+1)*sizeof(Q));
1.157 noro 4824: mkwc(k,l,ctab_q);
4825: }
4826: for ( j = min; j >= 0; j-- ) {
4827: for ( u = 0; u < nd_wpd; u++ ) d[u] = 0;
4828: PUT_EXP(d,i,a-j); PUT_EXP(d,n2+i,b-j);
4829: h = MUL_WEIGHT(a-j,i)+MUL_WEIGHT(b-j,n2+i);
4830: if ( homo ) {
4831: TD(d) = s;
4832: PUT_EXP(d,n-1,s-h);
4833: } else TD(d) = h;
4834: if ( nd_blockmask ) ndl_weight_mask(d);
4835: if ( mod ) c = ctab[j];
4836: else q = ctab_q[j];
4837: p = tab+curlen*j;
4838: if ( j == 0 ) {
4839: for ( u = 0; u < curlen; u++, p++ ) {
4840: if ( tab[u] ) {
4841: ndl_addto(DL(tab[u]),d);
4842: if ( mod ) {
4843: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1;
1.180 noro 4844: } else if ( nd_vc )
4845: mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u]));
1.245 noro 4846: else {
1.157 noro 4847: mulq(CQ(tab[u]),q,&q1); CQ(tab[u]) = q1;
4848: }
4849: }
4850: }
4851: } else {
4852: for ( u = 0; u < curlen; u++, p++ ) {
4853: if ( tab[u] ) {
4854: NEWNM(t);
4855: ndl_add(DL(tab[u]),d,DL(t));
4856: if ( mod ) {
4857: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1;
1.181 noro 4858: } else if ( nd_vc )
1.180 noro 4859: mulp(nd_vc,CP(tab[u]),(P)q,&CP(t));
1.245 noro 4860: else
1.157 noro 4861: mulq(CQ(tab[u]),q,&CQ(t));
4862: *p = t;
4863: }
4864: }
4865: }
4866: }
4867: curlen *= k+1;
4868: }
4869: FREENM(m);
1.167 noro 4870: if ( nd_module ) {
1.166 noro 4871: mpos = MPOS(d1);
1.167 noro 4872: for ( i = 0; i < tlen; i++ )
4873: if ( tab[i] ) {
4874: d = DL(tab[i]);
4875: MPOS(d) = mpos;
4876: TD(d) = ndl_weight(d);
4877: }
4878: }
1.55 noro 4879: }
4880:
1.63 noro 4881: ND ndv_mul_nm_symbolic(NM m0,NDV p)
4882: {
1.157 noro 4883: NM mr,mr0;
4884: NMV m;
4885: UINT *d,*dt,*dm;
4886: int c,n,td,i,c1,c2,len;
4887: Q q;
4888: ND r;
4889:
4890: if ( !p ) return 0;
4891: else {
4892: n = NV(p); m = BDY(p);
4893: d = DL(m0);
4894: len = LEN(p);
4895: mr0 = 0;
4896: td = TD(d);
4897: c = CM(m0);
4898: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4899: NEXTNM(mr0,mr);
4900: CM(mr) = 1;
4901: ndl_add(DL(m),d,DL(mr));
4902: }
4903: NEXT(mr) = 0;
4904: MKND(NV(p),mr0,len,r);
4905: SG(r) = SG(p) + TD(d);
4906: return r;
4907: }
1.63 noro 4908: }
4909:
1.55 noro 4910: ND ndv_mul_nm(int mod,NM m0,NDV p)
1.9 noro 4911: {
1.157 noro 4912: NM mr,mr0;
4913: NMV m;
4914: UINT *d,*dt,*dm;
4915: int c,n,td,i,c1,c2,len;
4916: P q;
4917: ND r;
4918:
4919: if ( !p ) return 0;
4920: else if ( do_weyl )
1.232 noro 4921: if ( mod < 0 )
1.157 noro 4922: error("ndv_mul_nm : not implemented (weyl)");
4923: else
4924: return weyl_ndv_mul_nm(mod,m0,p);
4925: else {
4926: n = NV(p); m = BDY(p);
4927: d = DL(m0);
4928: len = LEN(p);
4929: mr0 = 0;
4930: td = TD(d);
4931: if ( mod == -1 ) {
4932: c = CM(m0);
4933: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4934: NEXTNM(mr0,mr);
4935: CM(mr) = _mulsf(CM(m),c);
4936: ndl_add(DL(m),d,DL(mr));
4937: }
1.232 noro 4938: } else if ( mod == -2 ) {
4939: GZ cl;
4940: cl = CZ(m0);
4941: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4942: NEXTNM(mr0,mr);
4943: mullf(CZ(m),cl,&CZ(mr));
4944: ndl_add(DL(m),d,DL(mr));
4945: }
1.157 noro 4946: } else if ( mod ) {
4947: c = CM(m0);
4948: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4949: NEXTNM(mr0,mr);
4950: c1 = CM(m);
4951: DMAR(c1,c,0,mod,c2);
4952: CM(mr) = c2;
4953: ndl_add(DL(m),d,DL(mr));
4954: }
4955: } else {
4956: q = CP(m0);
4957: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
4958: NEXTNM(mr0,mr);
4959: mulp(nd_vc,CP(m),q,&CP(mr));
4960: ndl_add(DL(m),d,DL(mr));
4961: }
4962: }
4963: NEXT(mr) = 0;
4964: MKND(NV(p),mr0,len,r);
4965: SG(r) = SG(p) + TD(d);
4966: return r;
4967: }
1.4 noro 4968: }
4969:
1.104 noro 4970: ND nd_quo(int mod,PGeoBucket bucket,NDV d)
1.99 noro 4971: {
1.157 noro 4972: NM mq0,mq;
4973: NMV tm;
4974: Q q;
4975: int i,nv,sg,c,c1,c2,hindex;
4976: ND p,t,r;
4977: N tnm;
4978:
4979: if ( bucket->m < 0 ) return 0;
4980: else {
4981: nv = NV(d);
4982: mq0 = 0;
1.235 noro 4983: tm = (NMV)MALLOC(nmv_adv);
1.157 noro 4984: while ( 1 ) {
1.232 noro 4985: if ( mod > 0 || mod == -1 )
4986: hindex = head_pbucket(mod,bucket);
4987: else if ( mod == -2 )
4988: hindex = head_pbucket_lf(bucket);
4989: else
4990: hindex = head_pbucket_q(bucket);
1.157 noro 4991: if ( hindex < 0 ) break;
4992: p = bucket->body[hindex];
4993: NEXTNM(mq0,mq);
4994: ndl_sub(HDL(p),HDL(d),DL(mq));
4995: ndl_copy(DL(mq),DL(tm));
4996: if ( mod ) {
4997: c1 = invm(HCM(d),mod); c2 = HCM(p);
4998: DMAR(c1,c2,0,mod,c); CM(mq) = c;
4999: CM(tm) = mod-c;
5000: } else {
5001: divsn(NM(HCQ(p)),NM(HCQ(d)),&tnm);
5002: NTOQ(tnm,SGN(HCQ(p))*SGN(HCQ(d)),CQ(mq));
5003: chsgnq(CQ(mq),&CQ(tm));
5004: }
5005: t = ndv_mul_nmv_trunc(mod,tm,d,HDL(d));
5006: bucket->body[hindex] = nd_remove_head(p);
5007: t = nd_remove_head(t);
5008: add_pbucket(mod,bucket,t);
5009: }
5010: if ( !mq0 )
5011: r = 0;
5012: else {
5013: NEXT(mq) = 0;
5014: for ( i = 0, mq = mq0; mq; mq = NEXT(mq), i++ );
5015: MKND(nv,mq0,i,r);
5016: /* XXX */
5017: SG(r) = HTD(r);
5018: }
5019: return r;
5020: }
1.99 noro 5021: }
5022:
1.43 noro 5023: void ndv_realloc(NDV p,int obpe,int oadv,EPOS oepos)
1.11 noro 5024: {
1.157 noro 5025: NMV m,mr,mr0,t;
5026: int len,i,k;
1.11 noro 5027:
1.157 noro 5028: if ( !p ) return;
5029: m = BDY(p); len = LEN(p);
5030: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
5031: m = (NMV)((char *)mr0+(len-1)*oadv);
5032: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
1.235 noro 5033: t = (NMV)MALLOC(nmv_adv);
1.157 noro 5034: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
5035: CQ(t) = CQ(m);
5036: for ( k = 0; k < nd_wpd; k++ ) DL(t)[k] = 0;
5037: ndl_reconstruct(DL(m),DL(t),obpe,oepos);
5038: CQ(mr) = CQ(t);
5039: ndl_copy(DL(t),DL(mr));
5040: }
5041: BDY(p) = mr0;
1.61 noro 5042: }
5043:
5044: NDV ndv_dup_realloc(NDV p,int obpe,int oadv,EPOS oepos)
5045: {
1.157 noro 5046: NMV m,mr,mr0;
5047: int len,i;
5048: NDV r;
5049:
5050: if ( !p ) return 0;
5051: m = BDY(p); len = LEN(p);
5052: mr0 = mr = (NMV)MALLOC(len*nmv_adv);
5053: for ( i = 0; i < len; i++, NMV_OADV(m), NMV_ADV(mr) ) {
5054: ndl_zero(DL(mr));
5055: ndl_reconstruct(DL(m),DL(mr),obpe,oepos);
5056: CQ(mr) = CQ(m);
5057: }
5058: MKNDV(NV(p),mr0,len,r);
5059: SG(r) = SG(p);
5060: return r;
1.11 noro 5061: }
5062:
1.61 noro 5063: /* duplicate p */
5064:
5065: NDV ndv_dup(int mod,NDV p)
1.3 noro 5066: {
1.157 noro 5067: NDV d;
5068: NMV t,m,m0;
5069: int i,len;
5070:
5071: if ( !p ) return 0;
5072: len = LEN(p);
1.232 noro 5073: m0 = m = (NMV)((mod>0 || mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
1.157 noro 5074: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
5075: ndl_copy(DL(t),DL(m));
5076: CQ(m) = CQ(t);
5077: }
5078: MKNDV(NV(p),m0,len,d);
5079: SG(d) = SG(p);
5080: return d;
1.23 noro 5081: }
5082:
1.215 noro 5083: NDV ndvtondvgz(NDV p)
5084: {
1.245 noro 5085: NDV r;
5086: int len,i;
5087: NMV t;
1.215 noro 5088:
1.245 noro 5089: r = ndv_dup(0,p);
5090: len = LEN(p);
1.215 noro 5091: for ( t = BDY(r), i = 0; i < len; i++, NMV_ADV(t) ) CZ(t) = ztogz(CQ(t));
1.245 noro 5092: return r;
1.215 noro 5093: }
5094:
5095: NDV ndvgztondv(NDV p)
5096: {
1.245 noro 5097: NDV r;
5098: int len,i;
5099: NMV t;
1.215 noro 5100:
1.245 noro 5101: r = ndv_dup(0,p);
5102: len = LEN(p);
1.215 noro 5103: for ( t = BDY(r), i = 0; i < len; i++, NMV_ADV(t) ) CQ(t) = gztoz(CZ(t));
1.245 noro 5104: return r;
1.215 noro 5105: }
5106:
5107: NDV ndv_symbolic(int mod,NDV p)
5108: {
5109: NDV d;
5110: NMV t,m,m0;
5111: int i,len;
5112:
5113: if ( !p ) return 0;
5114: len = LEN(p);
1.232 noro 5115: m0 = m = (NMV)((mod>0||mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
1.215 noro 5116: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
5117: ndl_copy(DL(t),DL(m));
5118: CQ(m) = ONE;
5119: }
5120: MKNDV(NV(p),m0,len,d);
5121: SG(d) = SG(p);
5122: return d;
5123: }
5124:
1.63 noro 5125: ND nd_dup(ND p)
5126: {
1.157 noro 5127: ND d;
5128: NM t,m,m0;
1.63 noro 5129:
1.157 noro 5130: if ( !p ) return 0;
5131: for ( m0 = 0, t = BDY(p); t; t = NEXT(t) ) {
5132: NEXTNM(m0,m);
5133: ndl_copy(DL(t),DL(m));
5134: CQ(m) = CQ(t);
5135: }
5136: if ( m0 ) NEXT(m) = 0;
5137: MKND(NV(p),m0,LEN(p),d);
5138: SG(d) = SG(p);
5139: return d;
1.63 noro 5140: }
5141:
1.215 noro 5142: ND ndtondgz(ND p)
5143: {
1.245 noro 5144: ND r;
5145: NM t;
1.215 noro 5146:
1.245 noro 5147: r = nd_dup(p);
1.215 noro 5148: for ( t = BDY(r); t; t = NEXT(t) ) CZ(t) = ztogz(CQ(t));
1.245 noro 5149: return r;
1.215 noro 5150: }
5151:
5152:
5153: ND ndgztond(ND p)
5154: {
1.245 noro 5155: ND r;
5156: NM t;
1.215 noro 5157:
1.245 noro 5158: r = nd_dup(p);
1.215 noro 5159: for ( t = BDY(r); t; t = NEXT(t) ) CQ(t) = gztoz(CZ(t));
1.245 noro 5160: return r;
1.215 noro 5161: }
5162:
5163:
1.61 noro 5164: /* XXX if p->len == 0 then it represents 0 */
5165:
5166: void ndv_mod(int mod,NDV p)
5167: {
1.157 noro 5168: NMV t,d;
5169: int r,s,u;
5170: int i,len,dlen;
5171: P cp;
5172: Q c;
5173: Obj gfs;
5174:
5175: if ( !p ) return;
5176: len = LEN(p);
5177: dlen = 0;
5178: if ( mod == -1 )
5179: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
5180: simp_ff((Obj)CP(t),&gfs);
1.235 noro 5181: if ( gfs ) {
5182: r = FTOIF(CONT((GFS)gfs));
5183: CM(d) = r;
5184: ndl_copy(DL(t),DL(d));
5185: NMV_ADV(d);
5186: dlen++;
5187: }
1.157 noro 5188: }
1.232 noro 5189: else if ( mod == -2 )
5190: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
1.235 noro 5191: simp_ff((Obj)CP(t),&gfs);
5192: if ( gfs ) {
5193: lmtolf(gfs,&CZ(d));
5194: ndl_copy(DL(t),DL(d));
5195: NMV_ADV(d);
5196: dlen++;
5197: }
1.232 noro 5198: }
1.157 noro 5199: else
5200: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
5201: if ( nd_vc ) {
5202: nd_subst_vector(nd_vc,CP(t),nd_subst,&cp);
5203: c = (Q)cp;
5204: } else
5205: c = CQ(t);
5206: r = rem(NM(c),mod);
5207: if ( r ) {
5208: if ( SGN(c) < 0 )
5209: r = mod-r;
5210: if ( DN(c) ) {
5211: s = rem(DN(c),mod);
5212: if ( !s )
5213: error("ndv_mod : division by 0");
5214: s = invm(s,mod);
5215: DMAR(r,s,0,mod,u); r = u;
5216: }
5217: CM(d) = r;
5218: ndl_copy(DL(t),DL(d));
5219: NMV_ADV(d);
5220: dlen++;
5221: }
5222: }
5223: LEN(p) = dlen;
1.61 noro 5224: }
5225:
5226: NDV ptondv(VL vl,VL dvl,P p)
5227: {
1.157 noro 5228: ND nd;
5229:
5230: nd = ptond(vl,dvl,p);
5231: return ndtondv(0,nd);
5232: }
1.61 noro 5233:
1.157 noro 5234: void pltozpl(LIST l,Q *cont,LIST *pp)
5235: {
5236: NODE nd,nd1;
5237: int n;
5238: P *pl;
5239: Q *cl;
5240: int i;
5241: P dmy;
5242: Q dvr;
5243: LIST r;
5244:
5245: nd = BDY(l); n = length(nd);
1.235 noro 5246: pl = (P *)MALLOC(n*sizeof(P));
5247: cl = (Q *)MALLOC(n*sizeof(P));
1.157 noro 5248: for ( i = 0; i < n; i++, nd = NEXT(nd) )
5249: ptozp((P)BDY(nd),1,&cl[i],&dmy);
5250: qltozl(cl,n,&dvr);
5251: nd = BDY(l);
5252: for ( i = 0; i < n; i++, nd = NEXT(nd) ) {
5253: divsp(CO,(P)BDY(nd),(P)dvr,&pl[i]);
5254: }
5255: nd = 0;
5256: for ( i = n-1; i >= 0; i-- ) {
5257: MKNODE(nd1,pl[i],nd); nd = nd1;
5258: }
5259: MKLIST(r,nd);
5260: *pp = r;
5261: }
5262:
5263: /* (a1,a2,...,an) -> a1*e(1)+...+an*e(n) */
5264:
5265: NDV pltondv(VL vl,VL dvl,LIST p)
5266: {
5267: int i;
5268: NODE t;
5269: ND r,ri;
5270: NM m;
5271:
5272: if ( !nd_module ) error("pltond : module order must be set");
5273: r = 0;
5274: for ( i = 1, t = BDY(p); t; t = NEXT(t), i++ ) {
5275: ri = ptond(vl,dvl,(P)BDY(t));
1.163 noro 5276: if ( ri )
5277: for ( m = BDY(ri); m; m = NEXT(m) ) {
1.167 noro 5278: MPOS(DL(m)) = i;
5279: TD(DL(m)) = ndl_weight(DL(m));
1.163 noro 5280: if ( nd_blockmask ) ndl_weight_mask(DL(m));
5281: }
1.157 noro 5282: r = nd_add(0,r,ri);
5283: }
5284: return ndtondv(0,r);
1.61 noro 5285: }
5286:
5287: ND ptond(VL vl,VL dvl,P p)
1.23 noro 5288: {
1.157 noro 5289: int n,i,j,k,e;
5290: VL tvl;
5291: V v;
5292: DCP dc;
5293: DCP *w;
5294: ND r,s,t,u;
5295: P x;
5296: int c;
5297: UINT *d;
5298: NM m,m0;
5299:
5300: if ( !p )
5301: return 0;
5302: else if ( NUM(p) ) {
5303: NEWNM(m);
5304: ndl_zero(DL(m));
5305: CQ(m) = (Q)p;
5306: NEXT(m) = 0;
5307: MKND(nd_nvar,m,1,r);
5308: SG(r) = 0;
5309: return r;
5310: } else {
5311: for ( dc = DC(p), k = 0; dc; dc = NEXT(dc), k++ );
1.235 noro 5312: w = (DCP *)MALLOC(k*sizeof(DCP));
1.157 noro 5313: for ( dc = DC(p), j = 0; j < k; dc = NEXT(dc), j++ ) w[j] = dc;
5314: for ( i = 0, tvl = dvl, v = VR(p);
5315: tvl && tvl->v != v; tvl = NEXT(tvl), i++ );
5316: if ( !tvl ) {
5317: for ( j = k-1, s = 0, MKV(v,x); j >= 0; j-- ) {
5318: t = ptond(vl,dvl,COEF(w[j]));
5319: pwrp(vl,x,DEG(w[j]),&p);
5320: nd_mul_c_p(CO,t,p); s = nd_add(0,s,t);
5321: }
5322: return s;
5323: } else {
5324: NEWNM(m0); d = DL(m0);
5325: for ( j = k-1, s = 0; j >= 0; j-- ) {
5326: ndl_zero(d); e = QTOS(DEG(w[j])); PUT_EXP(d,i,e);
5327: TD(d) = MUL_WEIGHT(e,i);
5328: if ( nd_blockmask) ndl_weight_mask(d);
5329: if ( nd_module ) MPOS(d) = 0;
5330: t = ptond(vl,dvl,COEF(w[j]));
5331: for ( m = BDY(t); m; m = NEXT(m) )
5332: ndl_addto(DL(m),d);
5333: SG(t) += TD(d);
5334: s = nd_add(0,s,t);
5335: }
5336: FREENM(m0);
5337: return s;
5338: }
5339: }
1.61 noro 5340: }
5341:
5342: P ndvtop(int mod,VL vl,VL dvl,NDV p)
5343: {
1.157 noro 5344: VL tvl;
5345: int len,n,j,i,e;
5346: NMV m;
5347: Q q;
5348: P c;
5349: UINT *d;
5350: P s,r,u,t,w;
5351: GFS gfs;
5352:
5353: if ( !p ) return 0;
5354: else {
5355: len = LEN(p);
5356: n = NV(p);
5357: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
5358: for ( j = len-1, s = 0; j >= 0; j--, NMV_PREV(m) ) {
5359: if ( mod == -1 ) {
1.232 noro 5360: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
5361: } else if ( mod == -2 ) {
1.238 noro 5362: c = (P)gztoz(CZ(m));
1.232 noro 5363: } else if ( mod > 0 ) {
1.157 noro 5364: STOQ(CM(m),q); c = (P)q;
5365: } else
5366: c = CP(m);
5367: d = DL(m);
5368: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
5369: MKV(tvl->v,r); e = GET_EXP(d,i); STOQ(e,q);
5370: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
5371: }
5372: addp(vl,s,t,&u); s = u;
5373: }
5374: return s;
5375: }
5376: }
5377:
5378: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank)
5379: {
5380: VL tvl;
5381: int len,n,j,i,e;
5382: NMV m;
5383: Q q;
5384: P c;
5385: UINT *d;
5386: P s,r,u,t,w;
5387: GFS gfs;
5388: P *a;
5389: LIST l;
5390: NODE nd,nd1;
5391:
5392: if ( !p ) return 0;
5393: else {
1.235 noro 5394: a = (P *)MALLOC((rank+1)*sizeof(P));
1.157 noro 5395: for ( i = 0; i <= rank; i++ ) a[i] = 0;
5396: len = LEN(p);
5397: n = NV(p);
5398: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
5399: for ( j = len-1; j >= 0; j--, NMV_PREV(m) ) {
5400: if ( mod == -1 ) {
5401: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
5402: } else if ( mod ) {
5403: STOQ(CM(m),q); c = (P)q;
5404: } else
5405: c = CP(m);
5406: d = DL(m);
5407: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
5408: MKV(tvl->v,r); e = GET_EXP(d,i); STOQ(e,q);
5409: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
5410: }
5411: addp(vl,a[MPOS(d)],t,&u); a[MPOS(d)] = u;
5412: }
5413: nd = 0;
5414: for ( i = rank; i > 0; i-- ) {
5415: MKNODE(nd1,a[i],nd); nd = nd1;
5416: }
5417: MKLIST(l,nd);
5418: return l;
5419: }
1.3 noro 5420: }
5421:
1.61 noro 5422: NDV ndtondv(int mod,ND p)
1.11 noro 5423: {
1.157 noro 5424: NDV d;
5425: NMV m,m0;
5426: NM t;
5427: int i,len;
5428:
5429: if ( !p ) return 0;
5430: len = LEN(p);
1.232 noro 5431: if ( mod > 0 || mod == -1 )
1.200 noro 5432: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
1.157 noro 5433: else
5434: m0 = m = MALLOC(len*nmv_adv);
1.103 noro 5435: #if 0
1.157 noro 5436: ndv_alloc += nmv_adv*len;
1.103 noro 5437: #endif
1.157 noro 5438: for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, NMV_ADV(m) ) {
5439: ndl_copy(DL(t),DL(m));
5440: CQ(m) = CQ(t);
5441: }
5442: MKNDV(NV(p),m0,len,d);
5443: SG(d) = SG(p);
5444: return d;
1.11 noro 5445: }
5446:
1.61 noro 5447: ND ndvtond(int mod,NDV p)
1.11 noro 5448: {
1.157 noro 5449: ND d;
5450: NM m,m0;
5451: NMV t;
5452: int i,len;
5453:
5454: if ( !p ) return 0;
5455: m0 = 0;
5456: len = p->len;
5457: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
5458: NEXTNM(m0,m);
5459: ndl_copy(DL(t),DL(m));
5460: CQ(m) = CQ(t);
5461: }
5462: NEXT(m) = 0;
5463: MKND(NV(p),m0,len,d);
5464: SG(d) = SG(p);
5465: return d;
1.11 noro 5466: }
5467:
1.198 noro 5468: DP ndvtodp(int mod,NDV p)
5469: {
5470: MP m,m0;
1.245 noro 5471: DP d;
1.198 noro 5472: NMV t;
5473: int i,len;
5474:
5475: if ( !p ) return 0;
5476: m0 = 0;
5477: len = p->len;
5478: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
5479: NEXTMP(m0,m);
1.245 noro 5480: m->dl = ndltodl(nd_nvar,DL(t));
5481: m->c = (Obj)ndctop(mod,t->c);
1.198 noro 5482: }
5483: NEXT(m) = 0;
1.245 noro 5484: MKDP(nd_nvar,m0,d);
1.198 noro 5485: SG(d) = SG(p);
5486: return d;
5487: }
5488:
1.204 noro 5489: DP ndtodp(int mod,ND p)
5490: {
5491: MP m,m0;
1.245 noro 5492: DP d;
1.204 noro 5493: NM t;
5494: int i,len;
5495:
5496: if ( !p ) return 0;
5497: m0 = 0;
5498: len = p->len;
5499: for ( t = BDY(p); t; t = NEXT(t) ) {
5500: NEXTMP(m0,m);
1.245 noro 5501: m->dl = ndltodl(nd_nvar,DL(t));
5502: m->c = (Obj)ndctop(mod,t->c);
1.204 noro 5503: }
5504: NEXT(m) = 0;
1.245 noro 5505: MKDP(nd_nvar,m0,d);
1.204 noro 5506: SG(d) = SG(p);
5507: return d;
5508: }
5509:
1.3 noro 5510: void ndv_print(NDV p)
5511: {
1.157 noro 5512: NMV m;
5513: int i,len;
1.3 noro 5514:
1.157 noro 5515: if ( !p ) printf("0\n");
5516: else {
5517: len = LEN(p);
5518: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
5519: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
5520: else printf("+%d*",CM(m));
5521: ndl_print(DL(m));
5522: }
5523: printf("\n");
5524: }
1.16 noro 5525: }
5526:
1.113 noro 5527: void ndv_print_q(NDV p)
1.16 noro 5528: {
1.157 noro 5529: NMV m;
5530: int i,len;
1.16 noro 5531:
1.157 noro 5532: if ( !p ) printf("0\n");
5533: else {
5534: len = LEN(p);
5535: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
5536: printf("+");
5537: printexpr(CO,(Obj)CQ(m));
5538: printf("*");
5539: ndl_print(DL(m));
5540: }
5541: printf("\n");
5542: }
1.25 noro 5543: }
5544:
1.167 noro 5545: NODE ndv_reducebase(NODE x,int *perm)
1.27 noro 5546: {
1.157 noro 5547: int len,i,j;
1.167 noro 5548: NDVI w;
1.157 noro 5549: NODE t,t0;
5550:
5551: len = length(x);
1.235 noro 5552: w = (NDVI)MALLOC(len*sizeof(struct oNDVI));
1.167 noro 5553: for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) {
5554: w[i].p = BDY(t); w[i].i = perm[i];
5555: }
1.157 noro 5556: for ( i = 0; i < len; i++ ) {
5557: for ( j = 0; j < i; j++ ) {
1.167 noro 5558: if ( w[i].p && w[j].p )
5559: if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0;
5560: else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0;
1.157 noro 5561: }
5562: }
1.167 noro 5563: for ( i = j = 0, t0 = 0; i < len; i++ ) {
5564: if ( w[i].p ) {
5565: NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p;
5566: perm[j++] = w[i].i;
5567: }
1.157 noro 5568: }
5569: NEXT(t) = 0; x = t0;
5570: return x;
1.11 noro 5571: }
1.32 noro 5572:
1.43 noro 5573: /* XXX incomplete */
5574:
1.32 noro 5575: void nd_init_ord(struct order_spec *ord)
5576: {
1.224 noro 5577: nd_module = (ord->id >= 256);
5578: if ( nd_module ) {
5579: nd_dcomp = -1;
5580: nd_ispot = ord->ispot;
5581: nd_pot_nelim = ord->pot_nelim;
5582: nd_poly_weight_len = ord->nv;
5583: nd_poly_weight = ord->top_weight;
5584: nd_module_rank = ord->module_rank;
5585: nd_module_weight = ord->module_top_weight;
5586: }
1.245 noro 5587: nd_matrix = 0;
5588: nd_matrix_len = 0;
1.157 noro 5589: switch ( ord->id ) {
5590: case 0:
5591: switch ( ord->ord.simple ) {
5592: case 0:
5593: nd_dcomp = 1;
5594: nd_isrlex = 1;
5595: break;
5596: case 1:
5597: nd_dcomp = 1;
5598: nd_isrlex = 0;
5599: break;
5600: case 2:
5601: nd_dcomp = 0;
5602: nd_isrlex = 0;
5603: ndl_compare_function = ndl_lex_compare;
5604: break;
5605: case 11:
5606: /* XXX */
5607: nd_dcomp = 0;
5608: nd_isrlex = 1;
5609: ndl_compare_function = ndl_ww_lex_compare;
5610: break;
5611: default:
5612: error("nd_gr : unsupported order");
5613: }
5614: break;
5615: case 1:
5616: /* block order */
5617: /* XXX */
5618: nd_dcomp = -1;
5619: nd_isrlex = 0;
5620: ndl_compare_function = ndl_block_compare;
5621: break;
5622: case 2:
5623: /* matrix order */
5624: /* XXX */
5625: nd_dcomp = -1;
5626: nd_isrlex = 0;
5627: nd_matrix_len = ord->ord.matrix.row;
5628: nd_matrix = ord->ord.matrix.matrix;
5629: ndl_compare_function = ndl_matrix_compare;
5630: break;
5631: case 3:
5632: /* composite order */
5633: nd_dcomp = -1;
5634: nd_isrlex = 0;
5635: nd_worb_len = ord->ord.composite.length;
5636: nd_worb = ord->ord.composite.w_or_b;
5637: ndl_compare_function = ndl_composite_compare;
5638: break;
5639:
5640: /* module order */
5641: case 256:
5642: switch ( ord->ord.simple ) {
5643: case 0:
1.167 noro 5644: nd_isrlex = 1;
1.157 noro 5645: ndl_compare_function = ndl_module_grlex_compare;
5646: break;
5647: case 1:
1.167 noro 5648: nd_isrlex = 0;
1.157 noro 5649: ndl_compare_function = ndl_module_glex_compare;
5650: break;
5651: case 2:
1.167 noro 5652: nd_isrlex = 0;
1.157 noro 5653: ndl_compare_function = ndl_module_lex_compare;
5654: break;
5655: default:
5656: error("nd_gr : unsupported order");
5657: }
5658: break;
5659: case 257:
5660: /* block order */
1.174 noro 5661: nd_isrlex = 0;
1.157 noro 5662: ndl_compare_function = ndl_module_block_compare;
5663: break;
5664: case 258:
5665: /* matrix order */
1.174 noro 5666: nd_isrlex = 0;
1.157 noro 5667: nd_matrix_len = ord->ord.matrix.row;
5668: nd_matrix = ord->ord.matrix.matrix;
5669: ndl_compare_function = ndl_module_matrix_compare;
5670: break;
5671: case 259:
5672: /* composite order */
1.174 noro 5673: nd_isrlex = 0;
1.157 noro 5674: nd_worb_len = ord->ord.composite.length;
5675: nd_worb = ord->ord.composite.w_or_b;
5676: ndl_compare_function = ndl_module_composite_compare;
5677: break;
5678: }
5679: nd_ord = ord;
1.32 noro 5680: }
5681:
1.43 noro 5682: BlockMask nd_create_blockmask(struct order_spec *ord)
5683: {
1.157 noro 5684: int n,i,j,s,l;
5685: UINT *t;
5686: BlockMask bm;
5687:
5688: /* we only create mask table for block order */
1.164 noro 5689: if ( ord->id != 1 && ord->id != 257 )
1.157 noro 5690: return 0;
5691: n = ord->ord.block.length;
5692: bm = (BlockMask)MALLOC(sizeof(struct oBlockMask));
5693: bm->n = n;
5694: bm->order_pair = ord->ord.block.order_pair;
5695: bm->mask = (UINT **)MALLOC(n*sizeof(UINT *));
5696: for ( i = 0, s = 0; i < n; i++ ) {
5697: bm->mask[i] = t = (UINT *)MALLOC_ATOMIC(nd_wpd*sizeof(UINT));
5698: for ( j = 0; j < nd_wpd; j++ ) t[j] = 0;
5699: l = bm->order_pair[i].length;
5700: for ( j = 0; j < l; j++, s++ ) PUT_EXP(t,s,nd_mask0);
5701: }
5702: return bm;
1.57 noro 5703: }
5704:
5705: EPOS nd_create_epos(struct order_spec *ord)
5706: {
1.157 noro 5707: int i,j,l,s,ord_l,ord_o;
5708: EPOS epos;
5709: struct order_pair *op;
5710:
5711: epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS));
5712: switch ( ord->id ) {
1.164 noro 5713: case 0: case 256:
1.157 noro 5714: if ( nd_isrlex ) {
5715: for ( i = 0; i < nd_nvar; i++ ) {
5716: epos[i].i = nd_exporigin + (nd_nvar-1-i)/nd_epw;
5717: epos[i].s = (nd_epw-((nd_nvar-1-i)%nd_epw)-1)*nd_bpe;
5718: }
5719: } else {
5720: for ( i = 0; i < nd_nvar; i++ ) {
5721: epos[i].i = nd_exporigin + i/nd_epw;
5722: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
5723: }
5724: }
5725: break;
1.164 noro 5726: case 1: case 257:
1.157 noro 5727: /* block order */
5728: l = ord->ord.block.length;
5729: op = ord->ord.block.order_pair;
5730: for ( j = 0, s = 0; j < l; j++ ) {
5731: ord_o = op[j].order;
5732: ord_l = op[j].length;
5733: if ( !ord_o )
5734: for ( i = 0; i < ord_l; i++ ) {
5735: epos[s+i].i = nd_exporigin + (s+ord_l-i-1)/nd_epw;
5736: epos[s+i].s = (nd_epw-((s+ord_l-i-1)%nd_epw)-1)*nd_bpe;
5737: }
5738: else
5739: for ( i = 0; i < ord_l; i++ ) {
5740: epos[s+i].i = nd_exporigin + (s+i)/nd_epw;
5741: epos[s+i].s = (nd_epw-((s+i)%nd_epw)-1)*nd_bpe;
5742: }
5743: s += ord_l;
5744: }
5745: break;
5746: case 2:
5747: /* matrix order */
5748: case 3:
5749: /* composite order */
1.167 noro 5750: default:
1.157 noro 5751: for ( i = 0; i < nd_nvar; i++ ) {
5752: epos[i].i = nd_exporigin + i/nd_epw;
5753: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
5754: }
5755: break;
5756: }
5757: return epos;
1.43 noro 5758: }
1.59 noro 5759:
5760: /* external interface */
5761:
1.191 noro 5762: void nd_nf_p(Obj f,LIST g,LIST v,int m,struct order_spec *ord,Obj *rp)
1.59 noro 5763: {
1.157 noro 5764: NODE t,in0,in;
1.191 noro 5765: ND ndf,nf;
5766: NDV ndvf;
1.157 noro 5767: VL vv,tv;
1.191 noro 5768: int stat,nvar,max,mrank;
1.157 noro 5769: union oNDC dn;
5770: Q cont;
5771: P pp;
1.191 noro 5772: LIST ppl;
1.157 noro 5773:
5774: if ( !f ) {
5775: *rp = 0;
5776: return;
5777: }
5778: pltovl(v,&vv);
5779: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5780:
1.191 noro 5781: /* max=65536 implies nd_bpe=32 */
5782: max = 65536;
1.157 noro 5783:
1.245 noro 5784: nd_module = 0;
5785: /* nd_module will be set if ord is a module ordering */
1.157 noro 5786: nd_init_ord(ord);
5787: nd_setup_parameters(nvar,max);
1.191 noro 5788: if ( nd_module && OID(f) != O_LIST )
5789: error("nd_nf_p : the first argument must be a list");
1.245 noro 5790: if ( nd_module ) mrank = length(BDY((LIST)f));
1.157 noro 5791: /* conversion to ndv */
5792: for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) {
5793: NEXTNODE(in0,in);
1.191 noro 5794: if ( nd_module ) {
5795: if ( !BDY(t) || OID(BDY(t)) != O_LIST
5796: || length(BDY((LIST)BDY(t))) != mrank )
5797: error("nd_nf_p : inconsistent basis element");
5798: if ( !m ) pltozpl((LIST)BDY(t),&cont,&ppl);
5799: else ppl = (LIST)BDY(t);
5800: BDY(in) = (pointer)pltondv(CO,vv,ppl);
5801: } else {
5802: if ( !m ) ptozp((P)BDY(t),1,&cont,&pp);
5803: else pp = (P)BDY(t);
5804: BDY(in) = (pointer)ptondv(CO,vv,pp);
5805: }
1.157 noro 5806: if ( m ) ndv_mod(m,(NDV)BDY(in));
5807: }
1.191 noro 5808: if ( in0 ) NEXT(in) = 0;
5809:
5810: if ( nd_module ) ndvf = pltondv(CO,vv,(LIST)f);
5811: else ndvf = ptondv(CO,vv,(P)f);
5812: if ( m ) ndv_mod(m,ndvf);
5813: ndf = (pointer)ndvtond(m,ndvf);
1.157 noro 5814:
5815: /* dont sort, dont removecont */
5816: ndv_setup(m,0,in0,1,1);
5817: nd_scale=2;
1.191 noro 5818: stat = nd_nf(m,0,ndf,nd_ps,1,0,&nf);
5819: if ( !stat )
5820: error("nd_nf_p : exponent too large");
5821: if ( nd_module ) *rp = (Obj)ndvtopl(m,CO,vv,ndtondv(m,nf),mrank);
5822: else *rp = (Obj)ndvtop(m,CO,vv,ndtondv(m,nf));
1.63 noro 5823: }
5824:
5825: int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r)
5826: {
1.157 noro 5827: NM m;
5828: UINT *t,*s;
5829: int i;
5830:
5831: for ( i = 0; i < n; i++ ) r[i] = 0;
5832: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
5833: t = DL(m);
5834: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5835: r[i] = CM(m);
5836: }
5837: for ( i = 0; !r[i]; i++ );
5838: return i;
1.63 noro 5839: }
5840:
1.242 noro 5841: #if defined(__GNUC__) && SIZEOF_LONG==8
1.240 noro 5842:
5843: #define MOD128(a,c,m) ((a)=(((c)!=0||((a)>=(m)))?(((((U128)(c))<<64)+(a))%(m)):(a)))
5844:
5845: int nd_to_vect64(int mod,UINT *s0,int n,ND d,U64 *r)
1.239 noro 5846: {
5847: NM m;
5848: UINT *t,*s;
5849: int i;
5850:
5851: for ( i = 0; i < n; i++ ) r[i] = 0;
5852: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
5853: t = DL(m);
5854: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.240 noro 5855: r[i] = (U64)CM(m);
1.239 noro 5856: }
5857: for ( i = 0; !r[i]; i++ );
5858: return i;
5859: }
5860: #endif
5861:
1.113 noro 5862: int nd_to_vect_q(UINT *s0,int n,ND d,Q *r)
1.74 noro 5863: {
1.157 noro 5864: NM m;
5865: UINT *t,*s;
5866: int i;
5867:
5868: for ( i = 0; i < n; i++ ) r[i] = 0;
5869: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
5870: t = DL(m);
5871: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5872: r[i] = CQ(m);
5873: }
5874: for ( i = 0; !r[i]; i++ );
5875: return i;
1.74 noro 5876: }
5877:
1.232 noro 5878: int nd_to_vect_lf(UINT *s0,int n,ND d,mpz_t *r)
5879: {
5880: NM m;
5881: UINT *t,*s;
5882: int i;
5883:
5884: for ( i = 0; i < n; i++ ) { mpz_init(r[i]); mpz_set_ui(r[i],0); }
5885: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
5886: t = DL(m);
5887: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5888: mpz_set(r[i],BDY(CZ(m)));
5889: }
5890: for ( i = 0; !mpz_sgn(r[i]); i++ );
5891: return i;
5892: }
5893:
1.220 noro 5894: unsigned long *nd_to_vect_2(UINT *s0,int n,int *s0hash,ND p)
5895: {
5896: NM m;
5897: unsigned long *v;
5898: int i,j,h,size;
1.245 noro 5899: UINT *s,*t;
1.220 noro 5900:
1.245 noro 5901: size = sizeof(unsigned long)*(n+BLEN-1)/BLEN;
1.220 noro 5902: v = (unsigned long *)MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
5903: bzero(v,size);
5904: for ( i = j = 0, s = s0, m = BDY(p); m; j++, m = NEXT(m) ) {
1.245 noro 5905: t = DL(m);
5906: h = ndl_hash_value(t);
1.220 noro 5907: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
1.245 noro 5908: v[i/BLEN] |= 1L <<(i%BLEN);
1.220 noro 5909: }
5910: return v;
5911: }
5912:
5913: int nd_nm_to_vect_2(UINT *s0,int n,int *s0hash,NDV p,NM m,unsigned long *v)
5914: {
5915: NMV mr;
5916: UINT *d,*t,*s;
5917: int i,j,len,h,head;
5918:
5919: d = DL(m);
5920: len = LEN(p);
1.235 noro 5921: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
1.220 noro 5922: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
5923: ndl_add(d,DL(mr),t);
1.245 noro 5924: h = ndl_hash_value(t);
1.220 noro 5925: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
1.245 noro 5926: if ( j == 0 ) head = i;
5927: v[i/BLEN] |= 1L <<(i%BLEN);
1.220 noro 5928: }
5929: return head;
5930: }
5931:
1.129 noro 5932: Q *nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_pair pair)
5933: {
1.157 noro 5934: NM m;
5935: NMV mr;
5936: UINT *d,*t,*s;
5937: NDV p;
5938: int i,j,len;
5939: Q *r;
5940:
5941: m = pair->mul;
5942: d = DL(m);
5943: p = nd_ps[pair->index];
5944: len = LEN(p);
5945: r = (Q *)CALLOC(n,sizeof(Q));
1.235 noro 5946: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
1.157 noro 5947: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
5948: ndl_add(d,DL(mr),t);
5949: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
5950: r[i] = CQ(mr);
5951: }
5952: return r;
1.129 noro 5953: }
5954:
1.235 noro 5955: IndArray nm_ind_pair_to_vect_compress(int trace,UINT *s0,int n,int *s0hash,NM_ind_pair pair)
1.64 noro 5956: {
1.157 noro 5957: NM m;
5958: NMV mr;
5959: UINT *d,*t,*s;
5960: NDV p;
5961: unsigned char *ivc;
5962: unsigned short *ivs;
5963: UINT *v,*ivi,*s0v;
1.210 noro 5964: int i,j,len,prev,diff,cdiff,h;
1.157 noro 5965: IndArray r;
1.198 noro 5966: struct oEGT eg0,eg1;
1.157 noro 5967:
5968: m = pair->mul;
5969: d = DL(m);
1.235 noro 5970: if ( trace )
5971: p = nd_demand?nd_ps_trace_sym[pair->index]:nd_ps_trace[pair->index];
5972: else
5973: p = nd_demand?nd_ps_sym[pair->index]:nd_ps[pair->index];
5974:
1.157 noro 5975: len = LEN(p);
1.235 noro 5976: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
5977: v = (unsigned int *)MALLOC(len*sizeof(unsigned int));
1.198 noro 5978: get_eg(&eg0);
1.157 noro 5979: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
5980: ndl_add(d,DL(mr),t);
1.245 noro 5981: h = ndl_hash_value(t);
1.210 noro 5982: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
1.157 noro 5983: v[j] = i;
5984: }
1.198 noro 5985: get_eg(&eg1); add_eg(&eg_search,&eg0,&eg1);
1.157 noro 5986: r = (IndArray)MALLOC(sizeof(struct oIndArray));
5987: r->head = v[0];
5988: diff = 0;
5989: for ( i = 1; i < len; i++ ) {
5990: cdiff = v[i]-v[i-1]; diff = MAX(cdiff,diff);
5991: }
5992: if ( diff < 256 ) {
5993: r->width = 1;
5994: ivc = (unsigned char *)MALLOC_ATOMIC(len*sizeof(unsigned char));
5995: r->index.c = ivc;
5996: for ( i = 1, ivc[0] = 0; i < len; i++ ) ivc[i] = v[i]-v[i-1];
5997: } else if ( diff < 65536 ) {
5998: r->width = 2;
5999: ivs = (unsigned short *)MALLOC_ATOMIC(len*sizeof(unsigned short));
6000: r->index.s = ivs;
6001: for ( i = 1, ivs[0] = 0; i < len; i++ ) ivs[i] = v[i]-v[i-1];
6002: } else {
6003: r->width = 4;
6004: ivi = (unsigned int *)MALLOC_ATOMIC(len*sizeof(unsigned int));
6005: r->index.i = ivi;
6006: for ( i = 1, ivi[0] = 0; i < len; i++ ) ivi[i] = v[i]-v[i-1];
6007: }
6008: return r;
1.64 noro 6009: }
6010:
1.135 noro 6011: int compress_array(Q *svect,Q *cvect,int n)
6012: {
1.157 noro 6013: int i,j;
1.135 noro 6014:
1.157 noro 6015: for ( i = j = 0; i < n; i++ )
6016: if ( svect[i] ) cvect[j++] = svect[i];
6017: return j;
1.135 noro 6018: }
6019:
6020: void expand_array(Q *svect,Q *cvect,int n)
6021: {
1.157 noro 6022: int i,j;
1.135 noro 6023:
1.157 noro 6024: for ( i = j = 0; j < n; i++ )
6025: if ( svect[i] ) svect[i] = cvect[j++];
1.135 noro 6026: }
6027:
1.133 noro 6028: int ndv_reduce_vect_q(Q *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.107 noro 6029: {
1.157 noro 6030: int i,j,k,len,pos,prev,nz;
6031: Q cs,mcs,c1,c2,cr,gcd,t;
6032: IndArray ivect;
6033: unsigned char *ivc;
6034: unsigned short *ivs;
6035: unsigned int *ivi;
6036: NDV redv;
6037: NMV mr;
6038: NODE rp;
6039: int maxrs;
6040: double hmag;
6041: Q *cvect;
6042:
6043: maxrs = 0;
6044: for ( i = 0; i < col && !svect[i]; i++ );
6045: if ( i == col ) return maxrs;
6046: hmag = p_mag((P)svect[i])*nd_scale;
1.235 noro 6047: cvect = (Q *)MALLOC(col*sizeof(Q));
1.157 noro 6048: for ( i = 0; i < nred; i++ ) {
6049: ivect = imat[i];
6050: k = ivect->head;
6051: if ( svect[k] ) {
6052: maxrs = MAX(maxrs,rp0[i]->sugar);
1.215 noro 6053: redv = nd_demand?ndv_load(rp0[i]->index)
6054: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
1.157 noro 6055: len = LEN(redv); mr = BDY(redv);
6056: igcd_cofactor(svect[k],CQ(mr),&gcd,&cs,&cr);
6057: chsgnq(cs,&mcs);
6058: if ( !UNIQ(cr) ) {
6059: for ( j = 0; j < col; j++ ) {
6060: mulq(svect[j],cr,&c1); svect[j] = c1;
6061: }
6062: }
6063: svect[k] = 0; prev = k;
6064: switch ( ivect->width ) {
6065: case 1:
6066: ivc = ivect->index.c;
6067: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6068: pos = prev+ivc[j]; prev = pos;
6069: mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t;
6070: }
6071: break;
6072: case 2:
6073: ivs = ivect->index.s;
6074: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6075: pos = prev+ivs[j]; prev = pos;
6076: mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t;
6077: }
6078: break;
6079: case 4:
6080: ivi = ivect->index.i;
6081: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6082: pos = prev+ivi[j]; prev = pos;
6083: mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t;
6084: }
6085: break;
6086: }
6087: for ( j = k+1; j < col && !svect[j]; j++ );
6088: if ( j == col ) break;
6089: if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) {
6090: nz = compress_array(svect,cvect,col);
6091: removecont_array((P *)cvect,nz,1);
6092: expand_array(svect,cvect,nz);
6093: hmag = ((double)p_mag((P)svect[j]))*nd_scale;
6094: }
6095: }
6096: }
6097: nz = compress_array(svect,cvect,col);
6098: removecont_array((P *)cvect,nz,1);
6099: expand_array(svect,cvect,nz);
6100: if ( DP_Print ) {
6101: fprintf(asir_out,"-"); fflush(asir_out);
6102: }
6103: return maxrs;
1.107 noro 6104: }
6105:
1.215 noro 6106: int ndv_reduce_vect_gz(GZ *gvect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
6107: {
6108: int i,j,k,l,len,pos,prev,nz;
6109: GZ cs,mcs,c1,c2,cr,gcd,t;
6110: IndArray ivect;
6111: unsigned char *ivc;
6112: unsigned short *ivs;
6113: unsigned int *ivi;
6114: NDV redv;
6115: NMV mr;
6116: NODE rp;
6117: int maxrs;
6118: double hmag;
1.245 noro 6119: struct oVECT v;
1.215 noro 6120:
6121: maxrs = 0;
6122: for ( i = 0; i < col && !gvect[i]; i++ );
6123: if ( i == col ) return maxrs;
6124: hmag = (double)n_bits_gz(gvect[i])*nd_scale;
6125: for ( i = 0; i < nred; i++ ) {
6126: ivect = imat[i];
6127: k = ivect->head;
6128: if ( gvect[k] ) {
6129: maxrs = MAX(maxrs,rp0[i]->sugar);
6130: redv = nd_ps_gz[rp0[i]->index];
6131: len = LEN(redv); mr = BDY(redv);
1.245 noro 6132: gcdgz(gvect[k],CZ(mr),&gcd);
6133: divsgz(gvect[k],gcd,&cs);
6134: divsgz(CZ(mr),gcd,&cr);
1.215 noro 6135: chsgngz(cs,&mcs);
1.245 noro 6136: if ( !UNIGZ(cr) ) {
1.215 noro 6137: for ( j = 0; j < col; j++ ) {
6138: mulgz(gvect[j],cr,&c1); gvect[j] = c1;
6139: }
6140: }
6141: gvect[k] = 0; prev = k;
6142: switch ( ivect->width ) {
6143: case 1:
6144: ivc = ivect->index.c;
6145: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6146: pos = prev+ivc[j]; prev = pos;
6147: mulgz(CZ(mr),mcs,&c2); addgz(gvect[pos],c2,&t); gvect[pos] = t;
6148: }
6149: break;
6150: case 2:
6151: ivs = ivect->index.s;
6152: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6153: pos = prev+ivs[j]; prev = pos;
6154: mulgz(CZ(mr),mcs,&c2); addgz(gvect[pos],c2,&t); gvect[pos] = t;
6155: }
6156: break;
6157: case 4:
6158: ivi = ivect->index.i;
6159: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6160: pos = prev+ivi[j]; prev = pos;
6161: mulgz(CZ(mr),mcs,&c2); addgz(gvect[pos],c2,&t); gvect[pos] = t;
6162: }
6163: break;
6164: }
6165: for ( j = k+1; j < col && !gvect[j]; j++ );
6166: if ( j == col ) break;
6167: if ( hmag && ((double)n_bits_gz(gvect[j]) > hmag) ) {
1.245 noro 6168: v.len = col; v.body = (pointer)gvect; gcdvgz(&v,&gcd);
1.215 noro 6169: #if 1
1.245 noro 6170: for ( l = 0; l < col; l++ ) { divsgz(gvect[l],gcd,&t); gvect[l] = t; }
1.215 noro 6171: #endif
1.245 noro 6172: hmag = (double)n_bits_gz(gvect[j])*nd_scale;
1.215 noro 6173: }
6174: }
6175: }
6176: for ( j = 0; j < col && !gvect[j]; j++ );
1.245 noro 6177: if ( j < col ) {
6178: v.len = col; v.body = (pointer)gvect; gcdvgz(&v,&gcd);
6179: for ( l = 0; l < col; l++ ) { divsgz(gvect[l],gcd,&t); gvect[l] = t; }
6180: }
1.215 noro 6181: if ( DP_Print ) {
6182: fprintf(asir_out,"-"); fflush(asir_out);
6183: }
6184: return maxrs;
6185: }
6186:
1.76 noro 6187: int ndv_reduce_vect(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.65 noro 6188: {
1.157 noro 6189: int i,j,k,len,pos,prev;
6190: UINT c,c1,c2,c3,up,lo,dmy;
6191: IndArray ivect;
6192: unsigned char *ivc;
6193: unsigned short *ivs;
6194: unsigned int *ivi;
6195: NDV redv;
6196: NMV mr;
6197: NODE rp;
6198: int maxrs;
6199:
6200: maxrs = 0;
6201: for ( i = 0; i < nred; i++ ) {
6202: ivect = imat[i];
6203: k = ivect->head; svect[k] %= m;
6204: if ( c = svect[k] ) {
6205: maxrs = MAX(maxrs,rp0[i]->sugar);
6206: c = m-c; redv = nd_ps[rp0[i]->index];
6207: len = LEN(redv); mr = BDY(redv);
6208: svect[k] = 0; prev = k;
6209: switch ( ivect->width ) {
6210: case 1:
6211: ivc = ivect->index.c;
6212: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
1.215 noro 6213: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.245 noro 6214: if ( c1 ) {
6215: c2 = svect[pos];
6216: DMA(c1,c,c2,up,lo);
6217: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
6218: } else svect[pos] = lo;
6219: }
1.157 noro 6220: }
6221: break;
6222: case 2:
6223: ivs = ivect->index.s;
6224: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
1.215 noro 6225: pos = prev+ivs[j]; c1 = CM(mr);
1.157 noro 6226: prev = pos;
1.245 noro 6227: if ( c1 ) {
6228: c2 = svect[pos];
6229: DMA(c1,c,c2,up,lo);
6230: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
6231: } else svect[pos] = lo;
6232: }
1.157 noro 6233: }
6234: break;
6235: case 4:
6236: ivi = ivect->index.i;
6237: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
1.215 noro 6238: pos = prev+ivi[j]; c1 = CM(mr);
1.157 noro 6239: prev = pos;
1.245 noro 6240: if ( c1 ) {
6241: c2 = svect[pos];
6242: DMA(c1,c,c2,up,lo);
6243: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
6244: } else svect[pos] = lo;
6245: }
1.157 noro 6246: }
6247: break;
6248: }
6249: }
6250: }
6251: for ( i = 0; i < col; i++ )
6252: if ( svect[i] >= (UINT)m ) svect[i] %= m;
6253: return maxrs;
1.65 noro 6254: }
6255:
1.242 noro 6256: #if defined(__GNUC__) && SIZEOF_LONG==8
1.240 noro 6257:
6258: int ndv_reduce_vect64(int m,U64 *svect,U64 *cvect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.239 noro 6259: {
6260: int i,j,k,len,pos,prev;
1.240 noro 6261: U64 a,c,c1,c2;
1.239 noro 6262: IndArray ivect;
6263: unsigned char *ivc;
6264: unsigned short *ivs;
6265: unsigned int *ivi;
6266: NDV redv;
6267: NMV mr;
6268: NODE rp;
6269: int maxrs;
6270:
1.240 noro 6271: for ( i = 0; i < col; i++ ) cvect[i] = 0;
1.239 noro 6272: maxrs = 0;
6273: for ( i = 0; i < nred; i++ ) {
6274: ivect = imat[i];
1.240 noro 6275: k = ivect->head;
6276: a = svect[k]; c = cvect[k];
6277: MOD128(a,c,m);
6278: svect[k] = a; cvect[k] = 0;
1.239 noro 6279: if ( c = svect[k] ) {
6280: maxrs = MAX(maxrs,rp0[i]->sugar);
6281: c = m-c; redv = nd_ps[rp0[i]->index];
6282: len = LEN(redv); mr = BDY(redv);
6283: svect[k] = 0; prev = k;
6284: switch ( ivect->width ) {
6285: case 1:
6286: ivc = ivect->index.c;
6287: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6288: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.240 noro 6289: if ( c1 ) {
6290: c2 = svect[pos]+c1*c;
6291: if ( c2 < svect[pos] ) cvect[pos]++;
6292: svect[pos] = c2;
6293: }
1.239 noro 6294: }
6295: break;
6296: case 2:
6297: ivs = ivect->index.s;
6298: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6299: pos = prev+ivs[j]; c1 = CM(mr); prev = pos;
1.240 noro 6300: if ( c1 ) {
6301: c2 = svect[pos]+c1*c;
6302: if ( c2 < svect[pos] ) cvect[pos]++;
6303: svect[pos] = c2;
6304: }
1.239 noro 6305: }
6306: break;
6307: case 4:
6308: ivi = ivect->index.i;
6309: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6310: pos = prev+ivi[j]; c1 = CM(mr); prev = pos;
1.240 noro 6311: if ( c1 ) {
6312: c2 = svect[pos]+c1*c;
6313: if ( c2 < svect[pos] ) cvect[pos]++;
6314: svect[pos] = c2;
6315: }
1.239 noro 6316: }
6317: break;
6318: }
6319: }
6320: }
1.240 noro 6321: for ( i = 0; i < col; i++ ) {
6322: a = svect[i]; c = cvect[i]; MOD128(a,c,m); svect[i] = a;
6323: }
1.239 noro 6324: return maxrs;
6325: }
6326: #endif
6327:
1.76 noro 6328: int ndv_reduce_vect_sf(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.72 noro 6329: {
1.157 noro 6330: int i,j,k,len,pos,prev;
6331: UINT c,c1,c2,c3,up,lo,dmy;
6332: IndArray ivect;
6333: unsigned char *ivc;
6334: unsigned short *ivs;
6335: unsigned int *ivi;
6336: NDV redv;
6337: NMV mr;
6338: NODE rp;
6339: int maxrs;
6340:
6341: maxrs = 0;
6342: for ( i = 0; i < nred; i++ ) {
6343: ivect = imat[i];
1.232 noro 6344: k = ivect->head;
1.157 noro 6345: if ( c = svect[k] ) {
6346: maxrs = MAX(maxrs,rp0[i]->sugar);
6347: c = _chsgnsf(c); redv = nd_ps[rp0[i]->index];
6348: len = LEN(redv); mr = BDY(redv);
6349: svect[k] = 0; prev = k;
6350: switch ( ivect->width ) {
6351: case 1:
6352: ivc = ivect->index.c;
6353: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6354: pos = prev+ivc[j]; prev = pos;
6355: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
6356: }
6357: break;
6358: case 2:
6359: ivs = ivect->index.s;
6360: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6361: pos = prev+ivs[j]; prev = pos;
6362: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
6363: }
6364: break;
6365: case 4:
6366: ivi = ivect->index.i;
6367: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6368: pos = prev+ivi[j]; prev = pos;
6369: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
6370: }
6371: break;
6372: }
6373: }
6374: }
6375: return maxrs;
1.72 noro 6376: }
6377:
1.232 noro 6378: ND nd_add_lf(ND p1,ND p2)
6379: {
6380: int n,c,can;
6381: ND r;
6382: NM m1,m2,mr0,mr,s;
6383: GZ t;
6384:
6385: if ( !p1 ) return p2;
6386: else if ( !p2 ) return p1;
6387: else {
6388: can = 0;
6389: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
6390: c = DL_COMPARE(DL(m1),DL(m2));
6391: switch ( c ) {
6392: case 0:
6393: addlf(CZ(m1),CZ(m2),&t);
6394: s = m1; m1 = NEXT(m1);
6395: if ( t ) {
6396: can++; NEXTNM2(mr0,mr,s); CZ(mr) = (t);
6397: } else {
6398: can += 2; FREENM(s);
6399: }
6400: s = m2; m2 = NEXT(m2); FREENM(s);
6401: break;
6402: case 1:
6403: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
6404: break;
6405: case -1:
6406: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
6407: break;
6408: }
6409: }
6410: if ( !mr0 )
6411: if ( m1 ) mr0 = m1;
6412: else if ( m2 ) mr0 = m2;
6413: else return 0;
6414: else if ( m1 ) NEXT(mr) = m1;
6415: else if ( m2 ) NEXT(mr) = m2;
6416: else NEXT(mr) = 0;
6417: BDY(p1) = mr0;
6418: SG(p1) = MAX(SG(p1),SG(p2));
6419: LEN(p1) = LEN(p1)+LEN(p2)-can;
6420: FREEND(p2);
6421: return p1;
6422: }
6423: }
6424:
1.234 noro 6425: int ndv_reduce_vect_lf(mpz_t *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
1.232 noro 6426: {
6427: int i,j,k,len,pos,prev;
6428: mpz_t c,mc,c1;
6429: IndArray ivect;
6430: unsigned char *ivc;
6431: unsigned short *ivs;
6432: unsigned int *ivi;
6433: NDV redv;
6434: NMV mr;
6435: NODE rp;
6436: int maxrs;
6437:
6438: maxrs = 0;
6439: lf_lazy = 1;
6440: for ( i = 0; i < nred; i++ ) {
6441: ivect = imat[i];
6442: k = ivect->head;
6443: mpz_mod(svect[k],svect[k],BDY(current_mod_lf));
6444: if ( mpz_sgn(svect[k]) ) {
6445: maxrs = MAX(maxrs,rp0[i]->sugar);
6446: mpz_neg(svect[k],svect[k]);
1.234 noro 6447: redv = trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index];
1.232 noro 6448: len = LEN(redv); mr = BDY(redv);
6449: prev = k;
6450: switch ( ivect->width ) {
6451: case 1:
6452: ivc = ivect->index.c;
6453: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6454: pos = prev+ivc[j]; prev = pos;
6455: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
6456: }
6457: break;
6458: case 2:
6459: ivs = ivect->index.s;
6460: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6461: pos = prev+ivs[j]; prev = pos;
6462: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
6463: }
6464: break;
6465: case 4:
6466: ivi = ivect->index.i;
6467: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
6468: pos = prev+ivi[j]; prev = pos;
6469: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
6470: }
6471: break;
6472: }
6473: mpz_set_ui(svect[k],0);
6474: }
6475: }
6476: lf_lazy=0;
6477: for ( i = 0; i < col; i++ ) {
6478: mpz_mod(svect[i],svect[i],BDY(current_mod_lf));
6479: }
6480: return maxrs;
6481: }
6482:
6483: int nd_gauss_elim_lf(mpz_t **mat0,int *sugar,int row,int col,int *colstat)
6484: {
6485: int i,j,k,l,rank,s;
6486: mpz_t a,a1,inv;
6487: mpz_t *t,*pivot,*pk;
6488: mpz_t **mat;
6489: struct oEGT eg0,eg1,eg_forward,eg_mod,eg_back;
1.234 noro 6490: int size,size1;
1.232 noro 6491:
6492: mpz_init(inv);
6493: mpz_init(a);
6494: mat = (mpz_t **)mat0;
1.234 noro 6495: size = 0;
1.232 noro 6496: for ( rank = 0, j = 0; j < col; j++ ) {
6497: for ( i = rank; i < row; i++ ) {
6498: mpz_mod(mat[i][j],mat[i][j],BDY(current_mod_lf));
6499: }
6500: for ( i = rank; i < row; i++ )
6501: if ( mpz_sgn(mat[i][j]) )
6502: break;
6503: if ( i == row ) {
6504: colstat[j] = 0;
6505: continue;
6506: } else
6507: colstat[j] = 1;
6508: if ( i != rank ) {
6509: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
6510: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
6511: }
6512: pivot = mat[rank];
6513: s = sugar[rank];
6514: mpz_invert(inv,pivot[j],BDY(current_mod_lf));
6515: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
6516: if ( mpz_sgn(*pk) ) {
6517: mpz_mul(a,*pk,inv); mpz_mod(*pk,a,BDY(current_mod_lf));
6518: }
6519: for ( i = rank+1; i < row; i++ ) {
6520: t = mat[i];
6521: if ( mpz_sgn(t[j]) ) {
6522: sugar[i] = MAX(sugar[i],s);
6523: mpz_neg(a,t[j]);
6524: red_by_vect_lf(t+j,pivot+j,a,col-j);
6525: }
6526: }
6527: rank++;
6528: }
6529: for ( j = col-1, l = rank-1; j >= 0; j-- )
6530: if ( colstat[j] ) {
6531: pivot = mat[l];
6532: s = sugar[l];
6533: for ( k = j; k < col; k++ )
6534: mpz_mod(pivot[k],pivot[k],BDY(current_mod_lf));
6535: for ( i = 0; i < l; i++ ) {
6536: t = mat[i];
6537: if ( mpz_sgn(t[j]) ) {
6538: sugar[i] = MAX(sugar[i],s);
6539: mpz_neg(a,t[j]);
6540: red_by_vect_lf(t+j,pivot+j,a,col-j);
6541: }
6542: }
6543: l--;
6544: }
6545: for ( j = 0, l = 0; l < rank; j++ )
6546: if ( colstat[j] ) {
6547: t = mat[l];
6548: for ( k = j; k < col; k++ ) {
6549: mpz_mod(t[k],t[k],BDY(current_mod_lf));
6550: }
6551: l++;
6552: }
6553: return rank;
6554: }
6555:
6556:
1.65 noro 6557: NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhead,UINT *s0vect)
6558: {
1.157 noro 6559: int j,k,len;
6560: UINT *p;
6561: UINT c;
6562: NDV r;
6563: NMV mr0,mr;
6564:
6565: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
6566: if ( !len ) return 0;
6567: else {
1.200 noro 6568: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
1.103 noro 6569: #if 0
1.157 noro 6570: ndv_alloc += nmv_adv*len;
1.103 noro 6571: #endif
1.157 noro 6572: mr = mr0;
6573: p = s0vect;
6574: for ( j = k = 0; j < col; j++, p += nd_wpd )
6575: if ( !rhead[j] ) {
6576: if ( c = vect[k++] ) {
6577: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
6578: }
6579: }
6580: MKNDV(nd_nvar,mr0,len,r);
6581: return r;
6582: }
1.65 noro 6583: }
6584:
1.242 noro 6585: #if defined(__GNUC__) && SIZEOF_LONG==8
1.240 noro 6586: NDV vect64_to_ndv(U64 *vect,int spcol,int col,int *rhead,UINT *s0vect)
1.239 noro 6587: {
6588: int j,k,len;
6589: UINT *p;
6590: UINT c;
6591: NDV r;
6592: NMV mr0,mr;
6593:
6594: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
6595: if ( !len ) return 0;
6596: else {
6597: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
6598: #if 0
6599: ndv_alloc += nmv_adv*len;
6600: #endif
6601: mr = mr0;
6602: p = s0vect;
6603: for ( j = k = 0; j < col; j++, p += nd_wpd )
6604: if ( !rhead[j] ) {
6605: if ( c = (UINT)vect[k++] ) {
6606: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
6607: }
6608: }
6609: MKNDV(nd_nvar,mr0,len,r);
6610: return r;
6611: }
6612: }
6613: #endif
6614:
1.220 noro 6615: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect)
6616: {
6617: int j,k,len;
6618: UINT *p;
6619: NDV r;
6620: NMV mr0,mr;
6621:
6622: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) len++;
6623: if ( !len ) return 0;
6624: else {
6625: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
6626: mr = mr0;
6627: p = s0vect;
6628: for ( j = 0; j < col; j++, p += nd_wpd )
1.245 noro 6629: if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) {
1.220 noro 6630: ndl_copy(p,DL(mr)); CM(mr) = 1; NMV_ADV(mr);
6631: }
6632: MKNDV(nd_nvar,mr0,len,r);
6633: return r;
6634: }
6635: }
6636:
1.129 noro 6637: /* for preprocessed vector */
6638:
1.113 noro 6639: NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead,UINT *s0vect)
1.107 noro 6640: {
1.157 noro 6641: int j,k,len;
6642: UINT *p;
6643: Q c;
6644: NDV r;
6645: NMV mr0,mr;
6646:
6647: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
6648: if ( !len ) return 0;
6649: else {
1.200 noro 6650: mr0 = (NMV)MALLOC(nmv_adv*len);
1.107 noro 6651: #if 0
1.157 noro 6652: ndv_alloc += nmv_adv*len;
1.107 noro 6653: #endif
1.157 noro 6654: mr = mr0;
6655: p = s0vect;
6656: for ( j = k = 0; j < col; j++, p += nd_wpd )
6657: if ( !rhead[j] ) {
6658: if ( c = vect[k++] ) {
6659: if ( DN(c) )
6660: error("afo");
6661: ndl_copy(p,DL(mr)); CQ(mr) = c; NMV_ADV(mr);
6662: }
6663: }
6664: MKNDV(nd_nvar,mr0,len,r);
6665: return r;
6666: }
1.107 noro 6667: }
6668:
1.215 noro 6669: NDV vect_to_ndv_gz(GZ *vect,int spcol,int col,int *rhead,UINT *s0vect)
6670: {
6671: int j,k,len;
6672: UINT *p;
1.232 noro 6673: GZ c;
1.215 noro 6674: NDV r;
6675: NMV mr0,mr;
6676:
6677: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
6678: if ( !len ) return 0;
6679: else {
6680: mr0 = (NMV)MALLOC(nmv_adv*len);
6681: #if 0
6682: ndv_alloc += nmv_adv*len;
6683: #endif
6684: mr = mr0;
6685: p = s0vect;
6686: for ( j = k = 0; j < col; j++, p += nd_wpd )
6687: if ( !rhead[j] ) {
6688: if ( c = vect[k++] ) {
6689: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
6690: }
6691: }
6692: MKNDV(nd_nvar,mr0,len,r);
6693: return r;
6694: }
6695: }
6696:
1.232 noro 6697: NDV vect_to_ndv_lf(mpz_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
6698: {
6699: int j,k,len;
6700: UINT *p;
6701: mpz_t c;
6702: NDV r;
6703: NMV mr0,mr;
6704:
6705: for ( j = 0, len = 0; j < spcol; j++ ) if ( mpz_sgn(vect[j]) ) len++;
6706: if ( !len ) return 0;
6707: else {
6708: mr0 = (NMV)MALLOC(nmv_adv*len);
6709: #if 0
6710: ndv_alloc += nmv_adv*len;
6711: #endif
6712: mr = mr0;
6713: p = s0vect;
6714: for ( j = k = 0; j < col; j++, p += nd_wpd )
6715: if ( !rhead[j] ) {
6716: c[0] = vect[k++][0];
6717: if ( mpz_sgn(c) ) {
6718: ndl_copy(p,DL(mr)); MPZTOGZ(c,CZ(mr)); NMV_ADV(mr);
6719: }
6720: }
6721: MKNDV(nd_nvar,mr0,len,r);
6722: return r;
6723: }
6724: }
6725:
1.129 noro 6726: /* for plain vector */
6727:
6728: NDV plain_vect_to_ndv_q(Q *vect,int col,UINT *s0vect)
6729: {
1.157 noro 6730: int j,k,len;
6731: UINT *p;
6732: Q c;
6733: NDV r;
6734: NMV mr0,mr;
6735:
6736: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
6737: if ( !len ) return 0;
6738: else {
1.200 noro 6739: mr0 = (NMV)MALLOC(nmv_adv*len);
1.129 noro 6740: #if 0
1.157 noro 6741: ndv_alloc += nmv_adv*len;
1.129 noro 6742: #endif
1.157 noro 6743: mr = mr0;
6744: p = s0vect;
6745: for ( j = k = 0; j < col; j++, p += nd_wpd, k++ )
6746: if ( c = vect[k] ) {
6747: if ( DN(c) )
6748: error("afo");
6749: ndl_copy(p,DL(mr)); CQ(mr) = c; NMV_ADV(mr);
6750: }
6751: MKNDV(nd_nvar,mr0,len,r);
6752: return r;
6753: }
1.129 noro 6754: }
6755:
1.133 noro 6756: int nd_sp_f4(int m,int trace,ND_pairs l,PGeoBucket bucket)
1.65 noro 6757: {
1.157 noro 6758: ND_pairs t;
6759: NODE sp0,sp;
6760: int stat;
6761: ND spol;
6762:
6763: for ( t = l; t; t = NEXT(t) ) {
6764: stat = nd_sp(m,trace,t,&spol);
6765: if ( !stat ) return 0;
6766: if ( spol ) {
6767: add_pbucket_symbolic(bucket,spol);
6768: }
6769: }
6770: return 1;
1.65 noro 6771: }
6772:
1.133 noro 6773: int nd_symbolic_preproc(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
1.65 noro 6774: {
1.157 noro 6775: NODE rp0,rp;
6776: NM mul,head,s0,s;
6777: int index,col,i,sugar;
6778: RHist h;
6779: UINT *s0v,*p;
6780: NM_ind_pair pair;
6781: ND red;
6782: NDV *ps;
1.235 noro 6783: static int afo;
1.157 noro 6784:
6785: s0 = 0; rp0 = 0; col = 0;
1.245 noro 6786: if ( nd_demand )
6787: ps = trace?nd_ps_trace_sym:nd_ps_sym;
6788: else
6789: ps = trace?nd_ps_trace:nd_ps;
1.157 noro 6790: while ( 1 ) {
6791: head = remove_head_pbucket_symbolic(bucket);
6792: if ( !head ) break;
6793: if ( !s0 ) s0 = head;
6794: else NEXT(s) = head;
6795: s = head;
6796: index = ndl_find_reducer(DL(head));
6797: if ( index >= 0 ) {
6798: h = nd_psh[index];
6799: NEWNM(mul);
6800: ndl_sub(DL(head),DL(h),DL(mul));
1.235 noro 6801: if ( ndl_check_bound2(index,DL(mul)) )
6802: return 0;
1.157 noro 6803: sugar = TD(DL(mul))+SG(ps[index]);
6804: MKNM_ind_pair(pair,mul,index,sugar);
6805: red = ndv_mul_nm_symbolic(mul,ps[index]);
6806: add_pbucket_symbolic(bucket,nd_remove_head(red));
6807: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
6808: }
6809: col++;
6810: }
6811: if ( rp0 ) NEXT(rp) = 0;
6812: NEXT(s) = 0;
6813: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
6814: for ( i = 0, p = s0v, s = s0; i < col;
6815: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
6816: *s0vect = s0v;
6817: *r = rp0;
6818: return col;
1.65 noro 6819: }
6820:
1.244 noro 6821: void print_ndp(ND_pairs l)
6822: {
6823: ND_pairs t;
6824:
6825: for ( t = l; t; t = NEXT(t) )
6826: printf("[%d,%d] ",t->i1,t->i2);
6827: printf("\n");
6828: }
6829:
1.234 noro 6830: NODE nd_f4(int m,int checkonly,int **indp)
1.69 noro 6831: {
1.234 noro 6832: int i,nh,stat,index,f4red;
1.208 noro 6833: NODE r,g,tn0,tn,node;
1.244 noro 6834: ND_pairs d,l,t,ll0,ll,lh;
1.245 noro 6835: LIST l0,l1;
1.157 noro 6836: ND spol,red;
6837: NDV nf,redv;
6838: NM s0,s;
1.231 noro 6839: NODE rp0,srp0,nflist,nzlist,nzlist_t;
1.208 noro 6840: int nsp,nred,col,rank,len,k,j,a,i1s,i2s;
1.157 noro 6841: UINT c;
6842: UINT **spmat;
6843: UINT *s0vect,*svect,*p,*v;
6844: int *colstat;
6845: IndArray *imat;
6846: int *rhead;
6847: int spcol,sprow;
1.244 noro 6848: int sugar,sugarh;
1.157 noro 6849: PGeoBucket bucket;
6850: struct oEGT eg0,eg1,eg_f4;
1.208 noro 6851: Q i1,i2,sugarq;
1.103 noro 6852: #if 0
1.157 noro 6853: ndv_alloc = 0;
1.103 noro 6854: #endif
1.157 noro 6855: g = 0; d = 0;
6856: for ( i = 0; i < nd_psn; i++ ) {
1.244 noro 6857: d = update_pairs(d,g,i,0);
1.157 noro 6858: g = update_base(g,i);
6859: }
1.245 noro 6860: nzlist = 0;
1.231 noro 6861: nzlist_t = nd_nzlist;
1.241 noro 6862: f4red = 1;
6863: nd_last_nonzero = 0;
1.244 noro 6864: while ( d ) {
1.157 noro 6865: get_eg(&eg0);
1.244 noro 6866: l = nd_minsugarp(d,&d);
6867: sugar = nd_sugarweight?l->sugar2:SG(l);
6868: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
6869: if ( nzlist_t ) {
1.231 noro 6870: node = BDY((LIST)BDY(nzlist_t));
1.244 noro 6871: sugarh = QTOS((Q)ARG0(node));
1.231 noro 6872: tn = BDY((LIST)ARG1(node));
6873: if ( !tn ) {
6874: nzlist_t = NEXT(nzlist_t);
6875: continue;
6876: }
6877: /* tn = [[i1,i2],...] */
1.244 noro 6878: lh = nd_ipairtospair(tn);
1.208 noro 6879: }
1.157 noro 6880: bucket = create_pbucket();
6881: stat = nd_sp_f4(m,0,l,bucket);
6882: if ( !stat ) {
1.244 noro 6883: for ( t = l; NEXT(t); t = NEXT(t) );
6884: NEXT(t) = d; d = l;
6885: d = nd_reconstruct(0,d);
1.157 noro 6886: continue;
6887: }
6888: if ( bucket->m < 0 ) continue;
6889: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
6890: if ( !col ) {
6891: for ( t = l; NEXT(t); t = NEXT(t) );
6892: NEXT(t) = d; d = l;
6893: d = nd_reconstruct(0,d);
6894: continue;
6895: }
6896: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
6897: if ( DP_Print )
1.241 noro 6898: fprintf(asir_out,"sugar=%d,symb=%.3fsec,",
1.157 noro 6899: sugar,eg_f4.exectime+eg_f4.gctime);
1.244 noro 6900: nflist = nd_f4_red(m,nd_nzlist?lh:l,0,s0vect,col,rp0,nd_gentrace?&ll:0);
1.234 noro 6901: if ( checkonly && nflist ) return 0;
1.157 noro 6902: /* adding new bases */
1.241 noro 6903: if ( nflist ) nd_last_nonzero = f4red;
1.157 noro 6904: for ( r = nflist; r; r = NEXT(r) ) {
6905: nf = (NDV)BDY(r);
6906: ndv_removecont(m,nf);
6907: if ( !m && nd_nalg ) {
6908: ND nf1;
6909:
6910: nf1 = ndvtond(m,nf);
6911: nd_monic(0,&nf1);
6912: nd_removecont(m,nf1);
6913: nf = ndtondv(m,nf1);
6914: }
1.215 noro 6915: nh = ndv_newps(m,nf,0,1);
1.244 noro 6916: d = update_pairs(d,g,nh,0);
1.157 noro 6917: g = update_base(g,nh);
6918: }
1.234 noro 6919: if ( DP_Print ) {
1.241 noro 6920: fprintf(asir_out,"f4red=%d,gblen=%d\n",f4red,length(g)); fflush(asir_out);
1.234 noro 6921: }
1.208 noro 6922: if ( nd_gentrace ) {
1.245 noro 6923: for ( t = ll, tn0 = 0; t; t = NEXT(t) ) {
6924: NEXTNODE(tn0,tn);
1.208 noro 6925: STOQ(t->i1,i1); STOQ(t->i2,i2);
6926: node = mknode(2,i1,i2); MKLIST(l0,node);
1.245 noro 6927: BDY(tn) = l0;
6928: }
6929: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
1.208 noro 6930: STOQ(sugar,sugarq); node = mknode(2,sugarq,l0); MKLIST(l1,node);
6931: MKNODE(node,l1,nzlist); nzlist = node;
6932: }
1.231 noro 6933: if ( nd_nzlist ) nzlist_t = NEXT(nzlist_t);
1.234 noro 6934: f4red++;
1.241 noro 6935: if ( nd_f4red && f4red > nd_f4red ) break;
1.234 noro 6936: if ( nd_rank0 && !nflist ) break;
1.208 noro 6937: }
6938: if ( nd_gentrace ) {
1.245 noro 6939: MKLIST(l0,reverse_node(nzlist));
1.208 noro 6940: MKNODE(nd_alltracelist,l0,0);
1.157 noro 6941: }
1.103 noro 6942: #if 0
1.157 noro 6943: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.103 noro 6944: #endif
1.245 noro 6945: conv_ilist(nd_demand,0,g,indp);
1.157 noro 6946: return g;
1.69 noro 6947: }
1.74 noro 6948:
1.167 noro 6949: NODE nd_f4_trace(int m,int **indp)
1.133 noro 6950: {
1.157 noro 6951: int i,nh,stat,index;
6952: NODE r,g;
6953: ND_pairs d,l,l0,t;
6954: ND spol,red;
6955: NDV nf,redv,nfqv,nfv;
6956: NM s0,s;
6957: NODE rp0,srp0,nflist;
6958: int nsp,nred,col,rank,len,k,j,a;
6959: UINT c;
6960: UINT **spmat;
6961: UINT *s0vect,*svect,*p,*v;
6962: int *colstat;
6963: IndArray *imat;
6964: int *rhead;
6965: int spcol,sprow;
6966: int sugar;
6967: PGeoBucket bucket;
6968: struct oEGT eg0,eg1,eg_f4;
6969:
6970: g = 0; d = 0;
6971: for ( i = 0; i < nd_psn; i++ ) {
1.168 noro 6972: d = update_pairs(d,g,i,0);
1.157 noro 6973: g = update_base(g,i);
6974: }
6975: while ( d ) {
6976: get_eg(&eg0);
6977: l = nd_minsugarp(d,&d);
6978: sugar = SG(l);
1.228 noro 6979: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
1.157 noro 6980: bucket = create_pbucket();
6981: stat = nd_sp_f4(m,0,l,bucket);
6982: if ( !stat ) {
6983: for ( t = l; NEXT(t); t = NEXT(t) );
6984: NEXT(t) = d; d = l;
6985: d = nd_reconstruct(1,d);
6986: continue;
6987: }
6988: if ( bucket->m < 0 ) continue;
6989: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
6990: if ( !col ) {
6991: for ( t = l; NEXT(t); t = NEXT(t) );
6992: NEXT(t) = d; d = l;
6993: d = nd_reconstruct(1,d);
6994: continue;
6995: }
6996: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
6997: if ( DP_Print )
1.241 noro 6998: fprintf(asir_out,"sugar=%d,symb=%.3fsec,",
1.157 noro 6999: sugar,eg_f4.exectime+eg_f4.gctime);
7000: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
7001: if ( !l0 ) continue;
7002: l = l0;
7003:
7004: /* over Q */
7005: bucket = create_pbucket();
7006: stat = nd_sp_f4(0,1,l,bucket);
7007: if ( !stat ) {
7008: for ( t = l; NEXT(t); t = NEXT(t) );
7009: NEXT(t) = d; d = l;
7010: d = nd_reconstruct(1,d);
7011: continue;
7012: }
7013: if ( bucket->m < 0 ) continue;
7014: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
7015: if ( !col ) {
7016: for ( t = l; NEXT(t); t = NEXT(t) );
7017: NEXT(t) = d; d = l;
7018: d = nd_reconstruct(1,d);
7019: continue;
7020: }
7021: nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0);
7022: /* adding new bases */
7023: for ( r = nflist; r; r = NEXT(r) ) {
7024: nfqv = (NDV)BDY(r);
7025: ndv_removecont(0,nfqv);
7026: if ( !rem(NM(HCQ(nfqv)),m) ) return 0;
7027: if ( nd_nalg ) {
7028: ND nf1;
7029:
7030: nf1 = ndvtond(m,nfqv);
7031: nd_monic(0,&nf1);
7032: nd_removecont(0,nf1);
7033: nfqv = ndtondv(0,nf1); nd_free(nf1);
7034: }
7035: nfv = ndv_dup(0,nfqv);
7036: ndv_mod(m,nfv);
7037: ndv_removecont(m,nfv);
1.215 noro 7038: nh = ndv_newps(0,nfv,nfqv,1);
1.168 noro 7039: d = update_pairs(d,g,nh,0);
1.157 noro 7040: g = update_base(g,nh);
7041: }
7042: }
1.133 noro 7043: #if 0
1.157 noro 7044: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.133 noro 7045: #endif
1.245 noro 7046: conv_ilist(nd_demand,1,g,indp);
1.157 noro 7047: return g;
1.133 noro 7048: }
7049:
1.220 noro 7050: int rref(matrix mat,int *sugar)
7051: {
7052: int row,col,i,j,k,l,s,wcol,wj;
7053: unsigned long bj;
7054: unsigned long **a;
7055: unsigned long *ai,*ak,*as,*t;
7056: int *pivot;
7057:
7058: row = mat->row;
7059: col = mat->col;
7060: a = mat->a;
7061: wcol = (col+BLEN-1)/BLEN;
7062: pivot = (int *)MALLOC_ATOMIC(row*sizeof(int));
7063: i = 0;
7064: for ( j = 0; j < col; j++ ) {
1.245 noro 7065: wj = j/BLEN; bj = 1L<<(j%BLEN);
1.220 noro 7066: for ( k = i; k < row; k++ )
1.245 noro 7067: if ( a[k][wj] & bj ) break;
1.220 noro 7068: if ( k == row ) continue;
1.245 noro 7069: pivot[i] = j;
1.220 noro 7070: if ( k != i ) {
1.245 noro 7071: t = a[i]; a[i] = a[k]; a[k] = t;
7072: s = sugar[i]; sugar[i] = sugar[k]; sugar[k] = s;
7073: }
7074: ai = a[i];
1.220 noro 7075: for ( k = i+1; k < row; k++ ) {
1.245 noro 7076: ak = a[k];
7077: if ( ak[wj] & bj ) {
7078: for ( l = wj; l < wcol; l++ )
7079: ak[l] ^= ai[l];
7080: sugar[k] = MAX(sugar[k],sugar[i]);
7081: }
7082: }
7083: i++;
1.220 noro 7084: }
7085: for ( k = i-1; k >= 0; k-- ) {
7086: j = pivot[k]; wj = j/BLEN; bj = 1L<<(j%BLEN);
1.245 noro 7087: ak = a[k];
1.220 noro 7088: for ( s = 0; s < k; s++ ) {
1.245 noro 7089: as = a[s];
1.220 noro 7090: if ( as[wj] & bj ) {
7091: for ( l = wj; l < wcol; l++ )
1.245 noro 7092: as[l] ^= ak[l];
7093: sugar[s] = MAX(sugar[s],sugar[k]);
7094: }
7095: }
1.220 noro 7096: }
7097: return i;
7098: }
7099:
7100: void print_matrix(matrix mat)
7101: {
7102: int row,col,i,j;
7103: unsigned long *ai;
7104:
7105: row = mat->row;
7106: col = mat->col;
7107: printf("%d x %d\n",row,col);
7108: for ( i = 0; i < row; i++ ) {
1.245 noro 7109: ai = mat->a[i];
1.220 noro 7110: for ( j = 0; j < col; j++ ) {
1.245 noro 7111: if ( ai[j/BLEN] & (1L<<(j%BLEN)) ) putchar('1');
7112: else putchar('0');
7113: }
7114: putchar('\n');
1.220 noro 7115: }
7116: }
7117:
7118: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect);
7119:
7120: void red_by_vect_2(matrix mat,int *sugar,unsigned long *v,int rhead,int rsugar)
7121: {
7122: int row,col,wcol,wj,i,j;
7123: unsigned long bj;
7124: unsigned long *ai;
7125: unsigned long **a;
7126: int len;
7127: int *pos;
7128:
7129: row = mat->row;
7130: col = mat->col;
7131: wcol = (col+BLEN-1)/BLEN;
1.235 noro 7132: pos = (int *)MALLOC(wcol*sizeof(int));
1.220 noro 7133: bzero(pos,wcol*sizeof(int));
7134: for ( i = j = 0; i < wcol; i++ )
7135: if ( v[i] ) pos[j++] = i;;
7136: len = j;
7137: wj = rhead/BLEN;
7138: bj = 1L<<rhead%BLEN;
7139: a = mat->a;
7140: for ( i = 0; i < row; i++ ) {
1.245 noro 7141: ai = a[i];
1.220 noro 7142: if ( ai[wj]&bj ) {
1.245 noro 7143: for ( j = 0; j < len; j++ )
7144: ai[pos[j]] ^= v[pos[j]];
7145: sugar[i] = MAX(sugar[i],rsugar);
7146: }
1.220 noro 7147: }
7148: }
7149:
7150: NODE nd_f4_red_2(ND_pairs sp0,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
7151: {
7152: int nsp,nred,i,i0,k,rank,row;
7153: NODE r0,rp;
7154: ND_pairs sp;
1.245 noro 7155: ND spol;
7156: NM_ind_pair rt;
1.220 noro 7157: int *s0hash;
1.245 noro 7158: UINT *s;
7159: int *pivot,*sugar,*head;
7160: matrix mat;
1.220 noro 7161: NM m;
7162: NODE r;
1.245 noro 7163: struct oEGT eg0,eg1,eg2,eg_elim1,eg_elim2;
7164: int rhead,rsugar,size;
1.220 noro 7165: unsigned long *v;
7166:
7167: get_eg(&eg0);
7168: init_eg(&eg_search);
7169: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
7170: nred = length(rp0);
7171: mat = alloc_matrix(nsp,col);
1.235 noro 7172: s0hash = (int *)MALLOC(col*sizeof(int));
1.220 noro 7173: for ( i = 0, s = s0vect; i < col; i++, s += nd_wpd )
7174: s0hash[i] = ndl_hash_value(s);
7175:
1.245 noro 7176: sugar = (int *)MALLOC(nsp*sizeof(int));
7177: for ( i = 0, sp = sp0; sp; sp = NEXT(sp) ) {
7178: nd_sp(2,0,sp,&spol);
7179: if ( spol ) {
7180: mat->a[i] = nd_to_vect_2(s0vect,col,s0hash,spol);
7181: sugar[i] = SG(spol);
7182: i++;
7183: }
7184: }
7185: mat->row = i;
1.227 noro 7186: if ( DP_Print ) {
7187: fprintf(asir_out,"%dx%d,",mat->row,mat->col); fflush(asir_out);
7188: }
1.245 noro 7189: size = ((col+BLEN-1)/BLEN)*sizeof(unsigned long);
7190: v = CALLOC((col+BLEN-1)/BLEN,sizeof(unsigned long));
1.220 noro 7191: for ( rp = rp0, i = 0; rp; rp = NEXT(rp), i++ ) {
1.245 noro 7192: rt = (NM_ind_pair)BDY(rp);
7193: bzero(v,size);
1.220 noro 7194: rhead = nd_nm_to_vect_2(s0vect,col,s0hash,nd_ps[rt->index],rt->mul,v);
1.245 noro 7195: rsugar = SG(nd_ps[rt->index])+TD(DL(rt->mul));
7196: red_by_vect_2(mat,sugar,v,rhead,rsugar);
7197: }
1.220 noro 7198:
7199: get_eg(&eg1);
7200: init_eg(&eg_elim1); add_eg(&eg_elim1,&eg0,&eg1);
1.245 noro 7201: rank = rref(mat,sugar);
1.220 noro 7202:
7203: for ( i = 0, r0 = 0; i < rank; i++ ) {
7204: NEXTNODE(r0,r);
1.245 noro 7205: BDY(r) = (pointer)vect_to_ndv_2(mat->a[i],col,s0vect);
1.220 noro 7206: SG((NDV)BDY(r)) = sugar[i];
7207: }
7208: if ( r0 ) NEXT(r) = 0;
7209: get_eg(&eg2);
7210: init_eg(&eg_elim2); add_eg(&eg_elim2,&eg1,&eg2);
7211: if ( DP_Print ) {
1.241 noro 7212: fprintf(asir_out,"elim1=%.3fsec,elim2=%.3fsec,",
1.245 noro 7213: eg_elim1.exectime+eg_elim1.gctime,eg_elim2.exectime+eg_elim2.gctime);
1.220 noro 7214: fflush(asir_out);
1.245 noro 7215: }
1.220 noro 7216: return r0;
7217: }
7218:
7219:
1.133 noro 7220: NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
1.63 noro 7221: {
1.157 noro 7222: IndArray *imat;
7223: int nsp,nred,i;
7224: int *rhead;
7225: NODE r0,rp;
7226: ND_pairs sp;
7227: NM_ind_pair *rvect;
1.210 noro 7228: UINT *s;
7229: int *s0hash;
7230:
1.220 noro 7231: if ( m == 2 && nd_rref2 )
1.245 noro 7232: return nd_f4_red_2(sp0,s0vect,col,rp0,nz);
1.220 noro 7233:
1.198 noro 7234: init_eg(&eg_search);
1.157 noro 7235: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
7236: nred = length(rp0);
1.235 noro 7237: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
7238: rhead = (int *)MALLOC(col*sizeof(int));
1.157 noro 7239: for ( i = 0; i < col; i++ ) rhead[i] = 0;
7240:
7241: /* construction of index arrays */
1.227 noro 7242: if ( DP_Print ) {
1.245 noro 7243: fprintf(asir_out,"%dx%d,",nsp+nred,col);
1.227 noro 7244: }
1.235 noro 7245: rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
7246: s0hash = (int *)MALLOC(col*sizeof(int));
1.210 noro 7247: for ( i = 0, s = s0vect; i < col; i++, s += nd_wpd )
7248: s0hash[i] = ndl_hash_value(s);
1.157 noro 7249: for ( rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
7250: rvect[i] = (NM_ind_pair)BDY(rp);
1.235 noro 7251: imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,s0hash,rvect[i]);
1.157 noro 7252: rhead[imat[i]->head] = 1;
7253: }
1.240 noro 7254: if ( m > 0 )
1.242 noro 7255: #if defined(__GNUC__) && SIZEOF_LONG==8
1.240 noro 7256: r0 = nd_f4_red_mod64_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
7257: #else
7258: r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
1.239 noro 7259: #endif
7260: else if ( m == -1 )
7261: r0 = nd_f4_red_sf_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
1.232 noro 7262: else if ( m == -2 )
1.234 noro 7263: r0 = nd_f4_red_lf_main(m,sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
1.157 noro 7264: else
1.237 noro 7265: #if defined(VISUAL)
7266: r0 = nd_f4_red_q_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
7267: #else
1.215 noro 7268: r0 = nd_f4_red_gz_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
1.237 noro 7269: #endif
1.241 noro 7270: #if 0
1.227 noro 7271: if ( DP_Print ) print_eg("search",&eg_search);
1.241 noro 7272: #endif
1.157 noro 7273: return r0;
1.106 noro 7274: }
1.74 noro 7275:
1.239 noro 7276: /* for Fp, 2<=p<2^16 */
7277:
1.106 noro 7278: NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
1.133 noro 7279: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
1.106 noro 7280: {
1.157 noro 7281: int spcol,sprow,a;
7282: int i,j,k,l,rank;
7283: NODE r0,r;
7284: ND_pairs sp;
7285: ND spol;
7286: int **spmat;
7287: UINT *svect,*v;
7288: int *colstat;
7289: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
7290: int maxrs;
7291: int *spsugar;
7292: ND_pairs *spactive;
7293:
7294: spcol = col-nred;
7295: get_eg(&eg0);
7296: /* elimination (1st step) */
1.235 noro 7297: spmat = (int **)MALLOC(nsp*sizeof(UINT *));
7298: svect = (UINT *)MALLOC(col*sizeof(UINT));
7299: spsugar = (int *)MALLOC(nsp*sizeof(int));
7300: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
1.157 noro 7301: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
7302: nd_sp(m,0,sp,&spol);
7303: if ( !spol ) continue;
7304: nd_to_vect(m,s0vect,col,spol,svect);
7305: if ( m == -1 )
7306: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
7307: else
7308: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred);
7309: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
7310: if ( i < col ) {
7311: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
7312: for ( j = k = 0; j < col; j++ )
7313: if ( !rhead[j] ) v[k++] = svect[j];
7314: spsugar[sprow] = MAX(maxrs,SG(spol));
7315: if ( nz )
7316: spactive[sprow] = sp;
7317: sprow++;
7318: }
7319: nd_free(spol);
7320: }
7321: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
7322: if ( DP_Print ) {
1.241 noro 7323: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
1.157 noro 7324: fflush(asir_out);
7325: }
7326: /* free index arrays */
1.200 noro 7327: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
1.157 noro 7328:
7329: /* elimination (2nd step) */
1.235 noro 7330: colstat = (int *)MALLOC(spcol*sizeof(int));
1.157 noro 7331: if ( m == -1 )
7332: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
7333: else
7334: rank = nd_gauss_elim_mod(spmat,spsugar,spactive,sprow,spcol,m,colstat);
7335: r0 = 0;
7336: for ( i = 0; i < rank; i++ ) {
7337: NEXTNODE(r0,r); BDY(r) =
7338: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
7339: SG((NDV)BDY(r)) = spsugar[i];
1.200 noro 7340: GCFREE(spmat[i]);
1.157 noro 7341: }
7342: if ( r0 ) NEXT(r) = 0;
7343:
1.200 noro 7344: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
1.157 noro 7345: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
7346: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
7347: if ( DP_Print ) {
1.241 noro 7348: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime);
7349: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
1.157 noro 7350: nsp,nred,sprow,spcol,rank);
1.241 noro 7351: fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime);
1.157 noro 7352: }
7353: if ( nz ) {
7354: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
7355: if ( rank > 0 ) {
7356: NEXT(spactive[rank-1]) = 0;
7357: *nz = spactive[0];
7358: } else
7359: *nz = 0;
7360: }
7361: return r0;
1.74 noro 7362: }
7363:
1.242 noro 7364: #if defined(__GNUC__) && SIZEOF_LONG==8
1.239 noro 7365: /* for Fp, 2^15=<p<2^29 */
7366:
1.240 noro 7367: NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
1.239 noro 7368: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
7369: {
7370: int spcol,sprow,a;
7371: int i,j,k,l,rank;
7372: NODE r0,r;
7373: ND_pairs sp;
7374: ND spol;
1.240 noro 7375: U64 **spmat;
7376: U64 *svect,*cvect;
7377: U64 *v;
1.239 noro 7378: int *colstat;
7379: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
7380: int maxrs;
7381: int *spsugar;
7382: ND_pairs *spactive;
7383:
7384: spcol = col-nred;
7385: get_eg(&eg0);
7386: /* elimination (1st step) */
1.240 noro 7387: spmat = (U64 **)MALLOC(nsp*sizeof(U64 *));
7388: svect = (U64 *)MALLOC(col*sizeof(U64));
7389: cvect = (U64 *)MALLOC(col*sizeof(U64));
1.239 noro 7390: spsugar = (int *)MALLOC(nsp*sizeof(int));
7391: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
7392: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
7393: nd_sp(m,0,sp,&spol);
7394: if ( !spol ) continue;
1.240 noro 7395: nd_to_vect64(m,s0vect,col,spol,svect);
7396: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred);
1.239 noro 7397: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
7398: if ( i < col ) {
1.240 noro 7399: spmat[sprow] = v = (U64 *)MALLOC_ATOMIC(spcol*sizeof(U64));
1.239 noro 7400: for ( j = k = 0; j < col; j++ )
7401: if ( !rhead[j] ) v[k++] = (UINT)svect[j];
7402: spsugar[sprow] = MAX(maxrs,SG(spol));
7403: if ( nz )
7404: spactive[sprow] = sp;
7405: sprow++;
7406: }
7407: nd_free(spol);
7408: }
7409: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
7410: if ( DP_Print ) {
1.241 noro 7411: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
1.239 noro 7412: fflush(asir_out);
7413: }
7414: /* free index arrays */
7415: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
7416:
7417: /* elimination (2nd step) */
7418: colstat = (int *)MALLOC(spcol*sizeof(int));
1.240 noro 7419: rank = nd_gauss_elim_mod64(spmat,spsugar,spactive,sprow,spcol,m,colstat);
1.239 noro 7420: r0 = 0;
7421: for ( i = 0; i < rank; i++ ) {
7422: NEXTNODE(r0,r); BDY(r) =
1.240 noro 7423: (pointer)vect64_to_ndv(spmat[i],spcol,col,rhead,s0vect);
1.239 noro 7424: SG((NDV)BDY(r)) = spsugar[i];
7425: GCFREE(spmat[i]);
7426: }
7427: if ( r0 ) NEXT(r) = 0;
7428:
7429: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
7430: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
7431: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
7432: if ( DP_Print ) {
1.241 noro 7433: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime);
7434: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
1.239 noro 7435: nsp,nred,sprow,spcol,rank);
1.241 noro 7436: fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime);
1.239 noro 7437: }
7438: if ( nz ) {
7439: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
7440: if ( rank > 0 ) {
7441: NEXT(spactive[rank-1]) = 0;
7442: *nz = spactive[0];
7443: } else
7444: *nz = 0;
7445: }
7446: return r0;
7447: }
7448: #endif
7449:
7450: /* for small finite fields */
7451:
7452: NODE nd_f4_red_sf_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
7453: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
7454: {
7455: int spcol,sprow,a;
7456: int i,j,k,l,rank;
7457: NODE r0,r;
7458: ND_pairs sp;
7459: ND spol;
7460: int **spmat;
7461: UINT *svect,*v;
7462: int *colstat;
7463: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
7464: int maxrs;
7465: int *spsugar;
7466: ND_pairs *spactive;
7467:
7468: spcol = col-nred;
7469: get_eg(&eg0);
7470: /* elimination (1st step) */
7471: spmat = (int **)MALLOC(nsp*sizeof(UINT *));
7472: svect = (UINT *)MALLOC(col*sizeof(UINT));
7473: spsugar = (int *)MALLOC(nsp*sizeof(int));
7474: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
7475: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
7476: nd_sp(m,0,sp,&spol);
7477: if ( !spol ) continue;
7478: nd_to_vect(m,s0vect,col,spol,svect);
7479: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
7480: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
7481: if ( i < col ) {
7482: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
7483: for ( j = k = 0; j < col; j++ )
7484: if ( !rhead[j] ) v[k++] = svect[j];
7485: spsugar[sprow] = MAX(maxrs,SG(spol));
7486: if ( nz )
7487: spactive[sprow] = sp;
7488: sprow++;
7489: }
7490: nd_free(spol);
7491: }
7492: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
7493: if ( DP_Print ) {
1.241 noro 7494: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
1.239 noro 7495: fflush(asir_out);
7496: }
7497: /* free index arrays */
7498: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
7499:
7500: /* elimination (2nd step) */
7501: colstat = (int *)MALLOC(spcol*sizeof(int));
7502: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
7503: r0 = 0;
7504: for ( i = 0; i < rank; i++ ) {
7505: NEXTNODE(r0,r); BDY(r) =
7506: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
7507: SG((NDV)BDY(r)) = spsugar[i];
7508: GCFREE(spmat[i]);
7509: }
7510: if ( r0 ) NEXT(r) = 0;
7511:
7512: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
7513: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
7514: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
7515: if ( DP_Print ) {
1.241 noro 7516: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime);
7517: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
1.239 noro 7518: nsp,nred,sprow,spcol,rank);
1.241 noro 7519: fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime);
1.239 noro 7520: }
7521: if ( nz ) {
7522: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
7523: if ( rank > 0 ) {
7524: NEXT(spactive[rank-1]) = 0;
7525: *nz = spactive[0];
7526: } else
7527: *nz = 0;
7528: }
7529: return r0;
7530: }
7531:
1.234 noro 7532: NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
1.232 noro 7533: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
7534: {
7535: int spcol,sprow,a;
7536: int i,j,k,l,rank;
7537: NODE r0,r;
7538: ND_pairs sp;
7539: ND spol;
7540: mpz_t **spmat;
7541: mpz_t *svect,*v;
7542: int *colstat;
7543: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
7544: int maxrs;
7545: int *spsugar;
7546: pointer *w;
7547:
7548: spcol = col-nred;
7549: get_eg(&eg0);
7550: /* elimination (1st step) */
1.235 noro 7551: spmat = (mpz_t **)MALLOC(nsp*sizeof(mpz_t *));
7552: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
7553: spsugar = (int *)MALLOC(nsp*sizeof(int));
1.232 noro 7554: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
1.234 noro 7555: nd_sp(m,trace,sp,&spol);
1.232 noro 7556: if ( !spol ) continue;
7557: nd_to_vect_lf(s0vect,col,spol,svect);
1.234 noro 7558: maxrs = ndv_reduce_vect_lf(svect,trace,col,imat,rvect,nred);
1.232 noro 7559: for ( i = 0; i < col; i++ ) if ( mpz_sgn(svect[i]) ) break;
7560: if ( i < col ) {
7561: spmat[sprow] = v = (mpz_t *)MALLOC(spcol*sizeof(mpz_t));
7562: for ( j = k = 0; j < col; j++ )
7563: if ( !rhead[j] ) v[k++][0] = svect[j][0];
7564: spsugar[sprow] = MAX(maxrs,SG(spol));
7565: sprow++;
7566: }
7567: /* nd_free(spol); */
7568: }
7569: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
7570: if ( DP_Print ) {
1.241 noro 7571: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
1.232 noro 7572: fflush(asir_out);
7573: }
7574: /* free index arrays */
7575: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
7576:
7577: /* elimination (2nd step) */
1.235 noro 7578: colstat = (int *)MALLOC(spcol*sizeof(int));
1.232 noro 7579: rank = nd_gauss_elim_lf(spmat,spsugar,sprow,spcol,colstat);
1.235 noro 7580: w = (pointer *)MALLOC(rank*sizeof(pointer));
1.232 noro 7581: for ( i = 0; i < rank; i++ ) {
7582: #if 0
7583: w[rank-i-1] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
7584: SG((NDV)w[rank-i-1]) = spsugar[i];
7585: #else
7586: w[i] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
7587: SG((NDV)w[i]) = spsugar[i];
7588: #endif
7589: /* GCFREE(spmat[i]); */
1.245 noro 7590:
1.232 noro 7591: }
7592: #if 0
7593: qsort(w,rank,sizeof(NDV),
7594: (int (*)(const void *,const void *))ndv_compare);
7595: #endif
7596: r0 = 0;
7597: for ( i = 0; i < rank; i++ ) {
7598: NEXTNODE(r0,r); BDY(r) = w[i];
7599: }
7600: if ( r0 ) NEXT(r) = 0;
7601:
7602: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
7603: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
7604: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
7605: if ( DP_Print ) {
1.241 noro 7606: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime);
7607: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
1.232 noro 7608: nsp,nred,sprow,spcol,rank);
1.241 noro 7609: fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime);
1.232 noro 7610: }
7611: return r0;
7612: }
7613:
1.133 noro 7614: #if 1
7615: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
1.107 noro 7616: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
7617: {
1.157 noro 7618: int spcol,sprow,a;
7619: int i,j,k,l,rank;
7620: NODE r0,r;
7621: ND_pairs sp;
7622: ND spol;
7623: Q **spmat;
7624: Q *svect,*v;
7625: int *colstat;
7626: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
7627: int maxrs;
7628: int *spsugar;
7629: pointer *w;
7630:
7631: spcol = col-nred;
7632: get_eg(&eg0);
7633: /* elimination (1st step) */
1.235 noro 7634: spmat = (Q **)MALLOC(nsp*sizeof(Q *));
7635: svect = (Q *)MALLOC(col*sizeof(Q));
7636: spsugar = (int *)MALLOC(nsp*sizeof(int));
1.157 noro 7637: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
7638: nd_sp(0,trace,sp,&spol);
7639: if ( !spol ) continue;
7640: nd_to_vect_q(s0vect,col,spol,svect);
7641: maxrs = ndv_reduce_vect_q(svect,trace,col,imat,rvect,nred);
7642: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
7643: if ( i < col ) {
7644: spmat[sprow] = v = (Q *)MALLOC(spcol*sizeof(Q));
7645: for ( j = k = 0; j < col; j++ )
7646: if ( !rhead[j] ) v[k++] = svect[j];
7647: spsugar[sprow] = MAX(maxrs,SG(spol));
7648: sprow++;
7649: }
7650: /* nd_free(spol); */
7651: }
7652: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
7653: if ( DP_Print ) {
1.241 noro 7654: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
1.157 noro 7655: fflush(asir_out);
7656: }
7657: /* free index arrays */
1.200 noro 7658: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
1.157 noro 7659:
7660: /* elimination (2nd step) */
1.235 noro 7661: colstat = (int *)MALLOC(spcol*sizeof(int));
1.157 noro 7662: rank = nd_gauss_elim_q(spmat,spsugar,sprow,spcol,colstat);
1.235 noro 7663: w = (pointer *)MALLOC(rank*sizeof(pointer));
1.157 noro 7664: for ( i = 0; i < rank; i++ ) {
1.213 noro 7665: #if 0
1.157 noro 7666: w[rank-i-1] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
7667: SG((NDV)w[rank-i-1]) = spsugar[i];
1.213 noro 7668: #else
7669: w[i] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
7670: SG((NDV)w[i]) = spsugar[i];
7671: #endif
1.200 noro 7672: /* GCFREE(spmat[i]); */
1.157 noro 7673: }
1.138 noro 7674: #if 0
1.157 noro 7675: qsort(w,rank,sizeof(NDV),
7676: (int (*)(const void *,const void *))ndv_compare);
1.137 noro 7677: #endif
1.157 noro 7678: r0 = 0;
7679: for ( i = 0; i < rank; i++ ) {
7680: NEXTNODE(r0,r); BDY(r) = w[i];
7681: }
7682: if ( r0 ) NEXT(r) = 0;
7683:
1.200 noro 7684: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
1.157 noro 7685: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
7686: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
7687: if ( DP_Print ) {
1.241 noro 7688: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime);
7689: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
1.157 noro 7690: nsp,nred,sprow,spcol,rank);
1.241 noro 7691: fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime);
1.157 noro 7692: }
7693: return r0;
1.107 noro 7694: }
1.215 noro 7695:
7696: NODE nd_f4_red_gz_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
7697: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
7698: {
7699: int spcol,sprow,a;
7700: int i,j,k,l,rank;
7701: NODE r0,r;
7702: ND_pairs sp;
7703: ND spol;
7704: GZ **spmat;
7705: GZ *svect,*v;
7706: int *colstat;
7707: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
7708: int maxrs;
7709: int *spsugar;
7710: pointer *w;
7711:
7712: spcol = col-nred;
7713: get_eg(&eg0);
7714: /* elimination (1st step) */
1.235 noro 7715: spmat = (GZ **)MALLOC(nsp*sizeof(GZ *));
7716: svect = (GZ *)MALLOC(col*sizeof(GZ));
7717: spsugar = (int *)MALLOC(nsp*sizeof(int));
1.215 noro 7718: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
7719: nd_sp(0,trace,sp,&spol);
7720: if ( !spol ) continue;
1.245 noro 7721: spol = ndtondgz(spol);
1.215 noro 7722: nd_to_vect_q(s0vect,col,spol,(Q *)svect);
7723: maxrs = ndv_reduce_vect_gz(svect,trace,col,imat,rvect,nred);
7724: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
7725: if ( i < col ) {
7726: spmat[sprow] = v = (GZ *)MALLOC(spcol*sizeof(GZ));
7727: for ( j = k = 0; j < col; j++ )
7728: if ( !rhead[j] ) v[k++] = svect[j];
7729: spsugar[sprow] = MAX(maxrs,SG(spol));
7730: sprow++;
7731: }
7732: /* nd_free(spol); */
7733: }
7734: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
7735: if ( DP_Print ) {
1.241 noro 7736: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime);
1.215 noro 7737: fflush(asir_out);
7738: }
7739: /* free index arrays */
7740: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
7741:
7742: /* elimination (2nd step) */
1.235 noro 7743: colstat = (int *)MALLOC(spcol*sizeof(int));
1.215 noro 7744: rank = nd_gauss_elim_gz(spmat,spsugar,sprow,spcol,colstat);
1.235 noro 7745: w = (pointer *)MALLOC(rank*sizeof(pointer));
1.215 noro 7746: for ( i = 0; i < rank; i++ ) {
7747: #if 0
7748: w[rank-i-1] = (pointer)vect_to_ndv_gz(spmat[i],spcol,col,rhead,s0vect);
1.245 noro 7749: w[rank-i-1] = ndvgztondv(w[rank-i-1]);
1.215 noro 7750: SG((NDV)w[rank-i-1]) = spsugar[i];
7751: #else
1.232 noro 7752: w[i] = (pointer)vect_to_ndv_gz(spmat[i],spcol,col,rhead,s0vect);
1.245 noro 7753: w[i] = ndvgztondv(w[i]);
1.215 noro 7754: SG((NDV)w[i]) = spsugar[i];
7755: #endif
7756: /* GCFREE(spmat[i]); */
1.245 noro 7757:
1.215 noro 7758: }
7759: #if 0
7760: qsort(w,rank,sizeof(NDV),
7761: (int (*)(const void *,const void *))ndv_compare);
7762: #endif
7763: r0 = 0;
7764: for ( i = 0; i < rank; i++ ) {
7765: NEXTNODE(r0,r); BDY(r) = w[i];
7766: }
7767: if ( r0 ) NEXT(r) = 0;
7768:
7769: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
7770: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
7771: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
7772: if ( DP_Print ) {
1.241 noro 7773: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime);
7774: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
1.215 noro 7775: nsp,nred,sprow,spcol,rank);
1.241 noro 7776: fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime);
1.215 noro 7777: }
7778: return r0;
7779: }
1.129 noro 7780: #else
7781: void printm(Q **mat,int row,int col)
7782: {
1.157 noro 7783: int i,j;
7784: printf("[");
7785: for ( i = 0; i < row; i++ ) {
7786: for ( j = 0; j < col; j++ ) {
7787: printexpr(CO,mat[i][j]); printf(" ");
7788: }
7789: printf("]\n");
7790: }
1.129 noro 7791: }
7792:
7793: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vect,int col,
7794: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
7795: {
1.157 noro 7796: int row,a;
7797: int i,j,rank;
7798: NODE r0,r;
7799: ND_pairs sp;
7800: ND spol;
7801: Q **mat;
7802: int *colstat;
7803: int *sugar;
7804:
7805: row = nsp+nred;
7806: /* make the matrix */
1.235 noro 7807: mat = (Q **)MALLOC(row*sizeof(Q *));
7808: sugar = (int *)MALLOC(row*sizeof(int));
1.157 noro 7809: for ( row = a = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
7810: nd_sp(0,0,sp,&spol);
7811: if ( !spol ) continue;
7812: mat[row] = (Q *)MALLOC(col*sizeof(Q));
7813: nd_to_vect_q(s0vect,col,spol,mat[row]);
7814: sugar[row] = SG(spol);
7815: row++;
7816: }
7817: for ( i = 0; i < nred; i++, row++ ) {
7818: mat[row] = nm_ind_pair_to_vect(0,s0vect,col,rvect[i]);
7819: sugar[row] = rvect[i]->sugar;
7820: }
7821: /* elimination */
1.235 noro 7822: colstat = (int *)MALLOC(col*sizeof(int));
1.157 noro 7823: rank = nd_gauss_elim_q(mat,sugar,row,col,colstat);
7824: r0 = 0;
7825: for ( i = 0; i < rank; i++ ) {
7826: for ( j = 0; j < col; j++ ) if ( mat[i][j] ) break;
7827: if ( j == col ) error("nd_f4_red_q_main : cannot happen");
7828: if ( rhead[j] ) continue;
7829: NEXTNODE(r0,r); BDY(r) =
7830: (pointer)plain_vect_to_ndv_q(mat[i],col,s0vect);
7831: SG((NDV)BDY(r)) = sugar[i];
7832: }
7833: if ( r0 ) NEXT(r) = 0;
7834: printf("\n");
7835: return r0;
1.129 noro 7836: }
7837: #endif
1.107 noro 7838:
1.74 noro 7839: FILE *nd_write,*nd_read;
7840:
7841: void nd_send_int(int a) {
1.157 noro 7842: write_int(nd_write,&a);
1.74 noro 7843: }
7844:
7845: void nd_send_intarray(int *p,int len) {
1.157 noro 7846: write_intarray(nd_write,p,len);
1.74 noro 7847: }
7848:
7849: int nd_recv_int() {
1.157 noro 7850: int a;
1.74 noro 7851:
1.157 noro 7852: read_int(nd_read,&a);
7853: return a;
1.74 noro 7854: }
7855:
7856: void nd_recv_intarray(int *p,int len) {
1.157 noro 7857: read_intarray(nd_read,p,len);
1.74 noro 7858: }
7859:
7860: void nd_send_ndv(NDV p) {
1.157 noro 7861: int len,i;
7862: NMV m;
1.74 noro 7863:
1.157 noro 7864: if ( !p ) nd_send_int(0);
7865: else {
7866: len = LEN(p);
7867: nd_send_int(len);
7868: m = BDY(p);
7869: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7870: nd_send_int(CM(m));
7871: nd_send_intarray(DL(m),nd_wpd);
7872: }
7873: }
1.74 noro 7874: }
7875:
7876: void nd_send_nd(ND p) {
1.157 noro 7877: int len,i;
7878: NM m;
1.74 noro 7879:
1.157 noro 7880: if ( !p ) nd_send_int(0);
7881: else {
7882: len = LEN(p);
7883: nd_send_int(len);
7884: m = BDY(p);
7885: for ( i = 0; i < len; i++, m = NEXT(m) ) {
7886: nd_send_int(CM(m));
7887: nd_send_intarray(DL(m),nd_wpd);
7888: }
7889: }
1.74 noro 7890: }
1.65 noro 7891:
1.74 noro 7892: NDV nd_recv_ndv()
7893: {
1.157 noro 7894: int len,i;
7895: NMV m,m0;
7896: NDV r;
7897:
7898: len = nd_recv_int();
7899: if ( !len ) return 0;
7900: else {
1.200 noro 7901: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
1.103 noro 7902: #if 0
1.157 noro 7903: ndv_alloc += len*nmv_adv;
1.103 noro 7904: #endif
1.157 noro 7905: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7906: CM(m) = nd_recv_int();
7907: nd_recv_intarray(DL(m),nd_wpd);
7908: }
7909: MKNDV(nd_nvar,m0,len,r);
7910: return r;
7911: }
1.74 noro 7912: }
1.65 noro 7913:
1.113 noro 7914: int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int col,int *colstat)
1.107 noro 7915: {
1.176 noro 7916: int i,j,t,c,rank,inv;
1.157 noro 7917: int *ci,*ri;
7918: Q dn;
7919: MAT m,nm;
7920:
7921: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
7922: rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci);
7923: for ( i = 0; i < row; i++ )
7924: for ( j = 0; j < col; j++ )
7925: mat0[i][j] = 0;
7926: c = col-rank;
7927: for ( i = 0; i < rank; i++ ) {
7928: mat0[i][ri[i]] = dn;
7929: for ( j = 0; j < c; j++ )
7930: mat0[i][ci[j]] = (Q)BDY(nm)[i][j];
7931: }
7932: return rank;
1.76 noro 7933: }
7934:
1.215 noro 7935: int nd_gauss_elim_gz(GZ **mat0,int *sugar,int row,int col,int *colstat)
7936: {
7937: int i,j,t,c,rank,inv;
7938: int *ci,*ri;
1.216 noro 7939: GZ dn;
1.215 noro 7940: MAT m,nm;
7941:
7942: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
1.216 noro 7943: rank = gz_generic_gauss_elim(m,&nm,&dn,&ri,&ci);
1.215 noro 7944: for ( i = 0; i < row; i++ )
7945: for ( j = 0; j < col; j++ )
7946: mat0[i][j] = 0;
7947: c = col-rank;
7948: for ( i = 0; i < rank; i++ ) {
1.216 noro 7949: mat0[i][ri[i]] = dn;
1.215 noro 7950: for ( j = 0; j < c; j++ )
7951: mat0[i][ci[j]] = (GZ)BDY(nm)[i][j];
7952: }
7953: return rank;
7954: }
7955:
1.133 noro 7956: int nd_gauss_elim_mod(int **mat0,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
1.76 noro 7957: {
1.157 noro 7958: int i,j,k,l,inv,a,rank,s;
7959: unsigned int *t,*pivot,*pk;
7960: unsigned int **mat;
7961: ND_pairs pair;
7962:
7963: mat = (unsigned int **)mat0;
7964: for ( rank = 0, j = 0; j < col; j++ ) {
7965: for ( i = rank; i < row; i++ )
7966: mat[i][j] %= md;
7967: for ( i = rank; i < row; i++ )
7968: if ( mat[i][j] )
7969: break;
7970: if ( i == row ) {
7971: colstat[j] = 0;
7972: continue;
7973: } else
7974: colstat[j] = 1;
7975: if ( i != rank ) {
7976: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
7977: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
7978: if ( spactive ) {
7979: pair = spactive[i]; spactive[i] = spactive[rank];
7980: spactive[rank] = pair;
7981: }
7982: }
7983: pivot = mat[rank];
7984: s = sugar[rank];
7985: inv = invm(pivot[j],md);
7986: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
7987: if ( *pk ) {
7988: if ( *pk >= (unsigned int)md )
7989: *pk %= md;
7990: DMAR(*pk,inv,0,md,*pk)
7991: }
7992: for ( i = rank+1; i < row; i++ ) {
7993: t = mat[i];
7994: if ( a = t[j] ) {
7995: sugar[i] = MAX(sugar[i],s);
7996: red_by_vect(md,t+j,pivot+j,md-a,col-j);
7997: }
7998: }
7999: rank++;
8000: }
8001: for ( j = col-1, l = rank-1; j >= 0; j-- )
8002: if ( colstat[j] ) {
8003: pivot = mat[l];
8004: s = sugar[l];
8005: for ( i = 0; i < l; i++ ) {
8006: t = mat[i];
8007: t[j] %= md;
8008: if ( a = t[j] ) {
8009: sugar[i] = MAX(sugar[i],s);
8010: red_by_vect(md,t+j,pivot+j,md-a,col-j);
8011: }
8012: }
8013: l--;
8014: }
8015: for ( j = 0, l = 0; l < rank; j++ )
8016: if ( colstat[j] ) {
8017: t = mat[l];
8018: for ( k = j; k < col; k++ )
8019: if ( t[k] >= (unsigned int)md )
8020: t[k] %= md;
8021: l++;
8022: }
8023: return rank;
1.76 noro 8024: }
8025:
1.242 noro 8026: #if defined(__GNUC__) && SIZEOF_LONG==8
1.240 noro 8027:
8028: int nd_gauss_elim_mod64(U64 **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
1.239 noro 8029: {
1.240 noro 8030: int i,j,k,l,rank,s;
8031: U64 inv;
8032: U64 a;
8033: UINT c;
8034: U64 *t,*pivot,*pk;
8035: UINT *ck;
8036: UINT **cmat;
8037: UINT *ct;
8038: ND_pairs pair;
8039:
8040: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
8041: for ( i = 0; i < row; i++ ) {
8042: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
8043: bzero(cmat[i],col*sizeof(UINT));
8044: }
1.239 noro 8045:
1.240 noro 8046: for ( rank = 0, j = 0; j < col; j++ ) {
8047: for ( i = rank; i < row; i++ ) {
8048: a = mat[i][j]; c = cmat[i][j];
8049: MOD128(a,c,md);
8050: mat[i][j] = a; cmat[i][j] = 0;
8051: }
8052: for ( i = rank; i < row; i++ )
8053: if ( mat[i][j] )
8054: break;
8055: if ( i == row ) {
8056: colstat[j] = 0;
8057: continue;
8058: } else
8059: colstat[j] = 1;
8060: if ( i != rank ) {
8061: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
8062: ct = cmat[i]; cmat[i] = cmat[rank]; cmat[rank] = ct;
8063: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
8064: if ( spactive ) {
8065: pair = spactive[i]; spactive[i] = spactive[rank];
8066: spactive[rank] = pair;
8067: }
8068: }
8069: /* column j is normalized */
8070: s = sugar[rank];
8071: inv = invm((UINT)mat[rank][j],md);
8072: /* normalize pivot row */
8073: for ( k = j, pk = mat[rank]+j, ck = cmat[rank]+j; k < col; k++, pk++, ck++ ) {
8074: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
8075: }
8076: for ( i = rank+1; i < row; i++ ) {
8077: if ( a = mat[i][j] ) {
8078: sugar[i] = MAX(sugar[i],s);
8079: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[rank]+j,(int)(md-a),col-j);
8080: }
1.239 noro 8081: }
1.240 noro 8082: rank++;
8083: }
8084: for ( j = col-1, l = rank-1; j >= 0; j-- )
8085: if ( colstat[j] ) {
8086: for ( k = j, pk = mat[l]+j, ck = cmat[l]+j; k < col; k++, pk++, ck++ ) {
8087: a = *pk; c = *ck; MOD128(a,c,md); *pk = a; *ck = 0;
8088: }
8089: s = sugar[l];
8090: for ( i = 0; i < l; i++ ) {
8091: a = mat[i][j]; c = cmat[i][j]; MOD128(a,c,md); mat[i][j] = a; cmat[i][j] = 0;
8092: if ( a ) {
8093: sugar[i] = MAX(sugar[i],s);
8094: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[l]+j,(int)(md-a),col-j);
8095: }
8096: }
8097: l--;
8098: }
8099: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
8100: GCFREE(cmat);
8101: return rank;
1.239 noro 8102: }
8103: #endif
8104:
1.76 noro 8105: int nd_gauss_elim_sf(int **mat0,int *sugar,int row,int col,int md,int *colstat)
8106: {
1.157 noro 8107: int i,j,k,l,inv,a,rank,s;
8108: unsigned int *t,*pivot,*pk;
8109: unsigned int **mat;
8110:
8111: mat = (unsigned int **)mat0;
8112: for ( rank = 0, j = 0; j < col; j++ ) {
8113: for ( i = rank; i < row; i++ )
8114: if ( mat[i][j] )
8115: break;
8116: if ( i == row ) {
8117: colstat[j] = 0;
8118: continue;
8119: } else
8120: colstat[j] = 1;
8121: if ( i != rank ) {
8122: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
8123: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
8124: }
8125: pivot = mat[rank];
8126: s = sugar[rank];
8127: inv = _invsf(pivot[j]);
8128: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
8129: if ( *pk )
8130: *pk = _mulsf(*pk,inv);
8131: for ( i = rank+1; i < row; i++ ) {
8132: t = mat[i];
8133: if ( a = t[j] ) {
8134: sugar[i] = MAX(sugar[i],s);
8135: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
8136: }
8137: }
8138: rank++;
8139: }
8140: for ( j = col-1, l = rank-1; j >= 0; j-- )
8141: if ( colstat[j] ) {
8142: pivot = mat[l];
8143: s = sugar[l];
8144: for ( i = 0; i < l; i++ ) {
8145: t = mat[i];
8146: if ( a = t[j] ) {
8147: sugar[i] = MAX(sugar[i],s);
8148: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
8149: }
8150: }
8151: l--;
8152: }
8153: return rank;
1.77 noro 8154: }
8155:
8156: int ndv_ishomo(NDV p)
8157: {
1.157 noro 8158: NMV m;
8159: int len,h;
1.77 noro 8160:
1.157 noro 8161: if ( !p ) return 1;
8162: len = LEN(p);
8163: m = BDY(p);
8164: h = TD(DL(m));
8165: NMV_ADV(m);
8166: for ( len--; len; len--, NMV_ADV(m) )
8167: if ( TD(DL(m)) != h ) return 0;
8168: return 1;
1.77 noro 8169: }
8170:
8171: void ndv_save(NDV p,int index)
8172: {
1.157 noro 8173: FILE *s;
8174: char name[BUFSIZ];
8175: short id;
8176: int nv,sugar,len,n,i,td,e,j;
8177: NMV m;
8178: unsigned int *dl;
8179: int mpos;
8180:
8181: sprintf(name,"%s/%d",Demand,index);
8182: s = fopen(name,"w");
8183: savevl(s,0);
8184: if ( !p ) {
8185: saveobj(s,0);
8186: return;
8187: }
8188: id = O_DP;
8189: nv = NV(p);
8190: sugar = SG(p);
8191: len = LEN(p);
8192: write_short(s,&id); write_int(s,&nv); write_int(s,&sugar);
8193: write_int(s,&len);
8194:
8195: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
8196: saveobj(s,(Obj)CQ(m));
8197: dl = DL(m);
8198: td = TD(dl);
8199: write_int(s,&td);
8200: for ( j = 0; j < nv; j++ ) {
8201: e = GET_EXP(dl,j);
8202: write_int(s,&e);
8203: }
8204: if ( nd_module ) {
8205: mpos = MPOS(dl); write_int(s,&mpos);
8206: }
8207: }
8208: fclose(s);
1.77 noro 8209: }
8210:
1.206 noro 8211: void nd_save_mod(ND p,int index)
8212: {
8213: FILE *s;
8214: char name[BUFSIZ];
8215: int nv,sugar,len,c;
8216: NM m;
8217:
8218: sprintf(name,"%s/%d",Demand,index);
8219: s = fopen(name,"w");
8220: if ( !p ) {
1.245 noro 8221: len = 0;
8222: write_int(s,&len);
8223: fclose(s);
1.206 noro 8224: return;
8225: }
8226: nv = NV(p);
8227: sugar = SG(p);
8228: len = LEN(p);
8229: write_int(s,&nv); write_int(s,&sugar); write_int(s,&len);
1.245 noro 8230: for ( m = BDY(p); m; m = NEXT(m) ) {
8231: c = CM(m); write_int(s,&c);
8232: write_intarray(s,DL(m),nd_wpd);
8233: }
1.206 noro 8234: fclose(s);
8235: }
8236:
1.77 noro 8237: NDV ndv_load(int index)
8238: {
1.157 noro 8239: FILE *s;
8240: char name[BUFSIZ];
8241: short id;
8242: int nv,sugar,len,n,i,td,e,j;
8243: NDV d;
8244: NMV m0,m;
8245: unsigned int *dl;
8246: Obj obj;
8247: int mpos;
8248:
8249: sprintf(name,"%s/%d",Demand,index);
8250: s = fopen(name,"r");
8251: if ( !s ) return 0;
8252:
8253: skipvl(s);
8254: read_short(s,&id);
8255: if ( !id ) return 0;
8256: read_int(s,&nv);
8257: read_int(s,&sugar);
8258: read_int(s,&len);
8259:
8260: m0 = m = MALLOC(len*nmv_adv);
8261: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
8262: loadobj(s,&obj); CQ(m) = (Q)obj;
8263: dl = DL(m);
8264: ndl_zero(dl);
8265: read_int(s,&td); TD(dl) = td;
8266: for ( j = 0; j < nv; j++ ) {
8267: read_int(s,&e);
8268: PUT_EXP(dl,j,e);
8269: }
8270: if ( nd_module ) {
8271: read_int(s,&mpos); MPOS(dl) = mpos;
8272: }
8273: if ( nd_blockmask ) ndl_weight_mask(dl);
8274: }
8275: fclose(s);
8276: MKNDV(nv,m0,len,d);
8277: SG(d) = sugar;
8278: return d;
1.99 noro 8279: }
8280:
1.206 noro 8281: ND nd_load_mod(int index)
8282: {
8283: FILE *s;
8284: char name[BUFSIZ];
8285: int nv,sugar,len,i,c;
1.245 noro 8286: ND d;
1.206 noro 8287: NM m0,m;
8288:
8289: sprintf(name,"%s/%d",Demand,index);
8290: s = fopen(name,"r");
1.245 noro 8291: /* if the file does not exist, it means p[index]=0 */
1.206 noro 8292: if ( !s ) return 0;
8293:
8294: read_int(s,&nv);
1.245 noro 8295: if ( !nv ) { fclose(s); return 0; }
1.206 noro 8296:
8297: read_int(s,&sugar);
8298: read_int(s,&len);
1.245 noro 8299: for ( m0 = 0, i = 0; i < len; i++ ) {
8300: NEXTNM(m0,m);
8301: read_int(s,&c); CM(m) = c;
8302: read_intarray(s,DL(m),nd_wpd);
8303: }
8304: NEXT(m) = 0;
1.206 noro 8305: MKND(nv,m0,len,d);
8306: SG(d) = sugar;
1.245 noro 8307: fclose(s);
1.206 noro 8308: return d;
8309: }
8310:
1.102 noro 8311: void nd_det(int mod,MAT f,P *rp)
1.99 noro 8312: {
1.157 noro 8313: VL fv,tv;
8314: int n,i,j,max,e,nvar,sgn,k0,l0,len0,len,k,l,a;
8315: pointer **m;
8316: Q mone;
8317: P **w;
8318: P mp,r;
8319: NDV **dm;
8320: NDV *t,*mi,*mj;
8321: NDV d,s,mij,mjj;
8322: ND u;
8323: NMV nmv;
8324: UINT *bound;
8325: PGeoBucket bucket;
8326: struct order_spec *ord;
8327: Q dq,dt,ds;
8328: N gn,qn,dn0,nm,dn;
8329:
8330: create_order_spec(0,0,&ord);
8331: nd_init_ord(ord);
8332: get_vars((Obj)f,&fv);
8333: if ( f->row != f->col )
8334: error("nd_det : non-square matrix");
8335: n = f->row;
8336: m = f->body;
8337: for ( nvar = 0, tv = fv; tv; tv = NEXT(tv), nvar++ );
8338:
8339: if ( !nvar ) {
8340: if ( !mod )
8341: detp(CO,(P **)m,n,rp);
8342: else {
8343: w = (P **)almat_pointer(n,n);
8344: for ( i = 0; i < n; i++ )
8345: for ( j = 0; j < n; j++ )
8346: ptomp(mod,(P)m[i][j],&w[i][j]);
8347: detmp(CO,mod,w,n,&mp);
8348: mptop(mp,rp);
8349: }
8350: return;
8351: }
8352:
8353: if ( !mod ) {
8354: w = (P **)almat_pointer(n,n);
8355: dq = ONE;
8356: for ( i = 0; i < n; i++ ) {
8357: dn0 = ONEN;
8358: for ( j = 0; j < n; j++ ) {
8359: if ( !m[i][j] ) continue;
8360: lgp(m[i][j],&nm,&dn);
8361: gcdn(dn0,dn,&gn); divsn(dn0,gn,&qn); muln(qn,dn,&dn0);
8362: }
8363: if ( !UNIN(dn0) ) {
8364: NTOQ(dn0,1,ds);
8365: for ( j = 0; j < n; j++ )
8366: mulp(CO,(P)m[i][j],(P)ds,&w[i][j]);
8367: mulq(dq,ds,&dt); dq = dt;
8368: } else
8369: for ( j = 0; j < n; j++ )
8370: w[i][j] = (P)m[i][j];
8371: }
8372: m = (pointer **)w;
8373: }
8374:
1.178 noro 8375: for ( i = 0, max = 1; i < n; i++ )
1.157 noro 8376: for ( j = 0; j < n; j++ )
8377: for ( tv = fv; tv; tv = NEXT(tv) ) {
8378: e = getdeg(tv->v,(P)m[i][j]);
8379: max = MAX(e,max);
8380: }
8381: nd_setup_parameters(nvar,max);
8382: dm = (NDV **)almat_pointer(n,n);
1.178 noro 8383: for ( i = 0, max = 1; i < n; i++ )
1.157 noro 8384: for ( j = 0; j < n; j++ ) {
8385: dm[i][j] = ptondv(CO,fv,m[i][j]);
8386: if ( mod ) ndv_mod(mod,dm[i][j]);
8387: if ( dm[i][j] && !LEN(dm[i][j]) ) dm[i][j] = 0;
8388: }
8389: d = ptondv(CO,fv,(P)ONE);
8390: if ( mod ) ndv_mod(mod,d);
8391: chsgnq(ONE,&mone);
8392: for ( j = 0, sgn = 1; j < n; j++ ) {
1.222 fujimoto 8393: if ( DP_Print ) {
1.245 noro 8394: fprintf(asir_out,".",j);
8395: }
1.157 noro 8396: for ( i = j; i < n && !dm[i][j]; i++ );
8397: if ( i == n ) {
8398: *rp = 0;
8399: return;
8400: }
8401: k0 = i; l0 = j; len0 = LEN(dm[k0][l0]);
8402: for ( k = j; k < n; k++ )
8403: for ( l = j; l < n; l++ )
8404: if ( dm[k][l] && LEN(dm[k][l]) < len0 ) {
8405: k0 = k; l0 = l; len0 = LEN(dm[k][l]);
8406: }
8407: if ( k0 != j ) {
8408: t = dm[j]; dm[j] = dm[k0]; dm[k0] = t;
8409: sgn = -sgn;
8410: }
8411: if ( l0 != j ) {
8412: for ( k = j; k < n; k++ ) {
8413: s = dm[k][j]; dm[k][j] = dm[k][l0]; dm[k][l0] = s;
8414: }
8415: sgn = -sgn;
8416: }
8417: bound = nd_det_compute_bound(dm,n,j);
8418: for ( k = 0; k < nd_nvar; k++ )
8419: if ( bound[k]*2 > nd_mask0 ) break;
8420: if ( k < nd_nvar )
8421: nd_det_reconstruct(dm,n,j,d);
8422:
8423: for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) {
1.241 noro 8424: /* if ( DP_Print ) fprintf(asir_out," i=%d\n ",i); */
1.157 noro 8425: mi = dm[i]; mij = mi[j];
8426: if ( mod )
8427: ndv_mul_c(mod,mij,mod-1);
8428: else
8429: ndv_mul_c_q(mij,mone);
8430: for ( k = j+1; k < n; k++ ) {
1.241 noro 8431: /* if ( DP_Print ) fprintf(asir_out,"k=%d ",k); */
1.157 noro 8432: bucket = create_pbucket();
8433: if ( mi[k] ) {
8434: nmv = BDY(mjj); len = LEN(mjj);
8435: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
8436: u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d)));
8437: add_pbucket(mod,bucket,u);
8438: }
8439: }
8440: if ( mj[k] && mij ) {
8441: nmv = BDY(mij); len = LEN(mij);
8442: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
8443: u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d)));
8444: add_pbucket(mod,bucket,u);
8445: }
8446: }
8447: u = nd_quo(mod,bucket,d);
8448: mi[k] = ndtondv(mod,u);
8449: }
1.241 noro 8450: /* if ( DP_Print ) fprintf(asir_out,"\n",k); */
1.157 noro 8451: }
8452: d = mjj;
8453: }
1.222 fujimoto 8454: if ( DP_Print ) {
1.241 noro 8455: fprintf(asir_out,"\n",k);
1.222 fujimoto 8456: }
1.157 noro 8457: if ( sgn < 0 )
8458: if ( mod )
8459: ndv_mul_c(mod,d,mod-1);
8460: else
8461: ndv_mul_c_q(d,mone);
8462: r = ndvtop(mod,CO,fv,d);
8463: if ( !mod && !UNIQ(dq) )
8464: divsp(CO,r,(P)dq,rp);
8465: else
8466: *rp = r;
1.99 noro 8467: }
8468:
1.102 noro 8469: ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d)
1.99 noro 8470: {
1.157 noro 8471: NM mr,mr0;
8472: NM tnm;
8473: NMV m;
8474: UINT *d0,*dt,*dm;
8475: int c,n,td,i,c1,c2,len;
8476: Q q;
8477: ND r;
8478:
8479: if ( !p ) return 0;
8480: else {
8481: n = NV(p); m = BDY(p); len = LEN(p);
8482: d0 = DL(m0);
8483: td = TD(d);
8484: mr0 = 0;
8485: NEWNM(tnm);
8486: if ( mod ) {
8487: c = CM(m0);
8488: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
8489: ndl_add(DL(m),d0,DL(tnm));
8490: if ( ndl_reducible(DL(tnm),d) ) {
8491: NEXTNM(mr0,mr);
8492: c1 = CM(m); DMAR(c1,c,0,mod,c2); CM(mr) = c2;
8493: ndl_copy(DL(tnm),DL(mr));
8494: }
8495: }
8496: } else {
8497: q = CQ(m0);
8498: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
8499: ndl_add(DL(m),d0,DL(tnm));
8500: if ( ndl_reducible(DL(tnm),d) ) {
8501: NEXTNM(mr0,mr);
8502: mulq(CQ(m),q,&CQ(mr));
8503: ndl_copy(DL(tnm),DL(mr));
8504: }
8505: }
8506: }
8507: if ( !mr0 )
8508: return 0;
8509: else {
8510: NEXT(mr) = 0;
8511: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
8512: MKND(NV(p),mr0,len,r);
8513: SG(r) = SG(p) + TD(d0);
8514: return r;
8515: }
8516: }
1.114 noro 8517: }
8518:
8519: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d)
8520: {
1.157 noro 8521: int i,obpe,oadv,h,k,l;
8522: static NM prev_nm_free_list;
8523: EPOS oepos;
8524:
8525: obpe = nd_bpe;
8526: oadv = nmv_adv;
8527: oepos = nd_epos;
8528: if ( obpe < 2 ) nd_bpe = 2;
8529: else if ( obpe < 3 ) nd_bpe = 3;
8530: else if ( obpe < 4 ) nd_bpe = 4;
8531: else if ( obpe < 5 ) nd_bpe = 5;
8532: else if ( obpe < 6 ) nd_bpe = 6;
8533: else if ( obpe < 8 ) nd_bpe = 8;
8534: else if ( obpe < 10 ) nd_bpe = 10;
8535: else if ( obpe < 16 ) nd_bpe = 16;
8536: else if ( obpe < 32 ) nd_bpe = 32;
8537: else error("nd_det_reconstruct : exponent too large");
8538:
8539: nd_setup_parameters(nd_nvar,0);
8540: prev_nm_free_list = _nm_free_list;
8541: _nm_free_list = 0;
8542: for ( k = j; k < n; k++ )
8543: for (l = j; l < n; l++ )
8544: ndv_realloc(dm[k][l],obpe,oadv,oepos);
8545: ndv_realloc(d,obpe,oadv,oepos);
8546: prev_nm_free_list = 0;
1.114 noro 8547: #if 0
1.157 noro 8548: GC_gcollect();
1.114 noro 8549: #endif
8550: }
8551:
1.153 noro 8552: /* returns a UINT array containing degree bounds */
8553:
1.114 noro 8554: UINT *nd_det_compute_bound(NDV **dm,int n,int j)
8555: {
1.157 noro 8556: UINT *d0,*d1,*d,*t,*r;
8557: int k,l,i;
1.114 noro 8558:
1.157 noro 8559: d0 = (UINT *)MALLOC(nd_nvar*sizeof(UINT));
8560: for ( k = 0; k < nd_nvar; k++ ) d0[k] = 0;
8561: for ( k = j; k < n; k++ )
8562: for ( l = j; l < n; l++ )
8563: if ( dm[k][l] ) {
8564: d = ndv_compute_bound(dm[k][l]);
8565: for ( i = 0; i < nd_nvar; i++ )
8566: d0[i] = MAX(d0[i],d[i]);
8567: }
8568: return d0;
1.117 noro 8569: }
8570:
8571: DL nd_separate_d(UINT *d,UINT *trans)
8572: {
1.157 noro 8573: int n,td,i,e,j;
8574: DL a;
1.117 noro 8575:
1.157 noro 8576: ndl_zero(trans);
8577: td = 0;
8578: for ( i = 0; i < nd_ntrans; i++ ) {
8579: e = GET_EXP(d,i);
8580: PUT_EXP(trans,i,e);
8581: td += MUL_WEIGHT(e,i);
8582: }
8583: if ( nd_ntrans+nd_nalg < nd_nvar ) {
8584: /* homogenized */
8585: i = nd_nvar-1;
8586: e = GET_EXP(d,i);
8587: PUT_EXP(trans,i,e);
8588: td += MUL_WEIGHT(e,i);
8589: }
8590: TD(trans) = td;
8591: if ( nd_blockmask) ndl_weight_mask(trans);
8592: NEWDL(a,nd_nalg);
8593: td = 0;
8594: for ( i = 0; i < nd_nalg; i++ ) {
8595: j = nd_ntrans+i;
8596: e = GET_EXP(d,j);
8597: a->d[i] = e;
8598: td += e;
8599: }
8600: a->td = td;
8601: return a;
1.117 noro 8602: }
8603:
1.118 noro 8604: int nd_monic(int mod,ND *p)
1.117 noro 8605: {
1.157 noro 8606: UINT *trans,*t;
8607: DL alg;
8608: MP mp0,mp;
8609: NM m,m0,m1,ma0,ma,mb,mr0,mr;
8610: ND r;
8611: DL dl;
8612: DP nm;
8613: NDV ndv;
8614: DAlg inv,cd;
8615: ND s,c;
8616: Q l,mul;
8617: N ln;
8618: int n,ntrans,i,e,td,is_lc,len;
8619: NumberField nf;
8620: struct oEGT eg0,eg1;
8621:
8622: if ( !(nf = get_numberfield()) )
8623: error("nd_monic : current_numberfield is not set");
8624:
8625: /* Q coef -> DAlg coef */
8626: NEWNM(ma0); ma = ma0;
8627: m = BDY(*p);
8628: is_lc = 1;
8629: while ( 1 ) {
8630: NEWMP(mp0); mp = mp0;
1.238 noro 8631: mp->c = (Obj)CQ(m);
1.157 noro 8632: mp->dl = nd_separate_d(DL(m),DL(ma));
8633: NEWNM(mb);
8634: for ( m = NEXT(m); m; m = NEXT(m) ) {
8635: alg = nd_separate_d(DL(m),DL(mb));
8636: if ( !ndl_equal(DL(ma),DL(mb)) )
8637: break;
1.238 noro 8638: NEXTMP(mp0,mp); mp->c = (Obj)CQ(m); mp->dl = alg;
1.157 noro 8639: }
8640: NEXT(mp) = 0;
8641: MKDP(nd_nalg,mp0,nm);
8642: MKDAlg(nm,ONE,cd);
8643: if ( is_lc == 1 ) {
8644: /* if the lc is a rational number, we have nothing to do */
8645: if ( !mp0->dl->td )
8646: return 1;
8647:
8648: get_eg(&eg0);
8649: invdalg(cd,&inv);
8650: get_eg(&eg1); add_eg(&eg_invdalg,&eg0,&eg1);
8651: /* check the validity of inv */
8652: if ( mod && !rem(NM(inv->dn),mod) )
8653: return 0;
8654: CA(ma) = nf->one;
8655: is_lc = 0;
8656: ln = ONEN;
8657: } else {
8658: muldalg(cd,inv,&CA(ma));
8659: lcmn(ln,NM(CA(ma)->dn),&ln);
8660: }
8661: if ( m ) {
8662: NEXT(ma) = mb; ma = mb;
8663: } else {
8664: NEXT(ma) = 0;
8665: break;
8666: }
8667: }
8668: /* l = lcm(denoms) */
8669: NTOQ(ln,1,l);
8670: for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) {
8671: divq(l,CA(m)->dn,&mul);
8672: for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) {
8673: NEXTNM(mr0,mr);
8674: mulq((Q)mp->c,mul,&CQ(mr));
8675: dl = mp->dl;
8676: td = TD(DL(m));
8677: ndl_copy(DL(m),DL(mr));
8678: for ( i = 0; i < nd_nalg; i++ ) {
8679: e = dl->d[i];
8680: PUT_EXP(DL(mr),i+nd_ntrans,e);
8681: td += MUL_WEIGHT(e,i+nd_ntrans);
8682: }
1.163 noro 8683: if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m));
1.157 noro 8684: TD(DL(mr)) = td;
8685: if ( nd_blockmask) ndl_weight_mask(DL(mr));
8686: }
8687: }
8688: NEXT(mr) = 0;
8689: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
8690: MKND(NV(*p),mr0,len,r);
8691: /* XXX */
8692: SG(r) = SG(*p);
8693: nd_free(*p);
8694: *p = r;
8695: return 1;
1.59 noro 8696: }
1.167 noro 8697:
8698: NODE reverse_node(NODE n)
8699: {
8700: NODE t,t1;
8701:
8702: for ( t = 0; n; n = NEXT(n) ) {
8703: MKNODE(t1,BDY(n),t); t = t1;
8704: }
8705: return t;
8706: }
8707:
8708: P ndc_div(int mod,union oNDC a,union oNDC b)
8709: {
8710: union oNDC c;
8711: int inv,t;
8712:
8713: if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m));
1.232 noro 8714: else if ( mod == -2 ) divlf(a.z,b.z,&c.z);
1.167 noro 8715: else if ( mod ) {
8716: inv = invm(b.m,mod);
8717: DMAR(a.m,inv,0,mod,t); c.m = t;
8718: } else if ( nd_vc )
8719: divsp(nd_vc,a.p,b.p,&c.p);
8720: else
8721: divq(a.z,b.z,&c.z);
8722: return ndctop(mod,c);
8723: }
8724:
8725: P ndctop(int mod,union oNDC c)
8726: {
8727: Q q;
8728: int e;
8729: GFS gfs;
8730:
8731: if ( mod == -1 ) {
8732: e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs;
1.247 noro 8733: } else if ( mod == -2 ) {
8734: q = gztoz(c.gz); return (P)q;
1.232 noro 8735: } else if ( mod > 0 ) {
1.167 noro 8736: STOQ(c.m,q); return (P)q;
8737: } else
8738: return (P)c.p;
8739: }
8740:
8741: /* [0,0,0,cont] = p -> p/cont */
8742:
8743: void finalize_tracelist(int i,P cont)
8744: {
1.245 noro 8745: LIST l;
8746: NODE node;
1.167 noro 8747: Q iq;
8748:
1.245 noro 8749: if ( !UNIQ(cont) ) {
1.196 noro 8750: node = mknode(4,NULLP,NULLP,NULLP,cont);
1.167 noro 8751: MKLIST(l,node); MKNODE(node,l,nd_tracelist);
1.245 noro 8752: nd_tracelist = node;
8753: }
1.167 noro 8754: STOQ(i,iq);
8755: nd_tracelist = reverse_node(nd_tracelist);
8756: MKLIST(l,nd_tracelist);
8757: node = mknode(2,iq,l); MKLIST(l,node);
8758: MKNODE(node,l,nd_alltracelist); MKLIST(l,node);
8759: nd_alltracelist = node; nd_tracelist = 0;
8760: }
8761:
8762: void conv_ilist(int demand,int trace,NODE g,int **indp)
8763: {
8764: int n,i,j;
1.245 noro 8765: int *ind;
8766: NODE t;
1.167 noro 8767:
8768: n = length(g);
1.245 noro 8769: ind = (int *)MALLOC(n*sizeof(int));
8770: for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) {
8771: j = (long)BDY(t); ind[i] = j;
8772: BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j]));
8773: }
8774: if ( indp ) *indp = ind;
1.167 noro 8775: }
1.172 noro 8776:
8777: void parse_nd_option(NODE opt)
8778: {
1.187 noro 8779: NODE t,p,u;
1.245 noro 8780: int i,s,n;
1.172 noro 8781: char *key;
8782: Obj value;
8783:
1.187 noro 8784: nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_gbblock = 0;
1.245 noro 8785: nd_newelim = 0; nd_intersect = 0; nd_nzlist = 0;
8786: nd_splist = 0; nd_check_splist = 0;
1.231 noro 8787: nd_sugarweight = 0;
1.234 noro 8788: nd_f4red =0;
8789: nd_rank0 = 0;
1.172 noro 8790: for ( t = opt; t; t = NEXT(t) ) {
8791: p = BDY((LIST)BDY(t));
8792: key = BDY((STRING)BDY(p));
8793: value = (Obj)BDY(NEXT(p));
8794: if ( !strcmp(key,"gentrace") )
8795: nd_gentrace = value?1:0;
8796: else if ( !strcmp(key,"gensyz") )
8797: nd_gensyz = value?1:0;
1.173 noro 8798: else if ( !strcmp(key,"nora") )
8799: nd_nora = value?1:0;
1.187 noro 8800: else if ( !strcmp(key,"gbblock") ) {
1.233 noro 8801: if ( value && OID(value) == O_LIST ) {
1.245 noro 8802: u = BDY((LIST)value);
1.233 noro 8803: nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int));
1.245 noro 8804: for ( i = 0; u; u = NEXT(u) ) {
8805: p = BDY((LIST)BDY(u));
8806: s = nd_gbblock[i++] = QTOS((Q)BDY(p));
8807: nd_gbblock[i++] = s+QTOS((Q)BDY(NEXT(p)))-1;
8808: }
8809: nd_gbblock[i] = -1;
1.233 noro 8810: } else
8811: nd_gbblock = 0;
1.245 noro 8812: } else if ( !strcmp(key,"newelim") )
1.192 noro 8813: nd_newelim = value?1:0;
1.245 noro 8814: else if ( !strcmp(key,"intersect") )
1.195 noro 8815: nd_intersect = value?1:0;
1.245 noro 8816: else if ( !strcmp(key,"lf") )
1.234 noro 8817: nd_lf = value?1:0;
1.245 noro 8818: else if ( !strcmp(key,"trace") ) {
1.244 noro 8819: if ( value ) {
8820: u = BDY((LIST)value);
1.245 noro 8821: nd_nzlist = BDY((LIST)ARG2(u));
8822: nd_bpe = QTOS((Q)ARG3(u));
1.244 noro 8823: }
1.245 noro 8824: } else if ( !strcmp(key,"f4red") ) {
8825: nd_f4red = QTOS((Q)value);
8826: } else if ( !strcmp(key,"rank0") ) {
1.234 noro 8827: nd_rank0 = value?1:0;
1.245 noro 8828: } else if ( !strcmp(key,"splist") ) {
1.209 noro 8829: nd_splist = value?1:0;
1.245 noro 8830: } else if ( !strcmp(key,"check_splist") ) {
8831: nd_check_splist = BDY((LIST)value);
8832: } else if ( !strcmp(key,"sugarweight") ) {
8833: u = BDY((LIST)value);
1.231 noro 8834: n = length(u);
8835: nd_sugarweight = MALLOC(n*sizeof(int));
1.245 noro 8836: for ( i = 0; i < n; i++, u = NEXT(u) )
1.231 noro 8837: nd_sugarweight[i] = QTOS((Q)BDY(u));
1.245 noro 8838: }
1.172 noro 8839: }
8840: }
1.204 noro 8841:
8842: ND mdptond(DP d);
8843: ND nd_mul_nm(int mod,NM m0,ND p);
1.247 noro 8844: ND nd_mul_nm_lf(NM m0,ND p);
1.207 noro 8845: ND *btog(NODE ti,ND **p,int nb,int mod);
8846: ND btog_one(NODE ti,ND *p,int nb,int mod);
1.204 noro 8847: MAT nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,MAT *rp);
1.205 noro 8848: VECT nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos,MAT *rp);
1.204 noro 8849:
8850: /* d:monomial */
8851: ND mdptond(DP d)
8852: {
8853: NM m;
8854: ND r;
8855:
8856: if ( OID(d) == 1 )
1.245 noro 8857: r = ptond(CO,CO,(P)d);
1.204 noro 8858: else {
8859: NEWNM(m);
8860: dltondl(NV(d),BDY(d)->dl,DL(m));
8861: CQ(m) = (Q)BDY(d)->c;
8862: NEXT(m) = 0;
8863: MKND(NV(d),m,1,r);
8864: }
8865: return r;
8866: }
8867:
8868: ND nd_mul_nm(int mod,NM m0,ND p)
8869: {
8870: UINT *d0;
8871: int c0,c1,c;
8872: NM tm,mr,mr0;
8873: ND r;
8874:
8875: if ( !p ) return 0;
8876: d0 = DL(m0);
8877: c0 = CM(m0);
8878: mr0 = 0;
8879: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
8880: NEXTNM(mr0,mr);
1.245 noro 8881: c = CM(tm); DMAR(c0,c,0,mod,c1); CM(mr) = c1;
8882: ndl_add(d0,DL(tm),DL(mr));
1.204 noro 8883: }
8884: NEXT(mr) = 0;
8885: MKND(NV(p),mr0,LEN(p),r);
8886: return r;
8887: }
8888:
1.247 noro 8889: ND nd_mul_nm_lf(NM m0,ND p)
8890: {
8891: UINT *d0;
8892: GZ c0,c1,c;
8893: NM tm,mr,mr0;
8894: ND r;
8895:
8896: if ( !p ) return 0;
8897: d0 = DL(m0);
8898: c0 = CZ(m0);
8899: mr0 = 0;
8900: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
8901: NEXTNM(mr0,mr);
8902: c = CZ(tm); mullf(c0,CZ(tm),&c1); CZ(mr) = c1;
8903: ndl_add(d0,DL(tm),DL(mr));
8904: }
8905: NEXT(mr) = 0;
8906: MKND(NV(p),mr0,LEN(p),r);
8907: return r;
8908: }
8909:
1.207 noro 8910: ND *btog(NODE ti,ND **p,int nb,int mod)
1.204 noro 8911: {
8912: PGeoBucket *r;
8913: int i,ci;
8914: NODE t,s;
8915: ND m,tp;
8916: ND *pi,*rd;
8917: P c;
8918:
8919: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
8920: for ( i = 0; i < nb; i++ )
1.245 noro 8921: r[i] = create_pbucket();
1.204 noro 8922: for ( t = ti; t; t = NEXT(t) ) {
1.245 noro 8923: s = BDY((LIST)BDY(t));
1.204 noro 8924: if ( ARG0(s) ) {
1.245 noro 8925: m = mdptond((DP)ARG2(s));
8926: ptomp(mod,(P)HCQ(m),&c);
8927: if ( ci = ((MQ)c)->cont ) {
8928: HCM(m) = ci;
8929: pi = p[QTOS((Q)ARG1(s))];
8930: for ( i = 0; i < nb; i++ ) {
8931: tp = nd_mul_nm(mod,BDY(m),pi[i]);
8932: add_pbucket(mod,r[i],tp);
8933: }
8934: }
8935: ci = 1;
1.204 noro 8936: } else {
1.245 noro 8937: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
8938: ci = invm(ci,mod);
8939: }
1.204 noro 8940: }
8941: rd = (ND *)MALLOC(nb*sizeof(ND));
8942: for ( i = 0; i < nb; i++ )
1.245 noro 8943: rd[i] = normalize_pbucket(mod,r[i]);
1.204 noro 8944: if ( ci != 1 )
8945: for ( i = 0; i < nb; i++ ) nd_mul_c(mod,rd[i],ci);
8946: return rd;
8947: }
8948:
1.247 noro 8949: /* YYY */
8950: ND *btog_lf(NODE ti,ND **p,int nb)
8951: {
8952: PGeoBucket *r;
8953: int i;
8954: NODE t,s;
8955: ND m,tp;
8956: ND *pi,*rd;
8957: LM lm;
8958: GZ lf,c;
8959:
8960: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
8961: for ( i = 0; i < nb; i++ )
8962: r[i] = create_pbucket();
8963: for ( t = ti; t; t = NEXT(t) ) {
8964: s = BDY((LIST)BDY(t));
8965: if ( ARG0(s) ) {
8966: m = mdptond((DP)ARG2(s));
8967: simp_ff((Obj)HCQ(m),&lm);
8968: if ( lm ) {
8969: lmtolf(lm,&lf); HCZ(m) = lf;
8970: pi = p[QTOS((Q)ARG1(s))];
8971: for ( i = 0; i < nb; i++ ) {
8972: tp = nd_mul_nm_lf(BDY(m),pi[i]);
8973: add_pbucket(-2,r[i],tp);
8974: }
8975: }
8976: c = ONEGZ;
8977: } else {
8978: simp_ff((Obj)ARG3(s),&lm); lmtolf(lm,&lf); invgz(lf,&c);
8979: }
8980: }
8981: rd = (ND *)MALLOC(nb*sizeof(ND));
8982: for ( i = 0; i < nb; i++ )
8983: rd[i] = normalize_pbucket(-2,r[i]);
8984: for ( i = 0; i < nb; i++ ) nd_mul_c_lf(rd[i],c);
8985: return rd;
8986: }
8987:
1.207 noro 8988: ND btog_one(NODE ti,ND *p,int nb,int mod)
1.205 noro 8989: {
8990: PGeoBucket r;
1.206 noro 8991: int i,ci,j;
1.205 noro 8992: NODE t,s;
8993: ND m,tp;
8994: ND pi,rd;
8995: P c;
8996:
8997: r = create_pbucket();
8998: for ( t = ti; t; t = NEXT(t) ) {
1.245 noro 8999: s = BDY((LIST)BDY(t));
1.205 noro 9000: if ( ARG0(s) ) {
1.245 noro 9001: m = mdptond((DP)ARG2(s));
9002: ptomp(mod,(P)HCQ(m),&c);
9003: if ( ci = ((MQ)c)->cont ) {
9004: HCM(m) = ci;
9005: pi = p[j=QTOS((Q)ARG1(s))];
9006: if ( !pi ) {
9007: pi = nd_load_mod(j);
9008: tp = nd_mul_nm(mod,BDY(m),pi);
9009: nd_free(pi);
9010: add_pbucket(mod,r,tp);
1.205 noro 9011: } else {
1.245 noro 9012: tp = nd_mul_nm(mod,BDY(m),pi);
9013: add_pbucket(mod,r,tp);
9014: }
9015: }
9016: ci = 1;
9017: } else {
9018: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
9019: ci = invm(ci,mod);
9020: }
1.205 noro 9021: }
9022: rd = normalize_pbucket(mod,r);
1.206 noro 9023: free_pbucket(r);
1.205 noro 9024: if ( ci != 1 ) nd_mul_c(mod,rd,ci);
9025: return rd;
9026: }
1.204 noro 9027:
1.247 noro 9028: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp);
9029:
1.204 noro 9030: MAT nd_btog(LIST f,LIST v,int mod,struct order_spec *ord,LIST tlist,MAT *rp)
9031: {
9032: int i,j,n,m,nb,pi0,pi1,nvar;
9033: VL fv,tv,vv;
9034: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
9035: ND **p;
9036: ND *c;
9037: ND u;
9038: P inv;
9039: MAT mat;
9040:
1.247 noro 9041: if ( mod == -2 )
9042: return nd_btog_lf(f,v,ord,tlist,rp);
9043:
1.204 noro 9044: parse_nd_option(current_option);
9045: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
9046: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
9047: switch ( ord->id ) {
9048: case 1:
9049: if ( ord->nv != nvar )
9050: error("nd_check : invalid order specification");
9051: break;
9052: default:
9053: break;
9054: }
9055: nd_init_ord(ord);
9056: #if 0
9057: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
9058: #else
9059: nd_bpe = 32;
9060: #endif
9061: nd_setup_parameters(nvar,0);
9062: permtrace = BDY((LIST)ARG2(BDY(tlist)));
9063: intred = BDY((LIST)ARG3(BDY(tlist)));
9064: ind = BDY((LIST)ARG4(BDY(tlist)));
9065: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
9066: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.245 noro 9067: j = QTOS((Q)BDY(BDY((LIST)BDY(t))));
9068: if ( j > i ) i = j;
1.204 noro 9069: }
9070: n = i+1;
9071: nb = length(BDY(f));
9072: p = (ND **)MALLOC(n*sizeof(ND *));
9073: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
9074: pi = BDY((LIST)BDY(t));
1.247 noro 9075: pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi));
9076: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
9077: ptomp(mod,(P)ARG2(pi),&inv);
9078: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
9079: u = ptond(CO,vv,(P)ONE);
9080: HCM(u) = ((MQ)inv)->cont;
9081: c[pi1] = u;
1.204 noro 9082: }
9083: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
1.247 noro 9084: printf("%d ",i); fflush(stdout);
1.204 noro 9085: ti = BDY((LIST)BDY(t));
1.207 noro 9086: p[j=QTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.204 noro 9087: }
9088: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
1.247 noro 9089: printf("%d ",i); fflush(stdout);
1.204 noro 9090: ti = BDY((LIST)BDY(t));
1.207 noro 9091: p[j=QTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.204 noro 9092: }
9093: m = length(ind);
9094: MKMAT(mat,nb,m);
9095: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
9096: for ( i = 0, c = p[QTOS((Q)BDY(t))]; i < nb; i++ )
1.247 noro 9097: BDY(mat)[i][j] = ndtodp(mod,c[i]);
9098: return mat;
9099: }
9100:
9101: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp)
9102: {
9103: int i,j,n,m,nb,pi0,pi1,nvar;
9104: VL fv,tv,vv;
9105: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
9106: ND **p;
9107: ND *c;
9108: ND u;
9109: MAT mat;
9110: LM lm;
9111: GZ lf,inv;
9112:
9113: parse_nd_option(current_option);
9114: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
9115: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
9116: switch ( ord->id ) {
9117: case 1:
9118: if ( ord->nv != nvar )
9119: error("nd_check : invalid order specification");
9120: break;
9121: default:
9122: break;
9123: }
9124: nd_init_ord(ord);
9125: #if 0
9126: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
9127: #else
9128: nd_bpe = 32;
9129: #endif
9130: nd_setup_parameters(nvar,0);
9131: permtrace = BDY((LIST)ARG2(BDY(tlist)));
9132: intred = BDY((LIST)ARG3(BDY(tlist)));
9133: ind = BDY((LIST)ARG4(BDY(tlist)));
9134: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
9135: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
9136: j = QTOS((Q)BDY(BDY((LIST)BDY(t))));
9137: if ( j > i ) i = j;
9138: }
9139: n = i+1;
9140: nb = length(BDY(f));
9141: p = (ND **)MALLOC(n*sizeof(ND *));
9142: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
9143: pi = BDY((LIST)BDY(t));
9144: pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi));
9145: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
9146: simp_ff((Obj)ARG2(pi),&lm); lmtolf(lm,&lf); invgz(lf,&inv);
9147: u = ptond(CO,vv,(P)ONE);
9148: HCZ(u) = inv;
9149: c[pi1] = u;
9150: }
9151: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
9152: printf("%d ",i); fflush(stdout);
9153: ti = BDY((LIST)BDY(t));
9154: p[j=QTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
9155: }
9156: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
9157: printf("%d ",i); fflush(stdout);
9158: ti = BDY((LIST)BDY(t));
9159: p[j=QTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
9160: }
9161: m = length(ind);
9162: MKMAT(mat,nb,m);
9163: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
9164: for ( i = 0, c = p[QTOS((Q)BDY(t))]; i < nb; i++ )
9165: BDY(mat)[i][j] = ndtodp(-2,c[i]);
1.204 noro 9166: return mat;
9167: }
9168:
1.205 noro 9169: VECT nd_btog_one(LIST f,LIST v,int mod,struct order_spec *ord,
9170: LIST tlist,int pos,MAT *rp)
9171: {
9172: int i,j,n,m,nb,pi0,pi1,nvar;
9173: VL fv,tv,vv;
9174: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
9175: ND *p;
9176: ND *c;
9177: ND u;
9178: P inv;
9179: VECT vect;
9180:
1.247 noro 9181: if ( mod == -2 )
9182: error("nd_btog_one : not implemented yet for a large finite field");
9183:
1.205 noro 9184: parse_nd_option(current_option);
9185: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
9186: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
9187: switch ( ord->id ) {
9188: case 1:
9189: if ( ord->nv != nvar )
9190: error("nd_check : invalid order specification");
9191: break;
9192: default:
9193: break;
9194: }
9195: nd_init_ord(ord);
9196: #if 0
9197: nd_bpe = QTOS((Q)ARG7(BDY(tlist)));
9198: #else
9199: nd_bpe = 32;
9200: #endif
9201: nd_setup_parameters(nvar,0);
9202: permtrace = BDY((LIST)ARG2(BDY(tlist)));
9203: intred = BDY((LIST)ARG3(BDY(tlist)));
9204: ind = BDY((LIST)ARG4(BDY(tlist)));
9205: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
9206: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.245 noro 9207: j = QTOS((Q)BDY(BDY((LIST)BDY(t))));
9208: if ( j > i ) i = j;
1.205 noro 9209: }
9210: n = i+1;
9211: nb = length(BDY(f));
9212: p = (ND *)MALLOC(n*sizeof(ND *));
9213: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
9214: pi = BDY((LIST)BDY(t));
1.245 noro 9215: pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi));
9216: if ( pi1 == pos ) {
9217: ptomp(mod,(P)ARG2(pi),&inv);
9218: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
9219: u = ptond(CO,vv,(P)ONE);
9220: HCM(u) = ((MQ)inv)->cont;
9221: p[pi0] = u;
1.205 noro 9222: }
9223: }
9224: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
1.245 noro 9225: printf("%d ",i); fflush(stdout);
1.205 noro 9226: ti = BDY((LIST)BDY(t));
1.207 noro 9227: p[j=QTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.206 noro 9228: if ( Demand ) {
9229: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
1.245 noro 9230: }
1.205 noro 9231: }
9232: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
1.245 noro 9233: printf("%d ",i); fflush(stdout);
1.205 noro 9234: ti = BDY((LIST)BDY(t));
1.207 noro 9235: p[j=QTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.206 noro 9236: if ( Demand ) {
9237: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
1.245 noro 9238: }
1.205 noro 9239: }
9240: m = length(ind);
9241: MKVECT(vect,m);
1.206 noro 9242: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) {
1.245 noro 9243: u = p[QTOS((Q)BDY(t))];
9244: if ( !u ) {
9245: u = nd_load_mod(QTOS((Q)BDY(t)));
9246: BDY(vect)[j] = ndtodp(mod,u);
9247: nd_free(u);
9248: } else
9249: BDY(vect)[j] = ndtodp(mod,u);
1.206 noro 9250: }
1.205 noro 9251: return vect;
9252: }
1.232 noro 9253:
9254: void ndv_print_lf(NDV p)
9255: {
9256: NMV m;
9257: int i,len;
9258:
9259: if ( !p ) printf("0\n");
9260: else {
9261: len = LEN(p);
9262: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
9263: printf("+");
9264: mpz_out_str(asir_out,10,BDY(CZ(m)));
9265: printf("*");
9266: ndl_print(DL(m));
9267: }
9268: printf("\n");
9269: }
9270: }
1.234 noro 9271:
9272: void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp)
9273: {
9274: VL tv,fv,vv,vc,av;
9275: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
9276: int m,nocheck,nvar,mindex,e,max;
9277: NDV c;
9278: NMV a;
9279: P p,zp;
9280: Q dmy;
9281: EPOS oepos;
9282: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
9283: Alg alpha,dp;
9284: P poly;
9285: LIST f1,f2,zpl;
9286: Obj obj;
9287: NumberField nf;
9288: struct order_spec *ord1;
9289: struct oEGT eg_check,eg0,eg1;
9290: NODE tr,tl1,tl2,tl3,tl4;
9291: LIST l1,l2,l3,l4,l5;
9292: int *perm;
9293: int j,ret;
9294: Q jq,bpe;
9295:
9296: nd_module = 0;
9297: parse_nd_option(current_option);
9298: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
9299: if ( nd_vc )
9300: error("nd_f4_lf_trace : computation over a rational function field is not implemented");
9301: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
9302: switch ( ord->id ) {
9303: case 1:
9304: if ( ord->nv != nvar )
9305: error("nd_f4_lf_trace : invalid order specification");
9306: break;
9307: default:
9308: break;
9309: }
9310:
9311: nd_ntrans = nvar;
9312: nd_nalg = 0;
9313:
9314: nocheck = 0;
9315: mindex = 0;
9316:
1.235 noro 9317: /* do not use on-demand load/save */
9318: nd_demand = 0;
1.234 noro 9319: m = trace > 1 ? trace : get_lprime(mindex);
9320: nd_init_ord(ord);
9321: mrank = 0;
9322: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
9323: for ( tv = vv; tv; tv = NEXT(tv) ) {
9324: if ( nd_module ) {
9325: s = BDY((LIST)BDY(t));
9326: trank = length(s);
9327: mrank = MAX(mrank,trank);
9328: for ( ; s; s = NEXT(s) ) {
9329: e = getdeg(tv->v,(P)BDY(s));
9330: max = MAX(e,max);
9331: }
9332: } else {
9333: e = getdeg(tv->v,(P)BDY(t));
9334: max = MAX(e,max);
9335: }
9336: }
9337: nd_setup_parameters(nvar,max);
9338: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
9339: ishomo = 1;
9340: /* XXX */
9341: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
9342: if ( nd_module ) {
9343: c = (pointer)pltondv(CO,vv,(LIST)BDY(t));
9344: } else {
9345: c = (pointer)ptondv(CO,vv,(P)BDY(t));
9346: }
9347: if ( ishomo )
9348: ishomo = ishomo && ndv_ishomo(c);
9349: if ( c ) {
1.247 noro 9350: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
9351: ndv_mod(-2,c);
1.234 noro 9352: NEXTNODE(in0,in); BDY(in) = (pointer)c;
9353: }
9354: }
9355: if ( in0 ) NEXT(in) = 0;
9356: if ( fd0 ) NEXT(fd) = 0;
9357: if ( !ishomo && homo ) {
9358: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
9359: c = (NDV)BDY(t); len = LEN(c);
9360: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
9361: wmax = MAX(TD(DL(a)),wmax);
9362: }
9363: homogenize_order(ord,nvar,&ord1);
9364: nd_init_ord(ord1);
9365: nd_setup_parameters(nvar+1,wmax);
9366: for ( t = fd0; t; t = NEXT(t) )
9367: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
9368: }
9369: if ( MaxDeg > 0 ) nocheck = 1;
1.235 noro 9370: ret = ndv_setup(-2,m,fd0,nd_gbblock?1:0,0);
9371: if ( ret )
9372: cand = nd_f4_lf_trace_main(m,&perm);
9373: if ( !ret || !cand ) {
9374: *rp = 0; return;
9375: }
9376: if ( !ishomo && homo ) {
9377: /* dehomogenization */
9378: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
9379: nd_init_ord(ord);
9380: nd_setup_parameters(nvar,0);
1.234 noro 9381: }
1.235 noro 9382: cand = ndv_reducebase(cand,perm);
9383: cand = ndv_reduceall(-2,cand);
9384: cbpe = nd_bpe;
9385: get_eg(&eg0);
9386: if ( ret = ndv_check_membership(-2,in0,obpe,oadv,oepos,cand) ) {
9387: /* gbcheck : cand is a GB of Id(cand) ? */
9388: ret = nd_f4(-2,0,0);
9389: }
1.245 noro 9390: if ( !ret ) {
1.235 noro 9391: /* failure */
9392: *rp = 0; return;
9393: }
1.234 noro 9394: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
9395: if ( DP_Print )
1.241 noro 9396: fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime+eg_check.gctime);
1.234 noro 9397: /* dp->p */
9398: nd_bpe = cbpe;
9399: nd_setup_parameters(nd_nvar,0);
9400: for ( r = cand; r; r = NEXT(r) ) {
9401: if ( nd_module ) BDY(r) = ndvtopl(-2,CO,vv,BDY(r),mrank);
9402: else BDY(r) = (pointer)ndvtop(-2,CO,vv,BDY(r));
9403: }
9404: MKLIST(*rp,cand);
9405: }
9406:
9407: NODE nd_f4_lf_trace_main(int m,int **indp)
9408: {
9409: int i,nh,stat,index;
9410: NODE r,rm,g;
9411: ND_pairs d,l,l0,t;
9412: ND spol,red;
9413: NDV nf,redv,nfqv,nfv;
9414: NM s0,s;
9415: NODE rp0,srp0,nflist,nflist_lf;
9416: int nsp,nred,col,rank,len,k,j,a;
9417: UINT c;
9418: UINT **spmat;
9419: UINT *s0vect,*svect,*p,*v;
9420: int *colstat;
9421: IndArray *imat;
9422: int *rhead;
9423: int spcol,sprow;
9424: int sugar;
9425: PGeoBucket bucket;
9426: struct oEGT eg0,eg1,eg_f4;
9427:
9428: g = 0; d = 0;
9429: for ( i = 0; i < nd_psn; i++ ) {
9430: d = update_pairs(d,g,i,0);
9431: g = update_base(g,i);
9432: }
9433: while ( d ) {
9434: get_eg(&eg0);
9435: l = nd_minsugarp(d,&d);
9436: sugar = SG(l);
9437: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
9438: bucket = create_pbucket();
9439: stat = nd_sp_f4(m,0,l,bucket);
9440: if ( !stat ) {
9441: for ( t = l; NEXT(t); t = NEXT(t) );
9442: NEXT(t) = d; d = l;
9443: d = nd_reconstruct(1,d);
9444: continue;
9445: }
9446: if ( bucket->m < 0 ) continue;
9447: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
9448: if ( !col ) {
9449: for ( t = l; NEXT(t); t = NEXT(t) );
9450: NEXT(t) = d; d = l;
9451: d = nd_reconstruct(1,d);
9452: continue;
9453: }
9454: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
9455: if ( DP_Print )
1.241 noro 9456: fprintf(asir_out,"sugar=%d,symb=%.3fsec,",
1.234 noro 9457: sugar,eg_f4.exectime+eg_f4.gctime);
9458: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
9459: if ( !l0 ) continue;
9460: l = l0;
9461:
9462: /* over LF */
9463: bucket = create_pbucket();
9464: stat = nd_sp_f4(-2,1,l,bucket);
9465: if ( !stat ) {
9466: for ( t = l; NEXT(t); t = NEXT(t) );
9467: NEXT(t) = d; d = l;
9468: d = nd_reconstruct(1,d);
9469: continue;
9470: }
9471: if ( bucket->m < 0 ) continue;
9472: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
9473: if ( !col ) {
9474: for ( t = l; NEXT(t); t = NEXT(t) );
9475: NEXT(t) = d; d = l;
9476: d = nd_reconstruct(1,d);
9477: continue;
9478: }
9479: nflist_lf = nd_f4_red(-2,l,1,s0vect,col,rp0,0);
9480: /* adding new bases */
9481: for ( rm = nflist, r = nflist_lf; r && rm; rm = NEXT(rm), r = NEXT(r) ) {
9482: nfv = (NDV)BDY(rm);
9483: nfqv = (NDV)BDY(r);
9484: if ( DL_COMPARE(HDL(nfv),HDL(nfqv)) ) return 0;
9485: ndv_removecont(m,nfv);
9486: ndv_removecont(-2,nfqv);
9487: nh = ndv_newps(-2,nfv,nfqv,1);
9488: d = update_pairs(d,g,nh,0);
9489: g = update_base(g,nh);
9490: }
9491: if ( r || rm ) return 0;
9492: }
1.245 noro 9493: conv_ilist(nd_demand,1,g,indp);
1.234 noro 9494: return g;
9495: }
9496:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>