Annotation of OpenXM_contrib2/asir2018/engine/nd.c, Revision 1.55
1.55 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2018/engine/nd.c,v 1.54 2021/10/29 20:50:02 noro Exp $ */
1.1 noro 2:
3: #include "nd.h"
4:
1.45 noro 5: void print_siglist(NODE l);
6:
1.49 noro 7: NODE nd_hpdata;
1.47 noro 8: int Nnd_add,Nf4_red,NcriB,NcriMF,Ncri2,Npairs,Nnewpair;
1.12 noro 9: struct oEGT eg_search,f4_symb,f4_conv,f4_elim1,f4_elim2;
1.1 noro 10:
11: int diag_period = 6;
12: int weight_check = 1;
13: int (*ndl_compare_function)(UINT *a1,UINT *a2);
1.21 noro 14: /* for general module order */
1.19 noro 15: int (*ndl_base_compare_function)(UINT *a1,UINT *a2);
1.21 noro 16: int (*dl_base_compare_function)(int nv,DL a,DL b);
17: int nd_base_ordtype;
1.1 noro 18: int nd_dcomp;
19: int nd_rref2;
20: NM _nm_free_list;
21: ND _nd_free_list;
22: ND_pairs _ndp_free_list;
23: NODE nd_hcf;
1.35 noro 24: int Nsyz,Nsamesig;
1.1 noro 25:
26: Obj nd_top_weight;
27:
28: static NODE nd_subst;
29: static VL nd_vc;
30: static int nd_ntrans;
31: static int nd_nalg;
32: #if 0
33: static int ndv_alloc;
34: #endif
35: #if 1
36: static int nd_f4_nsp=0x7fffffff;
37: #else
38: static int nd_f4_nsp=50;
39: #endif
40: static double nd_scale=2;
41: static UINT **nd_bound;
42: static struct order_spec *nd_ord;
43: static EPOS nd_epos;
44: static BlockMask nd_blockmask;
45: static int nd_nvar;
46: static int nd_isrlex;
47: static int nd_epw,nd_bpe,nd_wpd,nd_exporigin;
48: static UINT nd_mask[32];
49: static UINT nd_mask0,nd_mask1;
50:
51: static NDV *nd_ps;
52: static NDV *nd_ps_trace;
53: static NDV *nd_ps_sym;
54: static NDV *nd_ps_trace_sym;
55: static RHist *nd_psh;
1.30 noro 56: static int nd_psn,nd_pslen,nd_nbase;
1.1 noro 57: static RHist *nd_red;
58: static int *nd_work_vector;
59: static int **nd_matrix;
60: static int nd_matrix_len;
61: static struct weight_or_block *nd_worb;
62: static int nd_worb_len;
63: static int nd_found,nd_create,nd_notfirst;
64: static int nmv_adv;
65: static int nd_demand;
1.21 noro 66: static int nd_module,nd_module_ordtype,nd_mpos,nd_pot_nelim;
1.1 noro 67: static int nd_module_rank,nd_poly_weight_len;
68: static int *nd_poly_weight,*nd_module_weight;
69: static NODE nd_tracelist;
70: static NODE nd_alltracelist;
1.41 noro 71: static int nd_gentrace,nd_gensyz,nd_nora,nd_newelim,nd_intersect,nd_lf,nd_norb;
72: static int nd_f4_td,nd_sba_f4step,nd_sba_pot,nd_sba_largelcm,nd_sba_dontsort,nd_sba_redundant_check;
1.46 noro 73: static int nd_top,nd_sba_syz,nd_sba_inputisgb;
1.1 noro 74: static int *nd_gbblock;
75: static NODE nd_nzlist,nd_check_splist;
76: static int nd_splist;
77: static int *nd_sugarweight;
78: static int nd_f4red,nd_rank0,nd_last_nonzero;
1.27 noro 79: static DL *nd_sba_hm;
1.29 noro 80: static NODE *nd_sba_pos;
1.1 noro 81:
1.46 noro 82: struct comp_sig_spec {
83: int n;
84: // current_i <-> oldv[i]
85: int *oldv;
86: int *weight;
87: struct order_pair *order_pair;
88: int block_length;
89: int **matrix;
90: int row;
91: int (*cmpdl)(int n,DL d1,DL d2);
92: };
93:
94: struct comp_sig_spec *nd_sba_modord;
95:
1.49 noro 96: DL ndltodl(int n,UINT *ndl);
1.1 noro 97: NumberField get_numberfield();
98: UINT *nd_det_compute_bound(NDV **dm,int n,int j);
99: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d);
100: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr);
101: int nd_monic(int m,ND *p);
102: NDV plain_vect_to_ndv_q(Z *mat,int col,UINT *s0vect);
103: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank);
104: NDV pltondv(VL vl,VL dvl,LIST p);
105: void pltozpl(LIST l,Q *cont,LIST *pp);
106: void ndl_max(UINT *d1,unsigned *d2,UINT *d);
107: void nmtodp(int mod,NM m,DP *r);
1.15 noro 108: void ndltodp(UINT *d,DP *r);
1.1 noro 109: NODE reverse_node(NODE n);
110: P ndc_div(int mod,union oNDC a,union oNDC b);
111: P ndctop(int mod,union oNDC c);
112: void finalize_tracelist(int i,P cont);
113: void conv_ilist(int demand,int trace,NODE g,int **indp);
1.46 noro 114: void parse_nd_option(VL vl,NODE opt);
1.1 noro 115: void dltondl(int n,DL dl,UINT *r);
116: DP ndvtodp(int mod,NDV p);
117: DP ndtodp(int mod,ND p);
1.16 noro 118: DPM ndvtodpm(int mod,NDV p);
1.43 noro 119: NDV dptondv(int mod,DP p);
1.16 noro 120: NDV dpmtondv(int mod,DPM p);
1.43 noro 121: int dp_getdeg(DP p);
1.16 noro 122: int dpm_getdeg(DPM p,int *rank);
123: void dpm_ptozp(DPM p,Z *cont,DPM *r);
124: int compdmm(int nv,DMM a,DMM b);
1.44 noro 125: DPM sigtodpm(SIG s);
126: SIG dup_sig(SIG sig);
1.1 noro 127:
128: void Pdp_set_weight(NODE,VECT *);
129: void Pox_cmo_rpc(NODE,Obj *);
130:
131: ND nd_add_lf(ND p1,ND p2);
132: void nd_mul_c_lf(ND p,Z mul);
133: void ndv_mul_c_lf(NDV p,Z mul);
134: NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
135: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz);
136: NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
137: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz);
138: NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
139: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred);
140: int nd_gauss_elim_lf(mpz_t **mat0,int *sugar,int row,int col,int *colstat);
1.40 noro 141: int nd_gauss_elim_mod_s(UINT **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat,SIG *sig);
1.1 noro 142: NODE nd_f4_lf_trace_main(int m,int **indp);
143: void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp);
144:
145: extern int lf_lazy;
146: extern Z current_mod_lf;
147:
148: extern int Denominator,DP_Multiple,MaxDeg;
149:
150: #define BLEN (8*sizeof(unsigned long))
151:
152: typedef struct matrix {
153: int row,col;
154: unsigned long **a;
155: } *matrix;
156:
157:
158: void nd_free_private_storage()
159: {
160: _nm_free_list = 0;
161: _ndp_free_list = 0;
162: #if 0
163: GC_gcollect();
164: #endif
165: }
166:
167: void _NM_alloc()
168: {
169: NM p;
170: int i;
171:
172: for ( i = 0; i < 1024; i++ ) {
173: p = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
174: p->next = _nm_free_list; _nm_free_list = p;
175: }
176: }
177:
178: matrix alloc_matrix(int row,int col)
179: {
180: unsigned long **a;
181: int i,len,blen;
182: matrix mat;
183:
184: mat = (matrix)MALLOC(sizeof(struct matrix));
185: mat->row = row;
186: mat->col = col;
187: mat->a = a = (unsigned long **)MALLOC(row*sizeof(unsigned long *));
188: return mat;
189: }
190:
191:
192: void _ND_alloc()
193: {
194: ND p;
195: int i;
196:
197: for ( i = 0; i < 1024; i++ ) {
198: p = (ND)MALLOC(sizeof(struct oND));
199: p->body = (NM)_nd_free_list; _nd_free_list = p;
200: }
201: }
202:
203: void _NDP_alloc()
204: {
205: ND_pairs p;
206: int i;
207:
208: for ( i = 0; i < 1024; i++ ) {
209: p = (ND_pairs)MALLOC(sizeof(struct oND_pairs)
210: +(nd_wpd-1)*sizeof(UINT));
211: p->next = _ndp_free_list; _ndp_free_list = p;
212: }
213: }
214:
215: INLINE int nd_length(ND p)
216: {
217: NM m;
218: int i;
219:
220: if ( !p )
221: return 0;
222: else {
223: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
224: return i;
225: }
226: }
227:
228: extern int dp_negative_weight;
229:
230: INLINE int ndl_reducible(UINT *d1,UINT *d2)
231: {
232: UINT u1,u2;
233: int i,j;
234:
235: if ( nd_module && (MPOS(d1) != MPOS(d2)) ) return 0;
236:
237: if ( !dp_negative_weight && TD(d1) < TD(d2) ) return 0;
238: #if USE_UNROLL
239: switch ( nd_bpe ) {
240: case 3:
241: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
242: u1 = d1[i]; u2 = d2[i];
243: if ( (u1&0x38000000) < (u2&0x38000000) ) return 0;
244: if ( (u1& 0x7000000) < (u2& 0x7000000) ) return 0;
245: if ( (u1& 0xe00000) < (u2& 0xe00000) ) return 0;
246: if ( (u1& 0x1c0000) < (u2& 0x1c0000) ) return 0;
247: if ( (u1& 0x38000) < (u2& 0x38000) ) return 0;
248: if ( (u1& 0x7000) < (u2& 0x7000) ) return 0;
249: if ( (u1& 0xe00) < (u2& 0xe00) ) return 0;
250: if ( (u1& 0x1c0) < (u2& 0x1c0) ) return 0;
251: if ( (u1& 0x38) < (u2& 0x38) ) return 0;
252: if ( (u1& 0x7) < (u2& 0x7) ) return 0;
253: }
254: return 1;
255: break;
256: case 4:
257: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
258: u1 = d1[i]; u2 = d2[i];
259: if ( (u1&0xf0000000) < (u2&0xf0000000) ) return 0;
260: if ( (u1& 0xf000000) < (u2& 0xf000000) ) return 0;
261: if ( (u1& 0xf00000) < (u2& 0xf00000) ) return 0;
262: if ( (u1& 0xf0000) < (u2& 0xf0000) ) return 0;
263: if ( (u1& 0xf000) < (u2& 0xf000) ) return 0;
264: if ( (u1& 0xf00) < (u2& 0xf00) ) return 0;
265: if ( (u1& 0xf0) < (u2& 0xf0) ) return 0;
266: if ( (u1& 0xf) < (u2& 0xf) ) return 0;
267: }
268: return 1;
269: break;
270: case 6:
271: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
272: u1 = d1[i]; u2 = d2[i];
273: if ( (u1&0x3f000000) < (u2&0x3f000000) ) return 0;
274: if ( (u1& 0xfc0000) < (u2& 0xfc0000) ) return 0;
275: if ( (u1& 0x3f000) < (u2& 0x3f000) ) return 0;
276: if ( (u1& 0xfc0) < (u2& 0xfc0) ) return 0;
277: if ( (u1& 0x3f) < (u2& 0x3f) ) return 0;
278: }
279: return 1;
280: break;
281: case 8:
282: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
283: u1 = d1[i]; u2 = d2[i];
284: if ( (u1&0xff000000) < (u2&0xff000000) ) return 0;
285: if ( (u1& 0xff0000) < (u2& 0xff0000) ) return 0;
286: if ( (u1& 0xff00) < (u2& 0xff00) ) return 0;
287: if ( (u1& 0xff) < (u2& 0xff) ) return 0;
288: }
289: return 1;
290: break;
291: case 16:
292: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
293: u1 = d1[i]; u2 = d2[i];
294: if ( (u1&0xffff0000) < (u2&0xffff0000) ) return 0;
295: if ( (u1& 0xffff) < (u2& 0xffff) ) return 0;
296: }
297: return 1;
298: break;
299: case 32:
300: for ( i = nd_exporigin; i < nd_wpd; i++ )
301: if ( d1[i] < d2[i] ) return 0;
302: return 1;
303: break;
304: default:
305: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
306: u1 = d1[i]; u2 = d2[i];
307: for ( j = 0; j < nd_epw; j++ )
308: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
309: }
310: return 1;
311: }
312: #else
313: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
314: u1 = d1[i]; u2 = d2[i];
315: for ( j = 0; j < nd_epw; j++ )
316: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
317: }
318: return 1;
319: #endif
320: }
321:
322: /*
323: * If the current order is a block order,
324: * then the last block is length 1 and contains
325: * the homo variable. Otherwise, the original
326: * order is either 0 or 2.
327: */
328:
329: void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepos,int ompos,int weight)
330: {
331: int w,i,e,n,omask0;
332:
333: omask0 = obpe==32?0xffffffff:((1<<obpe)-1);
334: n = nd_nvar-1;
335: ndl_zero(r);
336: for ( i = 0; i < n; i++ ) {
337: e = GET_EXP_OLD(d,i);
338: PUT_EXP(r,i,e);
339: }
340: w = TD(d);
341: PUT_EXP(r,nd_nvar-1,weight-w);
342: if ( nd_module ) MPOS(r) = d[ompos];
343: TD(r) = weight;
344: if ( nd_blockmask ) ndl_weight_mask(r);
345: }
346:
347: void ndl_dehomogenize(UINT *d)
348: {
349: UINT mask;
350: UINT h;
351: int i,bits;
352:
353: if ( nd_blockmask ) {
354: h = GET_EXP(d,nd_nvar-1);
355: XOR_EXP(d,nd_nvar-1,h);
356: TD(d) -= h;
357: ndl_weight_mask(d);
358: } else {
359: if ( nd_isrlex ) {
360: if ( nd_bpe == 32 ) {
361: h = d[nd_exporigin];
362: for ( i = nd_exporigin+1; i < nd_wpd; i++ )
363: d[i-1] = d[i];
364: d[i-1] = 0;
365: TD(d) -= h;
366: } else {
367: bits = nd_epw*nd_bpe;
368: mask = bits==32?0xffffffff:((1<<(nd_epw*nd_bpe))-1);
369: h = (d[nd_exporigin]>>((nd_epw-1)*nd_bpe))&nd_mask0;
370: for ( i = nd_exporigin; i < nd_wpd; i++ )
371: d[i] = ((d[i]<<nd_bpe)&mask)
372: |(i+1<nd_wpd?((d[i+1]>>((nd_epw-1)*nd_bpe))&nd_mask0):0);
373: TD(d) -= h;
374: }
375: } else {
376: h = GET_EXP(d,nd_nvar-1);
377: XOR_EXP(d,nd_nvar-1,h);
378: TD(d) -= h;
379: }
380: }
381: }
382:
383: void ndl_lcm(UINT *d1,unsigned *d2,UINT *d)
384: {
385: UINT t1,t2,u,u1,u2;
386: int i,j,l;
387:
388: if ( nd_module && (MPOS(d1) != MPOS(d2)) )
389: error("ndl_lcm : inconsistent monomials");
390: #if USE_UNROLL
391: switch ( nd_bpe ) {
392: case 3:
393: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
394: u1 = d1[i]; u2 = d2[i];
395: t1 = (u1&0x38000000); t2 = (u2&0x38000000); u = t1>t2?t1:t2;
396: t1 = (u1& 0x7000000); t2 = (u2& 0x7000000); u |= t1>t2?t1:t2;
397: t1 = (u1& 0xe00000); t2 = (u2& 0xe00000); u |= t1>t2?t1:t2;
398: t1 = (u1& 0x1c0000); t2 = (u2& 0x1c0000); u |= t1>t2?t1:t2;
399: t1 = (u1& 0x38000); t2 = (u2& 0x38000); u |= t1>t2?t1:t2;
400: t1 = (u1& 0x7000); t2 = (u2& 0x7000); u |= t1>t2?t1:t2;
401: t1 = (u1& 0xe00); t2 = (u2& 0xe00); u |= t1>t2?t1:t2;
402: t1 = (u1& 0x1c0); t2 = (u2& 0x1c0); u |= t1>t2?t1:t2;
403: t1 = (u1& 0x38); t2 = (u2& 0x38); u |= t1>t2?t1:t2;
404: t1 = (u1& 0x7); t2 = (u2& 0x7); u |= t1>t2?t1:t2;
405: d[i] = u;
406: }
407: break;
408: case 4:
409: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
410: u1 = d1[i]; u2 = d2[i];
411: t1 = (u1&0xf0000000); t2 = (u2&0xf0000000); u = t1>t2?t1:t2;
412: t1 = (u1& 0xf000000); t2 = (u2& 0xf000000); u |= t1>t2?t1:t2;
413: t1 = (u1& 0xf00000); t2 = (u2& 0xf00000); u |= t1>t2?t1:t2;
414: t1 = (u1& 0xf0000); t2 = (u2& 0xf0000); u |= t1>t2?t1:t2;
415: t1 = (u1& 0xf000); t2 = (u2& 0xf000); u |= t1>t2?t1:t2;
416: t1 = (u1& 0xf00); t2 = (u2& 0xf00); u |= t1>t2?t1:t2;
417: t1 = (u1& 0xf0); t2 = (u2& 0xf0); u |= t1>t2?t1:t2;
418: t1 = (u1& 0xf); t2 = (u2& 0xf); u |= t1>t2?t1:t2;
419: d[i] = u;
420: }
421: break;
422: case 6:
423: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
424: u1 = d1[i]; u2 = d2[i];
425: t1 = (u1&0x3f000000); t2 = (u2&0x3f000000); u = t1>t2?t1:t2;
426: t1 = (u1& 0xfc0000); t2 = (u2& 0xfc0000); u |= t1>t2?t1:t2;
427: t1 = (u1& 0x3f000); t2 = (u2& 0x3f000); u |= t1>t2?t1:t2;
428: t1 = (u1& 0xfc0); t2 = (u2& 0xfc0); u |= t1>t2?t1:t2;
429: t1 = (u1& 0x3f); t2 = (u2& 0x3f); u |= t1>t2?t1:t2;
430: d[i] = u;
431: }
432: break;
433: case 8:
434: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
435: u1 = d1[i]; u2 = d2[i];
436: t1 = (u1&0xff000000); t2 = (u2&0xff000000); u = t1>t2?t1:t2;
437: t1 = (u1& 0xff0000); t2 = (u2& 0xff0000); u |= t1>t2?t1:t2;
438: t1 = (u1& 0xff00); t2 = (u2& 0xff00); u |= t1>t2?t1:t2;
439: t1 = (u1& 0xff); t2 = (u2& 0xff); u |= t1>t2?t1:t2;
440: d[i] = u;
441: }
442: break;
443: case 16:
444: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
445: u1 = d1[i]; u2 = d2[i];
446: t1 = (u1&0xffff0000); t2 = (u2&0xffff0000); u = t1>t2?t1:t2;
447: t1 = (u1& 0xffff); t2 = (u2& 0xffff); u |= t1>t2?t1:t2;
448: d[i] = u;
449: }
450: break;
451: case 32:
452: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
453: u1 = d1[i]; u2 = d2[i];
454: d[i] = u1>u2?u1:u2;
455: }
456: break;
457: default:
458: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
459: u1 = d1[i]; u2 = d2[i];
460: for ( j = 0, u = 0; j < nd_epw; j++ ) {
461: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
462: }
463: d[i] = u;
464: }
465: break;
466: }
467: #else
468: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
469: u1 = d1[i]; u2 = d2[i];
470: for ( j = 0, u = 0; j < nd_epw; j++ ) {
471: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
472: }
473: d[i] = u;
474: }
475: #endif
476: if ( nd_module ) MPOS(d) = MPOS(d1);
477: TD(d) = ndl_weight(d);
478: if ( nd_blockmask ) ndl_weight_mask(d);
479: }
480:
481: void ndl_max(UINT *d1,unsigned *d2,UINT *d)
482: {
483: UINT t1,t2,u,u1,u2;
484: int i,j,l;
485:
486: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
487: u1 = d1[i]; u2 = d2[i];
488: for ( j = 0, u = 0; j < nd_epw; j++ ) {
489: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
490: }
491: d[i] = u;
492: }
493: }
494:
495: int ndl_weight(UINT *d)
496: {
497: UINT t,u;
498: int i,j;
499:
500: if ( current_dl_weight_vector )
501: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
502: u = GET_EXP(d,i);
503: t += MUL_WEIGHT(u,i);
504: }
505: else
506: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
507: u = d[i];
508: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
509: t += (u&nd_mask0);
510: }
1.20 noro 511: if ( nd_module && nd_module_rank && MPOS(d) )
512: t += nd_module_weight[MPOS(d)-1];
513: for ( i = nd_exporigin; i < nd_wpd; i++ )
514: if ( d[i] && !t )
515: printf("afo\n");
1.1 noro 516: return t;
517: }
518:
519: /* for sugarweight */
520:
521: int ndl_weight2(UINT *d)
522: {
523: int t,u;
524: int i,j;
525:
526: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
527: u = GET_EXP(d,i);
528: t += nd_sugarweight[i]*u;
529: }
1.20 noro 530: if ( nd_module && nd_module_rank && MPOS(d) )
531: t += nd_module_weight[MPOS(d)-1];
1.1 noro 532: return t;
533: }
534:
535: void ndl_weight_mask(UINT *d)
536: {
537: UINT t,u;
538: UINT *mask;
539: int i,j,k,l;
540:
541: l = nd_blockmask->n;
542: for ( k = 0; k < l; k++ ) {
543: mask = nd_blockmask->mask[k];
544: if ( current_dl_weight_vector )
545: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
546: u = GET_EXP_MASK(d,i,mask);
547: t += MUL_WEIGHT(u,i);
548: }
549: else
550: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
551: u = d[i]&mask[i];
552: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
553: t += (u&nd_mask0);
554: }
555: d[k+1] = t;
556: }
557: }
558:
1.21 noro 559: int ndl_glex_compare(UINT *d1,UINT *d2)
560: {
561: if ( TD(d1) > TD(d2) ) return 1;
562: else if ( TD(d1) < TD(d2) ) return -1;
563: else return ndl_lex_compare(d1,d2);
564: }
565:
1.1 noro 566: int ndl_lex_compare(UINT *d1,UINT *d2)
567: {
568: int i;
569:
570: d1 += nd_exporigin;
571: d2 += nd_exporigin;
572: for ( i = nd_exporigin; i < nd_wpd; i++, d1++, d2++ )
573: if ( *d1 > *d2 )
574: return nd_isrlex ? -1 : 1;
575: else if ( *d1 < *d2 )
576: return nd_isrlex ? 1 : -1;
577: return 0;
578: }
579:
580: int ndl_block_compare(UINT *d1,UINT *d2)
581: {
582: int i,l,j,ord_o,ord_l;
583: struct order_pair *op;
584: UINT t1,t2,m;
585: UINT *mask;
586:
587: l = nd_blockmask->n;
588: op = nd_blockmask->order_pair;
589: for ( j = 0; j < l; j++ ) {
590: mask = nd_blockmask->mask[j];
591: ord_o = op[j].order;
592: if ( ord_o < 2 ) {
593: if ( (t1=d1[j+1]) > (t2=d2[j+1]) ) return 1;
594: else if ( t1 < t2 ) return -1;
595: }
596: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
597: m = mask[i];
598: t1 = d1[i]&m;
599: t2 = d2[i]&m;
600: if ( t1 > t2 )
601: return !ord_o ? -1 : 1;
602: else if ( t1 < t2 )
603: return !ord_o ? 1 : -1;
604: }
605: }
606: return 0;
607: }
608:
609: int ndl_matrix_compare(UINT *d1,UINT *d2)
610: {
611: int i,j,s,row;
612: int *v;
613: Z **mat;
614: Z *w;
615: Z t1;
616: Z t,t2;
617:
1.6 noro 618: for ( j = 0; j < nd_nvar; j++ )
619: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
1.1 noro 620: if ( nd_top_weight ) {
621: if ( OID(nd_top_weight) == O_VECT ) {
1.6 noro 622: mat = (Z **)&BDY((VECT)nd_top_weight);
623: row = 1;
1.1 noro 624: } else {
625: mat = (Z **)BDY((MAT)nd_top_weight);
1.6 noro 626: row = ((MAT)nd_top_weight)->row;
1.1 noro 627: }
628: for ( i = 0; i < row; i++ ) {
1.6 noro 629: w = mat[i];
1.1 noro 630: for ( j = 0, t = 0; j < nd_nvar; j++ ) {
1.6 noro 631: STOZ(nd_work_vector[j],t1);
1.1 noro 632: mulz(w[j],t1,&t2);
633: addz(t,t2,&t1);
634: t = t1;
635: }
1.6 noro 636: if ( t ) {
637: s = sgnz(t);
1.1 noro 638: if ( s > 0 ) return 1;
639: else if ( s < 0 ) return -1;
1.6 noro 640: }
1.1 noro 641: }
1.6 noro 642: }
643: for ( i = 0; i < nd_matrix_len; i++ ) {
644: v = nd_matrix[i];
645: for ( j = 0, s = 0; j < nd_nvar; j++ )
646: s += v[j]*nd_work_vector[j];
647: if ( s > 0 ) return 1;
648: else if ( s < 0 ) return -1;
649: }
1.1 noro 650: if ( !ndl_equal(d1,d2) )
1.6 noro 651: error("ndl_matrix_compare : invalid matrix");
652: return 0;
1.1 noro 653: }
654:
655: int ndl_composite_compare(UINT *d1,UINT *d2)
656: {
657: int i,j,s,start,end,len,o;
658: int *v;
659: struct sparse_weight *sw;
660:
661: for ( j = 0; j < nd_nvar; j++ )
662: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
663: for ( i = 0; i < nd_worb_len; i++ ) {
664: len = nd_worb[i].length;
665: switch ( nd_worb[i].type ) {
666: case IS_DENSE_WEIGHT:
667: v = nd_worb[i].body.dense_weight;
668: for ( j = 0, s = 0; j < len; j++ )
669: s += v[j]*nd_work_vector[j];
670: if ( s > 0 ) return 1;
671: else if ( s < 0 ) return -1;
672: break;
673: case IS_SPARSE_WEIGHT:
674: sw = nd_worb[i].body.sparse_weight;
675: for ( j = 0, s = 0; j < len; j++ )
676: s += sw[j].value*nd_work_vector[sw[j].pos];
677: if ( s > 0 ) return 1;
678: else if ( s < 0 ) return -1;
679: break;
680: case IS_BLOCK:
681: o = nd_worb[i].body.block.order;
682: start = nd_worb[i].body.block.start;
683: switch ( o ) {
684: case 0:
685: end = start+len;
686: for ( j = start, s = 0; j < end; j++ )
687: s += MUL_WEIGHT(nd_work_vector[j],j);
688: if ( s > 0 ) return 1;
689: else if ( s < 0 ) return -1;
690: for ( j = end-1; j >= start; j-- )
691: if ( nd_work_vector[j] < 0 ) return 1;
692: else if ( nd_work_vector[j] > 0 ) return -1;
693: break;
694: case 1:
695: end = start+len;
696: for ( j = start, s = 0; j < end; j++ )
697: s += MUL_WEIGHT(nd_work_vector[j],j);
698: if ( s > 0 ) return 1;
699: else if ( s < 0 ) return -1;
700: for ( j = start; j < end; j++ )
701: if ( nd_work_vector[j] > 0 ) return 1;
702: else if ( nd_work_vector[j] < 0 ) return -1;
703: break;
704: case 2:
705: end = start+len;
706: for ( j = start; j < end; j++ )
707: if ( nd_work_vector[j] > 0 ) return 1;
708: else if ( nd_work_vector[j] < 0 ) return -1;
709: break;
710: }
711: break;
712: }
713: }
714: return 0;
715: }
716:
717: /* TDH -> WW -> TD-> RL */
718:
719: int ndl_ww_lex_compare(UINT *d1,UINT *d2)
720: {
721: int i,m,e1,e2;
722:
723: if ( TD(d1) > TD(d2) ) return 1;
724: else if ( TD(d1) < TD(d2) ) return -1;
725: m = nd_nvar>>1;
726: for ( i = 0, e1 = e2 = 0; i < m; i++ ) {
727: e1 += current_weyl_weight_vector[i]*(GET_EXP(d1,m+i)-GET_EXP(d1,i));
728: e2 += current_weyl_weight_vector[i]*(GET_EXP(d2,m+i)-GET_EXP(d2,i));
729: }
730: if ( e1 > e2 ) return 1;
731: else if ( e1 < e2 ) return -1;
732: return ndl_lex_compare(d1,d2);
733: }
734:
1.21 noro 735: // common function for module glex and grlex comparison
736: int ndl_module_glex_compare(UINT *d1,UINT *d2)
1.1 noro 737: {
1.21 noro 738: int c;
1.1 noro 739:
1.21 noro 740: switch ( nd_module_ordtype ) {
741: case 0:
742: if ( TD(d1) > TD(d2) ) return 1;
743: else if ( TD(d1) < TD(d2) ) return -1;
744: else if ( (c = ndl_lex_compare(d1,d2)) != 0 ) return c;
745: else if ( MPOS(d1) < MPOS(d2) ) return 1;
746: else if ( MPOS(d1) > MPOS(d2) ) return -1;
747: else return 0;
748: break;
1.1 noro 749:
1.21 noro 750: case 1:
1.19 noro 751: if ( nd_pot_nelim && MPOS(d1)>=nd_pot_nelim+1 && MPOS(d2) >= nd_pot_nelim+1 ) {
752: if ( TD(d1) > TD(d2) ) return 1;
753: else if ( TD(d1) < TD(d2) ) return -1;
754: if ( (c = ndl_lex_compare(d1,d2)) != 0 ) return c;
755: if ( MPOS(d1) < MPOS(d2) ) return 1;
756: else if ( MPOS(d1) > MPOS(d2) ) return -1;
757: }
758: if ( MPOS(d1) < MPOS(d2) ) return 1;
759: else if ( MPOS(d1) > MPOS(d2) ) return -1;
1.21 noro 760: else if ( TD(d1) > TD(d2) ) return 1;
761: else if ( TD(d1) < TD(d2) ) return -1;
762: else return ndl_lex_compare(d1,d2);
763: break;
1.1 noro 764:
1.21 noro 765: case 2: // weight -> POT
766: if ( TD(d1) > TD(d2) ) return 1;
767: else if ( TD(d1) < TD(d2) ) return -1;
768: else if ( MPOS(d1) < MPOS(d2) ) return 1;
769: else if ( MPOS(d1) > MPOS(d2) ) return -1;
770: else return ndl_lex_compare(d1,d2);
771: break;
1.1 noro 772:
1.21 noro 773: default:
774: error("ndl_module_glex_compare : invalid module_ordtype");
1.28 noro 775: return 0;
1.21 noro 776: }
1.1 noro 777: }
778:
1.21 noro 779: // common for module comparison
780: int ndl_module_compare(UINT *d1,UINT *d2)
1.1 noro 781: {
1.21 noro 782: int c;
1.1 noro 783:
1.21 noro 784: switch ( nd_module_ordtype ) {
785: case 0:
1.23 noro 786: if ( (c = (*ndl_base_compare_function)(d1,d2)) != 0 ) return c;
1.21 noro 787: else if ( MPOS(d1) > MPOS(d2) ) return -1;
788: else if ( MPOS(d1) < MPOS(d2) ) return 1;
789: else return 0;
790: break;
1.1 noro 791:
1.21 noro 792: case 1:
793: if ( MPOS(d1) < MPOS(d2) ) return 1;
794: else if ( MPOS(d1) > MPOS(d2) ) return -1;
795: else return (*ndl_base_compare_function)(d1,d2);
796: break;
1.1 noro 797:
1.21 noro 798: case 2: // weight -> POT
799: if ( TD(d1) > TD(d2) ) return 1;
800: else if ( TD(d1) < TD(d2) ) return -1;
801: else if ( MPOS(d1) < MPOS(d2) ) return 1;
802: else if ( MPOS(d1) > MPOS(d2) ) return -1;
803: else return (*ndl_base_compare_function)(d1,d2);
804: break;
1.1 noro 805:
1.21 noro 806: default:
807: error("ndl_module_compare : invalid module_ordtype");
1.28 noro 808: return 0;
1.21 noro 809: }
1.1 noro 810: }
811:
1.21 noro 812: extern DMMstack dmm_stack;
813: void _addtodl(int n,DL d1,DL d2);
1.31 noro 814: void _adddl(int n,DL d1,DL d2,DL d3);
1.21 noro 815: int _eqdl(int n,DL d1,DL d2);
816:
817: int ndl_module_schreyer_compare(UINT *m1,UINT *m2)
818: {
1.44 noro 819: int pos1,pos2,t,j,retpot;
1.21 noro 820: DMM *in;
821: DMMstack s;
822: static DL d1=0;
823: static DL d2=0;
824: static int dlen=0;
1.44 noro 825: extern int ReversePOT;
1.21 noro 826:
1.44 noro 827: if ( ReversePOT ) retpot = -1;
828: else retpot = 1;
1.21 noro 829: pos1 = MPOS(m1); pos2 = MPOS(m2);
830: if ( pos1 == pos2 ) return (*ndl_base_compare_function)(m1,m2);
831: if ( nd_nvar > dlen ) {
832: NEWDL(d1,nd_nvar);
833: NEWDL(d2,nd_nvar);
834: dlen = nd_nvar;
835: }
836: d1->td = TD(m1);
837: for ( j = 0; j < nd_nvar; j++ ) d1->d[j] = GET_EXP(m1,j);
838: d2->td = TD(m2);
839: for ( j = 0; j < nd_nvar; j++ ) d2->d[j] = GET_EXP(m2,j);
840: for ( s = dmm_stack; s; s = NEXT(s) ) {
841: in = s->in;
842: _addtodl(nd_nvar,in[pos1]->dl,d1);
843: _addtodl(nd_nvar,in[pos2]->dl,d2);
844: if ( in[pos1]->pos == in[pos2]->pos && _eqdl(nd_nvar,d1,d2)) {
1.44 noro 845: if ( pos1 < pos2 ) return retpot;
846: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 847: else return 0;
848: }
849: pos1 = in[pos1]->pos;
850: pos2 = in[pos2]->pos;
851: if ( pos1 == pos2 ) return (*dl_base_compare_function)(nd_nvar,d1,d2);
852: }
853: // comparison by the bottom order
854: LAST:
855: switch ( nd_base_ordtype ) {
856: case 0:
857: t = (*dl_base_compare_function)(nd_nvar,d1,d2);
858: if ( t ) return t;
1.44 noro 859: else if ( pos1 < pos2 ) return retpot;
860: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 861: else return 0;
862: break;
863: case 1:
1.44 noro 864: if ( pos1 < pos2 ) return retpot;
865: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 866: else return (*dl_base_compare_function)(nd_nvar,d1,d2);
867: break;
868: case 2:
869: if ( d1->td > d2->td ) return 1;
870: else if ( d1->td < d2->td ) return -1;
1.44 noro 871: else if ( pos1 < pos2 ) return retpot;
872: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 873: else return (*dl_base_compare_function)(nd_nvar,d1,d2);
874: break;
875: default:
876: error("ndl_schreyer_compare : invalid base ordtype");
1.28 noro 877: return 0;
1.21 noro 878: }
1.1 noro 879: }
880:
881: INLINE int ndl_equal(UINT *d1,UINT *d2)
882: {
883: int i;
884:
885: switch ( nd_wpd ) {
886: case 2:
887: if ( TD(d2) != TD(d1) ) return 0;
888: if ( d2[1] != d1[1] ) return 0;
889: return 1;
890: break;
891: case 3:
892: if ( TD(d2) != TD(d1) ) return 0;
893: if ( d2[1] != d1[1] ) return 0;
894: if ( d2[2] != d1[2] ) return 0;
895: return 1;
896: break;
897: default:
898: for ( i = 0; i < nd_wpd; i++ )
899: if ( *d1++ != *d2++ ) return 0;
900: return 1;
901: break;
902: }
903: }
904:
905: INLINE void ndl_copy(UINT *d1,UINT *d2)
906: {
907: int i;
908:
909: switch ( nd_wpd ) {
910: case 2:
911: TD(d2) = TD(d1);
912: d2[1] = d1[1];
913: break;
914: case 3:
915: TD(d2) = TD(d1);
916: d2[1] = d1[1];
917: d2[2] = d1[2];
918: break;
919: default:
920: for ( i = 0; i < nd_wpd; i++ )
921: d2[i] = d1[i];
922: break;
923: }
924: }
925:
926: INLINE void ndl_zero(UINT *d)
927: {
928: int i;
929: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
930: }
931:
932: INLINE void ndl_add(UINT *d1,UINT *d2,UINT *d)
933: {
934: int i;
935:
936: if ( nd_module ) {
937: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
938: error("ndl_add : invalid operation");
939: }
940: #if 1
941: switch ( nd_wpd ) {
942: case 2:
943: TD(d) = TD(d1)+TD(d2);
944: d[1] = d1[1]+d2[1];
945: break;
946: case 3:
947: TD(d) = TD(d1)+TD(d2);
948: d[1] = d1[1]+d2[1];
949: d[2] = d1[2]+d2[2];
950: break;
951: default:
952: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
953: break;
954: }
955: #else
956: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
957: #endif
958: }
959:
960: /* d1 += d2 */
961: INLINE void ndl_addto(UINT *d1,UINT *d2)
962: {
963: int i;
964:
965: if ( nd_module ) {
966: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
967: error("ndl_addto : invalid operation");
968: }
969: #if 1
970: switch ( nd_wpd ) {
971: case 2:
972: TD(d1) += TD(d2);
973: d1[1] += d2[1];
974: break;
975: case 3:
976: TD(d1) += TD(d2);
977: d1[1] += d2[1];
978: d1[2] += d2[2];
979: break;
980: default:
981: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
982: break;
983: }
984: #else
985: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
986: #endif
987: }
988:
989: INLINE void ndl_sub(UINT *d1,UINT *d2,UINT *d)
990: {
991: int i;
992:
993: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]-d2[i];
994: }
995:
996: int ndl_disjoint(UINT *d1,UINT *d2)
997: {
998: UINT t1,t2,u,u1,u2;
999: int i,j;
1000:
1001: if ( nd_module && (MPOS(d1) == MPOS(d2)) ) return 0;
1002: #if USE_UNROLL
1003: switch ( nd_bpe ) {
1004: case 3:
1005: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1006: u1 = d1[i]; u2 = d2[i];
1007: t1 = u1&0x38000000; t2 = u2&0x38000000; if ( t1&&t2 ) return 0;
1008: t1 = u1& 0x7000000; t2 = u2& 0x7000000; if ( t1&&t2 ) return 0;
1009: t1 = u1& 0xe00000; t2 = u2& 0xe00000; if ( t1&&t2 ) return 0;
1010: t1 = u1& 0x1c0000; t2 = u2& 0x1c0000; if ( t1&&t2 ) return 0;
1011: t1 = u1& 0x38000; t2 = u2& 0x38000; if ( t1&&t2 ) return 0;
1012: t1 = u1& 0x7000; t2 = u2& 0x7000; if ( t1&&t2 ) return 0;
1013: t1 = u1& 0xe00; t2 = u2& 0xe00; if ( t1&&t2 ) return 0;
1014: t1 = u1& 0x1c0; t2 = u2& 0x1c0; if ( t1&&t2 ) return 0;
1015: t1 = u1& 0x38; t2 = u2& 0x38; if ( t1&&t2 ) return 0;
1016: t1 = u1& 0x7; t2 = u2& 0x7; if ( t1&&t2 ) return 0;
1017: }
1018: return 1;
1019: break;
1020: case 4:
1021: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1022: u1 = d1[i]; u2 = d2[i];
1023: t1 = u1&0xf0000000; t2 = u2&0xf0000000; if ( t1&&t2 ) return 0;
1024: t1 = u1& 0xf000000; t2 = u2& 0xf000000; if ( t1&&t2 ) return 0;
1025: t1 = u1& 0xf00000; t2 = u2& 0xf00000; if ( t1&&t2 ) return 0;
1026: t1 = u1& 0xf0000; t2 = u2& 0xf0000; if ( t1&&t2 ) return 0;
1027: t1 = u1& 0xf000; t2 = u2& 0xf000; if ( t1&&t2 ) return 0;
1028: t1 = u1& 0xf00; t2 = u2& 0xf00; if ( t1&&t2 ) return 0;
1029: t1 = u1& 0xf0; t2 = u2& 0xf0; if ( t1&&t2 ) return 0;
1030: t1 = u1& 0xf; t2 = u2& 0xf; if ( t1&&t2 ) return 0;
1031: }
1032: return 1;
1033: break;
1034: case 6:
1035: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1036: u1 = d1[i]; u2 = d2[i];
1037: t1 = u1&0x3f000000; t2 = u2&0x3f000000; if ( t1&&t2 ) return 0;
1038: t1 = u1& 0xfc0000; t2 = u2& 0xfc0000; if ( t1&&t2 ) return 0;
1039: t1 = u1& 0x3f000; t2 = u2& 0x3f000; if ( t1&&t2 ) return 0;
1040: t1 = u1& 0xfc0; t2 = u2& 0xfc0; if ( t1&&t2 ) return 0;
1041: t1 = u1& 0x3f; t2 = u2& 0x3f; if ( t1&&t2 ) return 0;
1042: }
1043: return 1;
1044: break;
1045: case 8:
1046: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1047: u1 = d1[i]; u2 = d2[i];
1048: t1 = u1&0xff000000; t2 = u2&0xff000000; if ( t1&&t2 ) return 0;
1049: t1 = u1& 0xff0000; t2 = u2& 0xff0000; if ( t1&&t2 ) return 0;
1050: t1 = u1& 0xff00; t2 = u2& 0xff00; if ( t1&&t2 ) return 0;
1051: t1 = u1& 0xff; t2 = u2& 0xff; if ( t1&&t2 ) return 0;
1052: }
1053: return 1;
1054: break;
1055: case 16:
1056: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1057: u1 = d1[i]; u2 = d2[i];
1058: t1 = u1&0xffff0000; t2 = u2&0xffff0000; if ( t1&&t2 ) return 0;
1059: t1 = u1& 0xffff; t2 = u2& 0xffff; if ( t1&&t2 ) return 0;
1060: }
1061: return 1;
1062: break;
1063: case 32:
1064: for ( i = nd_exporigin; i < nd_wpd; i++ )
1065: if ( d1[i] && d2[i] ) return 0;
1066: return 1;
1067: break;
1068: default:
1069: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1070: u1 = d1[i]; u2 = d2[i];
1071: for ( j = 0; j < nd_epw; j++ ) {
1072: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
1073: u1 >>= nd_bpe; u2 >>= nd_bpe;
1074: }
1075: }
1076: return 1;
1077: break;
1078: }
1079: #else
1080: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1081: u1 = d1[i]; u2 = d2[i];
1082: for ( j = 0; j < nd_epw; j++ ) {
1083: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
1084: u1 >>= nd_bpe; u2 >>= nd_bpe;
1085: }
1086: }
1087: return 1;
1088: #endif
1089: }
1090:
1091: int ndl_check_bound(UINT *d1,UINT *d2)
1092: {
1093: UINT u2;
1094: int i,j,ind,k;
1095:
1096: ind = 0;
1097: #if USE_UNROLL
1098: switch ( nd_bpe ) {
1099: case 3:
1100: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1101: u2 = d2[i];
1102: if ( d1[ind++]+((u2>>27)&0x7) >= 0x8 ) return 1;
1103: if ( d1[ind++]+((u2>>24)&0x7) >= 0x8 ) return 1;
1104: if ( d1[ind++]+((u2>>21)&0x7) >= 0x8 ) return 1;
1105: if ( d1[ind++]+((u2>>18)&0x7) >= 0x8 ) return 1;
1106: if ( d1[ind++]+((u2>>15)&0x7) >= 0x8 ) return 1;
1107: if ( d1[ind++]+((u2>>12)&0x7) >= 0x8 ) return 1;
1108: if ( d1[ind++]+((u2>>9)&0x7) >= 0x8 ) return 1;
1109: if ( d1[ind++]+((u2>>6)&0x7) >= 0x8 ) return 1;
1110: if ( d1[ind++]+((u2>>3)&0x7) >= 0x8 ) return 1;
1111: if ( d1[ind++]+(u2&0x7) >= 0x8 ) return 1;
1112: }
1113: return 0;
1114: break;
1115: case 4:
1116: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1117: u2 = d2[i];
1118: if ( d1[ind++]+((u2>>28)&0xf) >= 0x10 ) return 1;
1119: if ( d1[ind++]+((u2>>24)&0xf) >= 0x10 ) return 1;
1120: if ( d1[ind++]+((u2>>20)&0xf) >= 0x10 ) return 1;
1121: if ( d1[ind++]+((u2>>16)&0xf) >= 0x10 ) return 1;
1122: if ( d1[ind++]+((u2>>12)&0xf) >= 0x10 ) return 1;
1123: if ( d1[ind++]+((u2>>8)&0xf) >= 0x10 ) return 1;
1124: if ( d1[ind++]+((u2>>4)&0xf) >= 0x10 ) return 1;
1125: if ( d1[ind++]+(u2&0xf) >= 0x10 ) return 1;
1126: }
1127: return 0;
1128: break;
1129: case 6:
1130: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1131: u2 = d2[i];
1132: if ( d1[ind++]+((u2>>24)&0x3f) >= 0x40 ) return 1;
1133: if ( d1[ind++]+((u2>>18)&0x3f) >= 0x40 ) return 1;
1134: if ( d1[ind++]+((u2>>12)&0x3f) >= 0x40 ) return 1;
1135: if ( d1[ind++]+((u2>>6)&0x3f) >= 0x40 ) return 1;
1136: if ( d1[ind++]+(u2&0x3f) >= 0x40 ) return 1;
1137: }
1138: return 0;
1139: break;
1140: case 8:
1141: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1142: u2 = d2[i];
1143: if ( d1[ind++]+((u2>>24)&0xff) >= 0x100 ) return 1;
1144: if ( d1[ind++]+((u2>>16)&0xff) >= 0x100 ) return 1;
1145: if ( d1[ind++]+((u2>>8)&0xff) >= 0x100 ) return 1;
1146: if ( d1[ind++]+(u2&0xff) >= 0x100 ) return 1;
1147: }
1148: return 0;
1149: break;
1150: case 16:
1151: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1152: u2 = d2[i];
1153: if ( d1[ind++]+((u2>>16)&0xffff) > 0x10000 ) return 1;
1154: if ( d1[ind++]+(u2&0xffff) > 0x10000 ) return 1;
1155: }
1156: return 0;
1157: break;
1158: case 32:
1159: for ( i = nd_exporigin; i < nd_wpd; i++ )
1160: if ( d1[i]+d2[i]<d1[i] ) return 1;
1161: return 0;
1162: break;
1163: default:
1164: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1165: u2 = d2[i];
1166: k = (nd_epw-1)*nd_bpe;
1167: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
1168: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1169: }
1170: return 0;
1171: break;
1172: }
1173: #else
1174: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1175: u2 = d2[i];
1176: k = (nd_epw-1)*nd_bpe;
1177: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
1178: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1179: }
1180: return 0;
1181: #endif
1182: }
1183:
1184: int ndl_check_bound2(int index,UINT *d2)
1185: {
1186: return ndl_check_bound(nd_bound[index],d2);
1187: }
1188:
1189: INLINE int ndl_hash_value(UINT *d)
1190: {
1191: int i;
1.11 noro 1192: UINT r;
1.1 noro 1193:
1194: r = 0;
1195: for ( i = 0; i < nd_wpd; i++ )
1.12 noro 1196: r = (r*1511+d[i]);
1.11 noro 1197: r %= REDTAB_LEN;
1.1 noro 1198: return r;
1199: }
1200:
1201: INLINE int ndl_find_reducer(UINT *dg)
1202: {
1203: RHist r;
1204: int d,k,i;
1205:
1206: d = ndl_hash_value(dg);
1207: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1208: if ( ndl_equal(dg,DL(r)) ) {
1209: if ( k > 0 ) nd_notfirst++;
1210: nd_found++;
1211: return r->index;
1212: }
1213: }
1214: if ( Reverse )
1215: for ( i = nd_psn-1; i >= 0; i-- ) {
1216: r = nd_psh[i];
1217: if ( ndl_reducible(dg,DL(r)) ) {
1218: nd_create++;
1219: nd_append_red(dg,i);
1220: return i;
1221: }
1222: }
1223: else
1224: for ( i = 0; i < nd_psn; i++ ) {
1225: r = nd_psh[i];
1226: if ( ndl_reducible(dg,DL(r)) ) {
1227: nd_create++;
1228: nd_append_red(dg,i);
1229: return i;
1230: }
1231: }
1232: return -1;
1233: }
1234:
1.41 noro 1235: INLINE int ndl_find_reducer_nonsig(UINT *dg)
1236: {
1237: RHist r;
1238: int i;
1239:
1240: for ( i = 0; i < nd_psn; i++ ) {
1241: r = nd_psh[i];
1242: if ( ndl_reducible(dg,DL(r)) ) return i;
1243: }
1244: return -1;
1245: }
1246:
1.24 noro 1247: // ret=0,...,nd_psn-1 => reducer found
1248: // ret=nd_psn => reducer not found
1249: // ret=-1 => singular top reducible
1250:
1251: int comp_sig(SIG s1,SIG s2);
1252: void _ndltodl(UINT *ndl,DL dl);
1253:
1254: void print_sig(SIG s)
1255: {
1256: int i;
1257:
1258: fprintf(asir_out,"<<");
1259: for ( i = 0; i < nd_nvar; i++ ) {
1260: fprintf(asir_out,"%d",s->dl->d[i]);
1261: if ( i != nd_nvar-1 ) fprintf(asir_out,",");
1262: }
1263: fprintf(asir_out,">>*e%d",s->pos);
1264: }
1265:
1.45 noro 1266: void print_siglist(NODE l)
1267: {
1268: for ( ; l; l = NEXT(l) )
1269: print_sig((SIG)l->body);
1270: }
1271:
1272:
1.35 noro 1273: // assuming increasing order wrt signature
1274:
1.24 noro 1275: INLINE int ndl_find_reducer_s(UINT *dg,SIG sig)
1276: {
1277: RHist r;
1.27 noro 1278: int i,singular,ret,d,k;
1.26 noro 1279: static int wpd,nvar;
1.24 noro 1280: static SIG quo;
1281: static UINT *tmp;
1282:
1.26 noro 1283: if ( !quo || nvar != nd_nvar ) NEWSIG(quo);
1284: if ( wpd != nd_wpd ) {
1.24 noro 1285: wpd = nd_wpd;
1286: tmp = (UINT *)MALLOC(wpd*sizeof(UINT));
1287: }
1.27 noro 1288: d = ndl_hash_value(dg);
1.35 noro 1289: #if 1
1.27 noro 1290: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1291: if ( ndl_equal(dg,DL(r)) ) {
1292: return r->index;
1293: }
1294: }
1.35 noro 1295: #endif
1.24 noro 1296: singular = 0;
1297: for ( i = 0; i < nd_psn; i++ ) {
1298: r = nd_psh[i];
1299: if ( ndl_reducible(dg,DL(r)) ) {
1.27 noro 1300: ndl_sub(dg,DL(r),tmp);
1.24 noro 1301: _ndltodl(tmp,DL(quo));
1302: _addtodl(nd_nvar,DL(nd_psh[i]->sig),DL(quo));
1303: quo->pos = nd_psh[i]->sig->pos;
1.55 ! noro 1304: _adddl(nd_nvar,DL(quo),nd_sba_hm[quo->pos],DL2(quo));
1.24 noro 1305: ret = comp_sig(sig,quo);
1306: if ( ret > 0 ) { singular = 0; break; }
1.38 noro 1307: if ( ret == 0 ) { /* fprintf(asir_out,"s"); fflush(asir_out); */ singular = 1; }
1.24 noro 1308: }
1309: }
1310: if ( singular ) return -1;
1.27 noro 1311: else if ( i < nd_psn )
1312: nd_append_red(dg,i);
1313: return i;
1.24 noro 1314: }
1315:
1.1 noro 1316: ND nd_merge(ND p1,ND p2)
1317: {
1318: int n,c;
1319: int t,can,td1,td2;
1320: ND r;
1321: NM m1,m2,mr0,mr,s;
1322:
1323: if ( !p1 ) return p2;
1324: else if ( !p2 ) return p1;
1325: else {
1326: can = 0;
1327: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1328: c = DL_COMPARE(DL(m1),DL(m2));
1329: switch ( c ) {
1330: case 0:
1331: s = m1; m1 = NEXT(m1);
1332: can++; NEXTNM2(mr0,mr,s);
1333: s = m2; m2 = NEXT(m2); FREENM(s);
1334: break;
1335: case 1:
1336: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1337: break;
1338: case -1:
1339: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1340: break;
1341: }
1342: }
1343: if ( !mr0 )
1344: if ( m1 ) mr0 = m1;
1345: else if ( m2 ) mr0 = m2;
1346: else return 0;
1347: else if ( m1 ) NEXT(mr) = m1;
1348: else if ( m2 ) NEXT(mr) = m2;
1349: else NEXT(mr) = 0;
1350: BDY(p1) = mr0;
1351: SG(p1) = MAX(SG(p1),SG(p2));
1352: LEN(p1) = LEN(p1)+LEN(p2)-can;
1353: FREEND(p2);
1354: return p1;
1355: }
1356: }
1357:
1358: ND nd_add(int mod,ND p1,ND p2)
1359: {
1360: int n,c;
1361: int t,can,td1,td2;
1362: ND r;
1363: NM m1,m2,mr0,mr,s;
1364:
1.11 noro 1365: Nnd_add++;
1.1 noro 1366: if ( !p1 ) return p2;
1367: else if ( !p2 ) return p1;
1368: else if ( mod == -1 ) return nd_add_sf(p1,p2);
1369: else if ( mod == -2 ) return nd_add_lf(p1,p2);
1370: else if ( !mod ) return nd_add_q(p1,p2);
1371: else {
1372: can = 0;
1373: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1374: c = DL_COMPARE(DL(m1),DL(m2));
1375: switch ( c ) {
1376: case 0:
1377: t = ((CM(m1))+(CM(m2))) - mod;
1378: if ( t < 0 ) t += mod;
1379: s = m1; m1 = NEXT(m1);
1380: if ( t ) {
1381: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1382: } else {
1383: can += 2; FREENM(s);
1384: }
1385: s = m2; m2 = NEXT(m2); FREENM(s);
1386: break;
1387: case 1:
1388: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1389: break;
1390: case -1:
1391: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1392: break;
1393: }
1394: }
1395: if ( !mr0 )
1396: if ( m1 ) mr0 = m1;
1397: else if ( m2 ) mr0 = m2;
1398: else return 0;
1399: else if ( m1 ) NEXT(mr) = m1;
1400: else if ( m2 ) NEXT(mr) = m2;
1401: else NEXT(mr) = 0;
1402: BDY(p1) = mr0;
1403: SG(p1) = MAX(SG(p1),SG(p2));
1404: LEN(p1) = LEN(p1)+LEN(p2)-can;
1405: FREEND(p2);
1406: return p1;
1407: }
1408: }
1409:
1410: /* XXX on opteron, the inlined manipulation of destructive additon of
1411: * two NM seems to make gcc optimizer get confused, so the part is
1412: * done in a function.
1413: */
1414:
1415: int nm_destructive_add_q(NM *m1,NM *m2,NM *mr0,NM *mr)
1416: {
1417: NM s;
1418: P t;
1419: int can;
1420:
1421: addp(nd_vc,CP(*m1),CP(*m2),&t);
1422: s = *m1; *m1 = NEXT(*m1);
1423: if ( t ) {
1424: can = 1; NEXTNM2(*mr0,*mr,s); CP(*mr) = (t);
1425: } else {
1426: can = 2; FREENM(s);
1427: }
1428: s = *m2; *m2 = NEXT(*m2); FREENM(s);
1429: return can;
1430: }
1431:
1432: ND nd_add_q(ND p1,ND p2)
1433: {
1434: int n,c,can;
1435: ND r;
1436: NM m1,m2,mr0,mr,s;
1437: P t;
1438:
1439: if ( !p1 ) return p2;
1440: else if ( !p2 ) return p1;
1441: else {
1442: can = 0;
1443: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1444: c = DL_COMPARE(DL(m1),DL(m2));
1445: switch ( c ) {
1446: case 0:
1447: #if defined(__x86_64__)
1448: can += nm_destructive_add_q(&m1,&m2,&mr0,&mr);
1449: #else
1450: addp(nd_vc,CP(m1),CP(m2),&t);
1451: s = m1; m1 = NEXT(m1);
1452: if ( t ) {
1453: can++; NEXTNM2(mr0,mr,s); CP(mr) = (t);
1454: } else {
1455: can += 2; FREENM(s);
1456: }
1457: s = m2; m2 = NEXT(m2); FREENM(s);
1458: #endif
1459: break;
1460: case 1:
1461: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1462: break;
1463: case -1:
1464: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1465: break;
1466: }
1467: }
1468: if ( !mr0 )
1469: if ( m1 ) mr0 = m1;
1470: else if ( m2 ) mr0 = m2;
1471: else return 0;
1472: else if ( m1 ) NEXT(mr) = m1;
1473: else if ( m2 ) NEXT(mr) = m2;
1474: else NEXT(mr) = 0;
1475: BDY(p1) = mr0;
1476: SG(p1) = MAX(SG(p1),SG(p2));
1477: LEN(p1) = LEN(p1)+LEN(p2)-can;
1478: FREEND(p2);
1479: return p1;
1480: }
1481: }
1482:
1483: ND nd_add_sf(ND p1,ND p2)
1484: {
1485: int n,c,can;
1486: ND r;
1487: NM m1,m2,mr0,mr,s;
1488: int t;
1489:
1490: if ( !p1 ) return p2;
1491: else if ( !p2 ) return p1;
1492: else {
1493: can = 0;
1494: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1495: c = DL_COMPARE(DL(m1),DL(m2));
1496: switch ( c ) {
1497: case 0:
1498: t = _addsf(CM(m1),CM(m2));
1499: s = m1; m1 = NEXT(m1);
1500: if ( t ) {
1501: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1502: } else {
1503: can += 2; FREENM(s);
1504: }
1505: s = m2; m2 = NEXT(m2); FREENM(s);
1506: break;
1507: case 1:
1508: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1509: break;
1510: case -1:
1511: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1512: break;
1513: }
1514: }
1515: if ( !mr0 )
1516: if ( m1 ) mr0 = m1;
1517: else if ( m2 ) mr0 = m2;
1518: else return 0;
1519: else if ( m1 ) NEXT(mr) = m1;
1520: else if ( m2 ) NEXT(mr) = m2;
1521: else NEXT(mr) = 0;
1522: BDY(p1) = mr0;
1523: SG(p1) = MAX(SG(p1),SG(p2));
1524: LEN(p1) = LEN(p1)+LEN(p2)-can;
1525: FREEND(p2);
1526: return p1;
1527: }
1528: }
1529:
1530:
1531: ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp)
1532: {
1533: int c,c1,c2;
1534: Z cg,cred,gcd,tq;
1535: P cgp,credp,gcdp;
1536: Obj tr,tr1;
1537:
1538: if ( mod == -1 ) {
1539: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1540: *divp = (Obj)ONE;
1541: } else if ( mod == -2 ) {
1542: Z inv,t;
1543: divlf(ONE,HCZ(p),&inv);
1544: chsgnlf(HCZ(g),&t);
1545: mullf(inv,t,&CZ(mul));
1546: *divp = (Obj)ONE;
1547: } else if ( mod ) {
1548: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1549: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1550: *divp = (Obj)ONE;
1551: } else if ( nd_vc ) {
1552: ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp);
1553: divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp);
1554: chsgnp(cgp,&CP(mul));
1555: nd_mul_c_q(d,credp); nd_mul_c_q(g,credp);
1556: if ( dn ) {
1557: mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr);
1558: reductr(nd_vc,tr,&tr1); dn->r = (R)tr1;
1559: }
1560: *divp = (Obj)credp;
1561: } else {
1.6 noro 1562: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1563: chsgnz(cg,&CZ(mul));
1.1 noro 1564: nd_mul_c_q(d,(P)cred); nd_mul_c_q(g,(P)cred);
1565: if ( dn ) {
1566: mulz(dn->z,cred,&tq); dn->z = tq;
1567: }
1568: *divp = (Obj)cred;
1569: }
1570: return nd_add(mod,g,ndv_mul_nm(mod,mul,p));
1571: }
1572:
1573: /* ret=1 : success, ret=0 : overflow */
1.6 noro 1574: int nd_nf(int mod,ND d,ND g,NDV *ps,int full,ND *rp)
1.1 noro 1575: {
1576: NM m,mrd,tail;
1577: NM mul;
1578: int n,sugar,psugar,sugar0,stat,index;
1579: int c,c1,c2,dummy;
1580: RHist h;
1581: NDV p,red;
1582: Q cg,cred,gcd,tq,qq;
1583: Z iq;
1584: DP dmul;
1585: NODE node;
1586: LIST hist;
1587: double hmag;
1588: P tp,tp1;
1589: Obj tr,tr1,div;
1590: union oNDC hg;
1591: P cont;
1592:
1593: if ( !g ) {
1594: *rp = d;
1595: return 1;
1596: }
1597: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1598:
1599: sugar0 = sugar = SG(g);
1600: n = NV(g);
1601: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1602: if ( d )
1603: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1604: for ( ; g; ) {
1605: index = ndl_find_reducer(HDL(g));
1606: if ( index >= 0 ) {
1607: h = nd_psh[index];
1608: ndl_sub(HDL(g),DL(h),DL(mul));
1609: if ( ndl_check_bound2(index,DL(mul)) ) {
1610: nd_free(g); nd_free(d);
1611: return 0;
1612: }
1613: p = nd_demand ? ndv_load(index) : ps[index];
1614: /* d+g -> div*(d+g)+mul*p */
1.6 noro 1615: g = nd_reduce2(mod,d,g,p,mul,0,&div);
1.1 noro 1616: if ( nd_gentrace ) {
1617: /* Trace=[div,index,mul,ONE] */
1.6 noro 1618: STOZ(index,iq);
1.1 noro 1619: nmtodp(mod,mul,&dmul);
1620: node = mknode(4,div,iq,dmul,ONE);
1621: }
1622: sugar = MAX(sugar,SG(p)+TD(DL(mul)));
1623: if ( !mod && g && !nd_vc && ((double)(p_mag(HCP(g))) > hmag) ) {
1624: hg = HCU(g);
1625: nd_removecont2(d,g);
1.6 noro 1626: if ( nd_gentrace ) {
1.1 noro 1627: /* overwrite cont : Trace=[div,index,mul,cont] */
1.6 noro 1628: /* exact division */
1.1 noro 1629: cont = ndc_div(mod,hg,HCU(g));
1630: if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont;
1631: }
1632: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1633: }
1634: MKLIST(hist,node);
1635: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1636: } else if ( !full ) {
1637: *rp = g;
1638: return 1;
1639: } else {
1640: m = BDY(g);
1641: if ( NEXT(m) ) {
1642: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1643: } else {
1644: FREEND(g); g = 0;
1645: }
1646: if ( d ) {
1647: NEXT(tail)=m; tail=m; LEN(d)++;
1648: } else {
1649: MKND(n,m,1,d); tail = BDY(d);
1650: }
1651: }
1652: }
1653: if ( d ) SG(d) = sugar;
1654: *rp = d;
1655: return 1;
1656: }
1657:
1.24 noro 1658: // ret=1 => success
1659: // ret=0 => overflow
1660: // ret=-1 => singular top reducible
1661:
1662: int nd_nf_s(int mod,ND d,ND g,NDV *ps,int full,ND *rp)
1663: {
1664: NM m,mrd,tail;
1665: NM mul;
1666: int n,sugar,psugar,sugar0,stat,index;
1667: int c,c1,c2,dummy;
1668: RHist h;
1669: NDV p,red;
1670: Q cg,cred,gcd,tq,qq;
1671: Z iq;
1672: DP dmul;
1673: NODE node;
1674: LIST hist;
1675: double hmag;
1676: P tp,tp1;
1677: Obj tr,tr1,div;
1678: union oNDC hg;
1679: P cont;
1680: SIG sig;
1681:
1682: if ( !g ) {
1683: *rp = d;
1684: return 1;
1685: }
1686: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1687:
1688: sugar0 = sugar = SG(g);
1689: n = NV(g);
1690: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1691: if ( d )
1692: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1693: sig = g->sig;
1694: for ( ; g; ) {
1695: index = ndl_find_reducer_s(HDL(g),sig);
1696: if ( index >= 0 && index < nd_psn ) {
1697: // reducer found
1698: h = nd_psh[index];
1699: ndl_sub(HDL(g),DL(h),DL(mul));
1700: if ( ndl_check_bound2(index,DL(mul)) ) {
1701: nd_free(g); nd_free(d);
1702: return 0;
1703: }
1704: p = ps[index];
1705: /* d+g -> div*(d+g)+mul*p */
1706: g = nd_reduce2(mod,d,g,p,mul,0,&div);
1707: sugar = MAX(sugar,SG(p)+TD(DL(mul)));
1708: if ( !mod && g && ((double)(p_mag(HCP(g))) > hmag) ) {
1709: hg = HCU(g);
1710: nd_removecont2(d,g);
1711: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1712: }
1.55 ! noro 1713: if ( nd_gentrace ) {
! 1714: /* Trace=[div,index,mul,ONE] */
! 1715: STOZ(index,iq);
! 1716: nmtodp(mod,mul,&dmul);
! 1717: node = mknode(4,div,iq,dmul,ONE);
! 1718: }
! 1719: MKLIST(hist,node);
! 1720: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1.24 noro 1721: } else if ( index == -1 ) {
1722: // singular top reducible
1723: return -1;
1724: } else if ( !full ) {
1725: *rp = g;
1726: g->sig = sig;
1727: return 1;
1728: } else {
1729: m = BDY(g);
1730: if ( NEXT(m) ) {
1731: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1732: } else {
1733: FREEND(g); g = 0;
1734: }
1735: if ( d ) {
1736: NEXT(tail)=m; tail=m; LEN(d)++;
1737: } else {
1738: MKND(n,m,1,d); tail = BDY(d);
1739: }
1740: }
1741: }
1742: if ( d ) {
1743: SG(d) = sugar;
1744: d->sig = sig;
1745: }
1746: *rp = d;
1747: return 1;
1748: }
1749:
1.1 noro 1750: int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp)
1751: {
1752: int hindex,index;
1753: NDV p;
1754: ND u,d,red;
1755: NODE l;
1756: NM mul,m,mrd,tail;
1757: int sugar,psugar,n,h_reducible;
1758: PGeoBucket bucket;
1759: int c,c1,c2;
1760: Z cg,cred,gcd,zzz;
1761: RHist h;
1762: double hmag,gmag;
1763: int count = 0;
1764: int hcount = 0;
1765:
1766: if ( !g ) {
1767: *rp = 0;
1768: return 1;
1769: }
1770: sugar = SG(g);
1771: n = NV(g);
1.6 noro 1772: if ( !mod ) hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1.1 noro 1773: bucket = create_pbucket();
1774: add_pbucket(mod,bucket,g);
1775: d = 0;
1776: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1777: while ( 1 ) {
1778: if ( mod > 0 || mod == -1 )
1779: hindex = head_pbucket(mod,bucket);
1780: else if ( mod == -2 )
1781: hindex = head_pbucket_lf(bucket);
1782: else
1783: hindex = head_pbucket_q(bucket);
1784: if ( hindex < 0 ) {
1785: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1786: if ( d ) SG(d) = sugar;
1787: *rp = d;
1788: return 1;
1789: }
1790: g = bucket->body[hindex];
1791: index = ndl_find_reducer(HDL(g));
1792: if ( index >= 0 ) {
1793: count++;
1794: if ( !d ) hcount++;
1795: h = nd_psh[index];
1796: ndl_sub(HDL(g),DL(h),DL(mul));
1797: if ( ndl_check_bound2(index,DL(mul)) ) {
1798: nd_free(d);
1799: free_pbucket(bucket);
1800: *rp = 0;
1801: return 0;
1802: }
1803: p = ps[index];
1804: if ( mod == -1 )
1805: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1806: else if ( mod == -2 ) {
1807: Z inv,t;
1808: divlf(ONE,HCZ(p),&inv);
1809: chsgnlf(HCZ(g),&t);
1810: mullf(inv,t,&CZ(mul));
1811: } else if ( mod ) {
1812: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1813: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1814: } else {
1.6 noro 1815: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1816: chsgnz(cg,&CZ(mul));
1.1 noro 1817: nd_mul_c_q(d,(P)cred);
1818: mulq_pbucket(bucket,cred);
1819: g = bucket->body[hindex];
1.6 noro 1820: gmag = (double)p_mag((P)HCZ(g));
1.1 noro 1821: }
1822: red = ndv_mul_nm(mod,mul,p);
1823: bucket->body[hindex] = nd_remove_head(g);
1824: red = nd_remove_head(red);
1825: add_pbucket(mod,bucket,red);
1826: psugar = SG(p)+TD(DL(mul));
1827: sugar = MAX(sugar,psugar);
1828: if ( !mod && hmag && (gmag > hmag) ) {
1829: g = normalize_pbucket(mod,bucket);
1830: if ( !g ) {
1831: if ( d ) SG(d) = sugar;
1832: *rp = d;
1833: return 1;
1834: }
1835: nd_removecont2(d,g);
1.6 noro 1836: hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1.1 noro 1837: add_pbucket(mod,bucket,g);
1838: }
1839: } else if ( !full ) {
1840: g = normalize_pbucket(mod,bucket);
1841: if ( g ) SG(g) = sugar;
1842: *rp = g;
1843: return 1;
1844: } else {
1845: m = BDY(g);
1846: if ( NEXT(m) ) {
1847: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1848: } else {
1849: FREEND(g); g = 0;
1850: }
1851: bucket->body[hindex] = g;
1852: NEXT(m) = 0;
1853: if ( d ) {
1854: NEXT(tail)=m; tail=m; LEN(d)++;
1855: } else {
1856: MKND(n,m,1,d); tail = BDY(d);
1857: }
1858: }
1859: }
1860: }
1861:
1.25 noro 1862: int nd_nf_pbucket_s(int mod,ND g,NDV *ps,int full,ND *rp)
1863: {
1864: int hindex,index;
1865: NDV p;
1866: ND u,d,red;
1867: NODE l;
1868: NM mul,m,mrd,tail;
1869: int sugar,psugar,n,h_reducible;
1870: PGeoBucket bucket;
1871: int c,c1,c2;
1872: Z cg,cred,gcd,zzz;
1873: RHist h;
1874: double hmag,gmag;
1875: int count = 0;
1876: int hcount = 0;
1877: SIG sig;
1878:
1879: if ( !g ) {
1880: *rp = 0;
1881: return 1;
1882: }
1883: sugar = SG(g);
1884: n = NV(g);
1885: if ( !mod ) hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1886: bucket = create_pbucket();
1887: add_pbucket(mod,bucket,g);
1888: d = 0;
1889: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1890: sig = g->sig;
1891: while ( 1 ) {
1892: if ( mod > 0 || mod == -1 )
1893: hindex = head_pbucket(mod,bucket);
1894: else if ( mod == -2 )
1895: hindex = head_pbucket_lf(bucket);
1896: else
1897: hindex = head_pbucket_q(bucket);
1898: if ( hindex < 0 ) {
1899: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1900: if ( d ) {
1901: SG(d) = sugar;
1902: d->sig = sig;
1903: }
1904: *rp = d;
1905: return 1;
1906: }
1907: g = bucket->body[hindex];
1908: index = ndl_find_reducer_s(HDL(g),sig);
1909: if ( index >= 0 && index < nd_psn ) {
1910: count++;
1911: if ( !d ) hcount++;
1912: h = nd_psh[index];
1913: ndl_sub(HDL(g),DL(h),DL(mul));
1914: if ( ndl_check_bound2(index,DL(mul)) ) {
1915: nd_free(d);
1916: free_pbucket(bucket);
1917: *rp = 0;
1918: return 0;
1919: }
1920: p = ps[index];
1921: if ( mod == -1 )
1922: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1923: else if ( mod == -2 ) {
1924: Z inv,t;
1925: divlf(ONE,HCZ(p),&inv);
1926: chsgnlf(HCZ(g),&t);
1927: mullf(inv,t,&CZ(mul));
1928: } else if ( mod ) {
1929: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1930: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1931: } else {
1932: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1933: chsgnz(cg,&CZ(mul));
1934: nd_mul_c_q(d,(P)cred);
1935: mulq_pbucket(bucket,cred);
1936: g = bucket->body[hindex];
1937: gmag = (double)p_mag((P)HCZ(g));
1938: }
1939: red = ndv_mul_nm(mod,mul,p);
1940: bucket->body[hindex] = nd_remove_head(g);
1941: red = nd_remove_head(red);
1942: add_pbucket(mod,bucket,red);
1943: psugar = SG(p)+TD(DL(mul));
1944: sugar = MAX(sugar,psugar);
1945: if ( !mod && hmag && (gmag > hmag) ) {
1946: g = normalize_pbucket(mod,bucket);
1947: if ( !g ) {
1948: if ( d ) {
1949: SG(d) = sugar;
1950: d->sig = sig;
1951: }
1952: *rp = d;
1953: return 1;
1954: }
1955: nd_removecont2(d,g);
1956: hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1957: add_pbucket(mod,bucket,g);
1958: }
1959: } else if ( index == -1 ) {
1960: // singular top reducible
1961: return -1;
1962: } else if ( !full ) {
1963: g = normalize_pbucket(mod,bucket);
1964: if ( g ) {
1965: SG(g) = sugar;
1966: g->sig = sig;
1967: }
1968: *rp = g;
1969: return 1;
1970: } else {
1971: m = BDY(g);
1972: if ( NEXT(m) ) {
1973: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1974: } else {
1975: FREEND(g); g = 0;
1976: }
1977: bucket->body[hindex] = g;
1978: NEXT(m) = 0;
1979: if ( d ) {
1980: NEXT(tail)=m; tail=m; LEN(d)++;
1981: } else {
1982: MKND(n,m,1,d); tail = BDY(d);
1983: }
1984: }
1985: }
1986: }
1987:
1.1 noro 1988: /* input : list of NDV, cand : list of NDV */
1989:
1990: int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand)
1991: {
1992: int n,i,stat;
1993: ND nf,d;
1994: NDV r;
1995: NODE t,s;
1996: union oNDC dn;
1997: Z q;
1998: LIST list;
1999:
1.24 noro 2000: ndv_setup(m,0,cand,nd_gentrace?1:0,1,0);
1.1 noro 2001: n = length(cand);
2002:
2003: if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; }
2004: /* membercheck : list is a subset of Id(cand) ? */
2005: for ( t = input, i = 0; t; t = NEXT(t), i++ ) {
2006: again:
2007: nd_tracelist = 0;
2008: if ( nd_bpe > obpe )
2009: r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos);
2010: else
2011: r = (NDV)BDY(t);
2012: #if 0
2013: // moved to nd_f4_lf_trace()
2014: if ( m == -2 ) ndv_mod(m,r);
2015: #endif
2016: d = ndvtond(m,r);
1.6 noro 2017: stat = nd_nf(m,0,d,nd_ps,0,&nf);
1.1 noro 2018: if ( !stat ) {
2019: nd_reconstruct(0,0);
2020: goto again;
2021: } else if ( nf ) return 0;
2022: if ( nd_gentrace ) {
2023: nd_tracelist = reverse_node(nd_tracelist);
2024: MKLIST(list,nd_tracelist);
1.6 noro 2025: STOZ(i,q); s = mknode(2,q,list); MKLIST(list,s);
1.1 noro 2026: MKNODE(s,list,nd_alltracelist);
2027: nd_alltracelist = s; nd_tracelist = 0;
2028: }
2029: if ( DP_Print ) { printf("."); fflush(stdout); }
2030: }
2031: if ( DP_Print ) { printf("\n"); }
2032: return 1;
2033: }
2034:
2035: ND nd_remove_head(ND p)
2036: {
2037: NM m;
2038:
2039: m = BDY(p);
2040: if ( !NEXT(m) ) {
2041: FREEND(p); p = 0;
2042: } else {
2043: BDY(p) = NEXT(m); LEN(p)--;
2044: }
2045: FREENM(m);
2046: return p;
2047: }
2048:
2049: ND nd_separate_head(ND p,ND *head)
2050: {
2051: NM m,m0;
2052: ND r;
2053:
2054: m = BDY(p);
2055: if ( !NEXT(m) ) {
2056: *head = p; p = 0;
2057: } else {
2058: m0 = m;
2059: BDY(p) = NEXT(m); LEN(p)--;
2060: NEXT(m0) = 0;
2061: MKND(NV(p),m0,1,r);
2062: *head = r;
2063: }
2064: return p;
2065: }
2066:
2067: PGeoBucket create_pbucket()
2068: {
2069: PGeoBucket g;
2070:
2071: g = CALLOC(1,sizeof(struct oPGeoBucket));
2072: g->m = -1;
2073: return g;
2074: }
2075:
2076: void free_pbucket(PGeoBucket b) {
2077: int i;
2078:
2079: for ( i = 0; i <= b->m; i++ )
2080: if ( b->body[i] ) {
2081: nd_free(b->body[i]);
2082: b->body[i] = 0;
2083: }
2084: GCFREE(b);
2085: }
2086:
1.39 noro 2087: #if 0
1.1 noro 2088: void add_pbucket_symbolic(PGeoBucket g,ND d)
2089: {
2090: int l,i,k,m;
2091:
2092: if ( !d )
2093: return;
2094: l = LEN(d);
2095: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2096: /* 2^(k-1) < l <= 2^k (=m) */
2097: d = nd_merge(g->body[k],d);
2098: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
2099: g->body[k] = 0;
2100: d = nd_merge(g->body[k+1],d);
2101: }
2102: g->body[k] = d;
2103: g->m = MAX(g->m,k);
2104: }
1.39 noro 2105: #else
2106: void add_pbucket_symbolic(PGeoBucket g,ND d)
2107: {
2108: int l,i,k,m,m0;
2109:
2110: if ( !d )
2111: return;
2112: m0 = g->m;
2113: while ( 1 ) {
2114: l = LEN(d);
2115: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2116: /* 2^(k-1) < l <= 2^k (=m) */
2117: if ( g->body[k] == 0 ) {
2118: g->body[k] = d;
2119: m0 = MAX(k,m0);
2120: break;
2121: } else {
2122: d = nd_merge(g->body[k],d);
2123: g->body[k] = 0;
2124: }
2125: }
2126: g->m = m0;
2127: }
2128: #endif
1.1 noro 2129:
1.39 noro 2130: #if 0
1.1 noro 2131: void add_pbucket(int mod,PGeoBucket g,ND d)
2132: {
2133: int l,i,k,m;
2134:
2135: if ( !d )
2136: return;
2137: l = LEN(d);
2138: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2139: /* 2^(k-1) < l <= 2^k (=m) */
2140: d = nd_add(mod,g->body[k],d);
2141: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
2142: g->body[k] = 0;
2143: d = nd_add(mod,g->body[k+1],d);
2144: }
2145: g->body[k] = d;
2146: g->m = MAX(g->m,k);
2147: }
1.39 noro 2148: #else
2149: void add_pbucket(int mod,PGeoBucket g,ND d)
2150: {
2151: int l,i,k,m,m0;
2152:
2153: m0 = g->m;
2154: while ( d != 0 ) {
2155: l = LEN(d);
2156: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2157: /* 2^(k-1) < l <= 2^k (=m) */
2158: if ( g->body[k] == 0 ) {
2159: g->body[k] = d;
2160: m0 = MAX(k,m0);
2161: break;
2162: } else {
2163: d = nd_add(mod,g->body[k],d);
2164: g->body[k] = 0;
2165: }
2166: }
2167: g->m = m0;
2168: }
2169: #endif
1.1 noro 2170:
2171: void mulq_pbucket(PGeoBucket g,Z c)
2172: {
2173: int k;
2174:
2175: for ( k = 0; k <= g->m; k++ )
2176: nd_mul_c_q(g->body[k],(P)c);
2177: }
2178:
2179: NM remove_head_pbucket_symbolic(PGeoBucket g)
2180: {
2181: int j,i,k,c;
2182: NM head;
2183:
2184: k = g->m;
2185: j = -1;
2186: for ( i = 0; i <= k; i++ ) {
2187: if ( !g->body[i] ) continue;
2188: if ( j < 0 ) j = i;
2189: else {
2190: c = DL_COMPARE(HDL(g->body[i]),HDL(g->body[j]));
2191: if ( c > 0 )
2192: j = i;
2193: else if ( c == 0 )
2194: g->body[i] = nd_remove_head(g->body[i]);
2195: }
2196: }
2197: if ( j < 0 ) return 0;
2198: else {
2199: head = BDY(g->body[j]);
2200: if ( !NEXT(head) ) {
2201: FREEND(g->body[j]);
2202: g->body[j] = 0;
2203: } else {
2204: BDY(g->body[j]) = NEXT(head);
2205: LEN(g->body[j])--;
2206: }
2207: return head;
2208: }
2209: }
2210:
2211: int head_pbucket(int mod,PGeoBucket g)
2212: {
2213: int j,i,c,k,nv,sum;
2214: UINT *di,*dj;
2215: ND gi,gj;
2216:
2217: k = g->m;
2218: while ( 1 ) {
2219: j = -1;
2220: for ( i = 0; i <= k; i++ ) {
2221: if ( !(gi = g->body[i]) )
2222: continue;
2223: if ( j < 0 ) {
2224: j = i;
2225: gj = g->body[j];
2226: dj = HDL(gj);
2227: sum = HCM(gj);
2228: } else {
2229: c = DL_COMPARE(HDL(gi),dj);
2230: if ( c > 0 ) {
2231: if ( sum ) HCM(gj) = sum;
2232: else g->body[j] = nd_remove_head(gj);
2233: j = i;
2234: gj = g->body[j];
2235: dj = HDL(gj);
2236: sum = HCM(gj);
2237: } else if ( c == 0 ) {
2238: if ( mod == -1 )
2239: sum = _addsf(sum,HCM(gi));
2240: else {
2241: sum = sum+HCM(gi)-mod;
2242: if ( sum < 0 ) sum += mod;
2243: }
2244: g->body[i] = nd_remove_head(gi);
2245: }
2246: }
2247: }
2248: if ( j < 0 ) return -1;
2249: else if ( sum ) {
2250: HCM(gj) = sum;
2251: return j;
2252: } else
2253: g->body[j] = nd_remove_head(gj);
2254: }
2255: }
2256:
2257: int head_pbucket_q(PGeoBucket g)
2258: {
2259: int j,i,c,k,nv;
2260: Z sum,t;
2261: ND gi,gj;
2262:
2263: k = g->m;
2264: while ( 1 ) {
2265: j = -1;
2266: for ( i = 0; i <= k; i++ ) {
2267: if ( !(gi = g->body[i]) ) continue;
2268: if ( j < 0 ) {
2269: j = i;
2270: gj = g->body[j];
1.6 noro 2271: sum = HCZ(gj);
1.1 noro 2272: } else {
2273: nv = NV(gi);
2274: c = DL_COMPARE(HDL(gi),HDL(gj));
2275: if ( c > 0 ) {
1.6 noro 2276: if ( sum ) HCZ(gj) = sum;
1.1 noro 2277: else g->body[j] = nd_remove_head(gj);
2278: j = i;
2279: gj = g->body[j];
1.6 noro 2280: sum = HCZ(gj);
1.1 noro 2281: } else if ( c == 0 ) {
1.6 noro 2282: addz(sum,HCZ(gi),&t);
1.1 noro 2283: sum = t;
2284: g->body[i] = nd_remove_head(gi);
2285: }
2286: }
2287: }
2288: if ( j < 0 ) return -1;
2289: else if ( sum ) {
1.6 noro 2290: HCZ(gj) = sum;
1.1 noro 2291: return j;
2292: } else
2293: g->body[j] = nd_remove_head(gj);
2294: }
2295: }
2296:
2297: int head_pbucket_lf(PGeoBucket g)
2298: {
2299: int j,i,c,k,nv;
2300: Z sum,t;
2301: ND gi,gj;
2302:
2303: k = g->m;
2304: while ( 1 ) {
2305: j = -1;
2306: for ( i = 0; i <= k; i++ ) {
2307: if ( !(gi = g->body[i]) ) continue;
2308: if ( j < 0 ) {
2309: j = i;
2310: gj = g->body[j];
2311: sum = HCZ(gj);
2312: } else {
2313: nv = NV(gi);
2314: c = DL_COMPARE(HDL(gi),HDL(gj));
2315: if ( c > 0 ) {
2316: if ( sum ) HCZ(gj) = sum;
2317: else g->body[j] = nd_remove_head(gj);
2318: j = i;
2319: gj = g->body[j];
2320: sum = HCZ(gj);
2321: } else if ( c == 0 ) {
2322: addlf(sum,HCZ(gi),&t);
2323: sum = t;
2324: g->body[i] = nd_remove_head(gi);
2325: }
2326: }
2327: }
2328: if ( j < 0 ) return -1;
2329: else if ( sum ) {
2330: HCZ(gj) = sum;
2331: return j;
2332: } else
2333: g->body[j] = nd_remove_head(gj);
2334: }
2335: }
2336:
2337: ND normalize_pbucket(int mod,PGeoBucket g)
2338: {
2339: int i;
2340: ND r,t;
2341:
2342: r = 0;
2343: for ( i = 0; i <= g->m; i++ ) {
2344: r = nd_add(mod,r,g->body[i]);
2345: g->body[i] = 0;
2346: }
2347: g->m = -1;
2348: return r;
2349: }
2350:
2351: #if 0
2352: void register_hcf(NDV p)
2353: {
2354: DCP dc,t;
2355: P hc,h;
2356: int c;
2357: NODE l,l1,prev;
2358:
2359: hc = p->body->c.p;
2360: if ( !nd_vc || NUM(hc) ) return;
2361: fctrp(nd_vc,hc,&dc);
2362: for ( t = dc; t; t = NEXT(t) ) {
2363: h = t->c;
2364: if ( NUM(h) ) continue;
2365: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2366: c = compp(nd_vc,h,(P)BDY(l));
2367: if ( c >= 0 ) break;
2368: }
2369: if ( !l || c > 0 ) {
2370: MKNODE(l1,h,l);
2371: if ( !prev )
2372: nd_hcf = l1;
2373: else
2374: NEXT(prev) = l1;
2375: }
2376: }
2377: }
2378: #else
2379: void register_hcf(NDV p)
2380: {
2381: DCP dc,t;
2382: P hc,h,q;
2383: Q dmy;
2384: int c;
2385: NODE l,l1,prev;
2386:
2387: hc = p->body->c.p;
2388: if ( NUM(hc) ) return;
2389: ptozp(hc,1,&dmy,&h);
2390: #if 1
2391: for ( l = nd_hcf; l; l = NEXT(l) ) {
2392: while ( 1 ) {
2393: if ( divtpz(nd_vc,h,(P)BDY(l),&q) ) h = q;
2394: else break;
2395: }
2396: }
2397: if ( NUM(h) ) return;
2398: #endif
2399: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2400: c = compp(nd_vc,h,(P)BDY(l));
2401: if ( c >= 0 ) break;
2402: }
2403: if ( !l || c > 0 ) {
2404: MKNODE(l1,h,l);
2405: if ( !prev )
2406: nd_hcf = l1;
2407: else
2408: NEXT(prev) = l1;
2409: }
2410: }
2411: #endif
2412:
2413: int do_diagonalize(int sugar,int m)
2414: {
1.6 noro 2415: int i,nh,stat;
2416: NODE r,g,t;
2417: ND h,nf,s,head;
2418: NDV nfv;
2419: Q q;
2420: P nm,nmp,dn,mnp,dnp,cont,cont1;
2421: union oNDC hc;
2422: NODE node;
2423: LIST l;
2424: Z iq;
1.1 noro 2425:
1.6 noro 2426: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
2427: if ( nd_gentrace ) {
2428: /* Trace = [1,index,1,1] */
2429: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2430: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2431: }
2432: if ( nd_demand )
2433: nfv = ndv_load(i);
2434: else
2435: nfv = nd_ps[i];
2436: s = ndvtond(m,nfv);
2437: s = nd_separate_head(s,&head);
2438: stat = nd_nf(m,head,s,nd_ps,1,&nf);
2439: if ( !stat ) return 0;
2440: ndv_free(nfv);
2441: hc = HCU(nf); nd_removecont(m,nf);
2442: /* exact division */
2443: cont = ndc_div(m,hc,HCU(nf));
1.1 noro 2444: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.6 noro 2445: nfv = ndtondv(m,nf);
2446: nd_free(nf);
2447: nd_bound[i] = ndv_compute_bound(nfv);
2448: if ( !m ) register_hcf(nfv);
2449: if ( nd_demand ) {
2450: ndv_save(nfv,i);
2451: ndv_free(nfv);
2452: } else
2453: nd_ps[i] = nfv;
2454: }
2455: return 1;
1.1 noro 2456: }
2457:
2458: LIST compute_splist()
2459: {
2460: NODE g,tn0,tn,node;
2461: LIST l0;
2462: ND_pairs d,t;
2463: int i;
2464: Z i1,i2;
2465:
2466: g = 0; d = 0;
2467: for ( i = 0; i < nd_psn; i++ ) {
2468: d = update_pairs(d,g,i,0);
2469: g = update_base(g,i);
2470: }
2471: for ( t = d, tn0 = 0; t; t = NEXT(t) ) {
2472: NEXTNODE(tn0,tn);
1.6 noro 2473: STOZ(t->i1,i1); STOZ(t->i2,i2);
1.1 noro 2474: node = mknode(2,i1,i2); MKLIST(l0,node);
2475: BDY(tn) = l0;
2476: }
2477: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
2478: return l0;
2479: }
2480:
1.49 noro 2481: typedef struct oHPDATA {
2482: P hn; // HP(t)=hn(t)/(1-t)^n
2483: int len;
2484: P *head; // hp(i)=head[i] (i=0,...,len-1)
2485: P hp; // dim Hm(i)=hp(i) (i >= len)
2486: VECT x; // BDY(x)[i] = <<0,...,1,...,0>>
2487: P *plist; // plist[i]=(1-t)^i
2488: } *HPDATA;
2489:
2490: void make_reduced(VECT b,int nv);
2491: void mhp_rec(VECT b,VECT x,P t,P *r);
2492: P mhp_ctop(P *r,P *plist,int n);
2493: void mhp_to_hf(VL vl,P hp,int n,P *plist,VECT *head,P *hf);
2494: DL monomial_colon(DL a,DL b,int n);
2495: LIST dp_monomial_hilbert_poincare(VECT b,VECT x,P *plist);
2496:
2497: int hpvalue(HPDATA data,int d)
2498: {
2499: P *head;
2500: int len;
2501: P hp,val;
2502: Z dz;
2503:
2504: head = data->head;
2505: len = data->len;
2506: hp = data->hp;
2507: if ( d < len )
2508: return ZTOS((Z)head[d]);
2509: else {
2510: STOZ(d,dz);
2511: substp(CO,hp,hp->v,(P)dz,&val);
2512: return ZTOS((Z)val);
2513: }
2514: }
2515:
2516: void setup_hpdata(HPDATA final,HPDATA current)
2517: {
2518: int n,i;
2519: P *r;
2520: DL *p;
2521: P tv;
2522: VECT b,x,head;
2523: DL dl;
2524:
2525: n = nd_nvar;
2526: final->hn = (P)ARG0(nd_hpdata);
2527: head = (VECT)ARG2(nd_hpdata);
2528: final->len = head->len;
2529: final->head = (P *)BDY(head);
2530: final->hp = (P)ARG3(nd_hpdata);
2531: final->plist = (P *)BDY((VECT)ARG4(nd_hpdata));
2532: MKVECT(x,n);
2533: for ( i = 0; i < n; i++ ) {
2534: NEWDL(dl,n); dl->d[i] = 1; dl->td = 1; BDY(x)[i] = dl;
2535: }
2536: final->x = x;
2537:
2538: r = (P *)CALLOC(n+1,sizeof(P));
2539: MKVECT(b,nd_psn); p = (DL *)BDY(b);
2540: for ( i = 0; i < nd_psn; i++ ) {
2541: p[i] = ndltodl(n,nd_psh[i]->dl);
2542: }
2543: make_reduced(b,n);
2544: makevar("t",&tv);
2545: mhp_rec(b,x,tv,r);
2546: current->hn = mhp_ctop(r,final->plist,n);
2547: mhp_to_hf(CO,current->hn,n,final->plist,&head,¤t->hp);
2548: current->head = (P *)BDY(head);
2549: current->len = head->len;
2550: current->x = x;
2551: current->plist = final->plist;
2552: }
2553:
2554: void update_hpdata(HPDATA current,int nh,int do_hf)
2555: {
2556: NODE data1,nd,t;
2557: DL new,dl;
2558: int len,i,n;
2559: Z dz;
2560: DL *p;
2561: VECT b,head;
2562: P tv,td,s,hn,hpoly;
2563: LIST list1;
2564:
2565: n = nd_nvar;
2566: new = ndltodl(n,nd_psh[nh]->dl);
2567: MKVECT(b,nh); p = (DL *)BDY(b);
2568: for ( i = 0; i < nh; i++ ) {
2569: p[i] = monomial_colon(ndltodl(n,nd_psh[i]->dl),new,n);
2570: }
2571: // compute HP(I:new)
2572: list1 = dp_monomial_hilbert_poincare(b,current->x,current->plist);
2573: data1 = BDY((LIST)list1);
2574: // HP(I+<new>) = H(I)-t^d*H(I:new), d=tdeg(new)
2575: makevar("t",&tv); UTOZ(new->td,dz);
2576: pwrp(CO,tv,dz,&td);
2577: mulp(CO,(P)ARG0(data1),td,&s);
2578: subp(CO,current->hn,s,&hn);
2579: current->hn = hn;
2580: if ( do_hf ) {
2581: mhp_to_hf(CO,hn,n,current->plist,&head,&hpoly);
2582: current->head = (P *)BDY(head);
2583: current->len = head->len;
2584: current->hp = hpoly;
2585: }
2586: }
2587:
2588: ND_pairs nd_remove_same_sugar( ND_pairs d, int sugar)
2589: {
2590: struct oND_pairs root;
2591: ND_pairs prev,cur;
2592:
2593: root.next = d;
2594: prev = &root; cur = d;
2595: while ( cur ) {
2596: if ( SG(cur) == sugar )
2597: prev->next = cur->next;
2598: else
2599: prev = cur;
2600: cur = cur->next;
2601: }
2602: return root.next;
2603: }
2604:
1.1 noro 2605: /* return value = 0 => input is not a GB */
2606:
2607: NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp)
2608: {
1.6 noro 2609: int i,nh,sugar,stat;
2610: NODE r,g,t;
2611: ND_pairs d;
2612: ND_pairs l;
2613: ND h,nf,s,head,nf1;
2614: NDV nfv;
2615: Z q;
2616: union oNDC dn,hc;
2617: int diag_count = 0;
1.41 noro 2618: int Nnfnz = 0,Nnfz = 0;
1.6 noro 2619: P cont;
2620: LIST list;
1.49 noro 2621: struct oHPDATA current_hpdata,final_hpdata;
2622: int final_hpvalue;
2623:
1.27 noro 2624: struct oEGT eg1,eg2,eg_update;
1.6 noro 2625:
1.27 noro 2626: init_eg(&eg_update);
1.11 noro 2627: Nnd_add = 0;
1.6 noro 2628: g = 0; d = 0;
2629: for ( i = 0; i < nd_psn; i++ ) {
2630: d = update_pairs(d,g,i,gensyz);
2631: g = update_base(g,i);
2632: }
2633: sugar = 0;
1.49 noro 2634: if ( nd_hpdata ) {
1.52 noro 2635: if ( DP_Print ) fprintf(asir_out,"Hilbert driven algorithm.\n");
1.49 noro 2636: setup_hpdata(&final_hpdata,¤t_hpdata);
2637: }
1.6 noro 2638: while ( d ) {
1.1 noro 2639: again:
1.6 noro 2640: l = nd_minp(d,&d);
2641: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
2642: if ( SG(l) != sugar ) {
2643: if ( ishomo ) {
2644: diag_count = 0;
2645: stat = do_diagonalize(sugar,m);
1.1 noro 2646: if ( !stat ) {
1.6 noro 2647: NEXT(l) = d; d = l;
2648: d = nd_reconstruct(0,d);
2649: goto again;
1.1 noro 2650: }
1.6 noro 2651: }
2652: sugar = SG(l);
2653: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
1.49 noro 2654: if ( nd_hpdata ) {
2655: if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) )
2656: break;
2657: else {
2658: final_hpvalue = hpvalue(&final_hpdata,sugar);
2659: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
1.52 noro 2660: // if ( DP_Print ) fprintf(asir_out,"done.\n",sugar);
1.49 noro 2661: d = nd_remove_same_sugar(d,sugar);
2662: continue;
2663: }
2664: }
2665: }
1.6 noro 2666: }
2667: stat = nd_sp(m,0,l,&h);
2668: if ( !stat ) {
2669: NEXT(l) = d; d = l;
2670: d = nd_reconstruct(0,d);
2671: goto again;
2672: }
1.1 noro 2673: #if USE_GEOBUCKET
1.39 noro 2674: stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!nd_top&&!Top,&nf)
2675: :nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 2676: #else
1.39 noro 2677: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 2678: #endif
1.6 noro 2679: if ( !stat ) {
2680: NEXT(l) = d; d = l;
2681: d = nd_reconstruct(0,d);
2682: goto again;
2683: } else if ( nf ) {
1.41 noro 2684: Nnfnz++;
1.6 noro 2685: if ( checkonly || gensyz ) return 0;
1.1 noro 2686: if ( nd_newelim ) {
2687: if ( nd_module ) {
2688: if ( MPOS(HDL(nf)) > 1 ) return 0;
2689: } else if ( !(HDL(nf)[nd_exporigin] & nd_mask[0]) ) return 0;
2690: }
1.6 noro 2691: if ( DP_Print ) { printf("+"); fflush(stdout); }
2692: hc = HCU(nf);
2693: nd_removecont(m,nf);
2694: if ( !m && nd_nalg ) {
2695: nd_monic(0,&nf);
2696: nd_removecont(m,nf);
2697: }
2698: if ( nd_gentrace ) {
2699: /* exact division */
1.1 noro 2700: cont = ndc_div(m,hc,HCU(nf));
2701: if ( m || !UNIQ(cont) ) {
1.6 noro 2702: t = mknode(4,NULLP,NULLP,NULLP,cont);
2703: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
1.1 noro 2704: nd_tracelist = t;
2705: }
2706: }
1.6 noro 2707: nfv = ndtondv(m,nf); nd_free(nf);
1.24 noro 2708: nh = ndv_newps(m,nfv,0);
1.6 noro 2709: if ( !m && (ishomo && ++diag_count == diag_period) ) {
2710: diag_count = 0;
2711: stat = do_diagonalize(sugar,m);
2712: if ( !stat ) {
2713: NEXT(l) = d; d = l;
2714: d = nd_reconstruct(1,d);
2715: goto again;
1.1 noro 2716: }
1.6 noro 2717: }
1.27 noro 2718: get_eg(&eg1);
1.6 noro 2719: d = update_pairs(d,g,nh,0);
1.27 noro 2720: get_eg(&eg2); add_eg(&eg_update,&eg1,&eg2);
1.6 noro 2721: g = update_base(g,nh);
2722: FREENDP(l);
1.49 noro 2723: if ( nd_hpdata ) {
2724: update_hpdata(¤t_hpdata,nh,1);
2725: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
1.52 noro 2726: // if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
1.49 noro 2727: d = nd_remove_same_sugar(d,sugar);
2728: }
2729: }
1.41 noro 2730: } else {
2731: Nnfz++;
2732: if ( nd_gentrace && gensyz ) {
2733: nd_tracelist = reverse_node(nd_tracelist);
2734: MKLIST(list,nd_tracelist);
2735: STOZ(-1,q); t = mknode(2,q,list); MKLIST(list,t);
2736: MKNODE(t,list,nd_alltracelist);
2737: nd_alltracelist = t; nd_tracelist = 0;
2738: }
2739: if ( DP_Print ) { printf("."); fflush(stdout); }
2740: FREENDP(l);
2741: }
1.36 noro 2742: }
2743: conv_ilist(nd_demand,0,g,indp);
1.41 noro 2744: if ( !checkonly && DP_Print ) {
2745: printf("\nnd_gb done. Nnd_add=%d,Npairs=%d, Nnfnz=%d,Nnfz=%d,",Nnd_add,Npairs,Nnfnz,Nnfz);
2746: printf("Nremoved=%d\n",NcriB+NcriMF+Ncri2);
2747: fflush(asir_out);
2748: }
2749: if ( DP_Print ) {
2750: print_eg("update",&eg_update); fprintf(asir_out,"\n");
2751: }
1.36 noro 2752: return g;
1.1 noro 2753: }
2754:
1.30 noro 2755: ND_pairs update_pairs_s(ND_pairs d,int t,NODE *syz);
1.47 noro 2756: int update_pairs_array_s(ND_pairs *d,int t,NODE *syz);
1.30 noro 2757: ND_pairs nd_newpairs_s(int t ,NODE *syz);
1.47 noro 2758: ND_pairs *nd_newpairs_array_s(int t ,NODE *syz);
1.24 noro 2759:
2760: int nd_nf_pbucket_s(int mod,ND g,NDV *ps,int full,ND *nf);
2761: int nd_nf_s(int mod,ND d,ND g,NDV *ps,int full,ND *nf);
2762:
2763: void _copydl(int n,DL d1,DL d2);
2764: void _subfromdl(int n,DL d1,DL d2);
2765: extern int (*cmpdl)(int n,DL d1,DL d2);
1.53 noro 2766: int _dl_redble_ext(DL,DL,DL,int);
2767:
2768: int primitive_irred(ND p,SIG sig)
2769: {
2770: static int wpd=0,dlen=0;
2771: static DL dquo,squo;
2772: static UINT *quo;
2773: int i;
2774:
2775: if ( dlen < nd_nvar ) {
2776: NEWDL(dquo,nd_nvar);
2777: NEWDL(squo,nd_nvar);
2778: dlen = nd_nvar;
2779: }
2780: if ( wpd != nd_wpd ) {
2781: wpd = nd_wpd;
2782: quo = (UINT *)MALLOC(wpd*sizeof(UINT));
2783: }
2784: for ( i = 0; i < nd_psn; i++ ) {
2785: if ( sig->pos == nd_psh[i]->sig->pos &&
2786: _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),squo,nd_nvar) )
2787: if ( ndl_reducible(HDL(p),DL(nd_psh[i])) ) {
2788: if ( DP_Print ) fprintf(asir_out,"D");
2789: ndl_sub(HDL(p),DL(nd_psh[i]),quo);
2790: _ndltodl(quo,dquo);
2791: if ( _eqdl(nd_nvar,squo,dquo) )
2792: return 0;
2793: }
2794: }
2795: return 1;
2796: }
1.24 noro 2797:
2798: NODE insert_sig(NODE l,SIG s)
2799: {
2800: int pos;
2801: DL sig;
2802: struct oNODE root;
2803: NODE p,prev,r;
2804: SIG t;
2805:
2806: pos = s->pos; sig = DL(s);
2807: root.next = l; prev = &root;
2808: for ( p = l; p; p = p->next ) {
2809: t = (SIG)p->body;
2810: if ( t->pos == pos ) {
2811: if ( _dl_redble(DL(t),sig,nd_nvar) )
2812: return root.next;
2813: else if ( _dl_redble(sig,DL(t),nd_nvar) )
2814: // remove p
2815: prev->next = p->next;
1.45 noro 2816: else
2817: prev = p;
1.24 noro 2818: } else
2819: prev = p;
2820: }
1.27 noro 2821: NEWNODE(r); r->body = (pointer)s; r->next = 0;
2822: for ( p = &root; p->next; p = p->next );
2823: p->next = r;
2824: // r->next = root.next;
2825: // return r;
2826: return root.next;
1.24 noro 2827: }
2828:
2829: ND_pairs remove_spair_s(ND_pairs d,SIG sig)
2830: {
2831: struct oND_pairs root;
2832: ND_pairs prev,p;
2833: SIG spsig;
2834:
2835: root.next = d;
2836: prev = &root; p = d;
2837: while ( p ) {
2838: spsig = p->sig;
1.26 noro 2839: if ( sig->pos == spsig->pos && _dl_redble(DL(sig),DL(spsig),nd_nvar) ) {
1.24 noro 2840: // remove p
2841: prev->next = p->next;
1.26 noro 2842: Nsyz++;
2843: } else
1.24 noro 2844: prev = p;
2845: p = p->next;
2846: }
2847: return (ND_pairs)root.next;
2848: }
2849:
1.28 noro 2850: int small_lcm(ND_pairs l)
2851: {
2852: SIG sig;
2853: int i;
1.29 noro 2854: NODE t;
1.28 noro 2855: static DL lcm,mul,quo;
1.44 noro 2856: static int nvar = 0;
1.28 noro 2857:
1.38 noro 2858: if ( nd_sba_largelcm ) return 0;
1.28 noro 2859: if ( nvar < nd_nvar ) {
2860: nvar = nd_nvar; NEWDL(lcm,nvar); NEWDL(quo,nvar); NEWDL(mul,nvar);
2861: }
2862: sig = l->sig;
2863: _ndltodl(l->lcm,lcm);
1.29 noro 2864: #if 0
1.28 noro 2865: for ( i = 0; i < nd_psn; i++ ) {
2866: if ( sig->pos == nd_psh[i]->sig->pos &&
1.29 noro 2867: _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
1.28 noro 2868: _ndltodl(DL(nd_psh[i]),mul);
2869: _addtodl(nd_nvar,quo,mul);
2870: if ( (*cmpdl)(nd_nvar,lcm,mul) > 0 )
2871: break;
2872: }
2873: }
2874: if ( i < nd_psn ) return 1;
2875: else return 0;
1.29 noro 2876: #else
2877: for ( t = nd_sba_pos[sig->pos]; t; t = t->next ) {
2878: i = (long)BDY(t);
2879: if ( _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
2880: _ndltodl(DL(nd_psh[i]),mul);
2881: _addtodl(nd_nvar,quo,mul);
2882: if ( (*cmpdl)(nd_nvar,lcm,mul) > 0 )
2883: break;
2884: }
2885: }
2886: if ( t ) return 1;
2887: else return 0;
2888: #endif
1.28 noro 2889: }
2890:
1.41 noro 2891: ND_pairs find_smallest_lcm(ND_pairs l)
2892: {
2893: SIG sig;
2894: int i,minindex;
2895: NODE t;
2896: ND_pairs r;
2897: struct oSIG sig1;
1.55 ! noro 2898: static DL mul,quo,quo2,minlm;
1.44 noro 2899: static int nvar = 0;
1.41 noro 2900:
2901: if ( nvar < nd_nvar ) {
2902: nvar = nd_nvar;
1.55 ! noro 2903: NEWDL(quo,nvar); NEWDL(quo2,nvar); NEWDL(mul,nvar);
1.41 noro 2904: NEWDL(minlm,nvar);
2905: }
2906: sig = l->sig;
2907: // find mg s.t. m*s(g)=sig and m*lm(g) is minimal
2908: _ndltodl(l->lcm,minlm); minindex = -1;
2909: for ( t = nd_sba_pos[sig->pos]; t; t = t->next ) {
2910: i = (long)BDY(t);
2911: if ( _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
2912: _ndltodl(DL(nd_psh[i]),mul);
2913: _addtodl(nd_nvar,quo,mul);
2914: if ( (*cmpdl)(nd_nvar,minlm,mul) > 0 ) {
2915: minindex = i;
1.47 noro 2916: break;
1.41 noro 2917: _copydl(nd_nvar,mul,minlm);
2918: }
2919: }
2920: }
2921: // l->lcm is minimal; return l itself
2922: if ( minindex < 0 ) return l;
1.47 noro 2923: else return 0;
1.41 noro 2924: for ( i = 0; i < nd_psn; i++ ) {
2925: if ( i == minindex ) continue;
2926: _ndltodl(DL(nd_psh[i]),mul);
2927: if ( _dl_redble_ext(mul,minlm,quo,nd_nvar) ) {
2928: _addtodl(nd_nvar,nd_ps[i]->sig->dl,quo);
2929: sig1.pos = nd_ps[i]->sig->pos;
2930: sig1.dl = quo;
1.55 ! noro 2931: sig1.dl2 = quo2;
! 2932: _adddl(nd_nvar,sig1.dl,nd_sba_hm[sig1.pos],sig1.dl2);
1.41 noro 2933: if ( comp_sig(sig,&sig1) > 0 ) {
2934: // printf("X");
2935: NEWND_pairs(r);
2936: r->sig = sig;
2937: r->i1 = minindex;
2938: r->i2 = i;
2939: dltondl(nd_nvar,minlm,r->lcm);
2940: r->next = 0;
2941: return r;
2942: }
2943: }
2944: }
2945: // there is no suitable spair
2946: return 0;
2947: }
2948:
1.28 noro 2949: ND_pairs remove_large_lcm(ND_pairs d)
2950: {
2951: struct oND_pairs root;
2952: ND_pairs prev,p;
2953:
2954: root.next = d;
2955: prev = &root; p = d;
2956: while ( p ) {
1.41 noro 2957: #if 0
1.28 noro 2958: if ( small_lcm(p) ) {
2959: // remove p
2960: prev->next = p->next;
2961: } else
1.41 noro 2962: #else
2963: if ( find_smallest_lcm(p) == 0 ) {
2964: // remove p
2965: prev->next = p->next;
2966: } else
2967: #endif
1.28 noro 2968: prev = p;
2969: p = p->next;
2970: }
2971: return (ND_pairs)root.next;
2972: }
2973:
1.26 noro 2974: struct oEGT eg_create,eg_newpairs,eg_merge;
2975:
1.30 noro 2976: NODE conv_ilist_s(int demand,int trace,int **indp);
2977:
1.44 noro 2978: // S(fj*ei-fi*ej)
2979:
1.45 noro 2980: void _subdl(int,DL,DL,DL);
2981:
1.44 noro 2982: SIG trivial_sig(int i,int j)
2983: {
1.45 noro 2984: static DL lcm;
1.44 noro 2985: static struct oSIG sigi,sigj;
2986: static int nvar = 0;
2987: SIG sig;
2988:
2989: if ( nvar != nd_nvar ) {
1.45 noro 2990: nvar = nd_nvar; NEWDL(lcm,nvar); NEWDL(sigi.dl,nvar); NEWDL(sigj.dl,nvar);
1.55 ! noro 2991: NEWDL(sigi.dl2,nvar); NEWDL(sigj.dl2,nvar);
1.45 noro 2992: }
1.46 noro 2993: if ( nd_sba_inputisgb != 0 ) {
1.45 noro 2994: lcm_of_DL(nd_nvar,nd_sba_hm[i],nd_sba_hm[j],lcm);
2995: sigi.pos = i; _subdl(nd_nvar,lcm,nd_sba_hm[i],sigi.dl);
1.55 ! noro 2996: _copydl(nd_nvar,lcm,sigi.dl2);
1.45 noro 2997: sigj.pos = j; _subdl(nd_nvar,lcm,nd_sba_hm[j],sigj.dl);
1.55 ! noro 2998: _copydl(nd_nvar,lcm,sigj.dl2);
1.45 noro 2999: if ( comp_sig(&sigi,&sigj) > 0 ) sig = dup_sig(&sigi);
3000: else sig = dup_sig(&sigj);
3001: } else {
3002: sigi.pos = i; _copydl(nd_nvar,nd_sba_hm[j],sigi.dl);
1.55 ! noro 3003: _adddl(nd_nvar,sigi.dl,nd_sba_hm[i],sigi.dl2);
1.45 noro 3004: sigj.pos = j; _copydl(nd_nvar,nd_sba_hm[i],sigj.dl);
1.55 ! noro 3005: _adddl(nd_nvar,sigj.dl,nd_sba_hm[j],sigj.dl2);
1.45 noro 3006: if ( comp_sig(&sigi,&sigj) > 0 ) sig = dup_sig(&sigi);
3007: else sig = dup_sig(&sigj);
1.44 noro 3008: }
3009: return sig;
3010: }
3011:
1.47 noro 3012: int nd_minsig(ND_pairs *d)
3013: {
3014: int min,i,ret;
3015:
3016: min = -1;
3017: for ( i = 0; i < nd_nbase; i++ ) {
3018: if ( d[i] != 0 ) {
3019: if ( min < 0 ) min = i;
3020: else {
3021: ret = comp_sig(d[i]->sig,d[min]->sig);
3022: if ( ret < 0 ) min = i;
3023: }
3024: }
3025: }
3026: return min;
3027: }
3028:
3029: int dlength(ND_pairs d)
3030: {
3031: int i;
3032: for ( i = 0; d; d = d->next, i++ );
3033: return i;
3034: }
3035:
1.44 noro 3036: NODE nd_sba_buch(int m,int ishomo,int **indp,NODE *syzp)
1.24 noro 3037: {
1.39 noro 3038: int i,j,nh,sugar,stat,pos;
1.30 noro 3039: NODE r,t,g;
1.47 noro 3040: ND_pairs *d;
1.41 noro 3041: ND_pairs l,l1;
1.24 noro 3042: ND h,nf,s,head,nf1;
3043: NDV nfv;
3044: Z q;
3045: union oNDC dn,hc;
3046: P cont;
3047: LIST list;
3048: SIG sig;
1.29 noro 3049: NODE *syzlist;
1.47 noro 3050: int ngen,ind;
1.41 noro 3051: int Nnominimal,Nredundant;
1.28 noro 3052: DL lcm,quo,mul;
1.49 noro 3053: struct oHPDATA final_hpdata,current_hpdata;
1.50 noro 3054: struct oEGT eg1,eg2,eg3,eg4,eg_update,eg_remove,eg_large,eg_nf,eg_nfzero;
3055: struct oEGT eg_minsig,eg_smallest,eg_removecont,eg_hpdata,eg_updatepairs,eg_sbabuch,eg_sp;
1.47 noro 3056: int Nnfs=0,Nnfz=0,Nnfnz=0,dlen,nsyz;
1.24 noro 3057:
1.27 noro 3058: init_eg(&eg_remove);
1.29 noro 3059: syzlist = (NODE *)MALLOC(nd_psn*sizeof(NODE));
1.47 noro 3060: d = (ND_pairs *)MALLOC(nd_psn*sizeof(ND_pairs));
3061: nd_nbase = nd_psn;
1.26 noro 3062: Nsyz = 0;
1.24 noro 3063: Nnd_add = 0;
1.41 noro 3064: Nnominimal = 0;
1.26 noro 3065: Nredundant = 0;
1.44 noro 3066: ngen = nd_psn;
1.48 noro 3067: if ( !do_weyl ) {
3068: for ( i = 0; i < nd_psn; i++ )
3069: for ( j = i+1; j < nd_psn; j++ ) {
3070: sig = trivial_sig(i,j);
3071: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
3072: }
1.29 noro 3073: }
1.47 noro 3074: dlen = 0;
1.41 noro 3075: for ( i = 0; i < nd_psn; i++ ) {
1.47 noro 3076: dlen += update_pairs_array_s(d,i,syzlist);
1.41 noro 3077: }
1.24 noro 3078: sugar = 0;
1.39 noro 3079: pos = 0;
1.49 noro 3080: if ( nd_hpdata ) {
3081: setup_hpdata(&final_hpdata,¤t_hpdata);
3082: }
1.26 noro 3083: NEWDL(lcm,nd_nvar); NEWDL(quo,nd_nvar); NEWDL(mul,nd_nvar);
1.50 noro 3084: init_eg(&eg_sp);
1.26 noro 3085: init_eg(&eg_create);
3086: init_eg(&eg_merge);
1.47 noro 3087: init_eg(&eg_minsig);
3088: init_eg(&eg_smallest);
1.29 noro 3089: init_eg(&eg_large);
1.31 noro 3090: init_eg(&eg_nf);
3091: init_eg(&eg_nfzero);
1.50 noro 3092: init_eg(&eg_removecont);
3093: init_eg(&eg_updatepairs);
3094: init_eg(&eg_hpdata);
3095: init_eg(&eg_sbabuch);
3096: get_eg(&eg3);
1.47 noro 3097: while ( 1 ) {
1.53 noro 3098: if ( DP_Print && !nd_hpdata && dlen%1000 == 0 ) fprintf(asir_out,"(%d)",dlen);
1.47 noro 3099: again :
3100: get_eg(&eg1);
3101: ind = nd_minsig(d);
3102: get_eg(&eg2); add_eg(&eg_minsig,&eg1,&eg2);
3103: if ( ind < 0 ) break;
3104: l = d[ind];
3105: // printf("(%d,%d)",l->i1,l->i2); print_sig(l->sig); printf("\n");
3106: get_eg(&eg1);
1.41 noro 3107: l1 = find_smallest_lcm(l);
1.47 noro 3108: get_eg(&eg2); add_eg(&eg_smallest,&eg1,&eg2);
1.41 noro 3109: if ( l1 == 0 ) {
1.47 noro 3110: d[ind] = d[ind]->next; dlen--;
1.53 noro 3111: // if ( DP_Print && !nd_hpdata ) fprintf(asir_out,"M");
1.41 noro 3112: Nnominimal++;
3113: continue;
3114: }
3115: if ( SG(l1) != sugar ) {
3116: sugar = SG(l1);
3117: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
3118: }
3119: sig = l1->sig;
3120: if ( DP_Print && nd_sba_pot ) {
3121: if ( sig->pos != pos ) {
3122: fprintf(asir_out,"[%d]",sig->pos);
3123: pos = sig->pos;
3124: }
3125: }
1.50 noro 3126: get_eg(&eg1);
1.41 noro 3127: stat = nd_sp(m,0,l1,&h);
1.50 noro 3128: get_eg(&eg2); add_eg(&eg_sp,&eg1,&eg2);
1.24 noro 3129: if ( !stat ) {
1.47 noro 3130: nd_reconstruct_s(0,d);
1.24 noro 3131: goto again;
3132: }
1.31 noro 3133: get_eg(&eg1);
1.25 noro 3134: #if USE_GEOBUCKET
1.55 ! noro 3135: stat = (m&&!nd_gentrace)?nd_nf_pbucket_s(m,h,nd_ps,!nd_top&&!Top,&nf):nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.24 noro 3136: #else
1.39 noro 3137: stat = nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.24 noro 3138: #endif
1.31 noro 3139: get_eg(&eg2);
1.24 noro 3140: if ( !stat ) {
1.47 noro 3141: nd_reconstruct_s(0,d);
1.24 noro 3142: goto again;
3143: } else if ( stat == -1 ) {
1.47 noro 3144: d[ind] = d[ind]->next; dlen--;
1.41 noro 3145: Nnfs++;
1.24 noro 3146: if ( DP_Print ) { printf("S"); fflush(stdout); }
3147: } else if ( nf ) {
1.47 noro 3148: d[ind] = d[ind]->next; dlen--;
1.41 noro 3149: Nnfnz++;
3150: if ( DP_Print ) {
3151: if ( nd_sba_redundant_check ) {
3152: if ( ndl_find_reducer_nonsig(HDL(nf)) >= 0 ) {
3153: Nredundant++;
3154: printf("R");
3155: } else
3156: printf("+");
3157: } else
3158: printf("+");
3159: fflush(stdout);
3160: }
1.31 noro 3161: add_eg(&eg_nf,&eg1,&eg2);
1.24 noro 3162: hc = HCU(nf);
1.55 ! noro 3163: get_eg(&eg1);
! 3164: nd_removecont(m,nf);
! 3165: get_eg(&eg2); add_eg(&eg_removecont,&eg1,&eg2);
! 3166: nfv = ndtondv(m,nf); nd_free(nf);
! 3167: nh = ndv_newps(m,nfv,0);
! 3168:
! 3169: get_eg(&eg1);
! 3170: dlen += update_pairs_array_s(d,nh,syzlist);
! 3171: get_eg(&eg2); add_eg(&eg_updatepairs,&eg1,&eg2);
! 3172: nd_sba_pos[sig->pos] = append_one(nd_sba_pos[sig->pos],nh);
! 3173: if ( nd_hpdata ) {
! 3174: get_eg(&eg1);
! 3175: update_hpdata(¤t_hpdata,nh,0);
! 3176: get_eg(&eg2); add_eg(&eg_hpdata,&eg1,&eg2);
! 3177: if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) ) {
! 3178: if ( DP_Print ) { printf("\nWe found a gb.\n"); }
! 3179: break;
! 3180: }
1.49 noro 3181: }
1.24 noro 3182: } else {
1.47 noro 3183: d[ind] = d[ind]->next; dlen--;
1.41 noro 3184: Nnfz++;
1.31 noro 3185: add_eg(&eg_nfzero,&eg1,&eg2);
1.24 noro 3186: // syzygy
1.27 noro 3187: get_eg(&eg1);
1.47 noro 3188: nsyz = Nsyz;
3189: d[sig->pos] = remove_spair_s(d[sig->pos],sig);
3190: dlen -= Nsyz-nsyz;
1.27 noro 3191: get_eg(&eg2); add_eg(&eg_remove,&eg1,&eg2);
1.29 noro 3192: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
1.24 noro 3193: if ( DP_Print ) { printf("."); fflush(stdout); }
3194: }
3195: }
1.50 noro 3196: get_eg(&eg4); add_eg(&eg_sbabuch,&eg3,&eg4);
1.30 noro 3197: g = conv_ilist_s(nd_demand,0,indp);
1.26 noro 3198: if ( DP_Print ) {
1.47 noro 3199: printf("\ndlen=%d,nd_sba done. nd_add=%d,Nsyz=%d,Nsamesig=%d,Nnominimal=%d\n",dlen,Nnd_add,Nsyz,Nsamesig,Nnominimal);
1.41 noro 3200: printf("Nnfnz=%d,Nnfz=%d,Nnfsingular=%d\n",Nnfnz,Nnfz,Nnfs);
1.50 noro 3201: fflush(stdout);
1.41 noro 3202: if ( nd_sba_redundant_check )
3203: printf("Nredundant=%d\n",Nredundant);
1.50 noro 3204: fflush(stdout);
3205: print_eg("sp",&eg_sp);
1.26 noro 3206: print_eg("create",&eg_create);
3207: print_eg("merge",&eg_merge);
1.47 noro 3208: print_eg("minsig",&eg_minsig);
3209: print_eg("smallest",&eg_smallest);
3210: print_eg("remove",&eg_remove);
1.50 noro 3211: printf("\n");
1.47 noro 3212: print_eg("nf",&eg_nf);
3213: print_eg("nfzero",&eg_nfzero);
1.50 noro 3214: print_eg("removecont",&eg_removecont);
3215: print_eg("updatepairs",&eg_updatepairs);
3216: print_eg("hpdata",&eg_hpdata);
3217: print_eg("total",&eg_sbabuch);
1.47 noro 3218: printf("\n");
3219: }
3220: if ( nd_sba_syz ) {
1.27 noro 3221: print_eg("remove",&eg_remove);
1.31 noro 3222: print_eg("nf",&eg_nf);
3223: print_eg("nfzero",&eg_nfzero);
1.27 noro 3224: printf("\n");
1.26 noro 3225: }
1.44 noro 3226: if ( nd_sba_syz ) {
3227: NODE hsyz,tsyz,prev;
3228:
3229: hsyz = 0;
3230: for ( i = 0; i < ngen; i++ ) {
3231: tsyz = syzlist[i];
3232: for ( prev = 0; tsyz != 0; prev = tsyz, tsyz = NEXT(tsyz))
3233: BDY(tsyz) = (pointer)sigtodpm((SIG)BDY(tsyz));
3234: if ( prev != 0 ) {
3235: prev->next = hsyz; hsyz = syzlist[i];
3236: }
3237: }
3238: *syzp = hsyz;
3239: } else *syzp = 0;
1.24 noro 3240: return g;
3241: }
3242:
1.1 noro 3243: /* splist = [[i1,i2],...] */
3244:
3245: int check_splist(int m,NODE splist)
3246: {
3247: NODE t,p;
3248: ND_pairs d,r,l;
3249: int stat;
3250: ND h,nf;
3251:
3252: for ( d = 0, t = splist; t; t = NEXT(t) ) {
3253: p = BDY((LIST)BDY(t));
1.6 noro 3254: NEXTND_pairs(d,r);
3255: r->i1 = ZTOS((Q)ARG0(p)); r->i2 = ZTOS((Q)ARG1(p));
3256: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.1 noro 3257: SG(r) = TD(LCM(r)); /* XXX */
3258: }
3259: if ( d ) NEXT(r) = 0;
3260:
1.6 noro 3261: while ( d ) {
1.1 noro 3262: again:
1.6 noro 3263: l = nd_minp(d,&d);
3264: stat = nd_sp(m,0,l,&h);
3265: if ( !stat ) {
3266: NEXT(l) = d; d = l;
3267: d = nd_reconstruct(0,d);
3268: goto again;
3269: }
1.39 noro 3270: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.6 noro 3271: if ( !stat ) {
3272: NEXT(l) = d; d = l;
3273: d = nd_reconstruct(0,d);
3274: goto again;
3275: } else if ( nf ) return 0;
1.1 noro 3276: if ( DP_Print) { printf("."); fflush(stdout); }
1.6 noro 3277: }
1.1 noro 3278: if ( DP_Print) { printf("done.\n"); fflush(stdout); }
3279: return 1;
3280: }
3281:
3282: int check_splist_f4(int m,NODE splist)
3283: {
3284: UINT *s0vect;
1.6 noro 3285: PGeoBucket bucket;
1.1 noro 3286: NODE p,rp0,t;
3287: ND_pairs d,r,l,ll;
3288: int col,stat;
3289:
3290: for ( d = 0, t = splist; t; t = NEXT(t) ) {
3291: p = BDY((LIST)BDY(t));
1.6 noro 3292: NEXTND_pairs(d,r);
3293: r->i1 = ZTOS((Q)ARG0(p)); r->i2 = ZTOS((Q)ARG1(p));
3294: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.1 noro 3295: SG(r) = TD(LCM(r)); /* XXX */
3296: }
3297: if ( d ) NEXT(r) = 0;
3298:
1.6 noro 3299: while ( d ) {
3300: l = nd_minsugarp(d,&d);
3301: bucket = create_pbucket();
3302: stat = nd_sp_f4(m,0,l,bucket);
3303: if ( !stat ) {
3304: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
3305: NEXT(ll) = d; d = l;
3306: d = nd_reconstruct(0,d);
3307: continue;
3308: }
3309: if ( bucket->m < 0 ) continue;
3310: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
3311: if ( !col ) {
3312: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
3313: NEXT(ll) = d; d = l;
3314: d = nd_reconstruct(0,d);
3315: continue;
1.1 noro 3316: }
1.6 noro 3317: if ( nd_f4_red(m,l,0,s0vect,col,rp0,0) ) return 0;
3318: }
3319: return 1;
1.1 noro 3320: }
3321:
3322: int do_diagonalize_trace(int sugar,int m)
3323: {
1.6 noro 3324: int i,nh,stat;
3325: NODE r,g,t;
3326: ND h,nf,nfq,s,head;
3327: NDV nfv,nfqv;
3328: Q q,den,num;
3329: union oNDC hc;
3330: NODE node;
3331: LIST l;
3332: Z iq;
3333: P cont,cont1;
1.1 noro 3334:
1.6 noro 3335: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
3336: if ( nd_gentrace ) {
3337: /* Trace = [1,index,1,1] */
3338: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
3339: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
3340: }
3341: /* for nd_ps */
3342: s = ndvtond(m,nd_ps[i]);
3343: s = nd_separate_head(s,&head);
3344: stat = nd_nf_pbucket(m,s,nd_ps,1,&nf);
3345: if ( !stat ) return 0;
3346: nf = nd_add(m,head,nf);
3347: ndv_free(nd_ps[i]);
3348: nd_ps[i] = ndtondv(m,nf);
3349: nd_free(nf);
3350:
3351: /* for nd_ps_trace */
3352: if ( nd_demand )
3353: nfv = ndv_load(i);
3354: else
3355: nfv = nd_ps_trace[i];
3356: s = ndvtond(0,nfv);
3357: s = nd_separate_head(s,&head);
3358: stat = nd_nf(0,head,s,nd_ps_trace,1,&nf);
3359: if ( !stat ) return 0;
3360: ndv_free(nfv);
3361: hc = HCU(nf); nd_removecont(0,nf);
3362: /* exact division */
1.1 noro 3363: cont = ndc_div(0,hc,HCU(nf));
1.6 noro 3364: if ( nd_gentrace ) finalize_tracelist(i,cont);
3365: nfv = ndtondv(0,nf);
3366: nd_free(nf);
3367: nd_bound[i] = ndv_compute_bound(nfv);
3368: register_hcf(nfv);
3369: if ( nd_demand ) {
3370: ndv_save(nfv,i);
3371: ndv_free(nfv);
3372: } else
3373: nd_ps_trace[i] = nfv;
3374: }
3375: return 1;
1.1 noro 3376: }
3377:
3378: static struct oEGT eg_invdalg;
3379: struct oEGT eg_le;
3380:
3381: void nd_subst_vector(VL vl,P p,NODE subst,P *r)
3382: {
3383: NODE tn;
3384: P p1;
3385:
3386: for ( tn = subst; tn; tn = NEXT(NEXT(tn)) ) {
3387: substp(vl,p,BDY(tn),BDY(NEXT(tn)),&p1); p = p1;
3388: }
3389: *r = p;
3390: }
3391:
3392: NODE nd_gb_trace(int m,int ishomo,int **indp)
3393: {
1.6 noro 3394: int i,nh,sugar,stat;
3395: NODE r,g,t;
3396: ND_pairs d;
3397: ND_pairs l;
3398: ND h,nf,nfq,s,head;
3399: NDV nfv,nfqv;
3400: Z q,den,num;
3401: P hc;
3402: union oNDC dn,hnfq;
3403: struct oEGT eg_monic,egm0,egm1;
3404: int diag_count = 0;
3405: P cont;
3406: LIST list;
1.49 noro 3407: struct oHPDATA current_hpdata,final_hpdata;
3408: int final_hpvalue;
1.6 noro 3409:
3410: init_eg(&eg_monic);
3411: init_eg(&eg_invdalg);
3412: init_eg(&eg_le);
3413: g = 0; d = 0;
3414: for ( i = 0; i < nd_psn; i++ ) {
3415: d = update_pairs(d,g,i,0);
3416: g = update_base(g,i);
3417: }
3418: sugar = 0;
1.49 noro 3419: if ( nd_hpdata ) {
1.52 noro 3420: if ( DP_Print ) fprintf(asir_out,"Hilbert driven algorithm.\n");
1.49 noro 3421: setup_hpdata(&final_hpdata,¤t_hpdata);
3422: }
3423:
1.6 noro 3424: while ( d ) {
1.1 noro 3425: again:
1.6 noro 3426: l = nd_minp(d,&d);
3427: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
3428: if ( SG(l) != sugar ) {
1.1 noro 3429: #if 1
1.6 noro 3430: if ( ishomo ) {
3431: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3432: stat = do_diagonalize_trace(sugar,m);
3433: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3434: diag_count = 0;
1.1 noro 3435: if ( !stat ) {
1.6 noro 3436: NEXT(l) = d; d = l;
3437: d = nd_reconstruct(1,d);
3438: goto again;
1.1 noro 3439: }
1.6 noro 3440: }
3441: #endif
3442: sugar = SG(l);
3443: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
1.49 noro 3444: if ( nd_hpdata ) {
3445: if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) )
3446: break;
3447: else {
3448: final_hpvalue = hpvalue(&final_hpdata,sugar);
3449: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
1.52 noro 3450: // if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
1.49 noro 3451: d = nd_remove_same_sugar(d,sugar);
3452: continue;
3453: }
3454: }
3455: }
1.6 noro 3456: }
3457: stat = nd_sp(m,0,l,&h);
3458: if ( !stat ) {
3459: NEXT(l) = d; d = l;
3460: d = nd_reconstruct(1,d);
3461: goto again;
3462: }
1.1 noro 3463: #if USE_GEOBUCKET
1.39 noro 3464: stat = nd_nf_pbucket(m,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 3465: #else
1.39 noro 3466: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 3467: #endif
1.6 noro 3468: if ( !stat ) {
3469: NEXT(l) = d; d = l;
3470: d = nd_reconstruct(1,d);
3471: goto again;
3472: } else if ( nf ) {
3473: if ( nd_demand ) {
3474: nfqv = ndv_load(nd_psn);
3475: nfq = ndvtond(0,nfqv);
3476: } else
3477: nfq = 0;
3478: if ( !nfq ) {
1.39 noro 3479: if ( !nd_sp(0,1,l,&h) || !nd_nf(0,0,h,nd_ps_trace,!nd_top&&!Top,&nfq) ) {
1.6 noro 3480: NEXT(l) = d; d = l;
3481: d = nd_reconstruct(1,d);
3482: goto again;
3483: }
3484: }
3485: if ( nfq ) {
3486: /* m|HC(nfq) => failure */
3487: if ( nd_vc ) {
3488: nd_subst_vector(nd_vc,HCP(nfq),nd_subst,&hc); q = (Z)hc;
3489: } else
3490: q = HCZ(nfq);
3491: if ( !remqi((Q)q,m) ) return 0;
3492:
3493: if ( DP_Print ) { printf("+"); fflush(stdout); }
3494: hnfq = HCU(nfq);
3495: if ( nd_nalg ) {
3496: /* m|DN(HC(nf)^(-1)) => failure */
3497: get_eg(&egm0);
3498: if ( !nd_monic(m,&nfq) ) return 0;
3499: get_eg(&egm1); add_eg(&eg_monic,&egm0,&egm1);
3500: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
3501: nfv = ndv_dup(0,nfqv); ndv_mod(m,nfv); nd_free(nf);
3502: } else {
3503: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
3504: nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf);
3505: }
3506: if ( nd_gentrace ) {
3507: /* exact division */
3508: cont = ndc_div(0,hnfq,HCU(nfqv));
3509: if ( !UNIQ(cont) ) {
3510: t = mknode(4,NULLP,NULLP,NULLP,cont);
3511: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
3512: nd_tracelist = t;
3513: }
3514: }
1.24 noro 3515: nh = ndv_newps(0,nfv,nfqv);
1.6 noro 3516: if ( ishomo && ++diag_count == diag_period ) {
3517: diag_count = 0;
3518: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3519: stat = do_diagonalize_trace(sugar,m);
3520: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3521: if ( !stat ) {
1.1 noro 3522: NEXT(l) = d; d = l;
3523: d = nd_reconstruct(1,d);
3524: goto again;
1.6 noro 3525: }
1.1 noro 3526: }
1.6 noro 3527: d = update_pairs(d,g,nh,0);
3528: g = update_base(g,nh);
1.49 noro 3529: if ( nd_hpdata ) {
3530: update_hpdata(¤t_hpdata,nh,1);
3531: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
1.52 noro 3532: // if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
1.49 noro 3533: d = nd_remove_same_sugar(d,sugar);
3534: }
3535: }
1.6 noro 3536: } else {
3537: if ( DP_Print ) { printf("*"); fflush(stdout); }
3538: }
3539: } else {
3540: if ( DP_Print ) { printf("."); fflush(stdout); }
1.1 noro 3541: }
1.6 noro 3542: FREENDP(l);
3543: }
3544: if ( nd_nalg ) {
3545: if ( DP_Print ) {
3546: print_eg("monic",&eg_monic);
3547: print_eg("invdalg",&eg_invdalg);
3548: print_eg("le",&eg_le);
1.1 noro 3549: }
1.6 noro 3550: }
1.1 noro 3551: conv_ilist(nd_demand,1,g,indp);
1.41 noro 3552: if ( DP_Print ) { printf("\nnd_gb_trace done.\n"); fflush(stdout); }
1.6 noro 3553: return g;
1.1 noro 3554: }
3555:
3556: int ndv_compare(NDV *p1,NDV *p2)
3557: {
3558: return DL_COMPARE(HDL(*p1),HDL(*p2));
3559: }
3560:
3561: int ndv_compare_rev(NDV *p1,NDV *p2)
3562: {
3563: return -DL_COMPARE(HDL(*p1),HDL(*p2));
3564: }
3565:
3566: int ndvi_compare(NDVI p1,NDVI p2)
3567: {
3568: return DL_COMPARE(HDL(p1->p),HDL(p2->p));
3569: }
3570:
3571: int ndvi_compare_rev(NDVI p1,NDVI p2)
3572: {
3573: return -DL_COMPARE(HDL(p1->p),HDL(p2->p));
3574: }
3575:
3576: NODE ndv_reduceall(int m,NODE f)
3577: {
3578: int i,j,n,stat;
3579: ND nf,g,head;
3580: NODE t,a0,a;
3581: union oNDC dn;
3582: Q q,num,den;
3583: NODE node;
3584: LIST l;
3585: Z iq,jq;
3586: int *perm;
3587: union oNDC hc;
3588: P cont,cont1;
3589:
3590: if ( nd_nora ) return f;
3591: n = length(f);
1.24 noro 3592: ndv_setup(m,0,f,0,1,0);
1.1 noro 3593: perm = (int *)MALLOC(n*sizeof(int));
3594: if ( nd_gentrace ) {
3595: for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) )
1.6 noro 3596: perm[i] = ZTOS((Q)ARG1(BDY((LIST)BDY(t))));
1.1 noro 3597: }
3598: for ( i = 0; i < n; ) {
3599: if ( nd_gentrace ) {
3600: /* Trace = [1,index,1,1] */
1.6 noro 3601: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
1.1 noro 3602: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
3603: }
3604: g = ndvtond(m,nd_ps[i]);
3605: g = nd_separate_head(g,&head);
1.6 noro 3606: stat = nd_nf(m,head,g,nd_ps,1,&nf);
1.1 noro 3607: if ( !stat )
3608: nd_reconstruct(0,0);
3609: else {
3610: if ( DP_Print ) { printf("."); fflush(stdout); }
3611: ndv_free(nd_ps[i]);
3612: hc = HCU(nf); nd_removecont(m,nf);
3613: if ( nd_gentrace ) {
3614: for ( t = nd_tracelist; t; t = NEXT(t) ) {
1.6 noro 3615: jq = ARG1(BDY((LIST)BDY(t))); j = ZTOS(jq);
3616: STOZ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq;
1.1 noro 3617: }
1.6 noro 3618: /* exact division */
1.1 noro 3619: cont = ndc_div(m,hc,HCU(nf));
3620: finalize_tracelist(perm[i],cont);
3621: }
3622: nd_ps[i] = ndtondv(m,nf); nd_free(nf);
3623: nd_bound[i] = ndv_compute_bound(nd_ps[i]);
3624: i++;
3625: }
3626: }
3627: if ( DP_Print ) { printf("\n"); }
3628: for ( a0 = 0, i = 0; i < n; i++ ) {
3629: NEXTNODE(a0,a);
3630: if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i];
3631: else {
3632: for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break;
3633: BDY(a) = (pointer)nd_ps[j];
3634: }
3635: }
3636: NEXT(a) = 0;
3637: return a0;
3638: }
3639:
1.41 noro 3640: int ndplength(ND_pairs d)
3641: {
3642: int i;
3643: for ( i = 0; d; i++ ) d = NEXT(d);
3644: return i;
3645: }
3646:
1.1 noro 3647: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz)
3648: {
3649: ND_pairs d1,nd,cur,head,prev,remove;
1.41 noro 3650: int len0;
1.1 noro 3651:
3652: if ( !g ) return d;
3653: /* for testing */
3654: if ( gensyz && nd_gensyz == 2 ) {
3655: d1 = nd_newpairs(g,t);
3656: if ( !d )
3657: return d1;
3658: else {
3659: nd = d;
3660: while ( NEXT(nd) ) nd = NEXT(nd);
3661: NEXT(nd) = d1;
3662: return d;
3663: }
3664: }
3665: d = crit_B(d,t);
3666: d1 = nd_newpairs(g,t);
1.41 noro 3667: len0 = ndplength(d1);
1.1 noro 3668: d1 = crit_M(d1);
3669: d1 = crit_F(d1);
1.41 noro 3670: NcriMF += len0-ndplength(d1);
1.1 noro 3671: if ( gensyz || do_weyl )
3672: head = d1;
3673: else {
3674: prev = 0; cur = head = d1;
3675: while ( cur ) {
3676: if ( crit_2( cur->i1,cur->i2 ) ) {
3677: remove = cur;
3678: if ( !prev ) head = cur = NEXT(cur);
3679: else cur = NEXT(prev) = NEXT(cur);
1.41 noro 3680: FREENDP(remove); Ncri2++;
1.1 noro 3681: } else {
3682: prev = cur; cur = NEXT(cur);
3683: }
3684: }
3685: }
3686: if ( !d )
3687: return head;
3688: else {
3689: nd = d;
3690: while ( NEXT(nd) ) nd = NEXT(nd);
3691: NEXT(nd) = head;
3692: return d;
3693: }
3694: }
3695:
1.24 noro 3696: ND_pairs merge_pairs_s(ND_pairs d,ND_pairs d1);
3697:
1.30 noro 3698: ND_pairs update_pairs_s( ND_pairs d, int t,NODE *syz)
1.24 noro 3699: {
3700: ND_pairs d1;
1.26 noro 3701: struct oEGT eg1,eg2,eg3;
1.24 noro 3702:
1.30 noro 3703: if ( !t ) return d;
1.26 noro 3704: get_eg(&eg1);
1.30 noro 3705: d1 = nd_newpairs_s(t,syz);
1.26 noro 3706: get_eg(&eg2); add_eg(&eg_create,&eg1,&eg2);
1.24 noro 3707: d = merge_pairs_s(d,d1);
1.26 noro 3708: get_eg(&eg3); add_eg(&eg_merge,&eg2,&eg3);
1.24 noro 3709: return d;
3710: }
1.1 noro 3711:
1.47 noro 3712: int update_pairs_array_s( ND_pairs *d, int t,NODE *syz)
3713: {
3714: ND_pairs *d1;
3715: struct oEGT eg1,eg2,eg3;
3716: int i;
3717:
3718: if ( !t ) return 0;
3719: get_eg(&eg1);
3720: Nnewpair = 0;
3721: d1 = nd_newpairs_array_s(t,syz);
3722: get_eg(&eg2); add_eg(&eg_create,&eg1,&eg2);
3723: for ( i = 0; i < nd_nbase; i++ )
3724: d[i] = merge_pairs_s(d[i],d1[i]);
3725: get_eg(&eg3); add_eg(&eg_merge,&eg2,&eg3);
3726: return Nnewpair;
3727: }
3728:
1.1 noro 3729: ND_pairs nd_newpairs( NODE g, int t )
3730: {
3731: NODE h;
3732: UINT *dl;
3733: int ts,s,i,t0,min,max;
3734: ND_pairs r,r0;
3735:
3736: dl = DL(nd_psh[t]);
3737: ts = SG(nd_psh[t]) - TD(dl);
1.17 noro 3738: if ( nd_module && nd_intersect && (MPOS(dl) > nd_intersect) ) return 0;
1.1 noro 3739: for ( r0 = 0, h = g; h; h = NEXT(h) ) {
3740: if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) )
3741: continue;
3742: if ( nd_gbblock ) {
3743: t0 = (long)BDY(h);
3744: for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) {
3745: min = nd_gbblock[i]; max = nd_gbblock[i+1];
3746: if ( t0 >= min && t0 <= max && t >= min && t <= max )
3747: break;
3748: }
3749: if ( nd_gbblock[i] >= 0 )
3750: continue;
3751: }
1.41 noro 3752: NEXTND_pairs(r0,r); Npairs++;
1.1 noro 3753: r->i1 = (long)BDY(h);
3754: r->i2 = t;
3755: ndl_lcm(DL(nd_psh[r->i1]),dl,r->lcm);
3756: s = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
3757: SG(r) = MAX(s,ts) + TD(LCM(r));
3758: /* experimental */
3759: if ( nd_sugarweight )
3760: r->sugar2 = ndl_weight2(r->lcm);
3761: }
3762: if ( r0 ) NEXT(r) = 0;
3763: return r0;
3764: }
3765:
1.46 noro 3766: int sig_cmpdl_op(int n,DL d1,DL d2)
3767: {
3768: int e1,e2,i,j,l;
3769: int *t1,*t2;
3770: int len,head;
3771: struct order_pair *pair;
3772:
3773: len = nd_sba_modord->block_length;
3774: pair = nd_sba_modord->order_pair;
3775:
3776: head = 0;
3777: for ( i = 0, t1 = d1->d, t2 = d2->d; i < len; i++ ) {
3778: l = pair[i].length;
3779: switch ( pair[i].order ) {
3780: case 0:
3781: for ( j = 0, e1 = e2 = 0; j < l; j++ ) {
3782: e1 += t1[j];
3783: e2 += t2[j];
3784: }
3785: if ( e1 > e2 )
3786: return 1;
3787: else if ( e1 < e2 )
3788: return -1;
3789: else {
3790: for ( j = l - 1; j >= 0 && t1[j] == t2[j]; j-- );
3791: if ( j >= 0 )
3792: return t1[j] < t2[j] ? 1 : -1;
3793: }
3794: break;
3795: case 1:
3796: for ( j = 0, e1 = e2 = 0; j < l; j++ ) {
3797: e1 += t1[j];
3798: e2 += t2[j];
3799: }
3800: if ( e1 > e2 )
3801: return 1;
3802: else if ( e1 < e2 )
3803: return -1;
3804: else {
3805: for ( j = 0; j < l && t1[j] == t2[j]; j++ );
3806: if ( j < l )
3807: return t1[j] > t2[j] ? 1 : -1;
3808: }
3809: break;
3810: case 2:
3811: for ( j = 0; j < l && t1[j] == t2[j]; j++ );
3812: if ( j < l )
3813: return t1[j] > t2[j] ? 1 : -1;
3814: break;
3815: default:
3816: error("sig_cmpdl_op : invalid order"); break;
3817: }
3818: t1 += l; t2 += l; head += l;
3819: }
3820: return 0;
3821: }
3822:
3823: int sig_cmpdl_mat(int n,DL d1,DL d2)
3824: {
3825: int *v,*t1,*t2;
3826: int s,i,j,len;
3827: int **matrix;
3828: static int *w;
3829: static int nvar = 0;
3830:
3831: if ( nvar != n ) {
3832: nvar = n; w = (int *)MALLOC(n*sizeof(int));
3833: }
3834: for ( i = 0, t1 = d1->d, t2 = d2->d; i < n; i++ )
3835: w[i] = t1[i]-t2[i];
3836: len = nd_sba_modord->row;
3837: matrix = nd_sba_modord->matrix;
3838: for ( j = 0; j < len; j++ ) {
3839: v = matrix[j];
3840: for ( i = 0, s = 0; i < n; i++ )
3841: s += v[i]*w[i];
3842: if ( s > 0 )
3843: return 1;
3844: else if ( s < 0 )
3845: return -1;
3846: }
3847: return 0;
3848: }
3849:
3850: struct comp_sig_spec *create_comp_sig_spec(VL current_vl,VL old_vl,Obj ord,Obj weight)
3851: {
3852: struct comp_sig_spec *spec;
3853: VL ovl,vl;
3854: V ov;
3855: int i,j,n,nvar,s;
3856: NODE node,t,tn;
3857: struct order_pair *l;
3858: MAT m;
3859: Obj **b;
3860: int **w;
3861: int *a;
3862:
3863: spec = (struct comp_sig_spec *)MALLOC(sizeof(struct comp_sig_spec));
3864: for ( i = 0, vl = current_vl; vl; vl = NEXT(vl), i++ );
3865: spec->n = nvar = i;
3866: if ( old_vl != 0 ) {
3867: spec->oldv = (int *)MALLOC(nvar*sizeof(int));
3868: for ( i = 0, ovl = old_vl; i < nvar; ovl = NEXT(ovl), i++ ) {
3869: ov = ovl->v;
3870: for ( j = 0, vl = current_vl; vl; vl = NEXT(vl), j++ )
3871: if ( ov == vl->v ) break;
3872: spec->oldv[i] = j;
3873: }
3874: } else
3875: spec->oldv = 0;
3876: if ( !ord || NUM(ord) ) {
3877: switch ( ZTOS((Z)ord) ) {
3878: case 0:
3879: spec->cmpdl = cmpdl_revgradlex; break;
3880: case 1:
3881: spec->cmpdl = cmpdl_gradlex; break;
3882: case 2:
3883: spec->cmpdl = cmpdl_lex; break;
3884: default:
3885: error("create_comp_sig_spec : invalid spec"); break;
3886: }
3887: } else if ( OID(ord) == O_LIST ) {
3888: node = BDY((LIST)ord);
3889: for ( n = 0, t = node; t; t = NEXT(t), n++ );
3890: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
3891: for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {
3892: tn = BDY((LIST)BDY(t)); l[i].order = ZTOS((Q)BDY(tn));
3893: tn = NEXT(tn); l[i].length = ZTOS((Q)BDY(tn));
3894: s += l[i].length;
3895: }
3896: if ( s != nvar )
3897: error("create_comp_sig_spec : invalid spec");
3898: spec->order_pair = l;
3899: spec->block_length = n;
3900: spec->cmpdl = sig_cmpdl_op;
3901: } else if ( OID(ord) == O_MAT ) {
3902: m = (MAT)ord; b = (Obj **)BDY(m);
3903: if ( m->col != nvar )
3904: error("create_comp_sig_spec : invalid spec");
3905: w = almat(m->row,m->col);
3906: for ( i = 0; i < m->row; i++ )
3907: for ( j = 0; j < m->col; j++ )
3908: w[i][j] = ZTOS((Q)b[i][j]);
3909: spec->row = m->row;
3910: spec->matrix = w;
3911: spec->cmpdl = sig_cmpdl_mat;
3912: } else
3913: error("create_comp_sig_spec : invalid spec");
3914: if ( weight != 0 ) {
3915: node = BDY((LIST)weight);
3916: a = (int *)MALLOC(nvar*sizeof(int));
3917: for ( i = 0; i < nvar; i++, node = NEXT(node) )
3918: a[i] = ZTOS((Z)BDY(node));
3919: spec->weight = a;
3920: }
3921: return spec;
3922: }
3923:
3924: #define SIG_MUL_WEIGHT(a,i) (weight?(a)*weight[i]:(a))
3925:
3926: int comp_sig_monomial(int n,DL d1,DL d2)
3927: {
3928: static DL m1,m2;
3929: static int nvar = 0;
3930: int *oldv,*weight;
3931: int i,w1,w2;
3932:
3933: if ( nvar != n ) {
3934: nvar = n; NEWDL(m1,nvar); NEWDL(m2,nvar);
3935: }
3936: if ( !nd_sba_modord )
3937: return (*cmpdl)(n,d1,d2);
1.55 ! noro 3938: else if ( !nd_sba_modord->weight && !nd_sba_modord->oldv ) {
! 3939: return (*nd_sba_modord->cmpdl)(n,d1,d2);
! 3940: } else {
1.46 noro 3941: weight = nd_sba_modord->weight;
3942: oldv = nd_sba_modord->oldv;
3943: if ( oldv ) {
3944: for ( i = 0; i < n; i++ ) {
3945: m1->d[i] = d1->d[oldv[i]]; m2->d[i] = d2->d[oldv[i]];
3946: }
3947: } else {
3948: for ( i = 0; i < n; i++ ) {
3949: m1->d[i] = d1->d[i]; m2->d[i] = d2->d[i];
3950: }
3951: }
3952: for ( i = 0, w1 = w2 = 0; i < n; i++ ) {
3953: w1 += SIG_MUL_WEIGHT(m1->d[i],i);
3954: w2 += SIG_MUL_WEIGHT(m2->d[i],i);
3955: }
3956: m1->td = w1; m2->td = w2;
3957: return (*nd_sba_modord->cmpdl)(n,m1,m2);
3958: }
3959: }
3960:
1.24 noro 3961: int comp_sig(SIG s1,SIG s2)
3962: {
1.38 noro 3963: if ( nd_sba_pot ) {
3964: if ( s1->pos > s2->pos ) return 1;
3965: else if ( s1->pos < s2->pos ) return -1;
1.55 ! noro 3966: else return comp_sig_monomial(nd_nvar,DL(s1),DL(s2));
1.38 noro 3967: } else {
3968: static DL m1,m2;
1.44 noro 3969: static int nvar = 0;
1.38 noro 3970: int ret;
3971:
3972: if ( nvar != nd_nvar ) {
3973: nvar = nd_nvar; NEWDL(m1,nvar); NEWDL(m2,nvar);
3974: }
1.47 noro 3975: if ( !nd_sba_modord )
1.55 ! noro 3976: ret = (*cmpdl)(nd_nvar,DL2(s1),DL2(s2));
1.47 noro 3977: else
1.55 ! noro 3978: ret = comp_sig_monomial(nd_nvar,DL2(s1),DL2(s2));
1.38 noro 3979: if ( ret != 0 ) return ret;
3980: else if ( s1->pos > s2->pos ) return 1;
3981: else if ( s1->pos < s2->pos ) return -1;
3982: else return 0;
1.24 noro 3983: }
3984: }
3985:
3986: int _create_spair_s(int i1,int i2,ND_pairs sp,SIG sig1,SIG sig2)
3987: {
3988: int ret,s1,s2;
3989: RHist p1,p2;
3990: static int wpd;
3991: static UINT *lcm;
3992:
3993: sp->i1 = i1;
3994: sp->i2 = i2;
3995: p1 = nd_psh[i1];
3996: p2 = nd_psh[i2];
3997: ndl_lcm(DL(p1),DL(p2),sp->lcm);
1.49 noro 3998: #if 0
1.24 noro 3999: s1 = SG(p1)-TD(DL(p1));
4000: s2 = SG(p2)-TD(DL(p2));
4001: SG(sp) = MAX(s1,s2) + TD(sp->lcm);
1.49 noro 4002: #endif
1.24 noro 4003:
1.26 noro 4004: if ( wpd != nd_wpd ) {
1.24 noro 4005: wpd = nd_wpd;
4006: lcm = (UINT *)MALLOC(wpd*sizeof(UINT));
4007: }
4008: // DL(sig1) <- sp->lcm
4009: // DL(sig1) -= DL(p1)
4010: // DL(sig1) += DL(p1->sig)
1.27 noro 4011: ndl_sub(sp->lcm,DL(p1),lcm);
1.24 noro 4012: _ndltodl(lcm,DL(sig1));
4013: _addtodl(nd_nvar,DL(p1->sig),DL(sig1));
4014: sig1->pos = p1->sig->pos;
1.55 ! noro 4015: _adddl(nd_nvar,DL(sig1),nd_sba_hm[sig1->pos],DL2(sig1));
1.24 noro 4016:
4017: // DL(sig2) <- sp->lcm
4018: // DL(sig2) -= DL(p2)
4019: // DL(sig2) += DL(p2->sig)
1.27 noro 4020: ndl_sub(sp->lcm,DL(p2),lcm);
1.24 noro 4021: _ndltodl(lcm,DL(sig2));
4022: _addtodl(nd_nvar,DL(p2->sig),DL(sig2));
4023: sig2->pos = p2->sig->pos;
1.55 ! noro 4024: _adddl(nd_nvar,DL(sig2),nd_sba_hm[sig2->pos],DL2(sig2));
1.24 noro 4025:
4026: ret = comp_sig(sig1,sig2);
4027: if ( ret == 0 ) return 0;
4028: else if ( ret > 0 ) sp->sig = sig1;
4029: else sp->sig = sig2;
1.49 noro 4030:
4031: s1 = DL(sig1)->td+nd_sba_hm[p1->sig->pos]->td;
4032: s2 = DL(sig2)->td+nd_sba_hm[p2->sig->pos]->td;
4033: SG(sp) = MAX(s1,s2);
4034:
1.24 noro 4035: return 1;
4036: }
4037:
4038: SIG dup_sig(SIG sig)
4039: {
4040: SIG r;
4041:
4042: if ( !sig ) return 0;
4043: else {
4044: NEWSIG(r);
4045: _copydl(nd_nvar,DL(sig),DL(r));
1.55 ! noro 4046: _copydl(nd_nvar,DL2(sig),DL2(r));
1.24 noro 4047: r->pos = sig->pos;
4048: return r;
4049: }
4050: }
4051:
4052: void dup_ND_pairs(ND_pairs to,ND_pairs from)
4053: {
4054: to->i1 = from->i1;
4055: to->i2 = from->i2;
4056: to->sugar = from->sugar;
4057: to->sugar2 = from->sugar2;
4058: ndl_copy(from->lcm,to->lcm);
4059: to->sig = dup_sig(from->sig);
4060: }
4061:
4062: ND_pairs merge_pairs_s(ND_pairs p1,ND_pairs p2)
4063: {
4064: struct oND_pairs root;
4065: ND_pairs q1,q2,r0,r;
4066: int ret;
4067:
4068: r = &root;
4069: for ( q1 = p1, q2 = p2; q1 != 0 && q2 != 0; ) {
4070: ret = comp_sig(q1->sig,q2->sig);
4071: if ( ret < 0 ) {
4072: r->next = q1; r = q1; q1 = q1->next;
4073: } else if ( ret > 0 ) {
4074: r->next = q2; r = q2; q2 = q2->next;
4075: } else {
1.47 noro 4076: Nnewpair--;
1.24 noro 4077: ret = DL_COMPARE(q1->lcm,q2->lcm);
1.35 noro 4078: Nsamesig++;
1.24 noro 4079: if ( ret < 0 ) {
4080: r->next = q1; r = q1; q1 = q1->next;
4081: q2 = q2->next;
4082: } else {
4083: r->next = q2; r = q2; q2 = q2->next;
4084: q1 = q1->next;
4085: }
4086: }
4087: }
4088: if ( q1 ) {
4089: r->next = q1;
4090: } else {
4091: r->next = q2;
4092: }
4093: return root.next;
4094: }
4095:
4096: ND_pairs insert_pair_s(ND_pairs l,ND_pairs s)
4097: {
4098: ND_pairs p,prev;
1.47 noro 4099: int ret=1;
1.24 noro 4100:
4101: for ( p = l, prev = 0; p != 0; prev = p, p = p->next ) {
4102: if ( (ret = comp_sig(s->sig,p->sig)) <= 0 )
4103: break;
4104: }
4105: if ( ret == 0 ) {
4106: ret = DL_COMPARE(s->lcm,p->lcm);
4107: if ( ret < 0 ) {
4108: // replace p with s
4109: s->next = p->next;
4110: if ( prev == 0 ) {
4111: return s;
4112: } else {
4113: prev->next = s;
4114: return l;
4115: }
4116: } else
4117: return l;
4118: } else {
4119: // insert s between prev and p
1.47 noro 4120: Nnewpair++;
1.24 noro 4121: s->next = p;
4122: if ( prev == 0 ) {
4123: return s;
4124: } else {
4125: prev->next = s;
4126: return l;
4127: }
4128: }
4129: }
4130:
1.29 noro 4131: INLINE int __dl_redble(DL d1,DL d2,int nvar)
4132: {
4133: int i;
4134:
4135: if ( d1->td > d2->td )
4136: return 0;
4137: for ( i = nvar-1; i >= 0; i-- )
4138: if ( d1->d[i] > d2->d[i] )
4139: break;
4140: if ( i >= 0 )
4141: return 0;
4142: else
4143: return 1;
4144: }
4145:
1.30 noro 4146: ND_pairs nd_newpairs_s(int t, NODE *syz)
1.24 noro 4147: {
4148: NODE h,s;
4149: UINT *dl;
1.27 noro 4150: int ts,ret,i;
1.24 noro 4151: ND_pairs r,r0,_sp,sp;
1.29 noro 4152: SIG spsig,tsig;
1.44 noro 4153: static int nvar = 0;
1.29 noro 4154: static SIG _sig1,_sig2;
1.26 noro 4155: struct oEGT eg1,eg2,eg3,eg4;
1.24 noro 4156:
4157: NEWND_pairs(_sp);
1.29 noro 4158: if ( !_sig1 || nvar != nd_nvar ) {
4159: nvar = nd_nvar; NEWSIG(_sig1); NEWSIG(_sig2);
4160: }
1.24 noro 4161: r0 = 0;
1.27 noro 4162: for ( i = 0; i < t; i++ ) {
4163: ret = _create_spair_s(i,t,_sp,_sig1,_sig2);
1.24 noro 4164: if ( ret ) {
4165: spsig = _sp->sig;
1.29 noro 4166: for ( s = syz[spsig->pos]; s; s = s->next ) {
1.24 noro 4167: tsig = (SIG)s->body;
1.29 noro 4168: if ( _dl_redble(DL(tsig),DL(spsig),nd_nvar) )
1.24 noro 4169: break;
4170: }
4171: if ( s == 0 ) {
4172: NEWND_pairs(sp);
4173: dup_ND_pairs(sp,_sp);
4174: r0 = insert_pair_s(r0,sp);
1.26 noro 4175: } else
4176: Nsyz++;
1.24 noro 4177: }
4178: }
4179: return r0;
4180: }
4181:
1.47 noro 4182: ND_pairs *nd_newpairs_array_s(int t, NODE *syz)
4183: {
4184: NODE h,s;
4185: UINT *dl;
4186: int ts,ret,i;
4187: ND_pairs r,r0,_sp,sp;
4188: ND_pairs *d;
4189: SIG spsig,tsig;
4190: static int nvar = 0;
4191: static SIG _sig1,_sig2;
4192: struct oEGT eg1,eg2,eg3,eg4;
4193:
4194: NEWND_pairs(_sp);
4195: if ( !_sig1 || nvar != nd_nvar ) {
4196: nvar = nd_nvar; NEWSIG(_sig1); NEWSIG(_sig2);
4197: }
4198: d = (ND_pairs *)MALLOC(nd_nbase*sizeof(ND_pairs));
4199: Nnewpair = 0;
4200: for ( i = 0; i < t; i++ ) {
4201: ret = _create_spair_s(i,t,_sp,_sig1,_sig2);
4202: if ( ret ) {
4203: spsig = _sp->sig;
4204: for ( s = syz[spsig->pos]; s; s = s->next ) {
4205: tsig = (SIG)s->body;
4206: if ( _dl_redble(DL(tsig),DL(spsig),nd_nvar) )
4207: break;
4208: }
4209: if ( s == 0 ) {
4210: NEWND_pairs(sp);
4211: dup_ND_pairs(sp,_sp);
4212: d[spsig->pos] = insert_pair_s(d[spsig->pos],sp);
4213: } else
4214: Nsyz++;
4215: }
4216: }
4217: return d;
4218: }
4219:
1.1 noro 4220: /* ipair = [i1,i2],[i1,i2],... */
4221: ND_pairs nd_ipairtospair(NODE ipair)
4222: {
4223: int s1,s2;
4224: NODE tn,t;
4225: ND_pairs r,r0;
4226:
4227: for ( r0 = 0, t = ipair; t; t = NEXT(t) ) {
4228: NEXTND_pairs(r0,r);
4229: tn = BDY((LIST)BDY(t));
1.6 noro 4230: r->i1 = ZTOS((Q)ARG0(tn));
4231: r->i2 = ZTOS((Q)ARG1(tn));
1.1 noro 4232: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
4233: s1 = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
4234: s2 = SG(nd_psh[r->i2])-TD(DL(nd_psh[r->i2]));
4235: SG(r) = MAX(s1,s2) + TD(LCM(r));
4236: /* experimental */
4237: if ( nd_sugarweight )
4238: r->sugar2 = ndl_weight2(r->lcm);
4239: }
4240: if ( r0 ) NEXT(r) = 0;
4241: return r0;
4242: }
4243:
4244: /* kokokara */
4245:
4246: ND_pairs crit_B( ND_pairs d, int s )
4247: {
4248: ND_pairs cur,head,prev,remove;
4249: UINT *t,*tl,*lcm;
4250: int td,tdl;
4251:
4252: if ( !d ) return 0;
4253: t = DL(nd_psh[s]);
4254: prev = 0;
4255: head = cur = d;
4256: lcm = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
4257: while ( cur ) {
4258: tl = cur->lcm;
4259: if ( ndl_reducible(tl,t) ) {
4260: ndl_lcm(DL(nd_psh[cur->i1]),t,lcm);
4261: if ( !ndl_equal(lcm,tl) ) {
4262: ndl_lcm(DL(nd_psh[cur->i2]),t,lcm);
4263: if (!ndl_equal(lcm,tl)) {
4264: remove = cur;
4265: if ( !prev ) {
4266: head = cur = NEXT(cur);
4267: } else {
4268: cur = NEXT(prev) = NEXT(cur);
4269: }
1.41 noro 4270: FREENDP(remove); NcriB++;
1.1 noro 4271: } else {
4272: prev = cur; cur = NEXT(cur);
4273: }
4274: } else {
4275: prev = cur; cur = NEXT(cur);
4276: }
4277: } else {
4278: prev = cur; cur = NEXT(cur);
4279: }
4280: }
4281: return head;
4282: }
4283:
4284: ND_pairs crit_M( ND_pairs d1 )
4285: {
4286: ND_pairs e,d2,d3,dd,p;
4287: UINT *id,*jd;
4288:
4289: if ( !d1 ) return d1;
4290: for ( dd = 0, e = d1; e; e = d3 ) {
4291: if ( !(d2 = NEXT(e)) ) {
4292: NEXT(e) = dd;
4293: return e;
4294: }
4295: id = LCM(e);
4296: for ( d3 = 0; d2; d2 = p ) {
4297: p = NEXT(d2);
4298: jd = LCM(d2);
4299: if ( ndl_equal(jd,id) )
4300: ;
4301: else if ( TD(jd) > TD(id) )
4302: if ( ndl_reducible(jd,id) ) continue;
4303: else ;
4304: else if ( ndl_reducible(id,jd) ) goto delit;
4305: NEXT(d2) = d3;
4306: d3 = d2;
4307: }
4308: NEXT(e) = dd;
4309: dd = e;
4310: continue;
4311: /**/
4312: delit: NEXT(d2) = d3;
4313: d3 = d2;
4314: for ( ; p; p = d2 ) {
4315: d2 = NEXT(p);
4316: NEXT(p) = d3;
4317: d3 = p;
4318: }
4319: FREENDP(e);
4320: }
4321: return dd;
4322: }
4323:
4324: ND_pairs crit_F( ND_pairs d1 )
4325: {
4326: ND_pairs rest, head,remove;
4327: ND_pairs last, p, r, w;
4328: int s;
4329:
4330: if ( !d1 ) return d1;
4331: for ( head = last = 0, p = d1; NEXT(p); ) {
4332: r = w = equivalent_pairs(p,&rest);
4333: s = SG(r);
4334: w = NEXT(w);
4335: while ( w ) {
4336: if ( crit_2(w->i1,w->i2) ) {
4337: r = w;
4338: w = NEXT(w);
4339: while ( w ) {
4340: remove = w;
4341: w = NEXT(w);
4342: FREENDP(remove);
4343: }
4344: break;
4345: } else if ( SG(w) < s ) {
4346: FREENDP(r);
4347: r = w;
4348: s = SG(r);
4349: w = NEXT(w);
4350: } else {
4351: remove = w;
4352: w = NEXT(w);
4353: FREENDP(remove);
4354: }
4355: }
4356: if ( last ) NEXT(last) = r;
4357: else head = r;
4358: NEXT(last = r) = 0;
4359: p = rest;
4360: if ( !p ) return head;
4361: }
4362: if ( !last ) return p;
4363: NEXT(last) = p;
4364: return head;
4365: }
4366:
4367: int crit_2( int dp1, int dp2 )
4368: {
4369: return ndl_disjoint(DL(nd_psh[dp1]),DL(nd_psh[dp2]));
4370: }
4371:
4372: ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest )
4373: {
4374: ND_pairs w,p,r,s;
4375: UINT *d;
4376:
4377: w = d1;
4378: d = LCM(w);
4379: s = NEXT(w);
4380: NEXT(w) = 0;
4381: for ( r = 0; s; s = p ) {
4382: p = NEXT(s);
4383: if ( ndl_equal(d,LCM(s)) ) {
4384: NEXT(s) = w; w = s;
4385: } else {
4386: NEXT(s) = r; r = s;
4387: }
4388: }
4389: *prest = r;
4390: return w;
4391: }
4392:
4393: NODE update_base(NODE nd,int ndp)
4394: {
4395: UINT *dl, *dln;
4396: NODE last, p, head;
4397:
4398: dl = DL(nd_psh[ndp]);
4399: for ( head = last = 0, p = nd; p; ) {
4400: dln = DL(nd_psh[(long)BDY(p)]);
4401: if ( ndl_reducible( dln, dl ) ) {
4402: p = NEXT(p);
4403: if ( last ) NEXT(last) = p;
4404: } else {
4405: if ( !last ) head = p;
4406: p = NEXT(last = p);
4407: }
4408: }
4409: head = append_one(head,ndp);
4410: return head;
4411: }
4412:
4413: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest )
4414: {
4415: ND_pairs m,ml,p,l;
4416: UINT *lcm;
4417: int s,td,len,tlen,c,c1;
4418:
4419: if ( !(p = NEXT(m = d)) ) {
4420: *prest = p;
4421: NEXT(m) = 0;
4422: return m;
4423: }
4424: if ( !NoSugar ) {
4425: if ( nd_sugarweight ) {
4426: s = m->sugar2;
4427: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4428: if ( (p->sugar2 < s)
4429: || ((p->sugar2 == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
4430: ml = l; m = p; s = m->sugar2;
4431: }
4432: } else {
4433: s = SG(m);
4434: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4435: if ( (SG(p) < s)
4436: || ((SG(p) == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
4437: ml = l; m = p; s = SG(m);
4438: }
4439: }
4440: } else {
4441: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4442: if ( DL_COMPARE(LCM(p),LCM(m)) < 0 ) {
4443: ml = l; m = p; s = SG(m);
4444: }
4445: }
4446: if ( !ml ) *prest = NEXT(m);
4447: else {
4448: NEXT(ml) = NEXT(m);
4449: *prest = d;
4450: }
4451: NEXT(m) = 0;
4452: return m;
4453: }
4454:
4455: ND_pairs nd_minsugarp( ND_pairs d, ND_pairs *prest )
4456: {
4457: int msugar,i;
4458: ND_pairs t,dm0,dm,dr0,dr;
4459:
4460: if ( nd_sugarweight ) {
4461: for ( msugar = d->sugar2, t = NEXT(d); t; t = NEXT(t) )
4462: if ( t->sugar2 < msugar ) msugar = t->sugar2;
4463: dm0 = 0; dr0 = 0;
4464: for ( i = 0, t = d; t; t = NEXT(t) )
4465: if ( i < nd_f4_nsp && t->sugar2 == msugar ) {
4466: if ( dm0 ) NEXT(dm) = t;
4467: else dm0 = t;
4468: dm = t;
4469: i++;
4470: } else {
4471: if ( dr0 ) NEXT(dr) = t;
4472: else dr0 = t;
4473: dr = t;
4474: }
4475: } else {
4476: for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) )
4477: if ( SG(t) < msugar ) msugar = SG(t);
4478: dm0 = 0; dr0 = 0;
4479: for ( i = 0, t = d; t; t = NEXT(t) )
4480: if ( i < nd_f4_nsp && SG(t) == msugar ) {
4481: if ( dm0 ) NEXT(dm) = t;
4482: else dm0 = t;
4483: dm = t;
4484: i++;
4485: } else {
4486: if ( dr0 ) NEXT(dr) = t;
4487: else dr0 = t;
4488: dr = t;
4489: }
4490: }
4491: NEXT(dm) = 0;
4492: if ( dr0 ) NEXT(dr) = 0;
4493: *prest = dr0;
4494: return dm0;
4495: }
4496:
1.28 noro 4497: ND_pairs nd_minsugarp_s( ND_pairs d, ND_pairs *prest )
4498: {
4499: int msugar;
4500: ND_pairs t,last;
4501:
4502: for ( msugar = SG(d), t = d; t; t = NEXT(t) )
4503: if ( SG(t) == msugar ) last = t;
4504: *prest = last->next;
4505: last->next = 0;
4506: return d;
4507: }
4508:
1.1 noro 4509: int nd_tdeg(NDV c)
4510: {
4511: int wmax = 0;
4512: int i,len;
4513: NMV a;
4514:
4515: len = LEN(c);
4516: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
4517: wmax = MAX(TD(DL(a)),wmax);
4518: return wmax;
4519: }
4520:
1.24 noro 4521: int ndv_newps(int m,NDV a,NDV aq)
1.1 noro 4522: {
4523: int len;
4524: RHist r;
4525: NDV b;
4526: NODE tn;
4527: LIST l;
4528: Z iq;
4529:
4530: if ( nd_psn == nd_pslen ) {
4531: nd_pslen *= 2;
4532: nd_ps = (NDV *)REALLOC((char *)nd_ps,nd_pslen*sizeof(NDV));
4533: nd_ps_trace = (NDV *)REALLOC((char *)nd_ps_trace,nd_pslen*sizeof(NDV));
4534: nd_psh = (RHist *)REALLOC((char *)nd_psh,nd_pslen*sizeof(RHist));
4535: nd_bound = (UINT **)
4536: REALLOC((char *)nd_bound,nd_pslen*sizeof(UINT *));
4537: nd_ps_sym = (NDV *)REALLOC((char *)nd_ps_sym,nd_pslen*sizeof(NDV));
4538: nd_ps_trace_sym = (NDV *)REALLOC((char *)nd_ps_trace_sym,nd_pslen*sizeof(NDV));
4539: }
4540: NEWRHist(r); nd_psh[nd_psn] = r;
4541: nd_ps[nd_psn] = a;
4542: if ( aq ) {
4543: nd_ps_trace[nd_psn] = aq;
4544: if ( !m ) {
4545: register_hcf(aq);
4546: } else if ( m == -2 ) {
4547: /* do nothing */
4548: } else
4549: error("ndv_newps : invalud modulus");
4550: nd_bound[nd_psn] = ndv_compute_bound(aq);
4551: #if 1
4552: SG(r) = SG(aq);
4553: #else
4554: SG(r) = nd_tdeg(aq);
4555: #endif
4556: ndl_copy(HDL(aq),DL(r));
1.24 noro 4557: r->sig = dup_sig(aq->sig);
1.1 noro 4558: } else {
4559: if ( !m ) register_hcf(a);
4560: nd_bound[nd_psn] = ndv_compute_bound(a);
4561: #if 1
4562: SG(r) = SG(a);
4563: #else
4564: SG(r) = nd_tdeg(a);
4565: #endif
4566: ndl_copy(HDL(a),DL(r));
1.24 noro 4567: r->sig = dup_sig(a->sig);
1.1 noro 4568: }
4569: if ( nd_demand ) {
4570: if ( aq ) {
4571: ndv_save(nd_ps_trace[nd_psn],nd_psn);
4572: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
4573: nd_ps_trace_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
4574: nd_ps_trace[nd_psn] = 0;
4575: } else {
4576: ndv_save(nd_ps[nd_psn],nd_psn);
4577: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps[nd_psn]);
4578: nd_ps[nd_psn] = 0;
4579: }
4580: }
4581: if ( nd_gentrace ) {
4582: /* reverse the tracelist and append it to alltracelist */
4583: nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist);
1.6 noro 4584: STOZ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn);
1.1 noro 4585: MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0;
4586: }
4587: return nd_psn++;
4588: }
4589:
1.46 noro 4590: // find LM wrt the specified modord
4591: void ndv_lm_modord(NDV p,DL d)
1.45 noro 4592: {
4593: NMV m;
4594: DL tmp;
4595: int len,i,ret;
4596:
4597: NEWDL(tmp,nd_nvar);
4598: m = BDY(p); len = LEN(p);
1.46 noro 4599: _ndltodl(DL(m),d); // printdl(d); printf("->");
1.45 noro 4600: for ( i = 1, NMV_ADV(m); i < len; i++, NMV_ADV(m) ) {
4601: _ndltodl(DL(m),tmp);
1.46 noro 4602: ret = comp_sig_monomial(nd_nvar,tmp,d);
1.45 noro 4603: if ( ret > 0 ) _copydl(nd_nvar,tmp,d);
4604: }
1.46 noro 4605: // printdl(d); printf("\n");
1.45 noro 4606: }
4607:
1.1 noro 4608: /* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */
4609: /* return 1 if success, 0 if failure (HC(a mod p)) */
4610:
1.24 noro 4611: int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont,int sba)
1.1 noro 4612: {
1.6 noro 4613: int i,j,td,len,max;
4614: NODE s,s0,f0,tn;
4615: UINT *d;
4616: RHist r;
4617: NDVI w;
4618: NDV a,am;
4619: union oNDC hc;
4620: NODE node;
4621: P hcp;
4622: Z iq,jq;
4623: LIST l;
4624:
4625: nd_found = 0; nd_notfirst = 0; nd_create = 0;
4626: /* initialize the tracelist */
4627: nd_tracelist = 0;
4628:
4629: for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++;
4630: w = (NDVI)MALLOC(nd_psn*sizeof(struct oNDVI));
4631: for ( i = j = 0, s = f; s; s = NEXT(s), j++ )
4632: if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; }
4633: if ( !dont_sort ) {
4634: /* XXX heuristic */
1.26 noro 4635: if ( !sba && !nd_ord->id && (nd_ord->ord.simple<2) )
1.6 noro 4636: qsort(w,nd_psn,sizeof(struct oNDVI),
4637: (int (*)(const void *,const void *))ndvi_compare_rev);
4638: else
4639: qsort(w,nd_psn,sizeof(struct oNDVI),
4640: (int (*)(const void *,const void *))ndvi_compare);
4641: }
4642: nd_pslen = 2*nd_psn;
4643: nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4644: nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4645: nd_ps_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4646: nd_ps_trace_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4647: nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist));
4648: nd_bound = (UINT **)MALLOC(nd_pslen*sizeof(UINT *));
4649: nd_hcf = 0;
1.1 noro 4650:
1.6 noro 4651: if ( trace && nd_vc )
4652: makesubst(nd_vc,&nd_subst);
4653: else
4654: nd_subst = 0;
1.1 noro 4655:
1.6 noro 4656: if ( !nd_red )
4657: nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
4658: for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0;
4659: for ( i = 0; i < nd_psn; i++ ) {
4660: hc = HCU(w[i].p);
4661: if ( trace ) {
4662: if ( mod == -2 ) {
4663: /* over a large finite field */
4664: /* trace = small modulus */
4665: a = nd_ps_trace[i] = ndv_dup(-2,w[i].p);
4666: ndv_mod(-2,a);
4667: if ( !dont_removecont) ndv_removecont(-2,a);
4668: am = nd_ps[i] = ndv_dup(trace,w[i].p);
4669: ndv_mod(trace,am);
4670: if ( DL_COMPARE(HDL(am),HDL(a)) )
4671: return 0;
4672: ndv_removecont(trace,am);
4673: } else {
4674: a = nd_ps_trace[i] = ndv_dup(0,w[i].p);
4675: if ( !dont_removecont) ndv_removecont(0,a);
4676: register_hcf(a);
4677: am = nd_ps[i] = ndv_dup(mod,a);
4678: ndv_mod(mod,am);
4679: if ( DL_COMPARE(HDL(am),HDL(a)) )
4680: return 0;
4681: ndv_removecont(mod,am);
4682: }
4683: } else {
4684: a = nd_ps[i] = ndv_dup(mod,w[i].p);
4685: if ( mod || !dont_removecont ) ndv_removecont(mod,a);
4686: if ( !mod ) register_hcf(a);
1.1 noro 4687: }
1.6 noro 4688: if ( nd_gentrace ) {
4689: STOZ(i,iq); STOZ(w[i].i,jq); node = mknode(3,iq,jq,ONE);
4690: /* exact division */
1.1 noro 4691: if ( !dont_removecont )
1.6 noro 4692: ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a));
4693: MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l;
4694: }
4695: NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r));
4696: nd_bound[i] = ndv_compute_bound(a);
4697: nd_psh[i] = r;
4698: if ( nd_demand ) {
4699: if ( trace ) {
4700: ndv_save(nd_ps_trace[i],i);
4701: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
4702: nd_ps_trace_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
4703: nd_ps_trace[i] = 0;
4704: } else {
4705: ndv_save(nd_ps[i],i);
4706: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps[i]);
4707: nd_ps[i] = 0;
4708: }
1.1 noro 4709: }
1.6 noro 4710: }
1.24 noro 4711: if ( sba ) {
1.27 noro 4712: nd_sba_hm = (DL *)MALLOC(nd_psn*sizeof(DL));
1.24 noro 4713: // setup signatures
1.27 noro 4714: for ( i = 0; i < nd_psn; i++ ) {
4715: SIG sig;
1.24 noro 4716:
1.27 noro 4717: NEWSIG(sig); sig->pos = i;
4718: nd_ps[i]->sig = sig;
4719: if ( nd_demand ) nd_ps_sym[i]->sig = sig;
4720: nd_psh[i]->sig = sig;
4721: if ( trace ) {
4722: nd_ps_trace[i]->sig = sig;
4723: if ( nd_demand ) nd_ps_trace_sym[i]->sig = sig;
4724: }
4725: NEWDL(nd_sba_hm[i],nd_nvar);
1.46 noro 4726: if ( nd_sba_modord )
4727: ndv_lm_modord(nd_ps[i],nd_sba_hm[i]);
1.45 noro 4728: else
4729: _ndltodl(DL(nd_psh[i]),nd_sba_hm[i]);
1.55 ! noro 4730: _adddl(nd_nvar,DL(sig),nd_sba_hm[i],DL2(sig));
1.27 noro 4731: }
1.29 noro 4732: nd_sba_pos = (NODE *)MALLOC(nd_psn*sizeof(NODE));
4733: for ( i = 0; i < nd_psn; i++ ) {
4734: j = nd_psh[i]->sig->pos;
4735: nd_sba_pos[j] = append_one(nd_sba_pos[j],i);
4736: }
1.24 noro 4737: }
1.6 noro 4738: if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0;
4739: return 1;
1.1 noro 4740: }
4741:
4742: struct order_spec *append_block(struct order_spec *spec,
4743: int nv,int nalg,int ord);
4744:
4745: extern VECT current_dl_weight_vector_obj;
4746: static VECT prev_weight_vector_obj;
4747:
4748: void preprocess_algcoef(VL vv,VL av,struct order_spec *ord,LIST f,
4749: struct order_spec **ord1p,LIST *f1p,NODE *alistp)
4750: {
4751: NODE alist,t,s,r0,r,arg;
4752: VL tv;
4753: P poly;
4754: DP d;
4755: Alg alpha,dp;
4756: DAlg inv,da,hc;
4757: MP m;
4758: int i,nvar,nalg,n;
4759: NumberField nf;
4760: LIST f1,f2;
4761: struct order_spec *current_spec;
4762: VECT obj,obj0;
4763: VECT tmp;
4764:
4765: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++);
4766: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++);
4767:
4768: for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) {
4769: NEXTNODE(alist,t); MKV(tv->v,poly);
4770: MKAlg(poly,alpha); BDY(t) = (pointer)alpha;
4771: tv->v = tv->v->priv;
4772: }
4773: NEXT(t) = 0;
4774:
4775: /* simplification, making polynomials monic */
4776: setfield_dalg(alist);
4777: obj_algtodalg((Obj)f,(Obj *)&f1);
4778: for ( t = BDY(f); t; t = NEXT(t) ) {
4779: initd(ord); ptod(vv,vv,(P)BDY(t),&d);
4780: hc = (DAlg)BDY(d)->c;
4781: if ( NID(hc) == N_DA ) {
4782: invdalg(hc,&inv);
4783: for ( m = BDY(d); m; m = NEXT(m) ) {
4784: muldalg(inv,(DAlg)m->c,&da); m->c = (Obj)da;
4785: }
4786: }
4787: initd(ord); dtop(vv,vv,d,(Obj *)&poly); BDY(f) = (pointer)poly;
4788: }
4789: obj_dalgtoalg((Obj)f1,(Obj *)&f);
4790:
4791: /* append alg vars to the var list */
4792: for ( tv = vv; NEXT(tv); tv = NEXT(tv) );
4793: NEXT(tv) = av;
4794:
4795: /* append a block to ord */
4796: *ord1p = append_block(ord,nvar,nalg,2);
4797:
4798: /* create generator list */
4799: nf = get_numberfield();
4800: for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) {
4801: MKAlg(nf->defpoly[i],dp);
4802: MKNODE(s,dp,t); t = s;
4803: }
4804: MKLIST(f1,t);
4805: *alistp = alist;
4806: algobjtorat((Obj)f1,(Obj *)f1p);
4807:
4808: /* creating a new weight vector */
4809: prev_weight_vector_obj = obj0 = current_dl_weight_vector_obj;
4810: n = nvar+nalg+1;
4811: MKVECT(obj,n);
4812: if ( obj0 && obj0->len == nvar )
4813: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = BDY(obj0)[i];
4814: else
4815: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = (pointer)ONE;
4816: for ( i = 0; i < nalg; i++ ) BDY(obj)[i+nvar] = 0;
4817: BDY(obj)[n-1] = (pointer)ONE;
4818: arg = mknode(1,obj);
4819: Pdp_set_weight(arg,&tmp);
4820: }
4821:
4822: NODE postprocess_algcoef(VL av,NODE alist,NODE r)
4823: {
4824: NODE s,t,u0,u;
4825: P p;
4826: VL tv;
4827: Obj obj;
4828: VECT tmp;
4829: NODE arg;
4830:
4831: u0 = 0;
4832: for ( t = r; t; t = NEXT(t) ) {
4833: p = (P)BDY(t);
4834: for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) {
4835: substr(CO,0,(Obj)p,tv->v,(Obj)BDY(s),&obj); p = (P)obj;
4836: }
4837: if ( OID(p) == O_P || (OID(p) == O_N && NID((Num)p) != N_A) ) {
4838: NEXTNODE(u0,u);
4839: BDY(u) = (pointer)p;
4840: }
4841: }
4842: arg = mknode(1,prev_weight_vector_obj);
4843: Pdp_set_weight(arg,&tmp);
4844:
4845: return u0;
4846: }
4847:
4848: void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
4849: {
4850: VL tv,fv,vv,vc,av;
4851: NODE fd,fd0,r,r0,t,x,s,xx,alist;
4852: int e,max,nvar,i;
4853: NDV b;
4854: int ishomo,nalg,mrank,trank,wmax,len;
4855: NMV a;
4856: Alg alpha,dp;
4857: P p,zp;
4858: Q dmy;
4859: LIST f1,f2,zpl;
4860: Obj obj;
4861: NumberField nf;
4862: struct order_spec *ord1;
4863: NODE tr,tl1,tl2,tl3,tl4,nzlist;
4864: LIST l1,l2,l3,l4,l5;
4865: int j;
4866: Z jq,bpe,last_nonzero;
4867: int *perm;
4868: EPOS oepos;
4869: int obpe,oadv,ompos,cbpe;
1.15 noro 4870: VECT hvect;
1.1 noro 4871:
1.41 noro 4872: NcriB = NcriMF = Ncri2 = 0;
1.1 noro 4873: nd_module = 0;
4874: if ( !m && Demand ) nd_demand = 1;
4875: else nd_demand = 0;
4876:
4877: if ( DP_Multiple )
4878: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
4879: #if 0
4880: ndv_alloc = 0;
4881: #endif
4882: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 4883: parse_nd_option(vv,current_option);
1.1 noro 4884: if ( m && nd_vc )
4885: error("nd_{gr,f4} : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
4886: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
4887: switch ( ord->id ) {
4888: case 1:
4889: if ( ord->nv != nvar )
4890: error("nd_{gr,f4} : invalid order specification");
4891: break;
4892: default:
4893: break;
4894: }
4895: nd_nalg = 0;
4896: av = 0;
4897: if ( !m ) {
4898: get_algtree((Obj)f,&av);
4899: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
4900: nd_ntrans = nvar;
4901: nd_nalg = nalg;
4902: /* #i -> t#i */
4903: if ( nalg ) {
4904: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
4905: ord = ord1;
4906: f = f1;
4907: }
4908: nvar += nalg;
4909: }
4910: nd_init_ord(ord);
4911: mrank = 0;
4912: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
4913: for ( tv = vv; tv; tv = NEXT(tv) ) {
4914: if ( nd_module ) {
1.16 noro 4915: if ( OID(BDY(t)) == O_DPM ) {
4916: e = dpm_getdeg((DPM)BDY(t),&trank);
4917: max = MAX(e,max);
4918: mrank = MAX(mrank,trank);
4919: } else {
4920: s = BDY((LIST)BDY(t));
4921: trank = length(s);
4922: mrank = MAX(mrank,trank);
4923: for ( ; s; s = NEXT(s) ) {
4924: e = getdeg(tv->v,(P)BDY(s));
4925: max = MAX(e,max);
4926: }
1.1 noro 4927: }
4928: } else {
1.43 noro 4929: if ( OID(BDY(t)) == O_DP ) {
4930: e = dp_getdeg((DP)BDY(t));
4931: max = MAX(e,max);
4932: } else {
4933: e = getdeg(tv->v,(P)BDY(t));
4934: max = MAX(e,max);
4935: }
1.1 noro 4936: }
4937: }
4938: nd_setup_parameters(nvar,nd_nzlist?0:max);
4939: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
4940: ishomo = 1;
4941: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
4942: if ( nd_module ) {
1.16 noro 4943: if ( OID(BDY(t)) == O_DPM ) {
4944: Z cont;
4945: DPM zdpm;
4946:
4947: if ( !m && !nd_gentrace ) dpm_ptozp((DPM)BDY(t),&cont,&zdpm);
4948: else zdpm = (DPM)BDY(t);
4949: b = (pointer)dpmtondv(m,zdpm);
4950: } else {
4951: if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
4952: else zpl = (LIST)BDY(t);
1.1 noro 4953: b = (pointer)pltondv(CO,vv,zpl);
1.16 noro 4954: }
1.1 noro 4955: } else {
1.43 noro 4956: if ( OID(BDY(t)) == O_DP ) {
4957: DP zdp;
4958:
4959: if ( !m && !nd_gentrace ) dp_ptozp((DP)BDY(t),&zdp);
4960: else zdp = (DP)BDY(t);
4961: b = (pointer)dptondv(m,zdp);
4962: } else {
4963: if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
4964: else zp = (P)BDY(t);
4965: b = (pointer)ptondv(CO,vv,zp);
4966: }
1.1 noro 4967: }
4968: if ( ishomo )
4969: ishomo = ishomo && ndv_ishomo(b);
4970: if ( m ) ndv_mod(m,b);
4971: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
4972: }
4973: if ( fd0 ) NEXT(fd) = 0;
4974:
4975: if ( !ishomo && homo ) {
4976: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
4977: b = (NDV)BDY(t); len = LEN(b);
4978: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
4979: wmax = MAX(TD(DL(a)),wmax);
4980: }
4981: homogenize_order(ord,nvar,&ord1);
4982: nd_init_ord(ord1);
4983: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
4984: for ( t = fd0; t; t = NEXT(t) )
4985: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
4986: }
4987:
1.24 noro 4988: ndv_setup(m,0,fd0,(nd_gbblock||nd_splist||nd_check_splist)?1:0,0,0);
1.1 noro 4989: if ( nd_gentrace ) {
4990: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
4991: }
4992: if ( nd_splist ) {
4993: *rp = compute_splist();
4994: return;
4995: }
4996: if ( nd_check_splist ) {
4997: if ( f4 ) {
4998: if ( check_splist_f4(m,nd_check_splist) ) *rp = (LIST)ONE;
4999: else *rp = 0;
5000: } else {
5001: if ( check_splist(m,nd_check_splist) ) *rp = (LIST)ONE;
5002: else *rp = 0;
5003: }
5004: return;
5005: }
5006: x = f4?nd_f4(m,0,&perm):nd_gb(m,ishomo || homo,0,0,&perm);
5007: if ( !x ) {
5008: *rp = 0; return;
5009: }
1.15 noro 5010: if ( nd_gentrace ) {
5011: MKVECT(hvect,nd_psn);
5012: for ( i = 0; i < nd_psn; i++ )
5013: ndltodp(nd_psh[i]->dl,(DP *)&BDY(hvect)[i]);
5014: }
1.1 noro 5015: if ( !ishomo && homo ) {
5016: /* dehomogenization */
5017: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5018: nd_init_ord(ord);
5019: nd_setup_parameters(nvar,0);
5020: }
5021: nd_demand = 0;
5022: if ( nd_module && nd_intersect ) {
5023: for ( j = nd_psn-1, x = 0; j >= 0; j-- )
1.17 noro 5024: if ( MPOS(DL(nd_psh[j])) > nd_intersect ) {
1.1 noro 5025: MKNODE(xx,(pointer)((unsigned long)j),x); x = xx;
5026: }
5027: conv_ilist(nd_demand,0,x,0);
5028: goto FINAL;
5029: }
5030: if ( nd_gentrace && f4 ) { nzlist = nd_alltracelist; }
5031: x = ndv_reducebase(x,perm);
5032: if ( nd_gentrace && !f4 ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
5033: x = ndv_reduceall(m,x);
5034: cbpe = nd_bpe;
5035: if ( nd_gentrace && !f4 ) {
5036: tl2 = nd_alltracelist; nd_alltracelist = 0;
5037: ndv_check_membership(m,fd0,obpe,oadv,oepos,x);
5038: tl3 = nd_alltracelist; nd_alltracelist = 0;
5039: if ( nd_gensyz ) {
5040: nd_gb(m,0,1,1,0);
5041: tl4 = nd_alltracelist; nd_alltracelist = 0;
5042: } else tl4 = 0;
5043: }
5044: nd_bpe = cbpe;
5045: nd_setup_parameters(nd_nvar,0);
5046: FINAL:
5047: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
1.16 noro 5048: NEXTNODE(r0,r);
5049: if ( nd_module ) {
5050: if ( retdp ) BDY(r) = ndvtodpm(m,BDY(t));
5051: else BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank);
5052: } else if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
5053: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.1 noro 5054: }
5055: if ( r0 ) NEXT(r) = 0;
5056: if ( !m && nd_nalg )
5057: r0 = postprocess_algcoef(av,alist,r0);
5058: MKLIST(*rp,r0);
5059: if ( nd_gentrace ) {
5060: if ( f4 ) {
1.6 noro 5061: STOZ(16,bpe);
5062: STOZ(nd_last_nonzero,last_nonzero);
1.15 noro 5063: tr = mknode(6,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe,last_nonzero,hvect); MKLIST(*rp,tr);
1.1 noro 5064: } else {
5065: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
5066: tl3 = reverse_node(tl3);
5067: /* tl2 = [[i,[[*,j,*,*],...]],...] */
5068: for ( t = tl2; t; t = NEXT(t) ) {
5069: /* s = [i,[*,j,*,*],...] */
5070: s = BDY((LIST)BDY(t));
1.6 noro 5071: j = perm[ZTOS((Q)ARG0(s))]; STOZ(j,jq); ARG0(s) = (pointer)jq;
1.1 noro 5072: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.6 noro 5073: j = perm[ZTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOZ(j,jq);
1.1 noro 5074: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
5075: }
5076: }
5077: for ( j = length(x)-1, t = 0; j >= 0; j-- ) {
1.6 noro 5078: STOZ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.1 noro 5079: }
5080: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
5081: MKLIST(l5,tl4);
1.6 noro 5082: STOZ(nd_bpe,bpe);
1.15 noro 5083: tr = mknode(9,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe,hvect); MKLIST(*rp,tr);
1.1 noro 5084: }
5085: }
5086: #if 0
5087: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
5088: #endif
5089: }
5090:
1.28 noro 5091: NODE nd_sba_f4(int m,int **indp);
5092:
5093: void nd_sba(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
1.24 noro 5094: {
5095: VL tv,fv,vv,vc,av;
1.55 ! noro 5096: NODE fd,fd0,r,r0,t,x,s,xx,nd,nd1,syz;
1.24 noro 5097: int e,max,nvar,i;
5098: NDV b;
5099: int ishomo,nalg,wmax,len;
5100: NMV a;
5101: P p,zp;
5102: Q dmy;
5103: struct order_spec *ord1;
5104: int j;
5105: int *perm;
5106: EPOS oepos;
5107: int obpe,oadv,ompos,cbpe;
1.51 noro 5108: struct oEGT eg0,eg1,egconv,egintred;
1.55 ! noro 5109: LIST l1,redind;
! 5110: Z z;
1.24 noro 5111:
5112: nd_module = 0;
5113: nd_demand = 0;
1.35 noro 5114: Nsamesig = 0;
1.24 noro 5115: if ( DP_Multiple )
5116: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
5117: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5118: parse_nd_option(vv,current_option);
1.24 noro 5119: if ( m && nd_vc )
5120: error("nd_sba : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
5121: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5122: switch ( ord->id ) {
5123: case 1:
5124: if ( ord->nv != nvar )
5125: error("nd_sba : invalid order specification");
5126: break;
5127: default:
5128: break;
5129: }
5130: nd_nalg = 0;
5131: nd_init_ord(ord);
5132: // for SIG comparison
5133: initd(ord);
5134: for ( t = BDY(f), max = 1; t; t = NEXT(t) ) {
5135: for ( tv = vv; tv; tv = NEXT(tv) ) {
1.43 noro 5136: if ( OID(BDY(t)) == O_DP ) {
5137: e = dp_getdeg((DP)BDY(t));
5138: max = MAX(e,max);
5139: } else {
5140: e = getdeg(tv->v,(P)BDY(t));
5141: max = MAX(e,max);
5142: }
1.24 noro 5143: }
5144: }
1.25 noro 5145: nd_setup_parameters(nvar,max);
1.24 noro 5146: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
5147: ishomo = 1;
5148: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.43 noro 5149: if ( OID(BDY(t)) == O_DP ) {
5150: DP zdp;
5151:
5152: if ( !m ) dp_ptozp((DP)BDY(t),&zdp);
5153: else zdp = (DP)BDY(t);
5154: b = (pointer)dptondv(m,zdp);
5155: } else {
5156: if ( !m ) ptozp((P)BDY(t),1,&dmy,&zp);
5157: else zp = (P)BDY(t);
5158: b = (pointer)ptondv(CO,vv,zp);
5159: }
1.24 noro 5160: if ( ishomo )
5161: ishomo = ishomo && ndv_ishomo(b);
5162: if ( m ) ndv_mod(m,b);
5163: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
5164: }
5165: if ( fd0 ) NEXT(fd) = 0;
5166:
5167: if ( !ishomo && homo ) {
5168: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
5169: b = (NDV)BDY(t); len = LEN(b);
5170: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
5171: wmax = MAX(TD(DL(a)),wmax);
5172: }
5173: homogenize_order(ord,nvar,&ord1);
5174: nd_init_ord(ord1);
1.42 noro 5175: // for SIG comparison
5176: initd(ord1);
1.24 noro 5177: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
5178: for ( t = fd0; t; t = NEXT(t) )
5179: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
5180: }
5181:
1.39 noro 5182: ndv_setup(m,0,fd0,nd_sba_dontsort,0,1);
1.55 ! noro 5183: if ( nd_gentrace ) {
! 5184: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
! 5185: }
1.44 noro 5186: x = f4 ? nd_sba_f4(m,&perm) : nd_sba_buch(m,ishomo || homo,&perm,&syz);
1.24 noro 5187: if ( !x ) {
5188: *rp = 0; return;
5189: }
5190: if ( !ishomo && homo ) {
5191: /* dehomogenization */
5192: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5193: nd_init_ord(ord);
1.42 noro 5194: // for SIG comparison
5195: initd(ord);
1.24 noro 5196: nd_setup_parameters(nvar,0);
5197: }
5198: nd_demand = 0;
1.51 noro 5199: get_eg(&eg0);
1.24 noro 5200: x = ndv_reducebase(x,perm);
1.55 ! noro 5201: for ( nd = 0, i = length(x)-1; i >= 0; i-- ) {
! 5202: STOZ(perm[i],z); MKNODE(nd1,z,nd); nd = nd1;
! 5203: }
! 5204: MKLIST(redind,nd);
1.24 noro 5205: x = ndv_reduceall(m,x);
1.51 noro 5206: get_eg(&eg1); init_eg(&egintred); add_eg(&egintred,&eg0,&eg1);
1.24 noro 5207: nd_setup_parameters(nd_nvar,0);
1.29 noro 5208: get_eg(&eg0);
1.24 noro 5209: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5210: NEXTNODE(r0,r);
5211: if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
1.34 noro 5212: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.24 noro 5213: }
5214: if ( r0 ) NEXT(r) = 0;
1.44 noro 5215: if ( nd_sba_syz ) {
5216: LIST gb,hsyz;
5217:
5218: MKLIST(gb,r0);
5219: MKLIST(hsyz,syz);
5220: nd = mknode(2,gb,hsyz);
5221: MKLIST(*rp,nd);
1.55 ! noro 5222: } else if ( nd_gentrace ) {
! 5223: LIST gb,trace;
! 5224:
! 5225: MKLIST(trace,nd_alltracelist);
! 5226: MKLIST(gb,r0);
! 5227: nd = mknode(3,gb,redind,trace);
! 5228: MKLIST(*rp,nd);
1.44 noro 5229: } else
5230: MKLIST(*rp,r0);
1.29 noro 5231: get_eg(&eg1); init_eg(&egconv); add_eg(&egconv,&eg0,&eg1);
1.51 noro 5232: print_eg("intred",&egintred); fprintf(asir_out,"\n");
1.29 noro 5233: print_eg("conv",&egconv); fprintf(asir_out,"\n");
1.24 noro 5234: }
5235:
1.1 noro 5236: void nd_gr_postproc(LIST f,LIST v,int m,struct order_spec *ord,int do_check,LIST *rp)
5237: {
5238: VL tv,fv,vv,vc,av;
5239: NODE fd,fd0,r,r0,t,x,s,xx,alist;
5240: int e,max,nvar,i;
5241: NDV b;
5242: int ishomo,nalg;
5243: Alg alpha,dp;
5244: P p,zp;
5245: Q dmy;
5246: LIST f1,f2;
5247: Obj obj;
5248: NumberField nf;
5249: struct order_spec *ord1;
5250: int *perm;
5251:
5252: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5253: parse_nd_option(vv,current_option);
1.1 noro 5254: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5255: switch ( ord->id ) {
5256: case 1:
5257: if ( ord->nv != nvar )
5258: error("nd_check : invalid order specification");
5259: break;
5260: default:
5261: break;
5262: }
5263: nd_nalg = 0;
5264: av = 0;
5265: if ( !m ) {
5266: get_algtree((Obj)f,&av);
5267: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
5268: nd_ntrans = nvar;
5269: nd_nalg = nalg;
5270: /* #i -> t#i */
5271: if ( nalg ) {
5272: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
5273: ord = ord1;
5274: f = f1;
5275: }
5276: nvar += nalg;
5277: }
5278: nd_init_ord(ord);
5279: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
5280: for ( tv = vv; tv; tv = NEXT(tv) ) {
5281: e = getdeg(tv->v,(P)BDY(t));
5282: max = MAX(e,max);
5283: }
5284: nd_setup_parameters(nvar,max);
5285: ishomo = 1;
5286: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
5287: ptozp((P)BDY(t),1,&dmy,&zp);
5288: b = (pointer)ptondv(CO,vv,zp);
5289: if ( ishomo )
5290: ishomo = ishomo && ndv_ishomo(b);
5291: if ( m ) ndv_mod(m,b);
5292: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
5293: }
5294: if ( fd0 ) NEXT(fd) = 0;
1.24 noro 5295: ndv_setup(m,0,fd0,0,1,0);
1.1 noro 5296: for ( x = 0, i = 0; i < nd_psn; i++ )
5297: x = update_base(x,i);
5298: if ( do_check ) {
5299: x = nd_gb(m,ishomo,1,0,&perm);
5300: if ( !x ) {
5301: *rp = 0;
5302: return;
5303: }
5304: } else {
5305: #if 0
5306: /* bug ? */
5307: for ( t = x; t; t = NEXT(t) )
5308: BDY(t) = (pointer)nd_ps[(long)BDY(t)];
5309: #else
5310: conv_ilist(0,0,x,&perm);
5311: #endif
5312: }
5313: x = ndv_reducebase(x,perm);
5314: x = ndv_reduceall(m,x);
5315: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5316: NEXTNODE(r0,r);
5317: BDY(r) = ndvtop(m,CO,vv,BDY(t));
5318: }
5319: if ( r0 ) NEXT(r) = 0;
5320: if ( !m && nd_nalg )
5321: r0 = postprocess_algcoef(av,alist,r0);
5322: MKLIST(*rp,r0);
5323: }
5324:
5325: NDV recompute_trace(NODE trace,NDV *p,int m);
5326: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp);
5327:
5328: NDV recompute_trace(NODE ti,NDV *p,int mod)
5329: {
5330: int c,c1,c2,i;
5331: NM mul,m,tail;
5332: ND d,r,rm;
5333: NODE sj;
5334: NDV red;
5335: Obj mj;
5336:
5337: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
5338: CM(mul) = 1;
5339: tail = 0;
5340: for ( i = 0, d = r = 0; ti; ti = NEXT(ti), i++ ) {
5341: sj = BDY((LIST)BDY(ti));
5342: if ( ARG0(sj) ) {
1.6 noro 5343: red = p[ZTOS((Q)ARG1(sj))];
1.1 noro 5344: mj = (Obj)ARG2(sj);
5345: if ( OID(mj) != O_DP ) ndl_zero(DL(mul));
5346: else dltondl(nd_nvar,BDY((DP)mj)->dl,DL(mul));
5347: rm = ndv_mul_nm(mod,mul,red);
5348: if ( !r ) r = rm;
5349: else {
5350: for ( m = BDY(r); m && !ndl_equal(m->dl,BDY(rm)->dl); m = NEXT(m), LEN(r)-- ) {
5351: if ( d ) {
5352: NEXT(tail) = m; tail = m; LEN(d)++;
5353: } else {
5354: MKND(nd_nvar,m,1,d); tail = BDY(d);
5355: }
5356: }
5357: if ( !m ) return 0; /* failure */
5358: else {
5359: BDY(r) = m;
5360: if ( mod > 0 || mod == -1 ) {
5361: c1 = invm(HCM(rm),mod); c2 = mod-HCM(r);
5362: DMAR(c1,c2,0,mod,c);
5363: nd_mul_c(mod,rm,c);
5364: } else {
5365: Z t,u;
5366:
5367: chsgnlf(HCZ(r),&t);
5368: divlf(t,HCZ(rm),&u);
5369: nd_mul_c_lf(rm,u);
5370: }
5371: r = nd_add(mod,r,rm);
5372: }
5373: }
5374: }
5375: }
5376: if ( tail ) NEXT(tail) = 0;
5377: d = nd_add(mod,d,r);
5378: nd_mul_c(mod,d,invm(HCM(d),mod));
5379: return ndtondv(mod,d);
5380: }
5381:
5382: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp)
5383: {
5384: VL tv,fv,vv,vc,av;
5385: NODE fd,fd0,r,r0,t,x,s,xx,alist;
5386: int e,max,nvar,i;
5387: NDV b;
5388: int ishomo,nalg;
5389: Alg alpha,dp;
5390: P p,zp;
5391: Q dmy;
5392: LIST f1,f2;
5393: Obj obj;
5394: NumberField nf;
5395: struct order_spec *ord1;
5396: NODE permtrace,intred,ind,perm,trace,ti;
5397: int len,n,j;
5398: NDV *db,*pb;
5399:
5400: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5401: parse_nd_option(vv,current_option);
1.1 noro 5402: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5403: switch ( ord->id ) {
5404: case 1:
5405: if ( ord->nv != nvar )
5406: error("nd_check : invalid order specification");
5407: break;
5408: default:
5409: break;
5410: }
5411: nd_init_ord(ord);
1.6 noro 5412: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 5413: nd_setup_parameters(nvar,0);
5414:
5415: len = length(BDY(f));
5416: db = (NDV *)MALLOC(len*sizeof(NDV *));
5417: for ( i = 0, t = BDY(f); t; i++, t = NEXT(t) ) {
5418: ptozp((P)BDY(t),1,&dmy,&zp);
5419: b = ptondv(CO,vv,zp);
5420: ndv_mod(m,b);
5421: ndv_mul_c(m,b,invm(HCM(b),m));
5422: db[i] = b;
5423: }
5424:
5425: permtrace = BDY((LIST)ARG2(BDY(tlist)));
5426: intred = BDY((LIST)ARG3(BDY(tlist)));
5427: ind = BDY((LIST)ARG4(BDY(tlist)));
5428: perm = BDY((LIST)ARG0(permtrace));
5429: trace = NEXT(permtrace);
5430:
5431: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 5432: j = ZTOS((Q)ARG0(BDY((LIST)BDY(t))));
1.1 noro 5433: if ( j > i ) i = j;
5434: }
5435: n = i+1;
5436: pb = (NDV *)MALLOC(n*sizeof(NDV *));
5437: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
5438: ti = BDY((LIST)BDY(t));
1.6 noro 5439: pb[ZTOS((Q)ARG0(ti))] = db[ZTOS((Q)ARG1(ti))];
1.1 noro 5440: }
5441: for ( t = trace; t; t = NEXT(t) ) {
5442: ti = BDY((LIST)BDY(t));
1.6 noro 5443: pb[ZTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
5444: if ( !pb[ZTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
1.1 noro 5445: if ( DP_Print ) {
5446: fprintf(asir_out,"."); fflush(asir_out);
5447: }
5448: }
5449: for ( t = intred; t; t = NEXT(t) ) {
5450: ti = BDY((LIST)BDY(t));
1.6 noro 5451: pb[ZTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
5452: if ( !pb[ZTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
1.1 noro 5453: if ( DP_Print ) {
5454: fprintf(asir_out,"*"); fflush(asir_out);
5455: }
5456: }
5457: for ( r0 = 0, t = ind; t; t = NEXT(t) ) {
5458: NEXTNODE(r0,r);
1.6 noro 5459: b = pb[ZTOS((Q)BDY(t))];
1.1 noro 5460: ndv_mul_c(m,b,invm(HCM(b),m));
5461: #if 0
1.6 noro 5462: BDY(r) = ndvtop(m,CO,vv,pb[ZTOS((Q)BDY(t))]);
1.1 noro 5463: #else
1.6 noro 5464: BDY(r) = ndvtodp(m,pb[ZTOS((Q)BDY(t))]);
1.1 noro 5465: #endif
5466: }
5467: if ( r0 ) NEXT(r) = 0;
5468: MKLIST(*rp,r0);
5469: if ( DP_Print ) fprintf(asir_out,"\n");
5470: }
5471:
1.16 noro 5472: void nd_gr_trace(LIST f,LIST v,int trace,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
1.1 noro 5473: {
5474: VL tv,fv,vv,vc,av;
5475: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
5476: int m,nocheck,nvar,mindex,e,max;
5477: NDV c;
5478: NMV a;
5479: P p,zp;
5480: Q dmy;
5481: EPOS oepos;
5482: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
5483: Alg alpha,dp;
5484: P poly;
5485: LIST f1,f2,zpl;
5486: Obj obj;
5487: NumberField nf;
5488: struct order_spec *ord1;
5489: struct oEGT eg_check,eg0,eg1;
5490: NODE tr,tl1,tl2,tl3,tl4;
5491: LIST l1,l2,l3,l4,l5;
5492: int *perm;
5493: int j,ret;
5494: Z jq,bpe;
1.15 noro 5495: VECT hvect;
1.1 noro 5496:
1.41 noro 5497: NcriB = NcriMF = Ncri2 = 0;
1.1 noro 5498: nd_module = 0;
5499: nd_lf = 0;
1.46 noro 5500: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
5501: parse_nd_option(vv,current_option);
1.1 noro 5502: if ( nd_lf ) {
5503: if ( f4 )
5504: nd_f4_lf_trace(f,v,trace,homo,ord,rp);
5505: else
5506: error("nd_gr_trace is not implemented yet over a large finite field");
5507: return;
5508: }
5509: if ( DP_Multiple )
5510: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
5511:
5512: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5513: switch ( ord->id ) {
5514: case 1:
5515: if ( ord->nv != nvar )
5516: error("nd_gr_trace : invalid order specification");
5517: break;
5518: default:
5519: break;
5520: }
5521:
5522: get_algtree((Obj)f,&av);
5523: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
5524: nd_ntrans = nvar;
5525: nd_nalg = nalg;
5526: /* #i -> t#i */
5527: if ( nalg ) {
5528: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
5529: ord = ord1;
5530: f = f1;
5531: }
5532: nvar += nalg;
5533:
5534: nocheck = 0;
5535: mindex = 0;
5536:
5537: if ( Demand ) nd_demand = 1;
5538: else nd_demand = 0;
5539:
5540: /* setup modulus */
5541: if ( trace < 0 ) {
5542: trace = -trace;
5543: nocheck = 1;
5544: }
5545: m = trace > 1 ? trace : get_lprime(mindex);
5546: nd_init_ord(ord);
5547: mrank = 0;
5548: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
5549: for ( tv = vv; tv; tv = NEXT(tv) ) {
5550: if ( nd_module ) {
1.16 noro 5551: if ( OID(BDY(t)) == O_DPM ) {
5552: e = dpm_getdeg((DPM)BDY(t),&trank);
5553: max = MAX(e,max);
5554: mrank = MAX(mrank,trank);
5555: } else {
1.1 noro 5556: s = BDY((LIST)BDY(t));
5557: trank = length(s);
5558: mrank = MAX(mrank,trank);
5559: for ( ; s; s = NEXT(s) ) {
5560: e = getdeg(tv->v,(P)BDY(s));
5561: max = MAX(e,max);
5562: }
1.16 noro 5563: }
1.1 noro 5564: } else {
1.43 noro 5565: if ( OID(BDY(t)) == O_DP ) {
5566: e = dp_getdeg((DP)BDY(t));
5567: max = MAX(e,max);
5568: } else {
1.1 noro 5569: e = getdeg(tv->v,(P)BDY(t));
5570: max = MAX(e,max);
1.43 noro 5571: }
1.1 noro 5572: }
5573: }
5574: nd_setup_parameters(nvar,max);
5575: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
5576: ishomo = 1;
5577: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
5578: if ( nd_module ) {
1.16 noro 5579: if ( OID(BDY(t)) == O_DPM ) {
5580: Z cont;
5581: DPM zdpm;
5582:
1.17 noro 5583: if ( !nd_gentrace ) dpm_ptozp((DPM)BDY(t),&cont,&zdpm);
1.16 noro 5584: else zdpm = (DPM)BDY(t);
5585: c = (pointer)dpmtondv(m,zdpm);
5586: } else {
5587: if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
5588: else zpl = (LIST)BDY(t);
1.1 noro 5589: c = (pointer)pltondv(CO,vv,zpl);
1.16 noro 5590: }
1.1 noro 5591: } else {
1.43 noro 5592: if ( OID(BDY(t)) == O_DP ) {
5593: DP zdp;
5594:
5595: if ( !nd_gentrace ) dp_ptozp((DP)BDY(t),&zdp);
5596: else zdp = (DP)BDY(t);
5597: c = (pointer)dptondv(m,zdp);
5598: } else {
5599: if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
5600: else zp = (P)BDY(t);
5601: c = (pointer)ptondv(CO,vv,zp);
5602: }
1.1 noro 5603: }
5604: if ( ishomo )
5605: ishomo = ishomo && ndv_ishomo(c);
5606: if ( c ) {
5607: NEXTNODE(in0,in); BDY(in) = (pointer)c;
5608: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
5609: }
5610: }
5611: if ( in0 ) NEXT(in) = 0;
5612: if ( fd0 ) NEXT(fd) = 0;
5613: if ( !ishomo && homo ) {
5614: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
5615: c = (NDV)BDY(t); len = LEN(c);
5616: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
5617: wmax = MAX(TD(DL(a)),wmax);
5618: }
5619: homogenize_order(ord,nvar,&ord1);
5620: nd_init_ord(ord1);
5621: nd_setup_parameters(nvar+1,wmax);
5622: for ( t = fd0; t; t = NEXT(t) )
5623: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
5624: }
5625: if ( MaxDeg > 0 ) nocheck = 1;
5626: while ( 1 ) {
5627: tl1 = tl2 = tl3 = tl4 = 0;
5628: if ( Demand )
5629: nd_demand = 1;
1.24 noro 5630: ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0,0);
1.1 noro 5631: if ( nd_gentrace ) {
5632: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
5633: }
5634: if ( ret )
5635: cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm);
5636: if ( !ret || !cand ) {
5637: /* failure */
5638: if ( trace > 1 ) { *rp = 0; return; }
5639: else m = get_lprime(++mindex);
5640: continue;
5641: }
1.15 noro 5642: if ( nd_gentrace ) {
5643: MKVECT(hvect,nd_psn);
5644: for ( i = 0; i < nd_psn; i++ )
5645: ndltodp(nd_psh[i]->dl,(DP *)&BDY(hvect)[i]);
5646: }
1.1 noro 5647: if ( !ishomo && homo ) {
5648: /* dehomogenization */
5649: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5650: nd_init_ord(ord);
5651: nd_setup_parameters(nvar,0);
5652: }
5653: nd_demand = 0;
5654: cand = ndv_reducebase(cand,perm);
5655: if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
5656: cand = ndv_reduceall(0,cand);
5657: cbpe = nd_bpe;
5658: if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; }
5659: get_eg(&eg0);
5660: if ( nocheck )
5661: break;
5662: if ( (ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand)) != 0 ) {
5663: if ( nd_gentrace ) {
5664: tl3 = nd_alltracelist; nd_alltracelist = 0;
5665: } else tl3 = 0;
5666: /* gbcheck : cand is a GB of Id(cand) ? */
1.54 noro 5667: if ( nd_vc || nd_gentrace || nd_gensyz || do_weyl )
1.1 noro 5668: ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0;
5669: else
5670: ret = nd_f4(0,1,0)!=0;
5671: if ( nd_gentrace && nd_gensyz ) {
5672: tl4 = nd_alltracelist; nd_alltracelist = 0;
5673: } else tl4 = 0;
5674: }
5675: if ( ret ) break;
5676: else if ( trace > 1 ) {
5677: /* failure */
5678: *rp = 0; return;
5679: } else {
5680: /* try the next modulus */
5681: m = get_lprime(++mindex);
5682: /* reset the parameters */
5683: if ( !ishomo && homo ) {
5684: nd_init_ord(ord1);
5685: nd_setup_parameters(nvar+1,wmax);
5686: } else {
5687: nd_init_ord(ord);
5688: nd_setup_parameters(nvar,max);
5689: }
5690: }
5691: }
5692: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
5693: if ( DP_Print )
1.6 noro 5694: fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime);
1.1 noro 5695: /* dp->p */
5696: nd_bpe = cbpe;
5697: nd_setup_parameters(nd_nvar,0);
5698: for ( r = cand; r; r = NEXT(r) ) {
1.16 noro 5699: if ( nd_module ) {
1.17 noro 5700: if ( retdp ) BDY(r) = ndvtodpm(0,BDY(r));
1.16 noro 5701: else BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank);
1.17 noro 5702: } else if ( retdp ) BDY(r) = ndvtodp(0,BDY(r));
5703: else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r));
1.1 noro 5704: }
5705: if ( nd_nalg )
5706: cand = postprocess_algcoef(av,alist,cand);
5707: MKLIST(*rp,cand);
5708: if ( nd_gentrace ) {
5709: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
5710: tl3 = reverse_node(tl3);
5711: /* tl2 = [[i,[[*,j,*,*],...]],...] */
5712: for ( t = tl2; t; t = NEXT(t) ) {
5713: /* s = [i,[*,j,*,*],...] */
5714: s = BDY((LIST)BDY(t));
1.6 noro 5715: j = perm[ZTOS((Q)ARG0(s))]; STOZ(j,jq); ARG0(s) = (pointer)jq;
1.1 noro 5716: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.6 noro 5717: j = perm[ZTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOZ(j,jq);
1.1 noro 5718: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
5719: }
5720: }
5721: for ( j = length(cand)-1, t = 0; j >= 0; j-- ) {
1.6 noro 5722: STOZ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.1 noro 5723: }
5724: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
5725: MKLIST(l5,tl4);
1.6 noro 5726: STOZ(nd_bpe,bpe);
1.15 noro 5727: tr = mknode(9,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe,hvect); MKLIST(*rp,tr);
1.1 noro 5728: }
5729: }
5730:
5731: /* XXX : module element is not considered */
5732:
5733: void dltondl(int n,DL dl,UINT *r)
5734: {
5735: UINT *d;
5736: int i,j,l,s,ord_l;
5737: struct order_pair *op;
5738:
5739: d = (unsigned int *)dl->d;
5740: for ( i = 0; i < nd_wpd; i++ ) r[i] = 0;
5741: if ( nd_blockmask ) {
5742: l = nd_blockmask->n;
5743: op = nd_blockmask->order_pair;
5744: for ( j = 0, s = 0; j < l; j++ ) {
5745: ord_l = op[j].length;
5746: for ( i = 0; i < ord_l; i++, s++ ) PUT_EXP(r,s,d[s]);
5747: }
5748: TD(r) = ndl_weight(r);
5749: ndl_weight_mask(r);
5750: } else {
5751: for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]);
5752: TD(r) = ndl_weight(r);
5753: }
5754: }
5755:
5756: DL ndltodl(int n,UINT *ndl)
5757: {
5758: DL dl;
5759: int *d;
5760: int i,j,l,s,ord_l;
5761: struct order_pair *op;
5762:
1.33 noro 5763: NEWDL_NOINIT(dl,n);
1.1 noro 5764: dl->td = TD(ndl);
5765: d = dl->d;
5766: if ( nd_blockmask ) {
5767: l = nd_blockmask->n;
5768: op = nd_blockmask->order_pair;
5769: for ( j = 0, s = 0; j < l; j++ ) {
5770: ord_l = op[j].length;
5771: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
5772: }
5773: } else {
5774: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
5775: }
5776: return dl;
5777: }
5778:
1.24 noro 5779: void _ndltodl(UINT *ndl,DL dl)
5780: {
5781: int *d;
5782: int i,j,l,s,ord_l,n;
5783: struct order_pair *op;
5784:
5785: n = nd_nvar;
5786: dl->td = TD(ndl);
5787: d = dl->d;
5788: if ( nd_blockmask ) {
5789: l = nd_blockmask->n;
5790: op = nd_blockmask->order_pair;
5791: for ( j = 0, s = 0; j < l; j++ ) {
5792: ord_l = op[j].length;
5793: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
5794: }
5795: } else {
5796: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
5797: }
5798: }
5799:
1.1 noro 5800: void nmtodp(int mod,NM m,DP *r)
5801: {
5802: DP dp;
5803: MP mr;
5804:
5805: NEWMP(mr);
5806: mr->dl = ndltodl(nd_nvar,DL(m));
5807: mr->c = (Obj)ndctop(mod,m->c);
5808: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
5809: *r = dp;
5810: }
5811:
1.15 noro 5812: void ndltodp(UINT *d,DP *r)
5813: {
5814: DP dp;
5815: MP mr;
5816:
5817: NEWMP(mr);
5818: mr->dl = ndltodl(nd_nvar,d);
5819: mr->c = (Obj)ONE;
5820: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
5821: *r = dp;
5822: }
5823:
1.1 noro 5824: void ndl_print(UINT *dl)
5825: {
5826: int n;
5827: int i,j,l,ord_l,s,s0;
5828: struct order_pair *op;
5829:
5830: n = nd_nvar;
5831: printf("<<");
5832: if ( nd_blockmask ) {
5833: l = nd_blockmask->n;
5834: op = nd_blockmask->order_pair;
5835: for ( j = 0, s = s0 = 0; j < l; j++ ) {
5836: ord_l = op[j].length;
5837: for ( i = 0; i < ord_l; i++, s++ )
5838: printf(s==n-1?"%d":"%d,",GET_EXP(dl,s));
5839: }
5840: } else {
5841: for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i));
5842: }
5843: printf(">>");
5844: if ( nd_module && MPOS(dl) )
5845: printf("*e%d",MPOS(dl));
5846: }
5847:
5848: void nd_print(ND p)
5849: {
5850: NM m;
5851:
5852: if ( !p )
5853: printf("0\n");
5854: else {
5855: for ( m = BDY(p); m; m = NEXT(m) ) {
5856: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
1.28 noro 5857: else printf("+%ld*",CM(m));
1.1 noro 5858: ndl_print(DL(m));
5859: }
5860: printf("\n");
5861: }
5862: }
5863:
5864: void nd_print_q(ND p)
5865: {
5866: NM m;
5867:
5868: if ( !p )
5869: printf("0\n");
5870: else {
5871: for ( m = BDY(p); m; m = NEXT(m) ) {
5872: printf("+");
1.6 noro 5873: printexpr(CO,(Obj)CZ(m));
1.1 noro 5874: printf("*");
5875: ndl_print(DL(m));
5876: }
5877: printf("\n");
5878: }
5879: }
5880:
5881: void ndp_print(ND_pairs d)
5882: {
5883: ND_pairs t;
5884:
5885: for ( t = d; t; t = NEXT(t) ) printf("%d,%d ",t->i1,t->i2);
5886: printf("\n");
5887: }
5888:
5889: void nd_removecont(int mod,ND p)
5890: {
5891: int i,n;
5892: Z *w;
5893: NM m;
5894: struct oVECT v;
5895:
5896: if ( mod == -1 ) nd_mul_c(mod,p,_invsf(HCM(p)));
5897: else if ( mod == -2 ) {
5898: Z inv;
5899: divlf(ONE,HCZ(p),&inv);
5900: nd_mul_c_lf(p,inv);
5901: } else if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod));
5902: else {
5903: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
5904: w = (Z *)MALLOC(n*sizeof(Q));
5905: v.len = n;
5906: v.body = (pointer *)w;
1.6 noro 5907: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5908: removecont_array((P *)w,n,1);
1.6 noro 5909: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5910: }
5911: }
5912:
5913: void nd_removecont2(ND p1,ND p2)
5914: {
5915: int i,n1,n2,n;
5916: Z *w;
5917: NM m;
5918: struct oVECT v;
5919:
5920: n1 = nd_length(p1);
5921: n2 = nd_length(p2);
5922: n = n1+n2;
5923: w = (Z *)MALLOC(n*sizeof(Q));
5924: v.len = n;
5925: v.body = (pointer *)w;
5926: i = 0;
5927: if ( p1 )
1.6 noro 5928: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5929: if ( p2 )
1.6 noro 5930: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5931: removecont_array((P *)w,n,1);
5932: i = 0;
5933: if ( p1 )
1.6 noro 5934: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5935: if ( p2 )
1.6 noro 5936: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5937: }
5938:
5939: void ndv_removecont(int mod,NDV p)
5940: {
5941: int i,len,all_p;
5942: Z *c;
5943: P *w;
5944: Z dvr,t;
5945: P g,cont,tp;
5946: NMV m;
5947:
5948: if ( mod == -1 )
5949: ndv_mul_c(mod,p,_invsf(HCM(p)));
5950: else if ( mod == -2 ) {
5951: Z inv;
5952: divlf(ONE,HCZ(p),&inv);
5953: ndv_mul_c_lf(p,inv);
5954: } else if ( mod )
5955: ndv_mul_c(mod,p,invm(HCM(p),mod));
5956: else {
5957: len = p->len;
5958: w = (P *)MALLOC(len*sizeof(P));
5959: c = (Z *)MALLOC(len*sizeof(Q));
5960: for ( m = BDY(p), all_p = 1, i = 0; i < len; NMV_ADV(m), i++ ) {
5961: ptozp(CP(m),1,(Q *)&c[i],&w[i]);
5962: all_p = all_p && !NUM(w[i]);
5963: }
5964: if ( all_p ) {
5965: qltozl((Q *)c,len,&dvr); nd_heu_nezgcdnpz(nd_vc,w,len,1,&g);
5966: mulp(nd_vc,(P)dvr,g,&cont);
5967: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
5968: divsp(nd_vc,CP(m),cont,&tp); CP(m) = tp;
5969: }
5970: } else {
5971: sortbynm((Q *)c,len);
5972: qltozl((Q *)c,len,&dvr);
5973: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
5974: divsp(nd_vc,CP(m),(P)dvr,&tp); CP(m) = tp;
5975: }
5976: }
5977: }
5978: }
5979:
5980: /* koko */
5981:
5982: void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos,int ompos)
5983: {
5984: int len,i,max;
5985: NMV m,mr0,mr,t;
5986:
5987: len = p->len;
1.14 noro 5988: for ( m = BDY(p), i = 0, max = 0; i < len; NMV_OADV(m), i++ )
1.1 noro 5989: max = MAX(max,TD(DL(m)));
5990: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
5991: m = (NMV)((char *)mr0+(len-1)*oadv);
5992: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
5993: t = (NMV)MALLOC(nmv_adv);
5994: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
5995: ndl_homogenize(DL(m),DL(t),obpe,oepos,ompos,max);
1.6 noro 5996: CZ(mr) = CZ(m);
1.1 noro 5997: ndl_copy(DL(t),DL(mr));
5998: }
5999: NV(p)++;
6000: BDY(p) = mr0;
6001: }
6002:
6003: void ndv_dehomogenize(NDV p,struct order_spec *ord)
6004: {
6005: int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos;
6006: int pos;
6007: Q *w;
6008: Q dvr,t;
6009: NMV m,r;
6010:
6011: len = p->len;
6012: newnvar = nd_nvar-1;
6013: newexporigin = nd_get_exporigin(ord);
6014: if ( nd_module ) newmpos = newexporigin-1;
6015: newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin;
6016: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ )
6017: ndl_dehomogenize(DL(m));
6018: if ( newwpd != nd_wpd ) {
6019: newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT));
6020: for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) {
1.6 noro 6021: CZ(r) = CZ(m);
1.1 noro 6022: if ( nd_module ) pos = MPOS(DL(m));
6023: for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j];
6024: adj = nd_exporigin-newexporigin;
6025: for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj];
6026: if ( nd_module ) {
6027: DL(r)[newmpos] = pos;
6028: }
6029: }
6030: }
6031: NV(p)--;
6032: }
6033:
6034: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr)
6035: {
6036: int i;
6037: P *tpl,*tpl1;
6038: NODE l;
6039: P h,gcd,t;
6040:
6041: tpl = (P *)MALLOC(m*sizeof(P));
6042: tpl1 = (P *)MALLOC(m*sizeof(P));
6043: bcopy(pl,tpl,m*sizeof(P));
6044: gcd = (P)ONE;
6045: for ( l = nd_hcf; l; l = NEXT(l) ) {
6046: h = (P)BDY(l);
6047: while ( 1 ) {
6048: for ( i = 0; i < m; i++ )
6049: if ( !divtpz(vl,tpl[i],h,&tpl1[i]) )
6050: break;
6051: if ( i == m ) {
6052: bcopy(tpl1,tpl,m*sizeof(P));
6053: mulp(vl,gcd,h,&t); gcd = t;
6054: } else
6055: break;
6056: }
6057: }
6058: if ( DP_Print > 2 ){fprintf(asir_out,"[%d]",nmonop(gcd)); fflush(asir_out);}
6059: if ( full ) {
6060: heu_nezgcdnpz(vl,tpl,m,&t);
6061: mulp(vl,gcd,t,pr);
6062: } else
6063: *pr = gcd;
6064: }
6065:
6066: void removecont_array(P *p,int n,int full)
6067: {
6068: int all_p,all_q,i;
6069: Z *c;
6070: P *w;
6071: P t,s;
6072:
6073: for ( all_q = 1, i = 0; i < n; i++ )
6074: all_q = all_q && NUM(p[i]);
6075: if ( all_q ) {
6076: removecont_array_q((Z *)p,n);
6077: } else {
6078: c = (Z *)MALLOC(n*sizeof(Z));
6079: w = (P *)MALLOC(n*sizeof(P));
6080: for ( i = 0; i < n; i++ ) {
6081: ptozp(p[i],1,(Q *)&c[i],&w[i]);
6082: }
6083: removecont_array_q(c,n);
6084: nd_heu_nezgcdnpz(nd_vc,w,n,full,&t);
6085: for ( i = 0; i < n; i++ ) {
6086: divsp(nd_vc,w[i],t,&s); mulp(nd_vc,s,(P)c[i],&p[i]);
6087: }
6088: }
6089: }
6090:
6091: /* c is an int array */
6092:
6093: void removecont_array_q(Z *c,int n)
6094: {
6095: struct oVECT v;
6096: Z d0,d1,a,u,u1,gcd;
6097: int i,j;
6098: Z *q,*r;
6099:
6100: q = (Z *)MALLOC(n*sizeof(Z));
6101: r = (Z *)MALLOC(n*sizeof(Z));
6102: v.id = O_VECT; v.len = n; v.body = (pointer *)c;
6103: gcdvz_estimate(&v,&d0);
6104: for ( i = 0; i < n; i++ ) {
6105: divqrz(c[i],d0,&q[i],&r[i]);
6106: }
6107: for ( i = 0; i < n; i++ ) if ( r[i] ) break;
6108: if ( i < n ) {
6109: v.id = O_VECT; v.len = n; v.body = (pointer *)r;
6110: gcdvz(&v,&d1);
6111: gcdz(d0,d1,&gcd);
1.6 noro 6112: /* exact division */
6113: divsz(d0,gcd,&a);
1.1 noro 6114: for ( i = 0; i < n; i++ ) {
6115: mulz(a,q[i],&u);
6116: if ( r[i] ) {
1.6 noro 6117: /* exact division */
6118: divsz(r[i],gcd,&u1);
1.1 noro 6119: addz(u,u1,&q[i]);
6120: } else
6121: q[i] = u;
6122: }
6123: }
6124: for ( i = 0; i < n; i++ ) c[i] = q[i];
6125: }
6126:
1.4 noro 6127: void gcdv_mpz_estimate(mpz_t d0,mpz_t *c,int n);
6128:
6129: void mpz_removecont_array(mpz_t *c,int n)
6130: {
6131: mpz_t d0,a,u,u1,gcd;
6132: int i,j;
1.13 noro 6133: static mpz_t *q,*r;
6134: static int c_len = 0;
1.4 noro 6135:
6136: for ( i = 0; i < n; i++ )
6137: if ( mpz_sgn(c[i]) ) break;
6138: if ( i == n ) return;
6139: gcdv_mpz_estimate(d0,c,n);
1.13 noro 6140: if ( n > c_len ) {
6141: q = (mpz_t *)MALLOC(n*sizeof(mpz_t));
6142: r = (mpz_t *)MALLOC(n*sizeof(mpz_t));
6143: c_len = n;
6144: }
1.4 noro 6145: for ( i = 0; i < n; i++ ) {
6146: mpz_init(q[i]); mpz_init(r[i]);
6147: mpz_fdiv_qr(q[i],r[i],c[i],d0);
6148: }
6149: for ( i = 0; i < n; i++ )
6150: if ( mpz_sgn(r[i]) ) break;
6151: mpz_init(gcd); mpz_init(a); mpz_init(u); mpz_init(u1);
6152: if ( i < n ) {
6153: mpz_gcd(gcd,d0,r[i]);
6154: for ( j = i+1; j < n; j++ ) mpz_gcd(gcd,gcd,r[j]);
6155: mpz_div(a,d0,gcd);
6156: for ( i = 0; i < n; i++ ) {
6157: mpz_mul(u,a,q[i]);
6158: if ( mpz_sgn(r[i]) ) {
6159: mpz_div(u1,r[i],gcd);
6160: mpz_add(q[i],u,u1);
6161: } else
6162: mpz_set(q[i],u);
6163: }
6164: }
6165: for ( i = 0; i < n; i++ )
6166: mpz_set(c[i],q[i]);
6167: }
6168:
1.1 noro 6169: void nd_mul_c(int mod,ND p,int mul)
6170: {
6171: NM m;
6172: int c,c1;
6173:
6174: if ( !p ) return;
6175: if ( mul == 1 ) return;
6176: if ( mod == -1 )
6177: for ( m = BDY(p); m; m = NEXT(m) )
6178: CM(m) = _mulsf(CM(m),mul);
6179: else
6180: for ( m = BDY(p); m; m = NEXT(m) ) {
6181: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
6182: }
6183: }
6184:
6185: void nd_mul_c_lf(ND p,Z mul)
6186: {
6187: NM m;
6188: Z c;
6189:
6190: if ( !p ) return;
6191: if ( UNIZ(mul) ) return;
6192: for ( m = BDY(p); m; m = NEXT(m) ) {
6193: mullf(CZ(m),mul,&c); CZ(m) = c;
6194: }
6195: }
6196:
6197: void nd_mul_c_q(ND p,P mul)
6198: {
6199: NM m;
6200: P c;
6201:
6202: if ( !p ) return;
6203: if ( UNIQ(mul) ) return;
6204: for ( m = BDY(p); m; m = NEXT(m) ) {
6205: mulp(nd_vc,CP(m),mul,&c); CP(m) = c;
6206: }
6207: }
6208:
6209: void nd_mul_c_p(VL vl,ND p,P mul)
6210: {
6211: NM m;
6212: P c;
6213:
6214: if ( !p ) return;
6215: for ( m = BDY(p); m; m = NEXT(m) ) {
6216: mulp(vl,CP(m),mul,&c); CP(m) = c;
6217: }
6218: }
6219:
6220: void nd_free(ND p)
6221: {
6222: NM t,s;
6223:
6224: if ( !p ) return;
6225: t = BDY(p);
6226: while ( t ) {
6227: s = NEXT(t);
6228: FREENM(t);
6229: t = s;
6230: }
6231: FREEND(p);
6232: }
6233:
6234: void ndv_free(NDV p)
6235: {
6236: GCFREE(BDY(p));
6237: }
6238:
6239: void nd_append_red(UINT *d,int i)
6240: {
6241: RHist m,m0;
6242: int h;
6243:
6244: NEWRHist(m);
6245: h = ndl_hash_value(d);
6246: m->index = i;
6247: ndl_copy(d,DL(m));
6248: NEXT(m) = nd_red[h];
6249: nd_red[h] = m;
6250: }
6251:
6252: UINT *ndv_compute_bound(NDV p)
6253: {
6254: UINT *d1,*d2,*t;
6255: UINT u;
6256: int i,j,k,l,len,ind;
6257: NMV m;
6258:
6259: if ( !p )
6260: return 0;
6261: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6262: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6263: len = LEN(p);
6264: m = BDY(p); ndl_copy(DL(m),d1); NMV_ADV(m);
6265: for ( i = 1; i < len; i++, NMV_ADV(m) ) {
6266: ndl_max(DL(m),d1,d2);
6267: t = d1; d1 = d2; d2 = t;
6268: }
6269: l = nd_nvar+31;
6270: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
6271: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
6272: u = d1[i];
6273: k = (nd_epw-1)*nd_bpe;
6274: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
6275: t[ind] = (u>>k)&nd_mask0;
6276: }
6277: for ( ; ind < l; ind++ ) t[ind] = 0;
6278: return t;
6279: }
6280:
6281: UINT *nd_compute_bound(ND p)
6282: {
6283: UINT *d1,*d2,*t;
6284: UINT u;
6285: int i,j,k,l,len,ind;
6286: NM m;
6287:
6288: if ( !p )
6289: return 0;
6290: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6291: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6292: len = LEN(p);
6293: m = BDY(p); ndl_copy(DL(m),d1); m = NEXT(m);
6294: for ( m = NEXT(m); m; m = NEXT(m) ) {
6295: ndl_lcm(DL(m),d1,d2);
6296: t = d1; d1 = d2; d2 = t;
6297: }
6298: l = nd_nvar+31;
6299: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
6300: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
6301: u = d1[i];
6302: k = (nd_epw-1)*nd_bpe;
6303: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
6304: t[ind] = (u>>k)&nd_mask0;
6305: }
6306: for ( ; ind < l; ind++ ) t[ind] = 0;
6307: return t;
6308: }
6309:
6310: /* if nd_module == 1 then d[nd_exporigin-1] indicates the position */
6311: /* of a term. In this case we need additional 1 word. */
6312:
6313: int nd_get_exporigin(struct order_spec *ord)
6314: {
6315: switch ( ord->id ) {
1.21 noro 6316: case 0: case 2: case 256: case 258: case 300:
1.1 noro 6317: return 1+nd_module;
6318: case 1: case 257:
6319: /* block order */
6320: /* poly ring d[0]:weight d[1]:w0,...,d[nd_exporigin-1]:w(n-1) */
6321: /* module d[0]:weight d[1]:w0,...,d[nd_exporigin-2]:w(n-1) */
6322: return ord->ord.block.length+1+nd_module;
6323: case 3: case 259:
6324: #if 0
6325: error("nd_get_exporigin : composite order is not supported yet.");
6326: #else
6327: return 1+nd_module;
6328: #endif
6329: default:
6330: error("nd_get_exporigin : ivalid argument.");
6331: return 0;
6332: }
6333: }
6334:
6335: void nd_setup_parameters(int nvar,int max) {
6336: int i,j,n,elen,ord_o,ord_l,l,s,wpd;
6337: struct order_pair *op;
1.45 noro 6338: extern int CNVars;
1.1 noro 6339:
6340: nd_nvar = nvar;
1.45 noro 6341: CNVars = nvar;
1.1 noro 6342: if ( max ) {
6343: /* XXX */
6344: if ( do_weyl ) nd_bpe = 32;
6345: else if ( max < 2 ) nd_bpe = 1;
6346: else if ( max < 4 ) nd_bpe = 2;
6347: else if ( max < 8 ) nd_bpe = 3;
6348: else if ( max < 16 ) nd_bpe = 4;
6349: else if ( max < 32 ) nd_bpe = 5;
6350: else if ( max < 64 ) nd_bpe = 6;
6351: else if ( max < 256 ) nd_bpe = 8;
6352: else if ( max < 1024 ) nd_bpe = 10;
6353: else if ( max < 65536 ) nd_bpe = 16;
6354: else nd_bpe = 32;
6355: }
6356: if ( !do_weyl && weight_check && (current_dl_weight_vector || nd_matrix) ) {
6357: UINT t;
6358: int st;
6359: int *v;
6360: /* t = max(weights) */
6361: t = 0;
6362: if ( current_dl_weight_vector )
6363: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
6364: if ( (st=current_dl_weight_vector[i]) < 0 ) st = -st;
6365: if ( t < st ) t = st;
6366: }
6367: if ( nd_matrix )
6368: for ( i = 0; i < nd_matrix_len; i++ )
6369: for ( j = 0, v = nd_matrix[i]; j < nd_nvar; j++ ) {
6370: if ( (st=v[j]) < 0 ) st = -st;
6371: if ( t < st ) t = st;
6372: }
6373: /* i = bitsize of t */
6374: for ( i = 0; t; t >>=1, i++ );
6375: /* i += bitsize of nd_nvar */
6376: for ( t = nd_nvar; t; t >>=1, i++);
6377: /* nd_bpe+i = bitsize of max(weights)*max(exp)*nd_nvar */
6378: if ( (nd_bpe+i) >= 31 )
6379: error("nd_setup_parameters : too large weight");
6380: }
6381: nd_epw = (sizeof(UINT)*8)/nd_bpe;
6382: elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0);
6383: nd_exporigin = nd_get_exporigin(nd_ord);
6384: wpd = nd_exporigin+elen;
6385: if ( nd_module )
6386: nd_mpos = nd_exporigin-1;
6387: else
6388: nd_mpos = -1;
6389: if ( wpd != nd_wpd ) {
6390: nd_free_private_storage();
6391: nd_wpd = wpd;
6392: }
6393: if ( nd_bpe < 32 ) {
6394: nd_mask0 = (1<<nd_bpe)-1;
6395: } else {
6396: nd_mask0 = 0xffffffff;
6397: }
6398: bzero(nd_mask,sizeof(nd_mask));
6399: nd_mask1 = 0;
6400: for ( i = 0; i < nd_epw; i++ ) {
6401: nd_mask[nd_epw-i-1] = (nd_mask0<<(i*nd_bpe));
6402: nd_mask1 |= (1<<(nd_bpe-1))<<(i*nd_bpe);
6403: }
6404: nmv_adv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(nd_wpd-1)*sizeof(UINT));
6405: nd_epos = nd_create_epos(nd_ord);
6406: nd_blockmask = nd_create_blockmask(nd_ord);
6407: nd_work_vector = (int *)REALLOC(nd_work_vector,nd_nvar*sizeof(int));
6408: }
6409:
6410: ND_pairs nd_reconstruct(int trace,ND_pairs d)
6411: {
6412: int i,obpe,oadv,h;
6413: static NM prev_nm_free_list;
6414: static ND_pairs prev_ndp_free_list;
6415: RHist mr0,mr;
6416: RHist r;
6417: RHist *old_red;
6418: ND_pairs s0,s,t;
6419: EPOS oepos;
6420:
6421: obpe = nd_bpe;
6422: oadv = nmv_adv;
6423: oepos = nd_epos;
6424: if ( obpe < 2 ) nd_bpe = 2;
6425: else if ( obpe < 3 ) nd_bpe = 3;
6426: else if ( obpe < 4 ) nd_bpe = 4;
6427: else if ( obpe < 5 ) nd_bpe = 5;
6428: else if ( obpe < 6 ) nd_bpe = 6;
6429: else if ( obpe < 8 ) nd_bpe = 8;
6430: else if ( obpe < 10 ) nd_bpe = 10;
6431: else if ( obpe < 16 ) nd_bpe = 16;
6432: else if ( obpe < 32 ) nd_bpe = 32;
6433: else error("nd_reconstruct : exponent too large");
6434:
6435: nd_setup_parameters(nd_nvar,0);
6436: prev_nm_free_list = _nm_free_list;
6437: prev_ndp_free_list = _ndp_free_list;
6438: _nm_free_list = 0;
6439: _ndp_free_list = 0;
6440: for ( i = nd_psn-1; i >= 0; i-- ) {
6441: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
6442: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
6443: }
6444: if ( trace )
6445: for ( i = nd_psn-1; i >= 0; i-- ) {
6446: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
6447: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
6448: }
6449: s0 = 0;
6450: for ( t = d; t; t = NEXT(t) ) {
6451: NEXTND_pairs(s0,s);
6452: s->i1 = t->i1;
6453: s->i2 = t->i2;
1.24 noro 6454: s->sig = t->sig;
1.1 noro 6455: SG(s) = SG(t);
6456: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
6457: }
6458:
6459: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
6460: for ( i = 0; i < REDTAB_LEN; i++ ) {
6461: old_red[i] = nd_red[i];
6462: nd_red[i] = 0;
6463: }
6464: for ( i = 0; i < REDTAB_LEN; i++ )
6465: for ( r = old_red[i]; r; r = NEXT(r) ) {
6466: NEWRHist(mr);
6467: mr->index = r->index;
6468: SG(mr) = SG(r);
6469: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
6470: h = ndl_hash_value(DL(mr));
6471: NEXT(mr) = nd_red[h];
6472: nd_red[h] = mr;
1.24 noro 6473: mr->sig = r->sig;
1.1 noro 6474: }
6475: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
6476: old_red = 0;
6477: for ( i = 0; i < nd_psn; i++ ) {
6478: NEWRHist(r); SG(r) = SG(nd_psh[i]);
6479: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
1.24 noro 6480: r->sig = nd_psh[i]->sig;
1.1 noro 6481: nd_psh[i] = r;
6482: }
6483: if ( s0 ) NEXT(s) = 0;
6484: prev_nm_free_list = 0;
6485: prev_ndp_free_list = 0;
6486: #if 0
6487: GC_gcollect();
6488: #endif
6489: return s0;
6490: }
6491:
1.30 noro 6492: void nd_reconstruct_s(int trace,ND_pairs *d)
6493: {
6494: int i,obpe,oadv,h;
6495: static NM prev_nm_free_list;
6496: static ND_pairs prev_ndp_free_list;
6497: RHist mr0,mr;
6498: RHist r;
6499: RHist *old_red;
6500: ND_pairs s0,s,t;
6501: EPOS oepos;
6502:
6503: obpe = nd_bpe;
6504: oadv = nmv_adv;
6505: oepos = nd_epos;
6506: if ( obpe < 2 ) nd_bpe = 2;
6507: else if ( obpe < 3 ) nd_bpe = 3;
6508: else if ( obpe < 4 ) nd_bpe = 4;
6509: else if ( obpe < 5 ) nd_bpe = 5;
6510: else if ( obpe < 6 ) nd_bpe = 6;
6511: else if ( obpe < 8 ) nd_bpe = 8;
6512: else if ( obpe < 10 ) nd_bpe = 10;
6513: else if ( obpe < 16 ) nd_bpe = 16;
6514: else if ( obpe < 32 ) nd_bpe = 32;
6515: else error("nd_reconstruct_s : exponent too large");
6516:
6517: nd_setup_parameters(nd_nvar,0);
6518: prev_nm_free_list = _nm_free_list;
6519: prev_ndp_free_list = _ndp_free_list;
6520: _nm_free_list = 0;
6521: _ndp_free_list = 0;
6522: for ( i = nd_psn-1; i >= 0; i-- ) {
6523: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
6524: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
6525: }
6526: if ( trace )
6527: for ( i = nd_psn-1; i >= 0; i-- ) {
6528: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
6529: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
6530: }
6531:
6532: for ( i = 0; i < nd_nbase; i++ ) {
6533: s0 = 0;
6534: for ( t = d[i]; t; t = NEXT(t) ) {
6535: NEXTND_pairs(s0,s);
6536: s->i1 = t->i1;
6537: s->i2 = t->i2;
6538: s->sig = t->sig;
6539: SG(s) = SG(t);
6540: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
6541: }
1.47 noro 6542: if ( s0 ) NEXT(s) = 0;
1.30 noro 6543: d[i] = s0;
6544: }
6545:
6546: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
6547: for ( i = 0; i < REDTAB_LEN; i++ ) {
6548: old_red[i] = nd_red[i];
6549: nd_red[i] = 0;
6550: }
6551: for ( i = 0; i < REDTAB_LEN; i++ )
6552: for ( r = old_red[i]; r; r = NEXT(r) ) {
6553: NEWRHist(mr);
6554: mr->index = r->index;
6555: SG(mr) = SG(r);
6556: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
6557: h = ndl_hash_value(DL(mr));
6558: NEXT(mr) = nd_red[h];
6559: nd_red[h] = mr;
6560: mr->sig = r->sig;
6561: }
6562: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
6563: old_red = 0;
6564: for ( i = 0; i < nd_psn; i++ ) {
6565: NEWRHist(r); SG(r) = SG(nd_psh[i]);
6566: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
6567: r->sig = nd_psh[i]->sig;
6568: nd_psh[i] = r;
6569: }
6570: if ( s0 ) NEXT(s) = 0;
6571: prev_nm_free_list = 0;
6572: prev_ndp_free_list = 0;
6573: #if 0
6574: GC_gcollect();
6575: #endif
6576: }
6577:
1.1 noro 6578: void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos)
6579: {
6580: int n,i,ei,oepw,omask0,j,s,ord_l,l;
6581: struct order_pair *op;
6582:
6583: n = nd_nvar;
6584: oepw = (sizeof(UINT)*8)/obpe;
6585: omask0 = (1<<obpe)-1;
6586: TD(r) = TD(d);
6587: for ( i = nd_exporigin; i < nd_wpd; i++ ) r[i] = 0;
6588: if ( nd_blockmask ) {
6589: l = nd_blockmask->n;
6590: op = nd_blockmask->order_pair;
6591: for ( i = 1; i < nd_exporigin; i++ )
6592: r[i] = d[i];
6593: for ( j = 0, s = 0; j < l; j++ ) {
6594: ord_l = op[j].length;
6595: for ( i = 0; i < ord_l; i++, s++ ) {
6596: ei = GET_EXP_OLD(d,s);
6597: PUT_EXP(r,s,ei);
6598: }
6599: }
6600: } else {
6601: for ( i = 0; i < n; i++ ) {
6602: ei = GET_EXP_OLD(d,i);
6603: PUT_EXP(r,i,ei);
6604: }
6605: }
6606: if ( nd_module ) MPOS(r) = MPOS(d);
6607: }
6608:
6609: ND nd_copy(ND p)
6610: {
6611: NM m,mr,mr0;
6612: int c,n;
6613: ND r;
6614:
6615: if ( !p )
6616: return 0;
6617: else {
6618: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
6619: NEXTNM(mr0,mr);
6620: CM(mr) = CM(m);
6621: ndl_copy(DL(m),DL(mr));
6622: }
6623: NEXT(mr) = 0;
6624: MKND(NV(p),mr0,LEN(p),r);
6625: SG(r) = SG(p);
6626: return r;
6627: }
6628: }
6629:
6630: int nd_sp(int mod,int trace,ND_pairs p,ND *rp)
6631: {
6632: NM m1,m2;
6633: NDV p1,p2;
6634: ND t1,t2;
6635: UINT *lcm;
6636: P gp,tp;
6637: Z g,t;
6638: Z iq;
6639: int td;
6640: LIST hist;
6641: NODE node;
6642: DP d;
6643:
6644: if ( !mod && nd_demand ) {
6645: p1 = ndv_load(p->i1); p2 = ndv_load(p->i2);
6646: } else {
6647: if ( trace ) {
6648: p1 = nd_ps_trace[p->i1]; p2 = nd_ps_trace[p->i2];
6649: } else {
6650: p1 = nd_ps[p->i1]; p2 = nd_ps[p->i2];
6651: }
6652: }
6653: lcm = LCM(p);
6654: NEWNM(m1); ndl_sub(lcm,HDL(p1),DL(m1));
6655: if ( ndl_check_bound2(p->i1,DL(m1)) ) {
6656: FREENM(m1); return 0;
6657: }
6658: NEWNM(m2); ndl_sub(lcm,HDL(p2),DL(m2));
6659: if ( ndl_check_bound2(p->i2,DL(m2)) ) {
6660: FREENM(m1); FREENM(m2); return 0;
6661: }
6662:
6663: if ( mod == -1 ) {
6664: CM(m1) = HCM(p2); CM(m2) = _chsgnsf(HCM(p1));
6665: } else if ( mod > 0 ) {
6666: CM(m1) = HCM(p2); CM(m2) = mod-HCM(p1);
6667: } else if ( mod == -2 ) {
6668: CZ(m1) = HCZ(p2); chsgnlf(HCZ(p1),&CZ(m2));
6669: } else if ( nd_vc ) {
6670: ezgcdpz(nd_vc,HCP(p1),HCP(p2),&gp);
6671: divsp(nd_vc,HCP(p2),gp,&CP(m1));
6672: divsp(nd_vc,HCP(p1),gp,&tp); chsgnp(tp,&CP(m2));
6673: } else {
1.6 noro 6674: igcd_cofactor(HCZ(p1),HCZ(p2),&g,&t,&CZ(m1)); chsgnz(t,&CZ(m2));
1.1 noro 6675: }
6676: t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2);
6677: *rp = nd_add(mod,t1,t2);
6678: if ( nd_gentrace ) {
6679: /* nd_tracelist is initialized */
1.6 noro 6680: STOZ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE);
1.1 noro 6681: MKLIST(hist,node); MKNODE(nd_tracelist,hist,0);
1.6 noro 6682: STOZ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE);
1.1 noro 6683: MKLIST(hist,node); MKNODE(node,hist,nd_tracelist);
6684: nd_tracelist = node;
6685: }
1.24 noro 6686: if ( *rp )
6687: (*rp)->sig = p->sig;
1.1 noro 6688: FREENM(m1); FREENM(m2);
6689: return 1;
6690: }
6691:
6692: void ndv_mul_c(int mod,NDV p,int mul)
6693: {
6694: NMV m;
6695: int c,c1,len,i;
6696:
6697: if ( !p ) return;
6698: len = LEN(p);
6699: if ( mod == -1 )
6700: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) )
6701: CM(m) = _mulsf(CM(m),mul);
6702: else
6703: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
6704: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
6705: }
6706: }
6707:
6708: void ndv_mul_c_lf(NDV p,Z mul)
6709: {
6710: NMV m;
6711: Z c;
6712: int len,i;
6713:
6714: if ( !p ) return;
6715: len = LEN(p);
6716: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
6717: mullf(CZ(m),mul,&c); CZ(m) = c;
6718: }
6719: }
6720:
6721: /* for nd_det */
6722: void ndv_mul_c_q(NDV p,Z mul)
6723: {
6724: NMV m;
6725: Z c;
6726: int len,i;
6727:
6728: if ( !p ) return;
6729: len = LEN(p);
6730: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 6731: mulz(CZ(m),mul,&c); CZ(m) = c;
1.1 noro 6732: }
6733: }
6734:
6735: ND weyl_ndv_mul_nm(int mod,NM m0,NDV p) {
6736: int n2,i,j,l,n,tlen;
6737: UINT *d0;
6738: NM *tab,*psum;
6739: ND s,r;
6740: NM t;
6741: NMV m1;
6742:
6743: if ( !p ) return 0;
6744: n = NV(p); n2 = n>>1;
6745: d0 = DL(m0);
6746: l = LEN(p);
6747: for ( i = 0, tlen = 1; i < n2; i++ ) tlen *= (GET_EXP(d0,n2+i)+1);
6748: tab = (NM *)MALLOC(tlen*sizeof(NM));
6749: psum = (NM *)MALLOC(tlen*sizeof(NM));
6750: for ( i = 0; i < tlen; i++ ) psum[i] = 0;
6751: m1 = (NMV)(((char *)BDY(p))+nmv_adv*(l-1));
6752: for ( i = l-1; i >= 0; i--, NMV_PREV(m1) ) {
6753: /* m0(NM) * m1(NMV) => tab(NM) */
6754: weyl_mul_nm_nmv(n,mod,m0,m1,tab,tlen);
6755: for ( j = 0; j < tlen; j++ ) {
6756: if ( tab[j] ) {
6757: NEXT(tab[j]) = psum[j]; psum[j] = tab[j];
6758: }
6759: }
6760: }
6761: for ( i = tlen-1, r = 0; i >= 0; i-- )
6762: if ( psum[i] ) {
6763: for ( j = 0, t = psum[i]; t; t = NEXT(t), j++ );
6764: MKND(n,psum[i],j,s);
6765: r = nd_add(mod,r,s);
6766: }
6767: if ( r ) SG(r) = SG(p)+TD(d0);
6768: return r;
6769: }
6770:
6771: /* product of monomials */
6772: /* XXX block order is not handled correctly */
6773:
6774: void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *tab,int tlen)
6775: {
6776: int i,n2,j,s,curlen,homo,h,a,b,k,l,u,min;
6777: UINT *d0,*d1,*d,*dt,*ctab;
6778: Z *ctab_q;
6779: Z q,q1;
6780: UINT c0,c1,c;
6781: NM *p;
6782: NM m,t;
6783: int mpos;
6784:
6785: for ( i = 0; i < tlen; i++ ) tab[i] = 0;
6786: if ( !m0 || !m1 ) return;
6787: d0 = DL(m0); d1 = DL(m1); n2 = n>>1;
6788: if ( nd_module )
6789: if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation");
6790:
6791: NEWNM(m); d = DL(m);
6792: if ( mod ) {
6793: c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c;
6794: } else if ( nd_vc )
6795: mulp(nd_vc,CP(m0),CP(m1),&CP(m));
6796: else
1.6 noro 6797: mulz(CZ(m0),CZ(m1),&CZ(m));
1.1 noro 6798: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
6799: homo = n&1 ? 1 : 0;
6800: if ( homo ) {
6801: /* offset of h-degree */
6802: h = GET_EXP(d0,n-1)+GET_EXP(d1,n-1);
6803: PUT_EXP(DL(m),n-1,h);
6804: TD(DL(m)) = h;
6805: if ( nd_blockmask ) ndl_weight_mask(DL(m));
6806: }
6807: tab[0] = m;
6808: NEWNM(m); d = DL(m);
6809: for ( i = 0, curlen = 1; i < n2; i++ ) {
6810: a = GET_EXP(d0,i); b = GET_EXP(d1,n2+i);
6811: k = GET_EXP(d0,n2+i); l = GET_EXP(d1,i);
6812: /* xi^a*(Di^k*xi^l)*Di^b */
6813: a += l; b += k;
6814: s = MUL_WEIGHT(a,i)+MUL_WEIGHT(b,n2+i);
6815: if ( !k || !l ) {
6816: for ( j = 0; j < curlen; j++ )
6817: if ( (t = tab[j]) != 0 ) {
6818: dt = DL(t);
6819: PUT_EXP(dt,i,a); PUT_EXP(dt,n2+i,b); TD(dt) += s;
6820: if ( nd_blockmask ) ndl_weight_mask(dt);
6821: }
6822: curlen *= k+1;
6823: continue;
6824: }
6825: min = MIN(k,l);
6826: if ( mod ) {
6827: ctab = (UINT *)MALLOC((min+1)*sizeof(UINT));
6828: mkwcm(k,l,mod,(int *)ctab);
6829: } else {
6830: ctab_q = (Z *)MALLOC((min+1)*sizeof(Z));
6831: mkwc(k,l,ctab_q);
6832: }
6833: for ( j = min; j >= 0; j-- ) {
6834: for ( u = 0; u < nd_wpd; u++ ) d[u] = 0;
6835: PUT_EXP(d,i,a-j); PUT_EXP(d,n2+i,b-j);
6836: h = MUL_WEIGHT(a-j,i)+MUL_WEIGHT(b-j,n2+i);
6837: if ( homo ) {
6838: TD(d) = s;
6839: PUT_EXP(d,n-1,s-h);
6840: } else TD(d) = h;
6841: if ( nd_blockmask ) ndl_weight_mask(d);
6842: if ( mod ) c = ctab[j];
6843: else q = ctab_q[j];
6844: p = tab+curlen*j;
6845: if ( j == 0 ) {
6846: for ( u = 0; u < curlen; u++, p++ ) {
6847: if ( tab[u] ) {
6848: ndl_addto(DL(tab[u]),d);
6849: if ( mod ) {
6850: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1;
6851: } else if ( nd_vc )
6852: mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u]));
6853: else {
1.6 noro 6854: mulz(CZ(tab[u]),q,&q1); CZ(tab[u]) = q1;
1.1 noro 6855: }
6856: }
6857: }
6858: } else {
6859: for ( u = 0; u < curlen; u++, p++ ) {
6860: if ( tab[u] ) {
6861: NEWNM(t);
6862: ndl_add(DL(tab[u]),d,DL(t));
6863: if ( mod ) {
6864: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1;
6865: } else if ( nd_vc )
6866: mulp(nd_vc,CP(tab[u]),(P)q,&CP(t));
6867: else
1.6 noro 6868: mulz(CZ(tab[u]),q,&CZ(t));
1.1 noro 6869: *p = t;
6870: }
6871: }
6872: }
6873: }
6874: curlen *= k+1;
6875: }
6876: FREENM(m);
6877: if ( nd_module ) {
6878: mpos = MPOS(d1);
6879: for ( i = 0; i < tlen; i++ )
6880: if ( tab[i] ) {
6881: d = DL(tab[i]);
6882: MPOS(d) = mpos;
6883: TD(d) = ndl_weight(d);
6884: }
6885: }
6886: }
6887:
6888: ND ndv_mul_nm_symbolic(NM m0,NDV p)
6889: {
6890: NM mr,mr0;
6891: NMV m;
6892: UINT *d,*dt,*dm;
6893: int c,n,td,i,c1,c2,len;
6894: Q q;
6895: ND r;
6896:
6897: if ( !p ) return 0;
6898: else {
6899: n = NV(p); m = BDY(p);
6900: d = DL(m0);
6901: len = LEN(p);
6902: mr0 = 0;
6903: td = TD(d);
6904: c = CM(m0);
6905: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6906: NEXTNM(mr0,mr);
6907: CM(mr) = 1;
6908: ndl_add(DL(m),d,DL(mr));
6909: }
6910: NEXT(mr) = 0;
6911: MKND(NV(p),mr0,len,r);
6912: SG(r) = SG(p) + TD(d);
6913: return r;
6914: }
6915: }
6916:
6917: ND ndv_mul_nm(int mod,NM m0,NDV p)
6918: {
6919: NM mr,mr0;
6920: NMV m;
6921: UINT *d,*dt,*dm;
6922: int c,n,td,i,c1,c2,len;
6923: P q;
6924: ND r;
6925:
6926: if ( !p ) return 0;
6927: else if ( do_weyl ) {
6928: if ( mod < 0 ) {
6929: error("ndv_mul_nm : not implemented (weyl)");
6930: return 0;
6931: } else
6932: return weyl_ndv_mul_nm(mod,m0,p);
6933: } else {
6934: n = NV(p); m = BDY(p);
6935: d = DL(m0);
6936: len = LEN(p);
6937: mr0 = 0;
6938: td = TD(d);
6939: if ( mod == -1 ) {
6940: c = CM(m0);
6941: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6942: NEXTNM(mr0,mr);
6943: CM(mr) = _mulsf(CM(m),c);
6944: ndl_add(DL(m),d,DL(mr));
6945: }
6946: } else if ( mod == -2 ) {
6947: Z cl;
6948: cl = CZ(m0);
6949: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6950: NEXTNM(mr0,mr);
6951: mullf(CZ(m),cl,&CZ(mr));
6952: ndl_add(DL(m),d,DL(mr));
6953: }
6954: } else if ( mod ) {
6955: c = CM(m0);
6956: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6957: NEXTNM(mr0,mr);
6958: c1 = CM(m);
6959: DMAR(c1,c,0,mod,c2);
6960: CM(mr) = c2;
6961: ndl_add(DL(m),d,DL(mr));
6962: }
6963: } else {
6964: q = CP(m0);
6965: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6966: NEXTNM(mr0,mr);
6967: mulp(nd_vc,CP(m),q,&CP(mr));
6968: ndl_add(DL(m),d,DL(mr));
6969: }
6970: }
6971: NEXT(mr) = 0;
6972: MKND(NV(p),mr0,len,r);
6973: SG(r) = SG(p) + TD(d);
6974: return r;
6975: }
6976: }
6977:
6978: ND nd_quo(int mod,PGeoBucket bucket,NDV d)
6979: {
6980: NM mq0,mq;
6981: NMV tm;
6982: Q q;
6983: int i,nv,sg,c,c1,c2,hindex;
6984: ND p,t,r;
6985:
6986: if ( bucket->m < 0 ) return 0;
6987: else {
6988: nv = NV(d);
6989: mq0 = 0;
6990: tm = (NMV)MALLOC(nmv_adv);
6991: while ( 1 ) {
6992: if ( mod > 0 || mod == -1 )
6993: hindex = head_pbucket(mod,bucket);
6994: else if ( mod == -2 )
6995: hindex = head_pbucket_lf(bucket);
6996: else
6997: hindex = head_pbucket_q(bucket);
6998: if ( hindex < 0 ) break;
6999: p = bucket->body[hindex];
7000: NEXTNM(mq0,mq);
7001: ndl_sub(HDL(p),HDL(d),DL(mq));
7002: ndl_copy(DL(mq),DL(tm));
7003: if ( mod ) {
7004: c1 = invm(HCM(d),mod); c2 = HCM(p);
7005: DMAR(c1,c2,0,mod,c); CM(mq) = c;
7006: CM(tm) = mod-c;
7007: } else {
1.6 noro 7008: divsz(HCZ(p),HCZ(d),&CZ(mq));
7009: chsgnz(CZ(mq),&CZ(tm));
1.1 noro 7010: }
7011: t = ndv_mul_nmv_trunc(mod,tm,d,HDL(d));
7012: bucket->body[hindex] = nd_remove_head(p);
7013: t = nd_remove_head(t);
7014: add_pbucket(mod,bucket,t);
7015: }
7016: if ( !mq0 )
7017: r = 0;
7018: else {
7019: NEXT(mq) = 0;
7020: for ( i = 0, mq = mq0; mq; mq = NEXT(mq), i++ );
7021: MKND(nv,mq0,i,r);
7022: /* XXX */
7023: SG(r) = HTD(r);
7024: }
7025: return r;
7026: }
7027: }
7028:
7029: void ndv_realloc(NDV p,int obpe,int oadv,EPOS oepos)
7030: {
7031: NMV m,mr,mr0,t;
7032: int len,i,k;
7033:
7034: if ( !p ) return;
7035: m = BDY(p); len = LEN(p);
7036: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
7037: m = (NMV)((char *)mr0+(len-1)*oadv);
7038: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
7039: t = (NMV)MALLOC(nmv_adv);
7040: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
1.6 noro 7041: CZ(t) = CZ(m);
1.1 noro 7042: for ( k = 0; k < nd_wpd; k++ ) DL(t)[k] = 0;
7043: ndl_reconstruct(DL(m),DL(t),obpe,oepos);
1.6 noro 7044: CZ(mr) = CZ(t);
1.1 noro 7045: ndl_copy(DL(t),DL(mr));
7046: }
7047: BDY(p) = mr0;
7048: }
7049:
7050: NDV ndv_dup_realloc(NDV p,int obpe,int oadv,EPOS oepos)
7051: {
7052: NMV m,mr,mr0;
7053: int len,i;
7054: NDV r;
7055:
7056: if ( !p ) return 0;
7057: m = BDY(p); len = LEN(p);
7058: mr0 = mr = (NMV)MALLOC(len*nmv_adv);
7059: for ( i = 0; i < len; i++, NMV_OADV(m), NMV_ADV(mr) ) {
7060: ndl_zero(DL(mr));
7061: ndl_reconstruct(DL(m),DL(mr),obpe,oepos);
1.6 noro 7062: CZ(mr) = CZ(m);
1.1 noro 7063: }
7064: MKNDV(NV(p),mr0,len,r);
7065: SG(r) = SG(p);
1.24 noro 7066: r->sig = p->sig;
1.1 noro 7067: return r;
7068: }
7069:
7070: /* duplicate p */
7071:
7072: NDV ndv_dup(int mod,NDV p)
7073: {
7074: NDV d;
7075: NMV t,m,m0;
7076: int i,len;
7077:
7078: if ( !p ) return 0;
7079: len = LEN(p);
7080: m0 = m = (NMV)((mod>0 || mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
7081: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
7082: ndl_copy(DL(t),DL(m));
1.6 noro 7083: CZ(m) = CZ(t);
1.1 noro 7084: }
7085: MKNDV(NV(p),m0,len,d);
7086: SG(d) = SG(p);
7087: return d;
7088: }
7089:
7090: NDV ndv_symbolic(int mod,NDV p)
7091: {
7092: NDV d;
7093: NMV t,m,m0;
7094: int i,len;
7095:
7096: if ( !p ) return 0;
7097: len = LEN(p);
7098: m0 = m = (NMV)((mod>0||mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
7099: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
7100: ndl_copy(DL(t),DL(m));
1.6 noro 7101: CZ(m) = ONE;
1.1 noro 7102: }
7103: MKNDV(NV(p),m0,len,d);
7104: SG(d) = SG(p);
7105: return d;
7106: }
7107:
7108: ND nd_dup(ND p)
7109: {
7110: ND d;
7111: NM t,m,m0;
7112:
7113: if ( !p ) return 0;
7114: for ( m0 = 0, t = BDY(p); t; t = NEXT(t) ) {
7115: NEXTNM(m0,m);
7116: ndl_copy(DL(t),DL(m));
1.6 noro 7117: CZ(m) = CZ(t);
1.1 noro 7118: }
7119: if ( m0 ) NEXT(m) = 0;
7120: MKND(NV(p),m0,LEN(p),d);
7121: SG(d) = SG(p);
7122: return d;
7123: }
7124:
7125: /* XXX if p->len == 0 then it represents 0 */
7126:
7127: void ndv_mod(int mod,NDV p)
7128: {
7129: NMV t,d;
7130: int r,s,u;
7131: int i,len,dlen;
7132: P cp;
7133: Z c;
7134: Obj gfs;
7135:
7136: if ( !p ) return;
7137: len = LEN(p);
7138: dlen = 0;
7139: if ( mod == -1 )
7140: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7141: simp_ff((Obj)CP(t),&gfs);
7142: if ( gfs ) {
7143: r = FTOIF(CONT((GFS)gfs));
7144: CM(d) = r;
7145: ndl_copy(DL(t),DL(d));
7146: NMV_ADV(d);
7147: dlen++;
7148: }
7149: }
7150: else if ( mod == -2 )
7151: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7152: simp_ff((Obj)CP(t),&gfs);
7153: if ( gfs ) {
7154: lmtolf((LM)gfs,&CZ(d));
7155: ndl_copy(DL(t),DL(d));
7156: NMV_ADV(d);
7157: dlen++;
7158: }
7159: }
7160: else
7161: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7162: if ( nd_vc ) {
7163: nd_subst_vector(nd_vc,CP(t),nd_subst,&cp);
7164: c = (Z)cp;
7165: } else
1.6 noro 7166: c = CZ(t);
1.1 noro 7167: r = remqi((Q)c,mod);
7168: if ( r ) {
7169: CM(d) = r;
7170: ndl_copy(DL(t),DL(d));
7171: NMV_ADV(d);
7172: dlen++;
7173: }
7174: }
7175: LEN(p) = dlen;
7176: }
7177:
7178: NDV ptondv(VL vl,VL dvl,P p)
7179: {
7180: ND nd;
7181:
7182: nd = ptond(vl,dvl,p);
7183: return ndtondv(0,nd);
7184: }
7185:
7186: void pltozpl(LIST l,Q *cont,LIST *pp)
7187: {
1.16 noro 7188: NODE nd,nd1;
7189: int n;
7190: P *pl;
7191: Q *cl;
7192: int i;
7193: P dmy;
7194: Z dvr,inv;
7195: LIST r;
7196:
7197: nd = BDY(l); n = length(nd);
7198: pl = (P *)MALLOC(n*sizeof(P));
7199: cl = (Q *)MALLOC(n*sizeof(Q));
7200: for ( i = 0; i < n; i++, nd = NEXT(nd) ) {
7201: ptozp((P)BDY(nd),1,&cl[i],&dmy);
7202: }
7203: qltozl(cl,n,&dvr);
7204: divz(ONE,dvr,&inv);
7205: nd = BDY(l);
7206: for ( i = 0; i < n; i++, nd = NEXT(nd) )
7207: divsp(CO,(P)BDY(nd),(P)dvr,&pl[i]);
7208: nd = 0;
7209: for ( i = n-1; i >= 0; i-- ) {
7210: MKNODE(nd1,pl[i],nd); nd = nd1;
7211: }
7212: MKLIST(r,nd);
7213: *pp = r;
1.1 noro 7214: }
7215:
7216: /* (a1,a2,...,an) -> a1*e(1)+...+an*e(n) */
7217:
7218: NDV pltondv(VL vl,VL dvl,LIST p)
7219: {
7220: int i;
7221: NODE t;
7222: ND r,ri;
7223: NM m;
7224:
7225: if ( !nd_module ) error("pltond : module order must be set");
7226: r = 0;
7227: for ( i = 1, t = BDY(p); t; t = NEXT(t), i++ ) {
7228: ri = ptond(vl,dvl,(P)BDY(t));
7229: if ( ri )
7230: for ( m = BDY(ri); m; m = NEXT(m) ) {
7231: MPOS(DL(m)) = i;
7232: TD(DL(m)) = ndl_weight(DL(m));
7233: if ( nd_blockmask ) ndl_weight_mask(DL(m));
7234: }
7235: r = nd_add(0,r,ri);
7236: }
7237: return ndtondv(0,r);
7238: }
7239:
7240: ND ptond(VL vl,VL dvl,P p)
7241: {
7242: int n,i,j,k,e;
7243: VL tvl;
7244: V v;
7245: DCP dc;
7246: DCP *w;
7247: ND r,s,t,u;
7248: P x;
7249: int c;
7250: UINT *d;
7251: NM m,m0;
7252:
7253: if ( !p )
7254: return 0;
7255: else if ( NUM(p) ) {
7256: NEWNM(m);
7257: ndl_zero(DL(m));
1.48 noro 7258: if ( RATN(p) && !INT((Q)p) )
1.1 noro 7259: error("ptond : input must be integer-coefficient");
1.6 noro 7260: CZ(m) = (Z)p;
1.1 noro 7261: NEXT(m) = 0;
7262: MKND(nd_nvar,m,1,r);
7263: SG(r) = 0;
7264: return r;
7265: } else {
7266: for ( dc = DC(p), k = 0; dc; dc = NEXT(dc), k++ );
7267: w = (DCP *)MALLOC(k*sizeof(DCP));
7268: for ( dc = DC(p), j = 0; j < k; dc = NEXT(dc), j++ ) w[j] = dc;
7269: for ( i = 0, tvl = dvl, v = VR(p);
7270: tvl && tvl->v != v; tvl = NEXT(tvl), i++ );
7271: if ( !tvl ) {
7272: for ( j = k-1, s = 0, MKV(v,x); j >= 0; j-- ) {
7273: t = ptond(vl,dvl,COEF(w[j]));
7274: pwrp(vl,x,DEG(w[j]),&p);
7275: nd_mul_c_p(CO,t,p); s = nd_add(0,s,t);
7276: }
7277: return s;
7278: } else {
7279: NEWNM(m0); d = DL(m0);
7280: for ( j = k-1, s = 0; j >= 0; j-- ) {
1.6 noro 7281: ndl_zero(d); e = ZTOS(DEG(w[j])); PUT_EXP(d,i,e);
1.1 noro 7282: TD(d) = MUL_WEIGHT(e,i);
7283: if ( nd_blockmask) ndl_weight_mask(d);
7284: if ( nd_module ) MPOS(d) = 0;
7285: t = ptond(vl,dvl,COEF(w[j]));
7286: for ( m = BDY(t); m; m = NEXT(m) )
7287: ndl_addto(DL(m),d);
7288: SG(t) += TD(d);
7289: s = nd_add(0,s,t);
7290: }
7291: FREENM(m0);
7292: return s;
7293: }
7294: }
7295: }
7296:
7297: P ndvtop(int mod,VL vl,VL dvl,NDV p)
7298: {
7299: VL tvl;
7300: int len,n,j,i,e;
7301: NMV m;
7302: Z q;
7303: P c;
7304: UINT *d;
7305: P s,r,u,t,w;
7306: GFS gfs;
7307:
7308: if ( !p ) return 0;
7309: else {
7310: len = LEN(p);
7311: n = NV(p);
7312: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
7313: for ( j = len-1, s = 0; j >= 0; j--, NMV_PREV(m) ) {
7314: if ( mod == -1 ) {
7315: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
7316: } else if ( mod == -2 ) {
7317: c = (P)CZ(m);
7318: } else if ( mod > 0 ) {
1.6 noro 7319: STOZ(CM(m),q); c = (P)q;
1.1 noro 7320: } else
7321: c = CP(m);
7322: d = DL(m);
7323: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
1.6 noro 7324: MKV(tvl->v,r); e = GET_EXP(d,i); STOZ(e,q);
1.1 noro 7325: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
7326: }
7327: addp(vl,s,t,&u); s = u;
7328: }
7329: return s;
7330: }
7331: }
7332:
7333: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank)
7334: {
7335: VL tvl;
7336: int len,n,j,i,e;
7337: NMV m;
7338: Z q;
7339: P c;
7340: UINT *d;
7341: P s,r,u,t,w;
7342: GFS gfs;
7343: P *a;
7344: LIST l;
7345: NODE nd,nd1;
7346:
7347: if ( !p ) return 0;
7348: else {
7349: a = (P *)MALLOC((rank+1)*sizeof(P));
7350: for ( i = 0; i <= rank; i++ ) a[i] = 0;
7351: len = LEN(p);
7352: n = NV(p);
7353: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
7354: for ( j = len-1; j >= 0; j--, NMV_PREV(m) ) {
7355: if ( mod == -1 ) {
7356: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
7357: } else if ( mod ) {
1.6 noro 7358: STOZ(CM(m),q); c = (P)q;
1.1 noro 7359: } else
7360: c = CP(m);
7361: d = DL(m);
7362: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
1.6 noro 7363: MKV(tvl->v,r); e = GET_EXP(d,i); STOZ(e,q);
1.1 noro 7364: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
7365: }
7366: addp(vl,a[MPOS(d)],t,&u); a[MPOS(d)] = u;
7367: }
7368: nd = 0;
7369: for ( i = rank; i > 0; i-- ) {
7370: MKNODE(nd1,a[i],nd); nd = nd1;
7371: }
7372: MKLIST(l,nd);
7373: return l;
7374: }
7375: }
7376:
7377: NDV ndtondv(int mod,ND p)
7378: {
7379: NDV d;
7380: NMV m,m0;
7381: NM t;
7382: int i,len;
7383:
7384: if ( !p ) return 0;
7385: len = LEN(p);
7386: if ( mod > 0 || mod == -1 )
7387: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7388: else
7389: m0 = m = MALLOC(len*nmv_adv);
7390: #if 0
7391: ndv_alloc += nmv_adv*len;
7392: #endif
7393: for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, NMV_ADV(m) ) {
7394: ndl_copy(DL(t),DL(m));
1.6 noro 7395: CZ(m) = CZ(t);
1.1 noro 7396: }
7397: MKNDV(NV(p),m0,len,d);
7398: SG(d) = SG(p);
1.24 noro 7399: d->sig = p->sig;
1.1 noro 7400: return d;
7401: }
7402:
1.16 noro 7403: static int dmm_comp_nv;
7404:
7405: int dmm_comp(DMM *a,DMM *b)
7406: {
7407: return -compdmm(dmm_comp_nv,*a,*b);
7408: }
7409:
7410: void dmm_sort_by_ord(DMM *a,int len,int nv)
7411: {
7412: dmm_comp_nv = nv;
7413: qsort(a,len,sizeof(DMM),(int (*)(const void *,const void *))dmm_comp);
7414: }
7415:
7416: void dpm_sort(DPM p,DPM *rp)
7417: {
7418: DMM t,t1;
7419: int len,i,n;
7420: DMM *a;
7421: DPM d;
7422:
7423: if ( !p ) *rp = 0;
7424: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7425: a = (DMM *)MALLOC(len*sizeof(DMM));
7426: for ( i = 0, t = BDY(p); i < len; i++, t = NEXT(t) ) a[i] = t;
7427: n = p->nv;
7428: dmm_sort_by_ord(a,len,n);
7429: t = 0;
7430: for ( i = len-1; i >= 0; i-- ) {
7431: NEWDMM(t1);
7432: t1->c = a[i]->c;
7433: t1->dl = a[i]->dl;
7434: t1->pos = a[i]->pos;
7435: t1->next = t;
7436: t = t1;
7437: }
7438: MKDPM(n,t,d);
7439: SG(d) = SG(p);
7440: *rp = d;
7441: }
7442:
1.18 noro 7443: int dpm_comp(DPM *a,DPM *b)
7444: {
1.22 noro 7445: return -compdpm(CO,*a,*b);
1.18 noro 7446: }
7447:
7448: NODE dpm_sort_list(NODE l)
7449: {
7450: int i,len;
7451: NODE t,t1;
7452: DPM *a;
7453:
7454: len = length(l);
7455: a = (DPM *)MALLOC(len*sizeof(DPM));
7456: for ( t = l, i = 0; i < len; i++, t = NEXT(t) ) a[i] = (DPM)BDY(t);
7457: qsort(a,len,sizeof(DPM),(int (*)(const void *,const void *))dpm_comp);
7458: t = 0;
7459: for ( i = len-1; i >= 0; i-- ) {
7460: MKNODE(t1,(pointer)a[i],t); t = t1;
7461: }
7462: return t;
7463: }
7464:
1.20 noro 7465: int nmv_comp(NMV a,NMV b)
7466: {
1.21 noro 7467: int t;
7468: t = DL_COMPARE(a->dl,b->dl);
7469: return -t;
1.20 noro 7470: }
7471:
1.43 noro 7472: NDV dptondv(int mod,DP p)
7473: {
7474: NDV d;
7475: NMV m,m0;
7476: MP t;
7477: MP *a;
7478: int i,len,n;
7479:
7480: if ( !p ) return 0;
7481: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7482: n = p->nv;
7483: if ( mod > 0 || mod == -1 )
7484: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7485: else
7486: m0 = m = MALLOC(len*nmv_adv);
7487: for ( i = 0, t = BDY(p); i < len; i++, NMV_ADV(m), t = NEXT(t) ) {
7488: dltondl(n,t->dl,DL(m));
7489: TD(DL(m)) = ndl_weight(DL(m));
7490: CZ(m) = (Z)t->c;
7491: }
7492: qsort(m0,len,nmv_adv,(int (*)(const void *,const void *))nmv_comp);
7493: MKNDV(NV(p),m0,len,d);
7494: SG(d) = SG(p);
7495: return d;
7496: }
7497:
1.16 noro 7498: NDV dpmtondv(int mod,DPM p)
7499: {
7500: NDV d;
7501: NMV m,m0;
7502: DMM t;
7503: DMM *a;
7504: int i,len,n;
7505:
7506: if ( !p ) return 0;
7507: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7508: a = (DMM *)MALLOC(len*sizeof(DMM));
7509: for ( i = 0, t = BDY(p); i < len; i++, t = NEXT(t) ) a[i] = t;
7510: n = p->nv;
7511: dmm_sort_by_ord(a,len,n);
7512: if ( mod > 0 || mod == -1 )
7513: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7514: else
7515: m0 = m = MALLOC(len*nmv_adv);
7516: #if 0
7517: ndv_alloc += nmv_adv*len;
7518: #endif
7519: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7520: dltondl(n,a[i]->dl,DL(m));
7521: MPOS(DL(m)) = a[i]->pos;
1.20 noro 7522: TD(DL(m)) = ndl_weight(DL(m));
1.16 noro 7523: CZ(m) = (Z)a[i]->c;
7524: }
1.20 noro 7525: qsort(m0,len,nmv_adv,(int (*)(const void *,const void *))nmv_comp);
1.16 noro 7526: MKNDV(NV(p),m0,len,d);
7527: SG(d) = SG(p);
7528: return d;
7529: }
7530:
1.1 noro 7531: ND ndvtond(int mod,NDV p)
7532: {
7533: ND d;
7534: NM m,m0;
7535: NMV t;
7536: int i,len;
7537:
7538: if ( !p ) return 0;
7539: m0 = 0;
7540: len = p->len;
7541: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7542: NEXTNM(m0,m);
7543: ndl_copy(DL(t),DL(m));
1.6 noro 7544: CZ(m) = CZ(t);
1.1 noro 7545: }
7546: NEXT(m) = 0;
7547: MKND(NV(p),m0,len,d);
7548: SG(d) = SG(p);
1.28 noro 7549: d->sig = p->sig;
1.1 noro 7550: return d;
7551: }
7552:
7553: DP ndvtodp(int mod,NDV p)
7554: {
7555: MP m,m0;
7556: DP d;
7557: NMV t;
7558: int i,len;
7559:
7560: if ( !p ) return 0;
7561: m0 = 0;
7562: len = p->len;
7563: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7564: NEXTMP(m0,m);
7565: m->dl = ndltodl(nd_nvar,DL(t));
7566: m->c = (Obj)ndctop(mod,t->c);
7567: }
7568: NEXT(m) = 0;
7569: MKDP(nd_nvar,m0,d);
7570: SG(d) = SG(p);
7571: return d;
7572: }
7573:
1.44 noro 7574: DPM sigtodpm(SIG s)
7575: {
7576: DMM m;
7577: DPM d;
7578:
7579: NEWDMM(m);
7580: m->c = (Obj)ONE;
7581: m->dl = s->dl;
7582: m->pos = s->pos+1;
7583: m->next = 0;
7584: MKDPM(nd_nvar,m,d);
7585: SG(d) = s->dl->td;
7586: return d;
7587: }
7588:
1.16 noro 7589: DPM ndvtodpm(int mod,NDV p)
7590: {
7591: DMM m,m0;
7592: DPM d;
7593: NMV t;
7594: int i,len;
7595:
7596: if ( !p ) return 0;
7597: m0 = 0;
7598: len = p->len;
7599: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7600: NEXTDMM(m0,m);
7601: m->dl = ndltodl(nd_nvar,DL(t));
7602: m->c = (Obj)ndctop(mod,t->c);
7603: m->pos = MPOS(DL(t));
7604: }
7605: NEXT(m) = 0;
7606: MKDPM(nd_nvar,m0,d);
7607: SG(d) = SG(p);
7608: return d;
7609: }
7610:
7611:
1.1 noro 7612: DP ndtodp(int mod,ND p)
7613: {
7614: MP m,m0;
7615: DP d;
7616: NM t;
7617: int i,len;
7618:
7619: if ( !p ) return 0;
7620: m0 = 0;
7621: len = p->len;
7622: for ( t = BDY(p); t; t = NEXT(t) ) {
7623: NEXTMP(m0,m);
7624: m->dl = ndltodl(nd_nvar,DL(t));
7625: m->c = (Obj)ndctop(mod,t->c);
7626: }
7627: NEXT(m) = 0;
7628: MKDP(nd_nvar,m0,d);
7629: SG(d) = SG(p);
7630: return d;
7631: }
7632:
7633: void ndv_print(NDV p)
7634: {
7635: NMV m;
7636: int i,len;
7637:
7638: if ( !p ) printf("0\n");
7639: else {
7640: len = LEN(p);
7641: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7642: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
1.28 noro 7643: else printf("+%ld*",CM(m));
1.1 noro 7644: ndl_print(DL(m));
7645: }
7646: printf("\n");
7647: }
7648: }
7649:
7650: void ndv_print_q(NDV p)
7651: {
7652: NMV m;
7653: int i,len;
7654:
7655: if ( !p ) printf("0\n");
7656: else {
7657: len = LEN(p);
7658: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7659: printf("+");
1.6 noro 7660: printexpr(CO,(Obj)CZ(m));
1.1 noro 7661: printf("*");
7662: ndl_print(DL(m));
7663: }
7664: printf("\n");
7665: }
7666: }
7667:
7668: NODE ndv_reducebase(NODE x,int *perm)
7669: {
7670: int len,i,j;
7671: NDVI w;
7672: NODE t,t0;
7673:
1.41 noro 7674: if ( nd_norb ) return x;
1.1 noro 7675: len = length(x);
7676: w = (NDVI)MALLOC(len*sizeof(struct oNDVI));
7677: for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) {
7678: w[i].p = BDY(t); w[i].i = perm[i];
7679: }
7680: for ( i = 0; i < len; i++ ) {
7681: for ( j = 0; j < i; j++ ) {
7682: if ( w[i].p && w[j].p ) {
7683: if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0;
7684: else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0;
7685: }
7686: }
7687: }
7688: for ( i = j = 0, t0 = 0; i < len; i++ ) {
7689: if ( w[i].p ) {
7690: NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p;
7691: perm[j++] = w[i].i;
7692: }
7693: }
7694: NEXT(t) = 0; x = t0;
7695: return x;
7696: }
7697:
7698: /* XXX incomplete */
7699:
1.21 noro 7700: extern DMMstack dmm_stack;
7701: int ndl_module_schreyer_compare(UINT *a,UINT *b);
1.16 noro 7702:
1.1 noro 7703: void nd_init_ord(struct order_spec *ord)
7704: {
7705: nd_module = (ord->id >= 256);
7706: if ( nd_module ) {
7707: nd_dcomp = -1;
1.21 noro 7708: nd_module_ordtype = ord->module_ordtype;
1.1 noro 7709: nd_pot_nelim = ord->pot_nelim;
7710: nd_poly_weight_len = ord->nv;
7711: nd_poly_weight = ord->top_weight;
7712: nd_module_rank = ord->module_rank;
7713: nd_module_weight = ord->module_top_weight;
7714: }
7715: nd_matrix = 0;
7716: nd_matrix_len = 0;
7717: switch ( ord->id ) {
7718: case 0:
7719: switch ( ord->ord.simple ) {
7720: case 0:
7721: nd_dcomp = 1;
7722: nd_isrlex = 1;
7723: break;
7724: case 1:
7725: nd_dcomp = 1;
7726: nd_isrlex = 0;
7727: break;
7728: case 2:
7729: nd_dcomp = 0;
7730: nd_isrlex = 0;
7731: ndl_compare_function = ndl_lex_compare;
7732: break;
7733: case 11:
7734: /* XXX */
7735: nd_dcomp = 0;
7736: nd_isrlex = 1;
7737: ndl_compare_function = ndl_ww_lex_compare;
7738: break;
7739: default:
7740: error("nd_gr : unsupported order");
7741: }
7742: break;
7743: case 1:
7744: /* block order */
7745: /* XXX */
7746: nd_dcomp = -1;
7747: nd_isrlex = 0;
7748: ndl_compare_function = ndl_block_compare;
7749: break;
7750: case 2:
7751: /* matrix order */
7752: /* XXX */
7753: nd_dcomp = -1;
7754: nd_isrlex = 0;
7755: nd_matrix_len = ord->ord.matrix.row;
7756: nd_matrix = ord->ord.matrix.matrix;
7757: ndl_compare_function = ndl_matrix_compare;
7758: break;
7759: case 3:
7760: /* composite order */
7761: nd_dcomp = -1;
7762: nd_isrlex = 0;
7763: nd_worb_len = ord->ord.composite.length;
7764: nd_worb = ord->ord.composite.w_or_b;
7765: ndl_compare_function = ndl_composite_compare;
7766: break;
7767:
7768: /* module order */
7769: case 256:
7770: switch ( ord->ord.simple ) {
7771: case 0:
1.21 noro 7772: nd_dcomp = 0;
1.1 noro 7773: nd_isrlex = 1;
1.21 noro 7774: ndl_compare_function = ndl_module_glex_compare;
1.1 noro 7775: break;
7776: case 1:
1.21 noro 7777: nd_dcomp = 0;
1.1 noro 7778: nd_isrlex = 0;
7779: ndl_compare_function = ndl_module_glex_compare;
7780: break;
7781: case 2:
1.21 noro 7782: nd_dcomp = 0;
1.1 noro 7783: nd_isrlex = 0;
1.21 noro 7784: ndl_compare_function = ndl_module_compare;
7785: ndl_base_compare_function = ndl_lex_compare;
1.1 noro 7786: break;
7787: default:
1.21 noro 7788: error("nd_init_ord : unsupported order");
1.1 noro 7789: }
7790: break;
7791: case 257:
7792: /* block order */
7793: nd_isrlex = 0;
1.21 noro 7794: ndl_compare_function = ndl_module_compare;
7795: ndl_base_compare_function = ndl_block_compare;
1.1 noro 7796: break;
7797: case 258:
7798: /* matrix order */
7799: nd_isrlex = 0;
7800: nd_matrix_len = ord->ord.matrix.row;
7801: nd_matrix = ord->ord.matrix.matrix;
1.21 noro 7802: ndl_compare_function = ndl_module_compare;
7803: ndl_base_compare_function = ndl_matrix_compare;
1.1 noro 7804: break;
7805: case 259:
7806: /* composite order */
7807: nd_isrlex = 0;
7808: nd_worb_len = ord->ord.composite.length;
7809: nd_worb = ord->ord.composite.w_or_b;
1.21 noro 7810: ndl_compare_function = ndl_module_compare;
7811: ndl_base_compare_function = ndl_composite_compare;
7812: break;
7813: case 300:
7814: /* schreyer order */
7815: if ( ord->base->id != 256 )
7816: error("nd_init_ord : unsupported base order");
7817: ndl_compare_function = ndl_module_schreyer_compare;
7818: dmm_stack = ord->dmmstack;
7819: switch ( ord->base->ord.simple ) {
7820: case 0:
7821: nd_isrlex = 1;
7822: ndl_base_compare_function = ndl_glex_compare;
7823: dl_base_compare_function = cmpdl_revgradlex;
7824: break;
7825: case 1:
7826: nd_isrlex = 0;
7827: ndl_base_compare_function = ndl_glex_compare;
7828: dl_base_compare_function = cmpdl_gradlex;
7829: break;
7830: case 2:
7831: nd_isrlex = 0;
7832: ndl_base_compare_function = ndl_lex_compare;
7833: dl_base_compare_function = cmpdl_lex;
7834: break;
7835: default:
7836: error("nd_init_ord : unsupported order");
7837: }
1.1 noro 7838: break;
7839: }
7840: nd_ord = ord;
7841: }
7842:
7843: BlockMask nd_create_blockmask(struct order_spec *ord)
7844: {
7845: int n,i,j,s,l;
7846: UINT *t;
7847: BlockMask bm;
7848:
7849: /* we only create mask table for block order */
7850: if ( ord->id != 1 && ord->id != 257 )
7851: return 0;
7852: n = ord->ord.block.length;
7853: bm = (BlockMask)MALLOC(sizeof(struct oBlockMask));
7854: bm->n = n;
7855: bm->order_pair = ord->ord.block.order_pair;
7856: bm->mask = (UINT **)MALLOC(n*sizeof(UINT *));
7857: for ( i = 0, s = 0; i < n; i++ ) {
7858: bm->mask[i] = t = (UINT *)MALLOC_ATOMIC(nd_wpd*sizeof(UINT));
7859: for ( j = 0; j < nd_wpd; j++ ) t[j] = 0;
7860: l = bm->order_pair[i].length;
7861: for ( j = 0; j < l; j++, s++ ) PUT_EXP(t,s,nd_mask0);
7862: }
7863: return bm;
7864: }
7865:
7866: EPOS nd_create_epos(struct order_spec *ord)
7867: {
7868: int i,j,l,s,ord_l,ord_o;
7869: EPOS epos;
7870: struct order_pair *op;
7871:
7872: epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS));
7873: switch ( ord->id ) {
1.21 noro 7874: case 0: case 256: case 300:
1.1 noro 7875: if ( nd_isrlex ) {
7876: for ( i = 0; i < nd_nvar; i++ ) {
7877: epos[i].i = nd_exporigin + (nd_nvar-1-i)/nd_epw;
7878: epos[i].s = (nd_epw-((nd_nvar-1-i)%nd_epw)-1)*nd_bpe;
7879: }
7880: } else {
7881: for ( i = 0; i < nd_nvar; i++ ) {
7882: epos[i].i = nd_exporigin + i/nd_epw;
7883: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
7884: }
7885: }
7886: break;
7887: case 1: case 257:
7888: /* block order */
7889: l = ord->ord.block.length;
7890: op = ord->ord.block.order_pair;
7891: for ( j = 0, s = 0; j < l; j++ ) {
7892: ord_o = op[j].order;
7893: ord_l = op[j].length;
7894: if ( !ord_o )
7895: for ( i = 0; i < ord_l; i++ ) {
7896: epos[s+i].i = nd_exporigin + (s+ord_l-i-1)/nd_epw;
7897: epos[s+i].s = (nd_epw-((s+ord_l-i-1)%nd_epw)-1)*nd_bpe;
7898: }
7899: else
7900: for ( i = 0; i < ord_l; i++ ) {
7901: epos[s+i].i = nd_exporigin + (s+i)/nd_epw;
7902: epos[s+i].s = (nd_epw-((s+i)%nd_epw)-1)*nd_bpe;
7903: }
7904: s += ord_l;
7905: }
7906: break;
7907: case 2:
7908: /* matrix order */
7909: case 3:
7910: /* composite order */
7911: default:
7912: for ( i = 0; i < nd_nvar; i++ ) {
7913: epos[i].i = nd_exporigin + i/nd_epw;
7914: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
7915: }
7916: break;
7917: }
7918: return epos;
7919: }
7920:
7921: /* external interface */
7922:
7923: void nd_nf_p(Obj f,LIST g,LIST v,int m,struct order_spec *ord,Obj *rp)
7924: {
7925: NODE t,in0,in;
7926: ND ndf,nf;
7927: NDV ndvf;
7928: VL vv,tv;
7929: int stat,nvar,max,mrank;
7930: union oNDC dn;
7931: Q cont;
7932: P pp;
7933: LIST ppl;
7934:
7935: if ( !f ) {
7936: *rp = 0;
7937: return;
7938: }
7939: pltovl(v,&vv);
7940: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
7941:
7942: /* max=65536 implies nd_bpe=32 */
7943: max = 65536;
7944:
7945: nd_module = 0;
7946: /* nd_module will be set if ord is a module ordering */
7947: nd_init_ord(ord);
7948: nd_setup_parameters(nvar,max);
7949: if ( nd_module && OID(f) != O_LIST )
7950: error("nd_nf_p : the first argument must be a list");
7951: if ( nd_module ) mrank = length(BDY((LIST)f));
7952: /* conversion to ndv */
7953: for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) {
7954: NEXTNODE(in0,in);
7955: if ( nd_module ) {
7956: if ( !BDY(t) || OID(BDY(t)) != O_LIST
7957: || length(BDY((LIST)BDY(t))) != mrank )
7958: error("nd_nf_p : inconsistent basis element");
7959: if ( !m ) pltozpl((LIST)BDY(t),&cont,&ppl);
7960: else ppl = (LIST)BDY(t);
7961: BDY(in) = (pointer)pltondv(CO,vv,ppl);
7962: } else {
7963: if ( !m ) ptozp((P)BDY(t),1,&cont,&pp);
7964: else pp = (P)BDY(t);
7965: BDY(in) = (pointer)ptondv(CO,vv,pp);
7966: }
7967: if ( m ) ndv_mod(m,(NDV)BDY(in));
7968: }
7969: if ( in0 ) NEXT(in) = 0;
7970:
7971: if ( nd_module ) ndvf = pltondv(CO,vv,(LIST)f);
7972: else ndvf = ptondv(CO,vv,(P)f);
7973: if ( m ) ndv_mod(m,ndvf);
7974: ndf = (pointer)ndvtond(m,ndvf);
7975:
7976: /* dont sort, dont removecont */
1.24 noro 7977: ndv_setup(m,0,in0,1,1,0);
1.1 noro 7978: nd_scale=2;
1.6 noro 7979: stat = nd_nf(m,0,ndf,nd_ps,1,&nf);
1.1 noro 7980: if ( !stat )
7981: error("nd_nf_p : exponent too large");
7982: if ( nd_module ) *rp = (Obj)ndvtopl(m,CO,vv,ndtondv(m,nf),mrank);
7983: else *rp = (Obj)ndvtop(m,CO,vv,ndtondv(m,nf));
7984: }
7985:
7986: int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r)
7987: {
7988: NM m;
7989: UINT *t,*s;
7990: int i;
7991:
7992: for ( i = 0; i < n; i++ ) r[i] = 0;
7993: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7994: t = DL(m);
7995: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
7996: r[i] = CM(m);
7997: }
7998: for ( i = 0; !r[i]; i++ );
7999: return i;
8000: }
8001:
8002: int nd_to_vect_q(UINT *s0,int n,ND d,Z *r)
8003: {
8004: NM m;
8005: UINT *t,*s;
8006: int i;
8007:
8008: for ( i = 0; i < n; i++ ) r[i] = 0;
8009: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
8010: t = DL(m);
8011: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.6 noro 8012: r[i] = CZ(m);
1.1 noro 8013: }
8014: for ( i = 0; !r[i]; i++ );
8015: return i;
8016: }
8017:
8018: int nd_to_vect_lf(UINT *s0,int n,ND d,mpz_t *r)
8019: {
8020: NM m;
8021: UINT *t,*s;
8022: int i;
8023:
8024: for ( i = 0; i < n; i++ ) { mpz_init(r[i]); mpz_set_ui(r[i],0); }
8025: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
8026: t = DL(m);
8027: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
8028: mpz_set(r[i],BDY(CZ(m)));
8029: }
8030: for ( i = 0; !mpz_sgn(r[i]); i++ );
8031: return i;
8032: }
8033:
8034: unsigned long *nd_to_vect_2(UINT *s0,int n,int *s0hash,ND p)
8035: {
8036: NM m;
8037: unsigned long *v;
8038: int i,j,h,size;
8039: UINT *s,*t;
8040:
8041: size = sizeof(unsigned long)*(n+BLEN-1)/BLEN;
8042: v = (unsigned long *)MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
8043: bzero(v,size);
8044: for ( i = j = 0, s = s0, m = BDY(p); m; j++, m = NEXT(m) ) {
8045: t = DL(m);
8046: h = ndl_hash_value(t);
8047: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
8048: v[i/BLEN] |= 1L <<(i%BLEN);
8049: }
8050: return v;
8051: }
8052:
8053: int nd_nm_to_vect_2(UINT *s0,int n,int *s0hash,NDV p,NM m,unsigned long *v)
8054: {
8055: NMV mr;
8056: UINT *d,*t,*s;
8057: int i,j,len,h,head;
8058:
8059: d = DL(m);
8060: len = LEN(p);
8061: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8062: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
8063: ndl_add(d,DL(mr),t);
8064: h = ndl_hash_value(t);
8065: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
8066: if ( j == 0 ) head = i;
8067: v[i/BLEN] |= 1L <<(i%BLEN);
8068: }
8069: return head;
8070: }
8071:
8072: Z *nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_pair pair)
8073: {
8074: NM m;
8075: NMV mr;
8076: UINT *d,*t,*s;
8077: NDV p;
8078: int i,j,len;
8079: Z *r;
8080:
8081: m = pair->mul;
8082: d = DL(m);
8083: p = nd_ps[pair->index];
8084: len = LEN(p);
8085: r = (Z *)CALLOC(n,sizeof(Q));
8086: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8087: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
8088: ndl_add(d,DL(mr),t);
8089: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.6 noro 8090: r[i] = CZ(mr);
1.1 noro 8091: }
8092: return r;
8093: }
8094:
1.11 noro 8095: IndArray nm_ind_pair_to_vect_compress(int trace,UINT *s0,int n,NM_ind_pair pair,int start)
1.1 noro 8096: {
8097: NM m;
8098: NMV mr;
1.11 noro 8099: UINT *d,*t,*s,*u;
1.1 noro 8100: NDV p;
8101: unsigned char *ivc;
8102: unsigned short *ivs;
8103: UINT *v,*ivi,*s0v;
1.11 noro 8104: int i,j,len,prev,diff,cdiff,h,st,ed,md,c;
1.1 noro 8105: IndArray r;
8106:
8107: m = pair->mul;
8108: d = DL(m);
8109: if ( trace )
8110: p = nd_demand?nd_ps_trace_sym[pair->index]:nd_ps_trace[pair->index];
8111: else
8112: p = nd_demand?nd_ps_sym[pair->index]:nd_ps[pair->index];
8113:
8114: len = LEN(p);
8115: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8116: v = (unsigned int *)MALLOC(len*sizeof(unsigned int));
1.11 noro 8117: for ( prev = start, mr = BDY(p), j = 0; j < len; j++, NMV_ADV(mr) ) {
8118: ndl_add(d,DL(mr),t);
8119: st = prev;
8120: ed = n;
8121: while ( ed > st ) {
8122: md = (st+ed)/2;
8123: u = s0+md*nd_wpd;
8124: c = DL_COMPARE(u,t);
8125: if ( c == 0 ) break;
8126: else if ( c > 0 ) st = md;
8127: else ed = md;
8128: }
8129: prev = v[j] = md;
1.1 noro 8130: }
8131: r = (IndArray)MALLOC(sizeof(struct oIndArray));
8132: r->head = v[0];
8133: diff = 0;
8134: for ( i = 1; i < len; i++ ) {
8135: cdiff = v[i]-v[i-1]; diff = MAX(cdiff,diff);
8136: }
8137: if ( diff < 256 ) {
8138: r->width = 1;
8139: ivc = (unsigned char *)MALLOC_ATOMIC(len*sizeof(unsigned char));
8140: r->index.c = ivc;
8141: for ( i = 1, ivc[0] = 0; i < len; i++ ) ivc[i] = v[i]-v[i-1];
8142: } else if ( diff < 65536 ) {
8143: r->width = 2;
8144: ivs = (unsigned short *)MALLOC_ATOMIC(len*sizeof(unsigned short));
8145: r->index.s = ivs;
8146: for ( i = 1, ivs[0] = 0; i < len; i++ ) ivs[i] = v[i]-v[i-1];
8147: } else {
8148: r->width = 4;
8149: ivi = (unsigned int *)MALLOC_ATOMIC(len*sizeof(unsigned int));
8150: r->index.i = ivi;
8151: for ( i = 1, ivi[0] = 0; i < len; i++ ) ivi[i] = v[i]-v[i-1];
8152: }
8153: return r;
8154: }
8155:
8156: int compress_array(Z *svect,Z *cvect,int n)
8157: {
8158: int i,j;
8159:
8160: for ( i = j = 0; i < n; i++ )
8161: if ( svect[i] ) cvect[j++] = svect[i];
8162: return j;
8163: }
8164:
8165: void expand_array(Z *svect,Z *cvect,int n)
8166: {
8167: int i,j;
8168:
8169: for ( i = j = 0; j < n; i++ )
8170: if ( svect[i] ) svect[i] = cvect[j++];
8171: }
8172:
1.8 noro 8173: #if 0
1.1 noro 8174: int ndv_reduce_vect_q(Z *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8175: {
8176: int i,j,k,len,pos,prev,nz;
8177: Z cs,mcs,c1,c2,cr,gcd,t;
8178: IndArray ivect;
8179: unsigned char *ivc;
8180: unsigned short *ivs;
8181: unsigned int *ivi;
8182: NDV redv;
8183: NMV mr;
8184: NODE rp;
8185: int maxrs;
8186: double hmag;
8187: Z *cvect;
1.3 noro 8188: int l;
1.1 noro 8189:
8190: maxrs = 0;
8191: for ( i = 0; i < col && !svect[i]; i++ );
8192: if ( i == col ) return maxrs;
8193: hmag = p_mag((P)svect[i])*nd_scale;
8194: cvect = (Z *)MALLOC(col*sizeof(Q));
8195: for ( i = 0; i < nred; i++ ) {
8196: ivect = imat[i];
8197: k = ivect->head;
8198: if ( svect[k] ) {
8199: maxrs = MAX(maxrs,rp0[i]->sugar);
8200: redv = nd_demand?ndv_load(rp0[i]->index)
8201: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
8202: len = LEN(redv); mr = BDY(redv);
1.6 noro 8203: igcd_cofactor(svect[k],CZ(mr),&gcd,&cs,&cr);
1.1 noro 8204: chsgnz(cs,&mcs);
8205: if ( !UNIQ(cr) ) {
8206: for ( j = 0; j < col; j++ ) {
8207: mulz(svect[j],cr,&c1); svect[j] = c1;
8208: }
8209: }
8210: svect[k] = 0; prev = k;
8211: switch ( ivect->width ) {
8212: case 1:
8213: ivc = ivect->index.c;
8214: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8215: pos = prev+ivc[j]; prev = pos;
1.6 noro 8216: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8217: }
8218: break;
8219: case 2:
8220: ivs = ivect->index.s;
8221: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8222: pos = prev+ivs[j]; prev = pos;
1.6 noro 8223: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8224: }
8225: break;
8226: case 4:
8227: ivi = ivect->index.i;
8228: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8229: pos = prev+ivi[j]; prev = pos;
1.6 noro 8230: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8231: }
8232: break;
8233: }
8234: for ( j = k+1; j < col && !svect[j]; j++ );
8235: if ( j == col ) break;
8236: if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) {
8237: nz = compress_array(svect,cvect,col);
8238: removecont_array((P *)cvect,nz,1);
8239: expand_array(svect,cvect,nz);
8240: hmag = ((double)p_mag((P)svect[j]))*nd_scale;
8241: }
8242: }
8243: }
8244: nz = compress_array(svect,cvect,col);
8245: removecont_array((P *)cvect,nz,1);
8246: expand_array(svect,cvect,nz);
8247: if ( DP_Print ) {
8248: fprintf(asir_out,"-"); fflush(asir_out);
8249: }
8250: return maxrs;
8251: }
1.4 noro 8252: #else
1.9 noro 8253:
1.4 noro 8254: /* direct mpz version */
8255: int ndv_reduce_vect_q(Z *svect0,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8256: {
8257: int i,j,k,len,pos,prev;
8258: mpz_t cs,cr,gcd;
8259: IndArray ivect;
8260: unsigned char *ivc;
8261: unsigned short *ivs;
8262: unsigned int *ivi;
8263: NDV redv;
8264: NMV mr;
8265: NODE rp;
8266: int maxrs;
8267: double hmag;
8268: int l;
1.13 noro 8269: static mpz_t *svect;
8270: static int svect_len=0;
1.4 noro 8271:
8272: maxrs = 0;
8273: for ( i = 0; i < col && !svect0[i]; i++ );
8274: if ( i == col ) return maxrs;
8275: hmag = p_mag((P)svect0[i])*nd_scale;
1.13 noro 8276: if ( col > svect_len ) {
8277: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
8278: svect_len = col;
8279: }
1.4 noro 8280: for ( i = 0; i < col; i++ ) {
8281: mpz_init(svect[i]);
8282: if ( svect0[i] )
8283: mpz_set(svect[i],BDY(svect0[i]));
8284: else
8285: mpz_set_ui(svect[i],0);
8286: }
8287: mpz_init(gcd); mpz_init(cs); mpz_init(cr);
8288: for ( i = 0; i < nred; i++ ) {
8289: ivect = imat[i];
8290: k = ivect->head;
8291: if ( mpz_sgn(svect[k]) ) {
8292: maxrs = MAX(maxrs,rp0[i]->sugar);
8293: redv = nd_demand?ndv_load(rp0[i]->index)
8294: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
8295: len = LEN(redv); mr = BDY(redv);
1.6 noro 8296: mpz_gcd(gcd,svect[k],BDY(CZ(mr)));
1.4 noro 8297: mpz_div(cs,svect[k],gcd);
1.6 noro 8298: mpz_div(cr,BDY(CZ(mr)),gcd);
1.4 noro 8299: mpz_neg(cs,cs);
1.9 noro 8300: if ( MUNIMPZ(cr) )
8301: for ( j = 0; j < col; j++ ) mpz_neg(svect[j],svect[j]);
8302: else if ( !UNIMPZ(cr) )
8303: for ( j = 0; j < col; j++ ) {
8304: if ( mpz_sgn(svect[j]) ) mpz_mul(svect[j],svect[j],cr);
8305: }
1.4 noro 8306: mpz_set_ui(svect[k],0);
8307: prev = k;
8308: switch ( ivect->width ) {
8309: case 1:
8310: ivc = ivect->index.c;
8311: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8312: pos = prev+ivc[j]; prev = pos;
1.6 noro 8313: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8314: }
8315: break;
8316: case 2:
8317: ivs = ivect->index.s;
8318: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8319: pos = prev+ivs[j]; prev = pos;
1.6 noro 8320: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8321: }
8322: break;
8323: case 4:
8324: ivi = ivect->index.i;
8325: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8326: pos = prev+ivi[j]; prev = pos;
1.6 noro 8327: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8328: }
8329: break;
8330: }
8331: for ( j = k+1; j < col && !svect[j]; j++ );
8332: if ( j == col ) break;
8333: if ( hmag && ((double)mpz_sizeinbase(svect[j],2) > hmag) ) {
8334: mpz_removecont_array(svect,col);
8335: hmag = ((double)mpz_sizeinbase(svect[j],2))*nd_scale;
8336: }
8337: }
8338: }
8339: mpz_removecont_array(svect,col);
8340: if ( DP_Print ) {
8341: fprintf(asir_out,"-"); fflush(asir_out);
8342: }
8343: for ( i = 0; i < col; i++ )
8344: if ( mpz_sgn(svect[i]) ) MPZTOZ(svect[i],svect0[i]);
8345: else svect0[i] = 0;
8346: return maxrs;
8347: }
8348: #endif
1.1 noro 8349:
1.40 noro 8350: int ndv_reduce_vect(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred,SIG sig)
1.1 noro 8351: {
8352: int i,j,k,len,pos,prev;
8353: UINT c,c1,c2,c3,up,lo,dmy;
8354: IndArray ivect;
8355: unsigned char *ivc;
8356: unsigned short *ivs;
8357: unsigned int *ivi;
8358: NDV redv;
8359: NMV mr;
8360: NODE rp;
8361: int maxrs;
8362:
8363: maxrs = 0;
8364: for ( i = 0; i < nred; i++ ) {
8365: ivect = imat[i];
8366: k = ivect->head; svect[k] %= m;
1.40 noro 8367: if ( (c = svect[k]) != 0 && (sig == 0 || comp_sig(sig,rp0[i]->sig) > 0 ) ) {
1.1 noro 8368: maxrs = MAX(maxrs,rp0[i]->sugar);
8369: c = m-c; redv = nd_ps[rp0[i]->index];
8370: len = LEN(redv); mr = BDY(redv);
8371: svect[k] = 0; prev = k;
8372: switch ( ivect->width ) {
8373: case 1:
8374: ivc = ivect->index.c;
8375: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8376: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.40 noro 8377: if ( c1 ) {
8378: c2 = svect[pos];
1.1 noro 8379: DMA(c1,c,c2,up,lo);
8380: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8381: } else svect[pos] = lo;
1.40 noro 8382: }
1.1 noro 8383: }
8384: break;
8385: case 2:
8386: ivs = ivect->index.s;
8387: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8388: pos = prev+ivs[j]; c1 = CM(mr);
8389: prev = pos;
1.40 noro 8390: if ( c1 ) {
8391: c2 = svect[pos];
1.1 noro 8392: DMA(c1,c,c2,up,lo);
8393: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8394: } else svect[pos] = lo;
1.40 noro 8395: }
1.1 noro 8396: }
8397: break;
8398: case 4:
8399: ivi = ivect->index.i;
8400: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8401: pos = prev+ivi[j]; c1 = CM(mr);
8402: prev = pos;
1.40 noro 8403: if ( c1 ) {
8404: c2 = svect[pos];
1.1 noro 8405: DMA(c1,c,c2,up,lo);
8406: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8407: } else svect[pos] = lo;
1.40 noro 8408: }
1.1 noro 8409: }
8410: break;
8411: }
8412: }
8413: }
8414: for ( i = 0; i < col; i++ )
8415: if ( svect[i] >= (UINT)m ) svect[i] %= m;
8416: return maxrs;
8417: }
8418:
8419: int ndv_reduce_vect_sf(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8420: {
8421: int i,j,k,len,pos,prev;
8422: UINT c,c1,c2,c3,up,lo,dmy;
8423: IndArray ivect;
8424: unsigned char *ivc;
8425: unsigned short *ivs;
8426: unsigned int *ivi;
8427: NDV redv;
8428: NMV mr;
8429: NODE rp;
8430: int maxrs;
8431:
8432: maxrs = 0;
8433: for ( i = 0; i < nred; i++ ) {
8434: ivect = imat[i];
8435: k = ivect->head;
8436: if ( (c = svect[k]) != 0 ) {
8437: maxrs = MAX(maxrs,rp0[i]->sugar);
8438: c = _chsgnsf(c); redv = nd_ps[rp0[i]->index];
8439: len = LEN(redv); mr = BDY(redv);
8440: svect[k] = 0; prev = k;
8441: switch ( ivect->width ) {
8442: case 1:
8443: ivc = ivect->index.c;
8444: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8445: pos = prev+ivc[j]; prev = pos;
8446: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8447: }
8448: break;
8449: case 2:
8450: ivs = ivect->index.s;
8451: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8452: pos = prev+ivs[j]; prev = pos;
8453: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8454: }
8455: break;
8456: case 4:
8457: ivi = ivect->index.i;
8458: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8459: pos = prev+ivi[j]; prev = pos;
8460: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8461: }
8462: break;
8463: }
8464: }
8465: }
8466: return maxrs;
8467: }
8468:
8469: ND nd_add_lf(ND p1,ND p2)
8470: {
8471: int n,c,can;
8472: ND r;
8473: NM m1,m2,mr0,mr,s;
8474: Z t;
8475:
8476: if ( !p1 ) return p2;
8477: else if ( !p2 ) return p1;
8478: else {
8479: can = 0;
8480: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
8481: c = DL_COMPARE(DL(m1),DL(m2));
8482: switch ( c ) {
8483: case 0:
8484: addlf(CZ(m1),CZ(m2),&t);
8485: s = m1; m1 = NEXT(m1);
8486: if ( t ) {
8487: can++; NEXTNM2(mr0,mr,s); CZ(mr) = (t);
8488: } else {
8489: can += 2; FREENM(s);
8490: }
8491: s = m2; m2 = NEXT(m2); FREENM(s);
8492: break;
8493: case 1:
8494: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
8495: break;
8496: case -1:
8497: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
8498: break;
8499: }
8500: }
8501: if ( !mr0 )
8502: if ( m1 ) mr0 = m1;
8503: else if ( m2 ) mr0 = m2;
8504: else return 0;
8505: else if ( m1 ) NEXT(mr) = m1;
8506: else if ( m2 ) NEXT(mr) = m2;
8507: else NEXT(mr) = 0;
8508: BDY(p1) = mr0;
8509: SG(p1) = MAX(SG(p1),SG(p2));
8510: LEN(p1) = LEN(p1)+LEN(p2)-can;
8511: FREEND(p2);
8512: return p1;
8513: }
8514: }
8515:
8516: int ndv_reduce_vect_lf(mpz_t *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8517: {
8518: int i,j,k,len,pos,prev;
8519: mpz_t c,mc,c1;
8520: IndArray ivect;
8521: unsigned char *ivc;
8522: unsigned short *ivs;
8523: unsigned int *ivi;
8524: NDV redv;
8525: NMV mr;
8526: NODE rp;
8527: int maxrs;
8528:
8529: maxrs = 0;
8530: lf_lazy = 1;
8531: for ( i = 0; i < nred; i++ ) {
8532: ivect = imat[i];
8533: k = ivect->head;
8534: mpz_mod(svect[k],svect[k],BDY(current_mod_lf));
8535: if ( mpz_sgn(svect[k]) ) {
8536: maxrs = MAX(maxrs,rp0[i]->sugar);
8537: mpz_neg(svect[k],svect[k]);
8538: redv = trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index];
8539: len = LEN(redv); mr = BDY(redv);
8540: prev = k;
8541: switch ( ivect->width ) {
8542: case 1:
8543: ivc = ivect->index.c;
8544: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8545: pos = prev+ivc[j]; prev = pos;
8546: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8547: }
8548: break;
8549: case 2:
8550: ivs = ivect->index.s;
8551: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8552: pos = prev+ivs[j]; prev = pos;
8553: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8554: }
8555: break;
8556: case 4:
8557: ivi = ivect->index.i;
8558: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8559: pos = prev+ivi[j]; prev = pos;
8560: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8561: }
8562: break;
8563: }
8564: mpz_set_ui(svect[k],0);
8565: }
8566: }
8567: lf_lazy=0;
8568: for ( i = 0; i < col; i++ ) {
8569: mpz_mod(svect[i],svect[i],BDY(current_mod_lf));
8570: }
8571: return maxrs;
8572: }
8573:
8574: int nd_gauss_elim_lf(mpz_t **mat0,int *sugar,int row,int col,int *colstat)
8575: {
8576: int i,j,k,l,rank,s;
8577: mpz_t a,a1,inv;
8578: mpz_t *t,*pivot,*pk;
8579: mpz_t **mat;
8580: struct oEGT eg0,eg1,eg_forward,eg_mod,eg_back;
8581: int size,size1;
8582:
8583: mpz_init(inv);
8584: mpz_init(a);
8585: mat = (mpz_t **)mat0;
8586: size = 0;
8587: for ( rank = 0, j = 0; j < col; j++ ) {
8588: for ( i = rank; i < row; i++ ) {
8589: mpz_mod(mat[i][j],mat[i][j],BDY(current_mod_lf));
8590: }
8591: for ( i = rank; i < row; i++ )
8592: if ( mpz_sgn(mat[i][j]) )
8593: break;
8594: if ( i == row ) {
8595: colstat[j] = 0;
8596: continue;
8597: } else
8598: colstat[j] = 1;
8599: if ( i != rank ) {
8600: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
8601: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
8602: }
8603: pivot = mat[rank];
8604: s = sugar[rank];
8605: mpz_invert(inv,pivot[j],BDY(current_mod_lf));
8606: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
8607: if ( mpz_sgn(*pk) ) {
8608: mpz_mul(a,*pk,inv); mpz_mod(*pk,a,BDY(current_mod_lf));
8609: }
8610: for ( i = rank+1; i < row; i++ ) {
8611: t = mat[i];
8612: if ( mpz_sgn(t[j]) ) {
8613: sugar[i] = MAX(sugar[i],s);
8614: mpz_neg(a,t[j]);
8615: red_by_vect_lf(t+j,pivot+j,a,col-j);
8616: }
8617: }
8618: rank++;
8619: }
8620: for ( j = col-1, l = rank-1; j >= 0; j-- )
8621: if ( colstat[j] ) {
8622: pivot = mat[l];
8623: s = sugar[l];
8624: for ( k = j; k < col; k++ )
8625: mpz_mod(pivot[k],pivot[k],BDY(current_mod_lf));
8626: for ( i = 0; i < l; i++ ) {
8627: t = mat[i];
8628: if ( mpz_sgn(t[j]) ) {
8629: sugar[i] = MAX(sugar[i],s);
8630: mpz_neg(a,t[j]);
8631: red_by_vect_lf(t+j,pivot+j,a,col-j);
8632: }
8633: }
8634: l--;
8635: }
8636: for ( j = 0, l = 0; l < rank; j++ )
8637: if ( colstat[j] ) {
8638: t = mat[l];
8639: for ( k = j; k < col; k++ ) {
8640: mpz_mod(t[k],t[k],BDY(current_mod_lf));
8641: }
8642: l++;
8643: }
8644: return rank;
8645: }
8646:
8647:
8648: NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhead,UINT *s0vect)
8649: {
8650: int j,k,len;
8651: UINT *p;
8652: UINT c;
8653: NDV r;
8654: NMV mr0,mr;
8655:
8656: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
8657: if ( !len ) return 0;
8658: else {
8659: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8660: #if 0
8661: ndv_alloc += nmv_adv*len;
8662: #endif
8663: mr = mr0;
8664: p = s0vect;
8665: for ( j = k = 0; j < col; j++, p += nd_wpd )
8666: if ( !rhead[j] ) {
8667: if ( (c = vect[k++]) != 0 ) {
8668: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
8669: }
8670: }
8671: MKNDV(nd_nvar,mr0,len,r);
8672: return r;
8673: }
8674: }
8675:
1.40 noro 8676: NDV vect_to_ndv_s(UINT *vect,int col,UINT *s0vect)
8677: {
8678: int j,k,len;
8679: UINT *p;
8680: UINT c;
8681: NDV r;
8682: NMV mr0,mr;
8683:
8684: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
8685: if ( !len ) return 0;
8686: else {
8687: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8688: mr = mr0;
8689: p = s0vect;
8690: for ( j = k = 0; j < col; j++, p += nd_wpd )
8691: if ( (c = vect[k++]) != 0 ) {
8692: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
8693: }
8694: MKNDV(nd_nvar,mr0,len,r);
8695: return r;
8696: }
8697: }
8698:
1.1 noro 8699: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect)
8700: {
8701: int j,k,len;
8702: UINT *p;
8703: NDV r;
8704: NMV mr0,mr;
8705:
8706: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) len++;
8707: if ( !len ) return 0;
8708: else {
8709: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8710: mr = mr0;
8711: p = s0vect;
8712: for ( j = 0; j < col; j++, p += nd_wpd )
8713: if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) {
8714: ndl_copy(p,DL(mr)); CM(mr) = 1; NMV_ADV(mr);
8715: }
8716: MKNDV(nd_nvar,mr0,len,r);
8717: return r;
8718: }
8719: }
8720:
8721: /* for preprocessed vector */
8722:
8723: NDV vect_to_ndv_q(Z *vect,int spcol,int col,int *rhead,UINT *s0vect)
8724: {
1.6 noro 8725: int j,k,len;
8726: UINT *p;
8727: Z c;
8728: NDV r;
8729: NMV mr0,mr;
1.1 noro 8730:
1.6 noro 8731: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
8732: if ( !len ) return 0;
8733: else {
8734: mr0 = (NMV)MALLOC(nmv_adv*len);
1.1 noro 8735: #if 0
1.6 noro 8736: ndv_alloc += nmv_adv*len;
1.1 noro 8737: #endif
1.6 noro 8738: mr = mr0;
8739: p = s0vect;
8740: for ( j = k = 0; j < col; j++, p += nd_wpd ) {
8741: if ( !rhead[j] ) {
8742: if ( (c = vect[k++]) != 0 ) {
8743: if ( !INT(c) )
8744: error("vect_to_ndv_q : components must be integers");
8745: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
8746: }
8747: }
1.1 noro 8748: }
1.6 noro 8749: MKNDV(nd_nvar,mr0,len,r);
8750: return r;
8751: }
1.1 noro 8752: }
8753:
8754: NDV vect_to_ndv_lf(mpz_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
8755: {
8756: int j,k,len;
8757: UINT *p;
8758: mpz_t c;
8759: NDV r;
8760: NMV mr0,mr;
8761:
8762: for ( j = 0, len = 0; j < spcol; j++ ) if ( mpz_sgn(vect[j]) ) len++;
8763: if ( !len ) return 0;
8764: else {
8765: mr0 = (NMV)MALLOC(nmv_adv*len);
8766: #if 0
8767: ndv_alloc += nmv_adv*len;
8768: #endif
8769: mr = mr0;
8770: p = s0vect;
8771: for ( j = k = 0; j < col; j++, p += nd_wpd )
8772: if ( !rhead[j] ) {
8773: c[0] = vect[k++][0];
8774: if ( mpz_sgn(c) ) {
8775: ndl_copy(p,DL(mr)); MPZTOZ(c,CZ(mr)); NMV_ADV(mr);
8776: }
8777: }
8778: MKNDV(nd_nvar,mr0,len,r);
8779: return r;
8780: }
8781: }
8782:
8783: /* for plain vector */
8784:
8785: NDV plain_vect_to_ndv_q(Z *vect,int col,UINT *s0vect)
8786: {
8787: int j,k,len;
8788: UINT *p;
8789: Z c;
8790: NDV r;
8791: NMV mr0,mr;
8792:
8793: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
8794: if ( !len ) return 0;
8795: else {
8796: mr0 = (NMV)MALLOC(nmv_adv*len);
8797: #if 0
8798: ndv_alloc += nmv_adv*len;
8799: #endif
8800: mr = mr0;
8801: p = s0vect;
8802: for ( j = k = 0; j < col; j++, p += nd_wpd, k++ )
8803: if ( (c = vect[k]) != 0 ) {
8804: if ( !INT(c) )
1.6 noro 8805: error("plain_vect_to_ndv_q : components must be integers");
8806: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
1.1 noro 8807: }
8808: MKNDV(nd_nvar,mr0,len,r);
8809: return r;
8810: }
8811: }
8812:
8813: int nd_sp_f4(int m,int trace,ND_pairs l,PGeoBucket bucket)
8814: {
8815: ND_pairs t;
8816: NODE sp0,sp;
8817: int stat;
8818: ND spol;
8819:
8820: for ( t = l; t; t = NEXT(t) ) {
8821: stat = nd_sp(m,trace,t,&spol);
8822: if ( !stat ) return 0;
8823: if ( spol ) {
8824: add_pbucket_symbolic(bucket,spol);
8825: }
8826: }
8827: return 1;
8828: }
8829:
8830: int nd_symbolic_preproc(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
8831: {
8832: NODE rp0,rp;
8833: NM mul,head,s0,s;
8834: int index,col,i,sugar;
8835: RHist h;
8836: UINT *s0v,*p;
8837: NM_ind_pair pair;
8838: ND red;
8839: NDV *ps;
8840:
8841: s0 = 0; rp0 = 0; col = 0;
8842: if ( nd_demand )
8843: ps = trace?nd_ps_trace_sym:nd_ps_sym;
8844: else
8845: ps = trace?nd_ps_trace:nd_ps;
8846: while ( 1 ) {
8847: head = remove_head_pbucket_symbolic(bucket);
8848: if ( !head ) break;
8849: if ( !s0 ) s0 = head;
8850: else NEXT(s) = head;
8851: s = head;
8852: index = ndl_find_reducer(DL(head));
8853: if ( index >= 0 ) {
8854: h = nd_psh[index];
8855: NEWNM(mul);
8856: ndl_sub(DL(head),DL(h),DL(mul));
8857: if ( ndl_check_bound2(index,DL(mul)) )
8858: return 0;
8859: sugar = TD(DL(mul))+SG(ps[index]);
1.28 noro 8860: MKNM_ind_pair(pair,mul,index,sugar,0);
1.1 noro 8861: red = ndv_mul_nm_symbolic(mul,ps[index]);
8862: add_pbucket_symbolic(bucket,nd_remove_head(red));
8863: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
8864: }
8865: col++;
8866: }
8867: if ( rp0 ) NEXT(rp) = 0;
8868: NEXT(s) = 0;
8869: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
8870: for ( i = 0, p = s0v, s = s0; i < col;
8871: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
8872: *s0vect = s0v;
8873: *r = rp0;
8874: return col;
8875: }
8876:
8877: void print_ndp(ND_pairs l)
8878: {
8879: ND_pairs t;
8880:
8881: for ( t = l; t; t = NEXT(t) )
8882: printf("[%d,%d] ",t->i1,t->i2);
8883: printf("\n");
8884: }
8885:
8886: NODE nd_f4(int m,int checkonly,int **indp)
8887: {
8888: int i,nh,stat,index,f4red;
8889: NODE r,g,tn0,tn,node;
8890: ND_pairs d,l,t,ll0,ll,lh;
8891: LIST l0,l1;
8892: ND spol,red;
8893: NDV nf,redv;
8894: NM s0,s;
8895: NODE rp0,srp0,nflist,nzlist,nzlist_t;
8896: int nsp,nred,col,rank,len,k,j,a,i1s,i2s;
8897: UINT c;
8898: UINT **spmat;
8899: UINT *s0vect,*svect,*p,*v;
8900: int *colstat;
8901: IndArray *imat;
8902: int *rhead;
8903: int spcol,sprow;
8904: int sugar,sugarh;
8905: PGeoBucket bucket;
8906: struct oEGT eg0,eg1,eg_f4;
8907: Z i1,i2,sugarq;
1.12 noro 8908:
8909: init_eg(&f4_symb); init_eg(&f4_conv); init_eg(&f4_conv); init_eg(&f4_elim1); init_eg(&f4_elim2);
1.1 noro 8910: #if 0
8911: ndv_alloc = 0;
8912: #endif
1.11 noro 8913: Nf4_red=0;
1.1 noro 8914: g = 0; d = 0;
8915: for ( i = 0; i < nd_psn; i++ ) {
8916: d = update_pairs(d,g,i,0);
8917: g = update_base(g,i);
8918: }
8919: nzlist = 0;
8920: nzlist_t = nd_nzlist;
8921: f4red = 1;
8922: nd_last_nonzero = 0;
8923: while ( d ) {
8924: get_eg(&eg0);
8925: l = nd_minsugarp(d,&d);
8926: sugar = nd_sugarweight?l->sugar2:SG(l);
8927: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
8928: if ( nzlist_t ) {
8929: node = BDY((LIST)BDY(nzlist_t));
1.6 noro 8930: sugarh = ZTOS((Q)ARG0(node));
1.1 noro 8931: tn = BDY((LIST)ARG1(node));
8932: if ( !tn ) {
8933: nzlist_t = NEXT(nzlist_t);
8934: continue;
8935: }
8936: /* tn = [[i1,i2],...] */
8937: lh = nd_ipairtospair(tn);
8938: }
8939: bucket = create_pbucket();
8940: stat = nd_sp_f4(m,0,l,bucket);
8941: if ( !stat ) {
8942: for ( t = l; NEXT(t); t = NEXT(t) );
8943: NEXT(t) = d; d = l;
8944: d = nd_reconstruct(0,d);
8945: continue;
8946: }
8947: if ( bucket->m < 0 ) continue;
8948: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
8949: if ( !col ) {
8950: for ( t = l; NEXT(t); t = NEXT(t) );
8951: NEXT(t) = d; d = l;
8952: d = nd_reconstruct(0,d);
8953: continue;
8954: }
1.12 noro 8955: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); add_eg(&f4_symb,&eg0,&eg1);
1.1 noro 8956: if ( DP_Print )
1.6 noro 8957: fprintf(asir_out,"sugar=%d,symb=%.3fsec,",
1.5 noro 8958: sugar,eg_f4.exectime);
1.1 noro 8959: nflist = nd_f4_red(m,nd_nzlist?lh:l,0,s0vect,col,rp0,nd_gentrace?&ll:0);
8960: if ( checkonly && nflist ) return 0;
8961: /* adding new bases */
8962: if ( nflist ) nd_last_nonzero = f4red;
8963: for ( r = nflist; r; r = NEXT(r) ) {
8964: nf = (NDV)BDY(r);
1.38 noro 8965: if ( nd_f4_td ) SG(nf) = nd_tdeg(nf);
1.1 noro 8966: ndv_removecont(m,nf);
8967: if ( !m && nd_nalg ) {
8968: ND nf1;
8969:
8970: nf1 = ndvtond(m,nf);
8971: nd_monic(0,&nf1);
8972: nd_removecont(m,nf1);
8973: nf = ndtondv(m,nf1);
8974: }
1.24 noro 8975: nh = ndv_newps(m,nf,0);
1.1 noro 8976: d = update_pairs(d,g,nh,0);
8977: g = update_base(g,nh);
8978: }
8979: if ( DP_Print ) {
8980: fprintf(asir_out,"f4red=%d,gblen=%d\n",f4red,length(g)); fflush(asir_out);
8981: }
8982: if ( nd_gentrace ) {
8983: for ( t = ll, tn0 = 0; t; t = NEXT(t) ) {
8984: NEXTNODE(tn0,tn);
1.6 noro 8985: STOZ(t->i1,i1); STOZ(t->i2,i2);
1.1 noro 8986: node = mknode(2,i1,i2); MKLIST(l0,node);
8987: BDY(tn) = l0;
8988: }
8989: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
1.6 noro 8990: STOZ(sugar,sugarq); node = mknode(2,sugarq,l0); MKLIST(l1,node);
1.1 noro 8991: MKNODE(node,l1,nzlist); nzlist = node;
8992: }
8993: if ( nd_nzlist ) nzlist_t = NEXT(nzlist_t);
8994: f4red++;
8995: if ( nd_f4red && f4red > nd_f4red ) break;
8996: if ( nd_rank0 && !nflist ) break;
8997: }
8998: if ( nd_gentrace ) {
8999: MKLIST(l0,reverse_node(nzlist));
9000: MKNODE(nd_alltracelist,l0,0);
9001: }
9002: #if 0
9003: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
9004: #endif
1.12 noro 9005: if ( DP_Print ) {
9006: fprintf(asir_out,"number of red=%d,",Nf4_red);
9007: fprintf(asir_out,"symb=%.3fsec,conv=%.3fsec,elim1=%.3fsec,elim2=%.3fsec\n",
9008: f4_symb.exectime,f4_conv.exectime,f4_elim1.exectime,f4_elim2.exectime);
1.41 noro 9009: fprintf(asir_out,"number of removed pairs=%d\n,",NcriB+NcriMF+Ncri2);
1.12 noro 9010: }
1.1 noro 9011: conv_ilist(nd_demand,0,g,indp);
9012: return g;
9013: }
9014:
9015: NODE nd_f4_trace(int m,int **indp)
9016: {
9017: int i,nh,stat,index;
9018: NODE r,g;
9019: ND_pairs d,l,l0,t;
9020: ND spol,red;
9021: NDV nf,redv,nfqv,nfv;
9022: NM s0,s;
9023: NODE rp0,srp0,nflist;
9024: int nsp,nred,col,rank,len,k,j,a;
9025: UINT c;
9026: UINT **spmat;
9027: UINT *s0vect,*svect,*p,*v;
9028: int *colstat;
9029: IndArray *imat;
9030: int *rhead;
9031: int spcol,sprow;
9032: int sugar;
9033: PGeoBucket bucket;
9034: struct oEGT eg0,eg1,eg_f4;
9035:
9036: g = 0; d = 0;
9037: for ( i = 0; i < nd_psn; i++ ) {
9038: d = update_pairs(d,g,i,0);
9039: g = update_base(g,i);
9040: }
9041: while ( d ) {
9042: get_eg(&eg0);
9043: l = nd_minsugarp(d,&d);
9044: sugar = SG(l);
9045: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
9046: bucket = create_pbucket();
9047: stat = nd_sp_f4(m,0,l,bucket);
9048: if ( !stat ) {
9049: for ( t = l; NEXT(t); t = NEXT(t) );
9050: NEXT(t) = d; d = l;
9051: d = nd_reconstruct(1,d);
9052: continue;
9053: }
9054: if ( bucket->m < 0 ) continue;
9055: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
9056: if ( !col ) {
9057: for ( t = l; NEXT(t); t = NEXT(t) );
9058: NEXT(t) = d; d = l;
9059: d = nd_reconstruct(1,d);
9060: continue;
9061: }
9062: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
9063: if ( DP_Print )
1.3 noro 9064: fprintf(asir_out,"\nsugar=%d,symb=%.3fsec,",
1.5 noro 9065: sugar,eg_f4.exectime);
1.1 noro 9066: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
9067: if ( !l0 ) continue;
9068: l = l0;
9069:
9070: /* over Q */
9071: bucket = create_pbucket();
9072: stat = nd_sp_f4(0,1,l,bucket);
9073: if ( !stat ) {
9074: for ( t = l; NEXT(t); t = NEXT(t) );
9075: NEXT(t) = d; d = l;
9076: d = nd_reconstruct(1,d);
9077: continue;
9078: }
9079: if ( bucket->m < 0 ) continue;
9080: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
9081: if ( !col ) {
9082: for ( t = l; NEXT(t); t = NEXT(t) );
9083: NEXT(t) = d; d = l;
9084: d = nd_reconstruct(1,d);
9085: continue;
9086: }
9087: nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0);
9088: /* adding new bases */
9089: for ( r = nflist; r; r = NEXT(r) ) {
9090: nfqv = (NDV)BDY(r);
9091: ndv_removecont(0,nfqv);
1.6 noro 9092: if ( !remqi((Q)HCZ(nfqv),m) ) return 0;
1.1 noro 9093: if ( nd_nalg ) {
9094: ND nf1;
9095:
9096: nf1 = ndvtond(m,nfqv);
9097: nd_monic(0,&nf1);
9098: nd_removecont(0,nf1);
9099: nfqv = ndtondv(0,nf1); nd_free(nf1);
9100: }
9101: nfv = ndv_dup(0,nfqv);
9102: ndv_mod(m,nfv);
9103: ndv_removecont(m,nfv);
1.24 noro 9104: nh = ndv_newps(0,nfv,nfqv);
1.1 noro 9105: d = update_pairs(d,g,nh,0);
9106: g = update_base(g,nh);
9107: }
9108: }
9109: #if 0
9110: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
9111: #endif
9112: conv_ilist(nd_demand,1,g,indp);
9113: return g;
9114: }
9115:
9116: int rref(matrix mat,int *sugar)
9117: {
9118: int row,col,i,j,k,l,s,wcol,wj;
9119: unsigned long bj;
9120: unsigned long **a;
9121: unsigned long *ai,*ak,*as,*t;
9122: int *pivot;
9123:
9124: row = mat->row;
9125: col = mat->col;
9126: a = mat->a;
9127: wcol = (col+BLEN-1)/BLEN;
9128: pivot = (int *)MALLOC_ATOMIC(row*sizeof(int));
9129: i = 0;
9130: for ( j = 0; j < col; j++ ) {
9131: wj = j/BLEN; bj = 1L<<(j%BLEN);
9132: for ( k = i; k < row; k++ )
9133: if ( a[k][wj] & bj ) break;
9134: if ( k == row ) continue;
9135: pivot[i] = j;
9136: if ( k != i ) {
9137: t = a[i]; a[i] = a[k]; a[k] = t;
9138: s = sugar[i]; sugar[i] = sugar[k]; sugar[k] = s;
9139: }
9140: ai = a[i];
9141: for ( k = i+1; k < row; k++ ) {
9142: ak = a[k];
9143: if ( ak[wj] & bj ) {
9144: for ( l = wj; l < wcol; l++ )
9145: ak[l] ^= ai[l];
9146: sugar[k] = MAX(sugar[k],sugar[i]);
9147: }
9148: }
9149: i++;
9150: }
9151: for ( k = i-1; k >= 0; k-- ) {
9152: j = pivot[k]; wj = j/BLEN; bj = 1L<<(j%BLEN);
9153: ak = a[k];
9154: for ( s = 0; s < k; s++ ) {
9155: as = a[s];
9156: if ( as[wj] & bj ) {
9157: for ( l = wj; l < wcol; l++ )
9158: as[l] ^= ak[l];
9159: sugar[s] = MAX(sugar[s],sugar[k]);
9160: }
9161: }
9162: }
9163: return i;
9164: }
9165:
9166: void print_matrix(matrix mat)
9167: {
9168: int row,col,i,j;
9169: unsigned long *ai;
9170:
9171: row = mat->row;
9172: col = mat->col;
9173: printf("%d x %d\n",row,col);
9174: for ( i = 0; i < row; i++ ) {
9175: ai = mat->a[i];
9176: for ( j = 0; j < col; j++ ) {
9177: if ( ai[j/BLEN] & (1L<<(j%BLEN)) ) putchar('1');
9178: else putchar('0');
9179: }
9180: putchar('\n');
9181: }
9182: }
9183:
9184: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect);
9185:
9186: void red_by_vect_2(matrix mat,int *sugar,unsigned long *v,int rhead,int rsugar)
9187: {
9188: int row,col,wcol,wj,i,j;
9189: unsigned long bj;
9190: unsigned long *ai;
9191: unsigned long **a;
9192: int len;
9193: int *pos;
9194:
9195: row = mat->row;
9196: col = mat->col;
9197: wcol = (col+BLEN-1)/BLEN;
9198: pos = (int *)MALLOC(wcol*sizeof(int));
9199: bzero(pos,wcol*sizeof(int));
9200: for ( i = j = 0; i < wcol; i++ )
9201: if ( v[i] ) pos[j++] = i;;
9202: len = j;
9203: wj = rhead/BLEN;
9204: bj = 1L<<rhead%BLEN;
9205: a = mat->a;
9206: for ( i = 0; i < row; i++ ) {
9207: ai = a[i];
9208: if ( ai[wj]&bj ) {
9209: for ( j = 0; j < len; j++ )
9210: ai[pos[j]] ^= v[pos[j]];
9211: sugar[i] = MAX(sugar[i],rsugar);
9212: }
9213: }
9214: }
9215:
9216: NODE nd_f4_red_2(ND_pairs sp0,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
9217: {
9218: int nsp,nred,i,i0,k,rank,row;
9219: NODE r0,rp;
9220: ND_pairs sp;
9221: ND spol;
9222: NM_ind_pair rt;
9223: int *s0hash;
9224: UINT *s;
9225: int *pivot,*sugar,*head;
9226: matrix mat;
9227: NM m;
9228: NODE r;
9229: struct oEGT eg0,eg1,eg2,eg_elim1,eg_elim2;
9230: int rhead,rsugar,size;
9231: unsigned long *v;
9232:
9233: get_eg(&eg0);
9234: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
9235: nred = length(rp0);
9236: mat = alloc_matrix(nsp,col);
9237: s0hash = (int *)MALLOC(col*sizeof(int));
9238: for ( i = 0, s = s0vect; i < col; i++, s += nd_wpd )
9239: s0hash[i] = ndl_hash_value(s);
9240:
9241: sugar = (int *)MALLOC(nsp*sizeof(int));
9242: for ( i = 0, sp = sp0; sp; sp = NEXT(sp) ) {
9243: nd_sp(2,0,sp,&spol);
9244: if ( spol ) {
9245: mat->a[i] = nd_to_vect_2(s0vect,col,s0hash,spol);
9246: sugar[i] = SG(spol);
9247: i++;
9248: }
9249: }
9250: mat->row = i;
9251: if ( DP_Print ) {
9252: fprintf(asir_out,"%dx%d,",mat->row,mat->col); fflush(asir_out);
9253: }
9254: size = ((col+BLEN-1)/BLEN)*sizeof(unsigned long);
9255: v = CALLOC((col+BLEN-1)/BLEN,sizeof(unsigned long));
9256: for ( rp = rp0, i = 0; rp; rp = NEXT(rp), i++ ) {
9257: rt = (NM_ind_pair)BDY(rp);
9258: bzero(v,size);
9259: rhead = nd_nm_to_vect_2(s0vect,col,s0hash,nd_ps[rt->index],rt->mul,v);
9260: rsugar = SG(nd_ps[rt->index])+TD(DL(rt->mul));
9261: red_by_vect_2(mat,sugar,v,rhead,rsugar);
9262: }
9263:
9264: get_eg(&eg1);
9265: init_eg(&eg_elim1); add_eg(&eg_elim1,&eg0,&eg1);
9266: rank = rref(mat,sugar);
9267:
9268: for ( i = 0, r0 = 0; i < rank; i++ ) {
9269: NEXTNODE(r0,r);
9270: BDY(r) = (pointer)vect_to_ndv_2(mat->a[i],col,s0vect);
9271: SG((NDV)BDY(r)) = sugar[i];
9272: }
9273: if ( r0 ) NEXT(r) = 0;
9274: get_eg(&eg2);
9275: init_eg(&eg_elim2); add_eg(&eg_elim2,&eg1,&eg2);
9276: if ( DP_Print ) {
9277: fprintf(asir_out,"elim1=%.3fsec,elim2=%.3fsec,",
1.5 noro 9278: eg_elim1.exectime,eg_elim2.exectime);
1.1 noro 9279: fflush(asir_out);
9280: }
9281: return r0;
9282: }
9283:
9284:
9285: NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
9286: {
9287: IndArray *imat;
1.11 noro 9288: int nsp,nred,i,start;
1.1 noro 9289: int *rhead;
9290: NODE r0,rp;
9291: ND_pairs sp;
9292: NM_ind_pair *rvect;
9293: UINT *s;
9294: int *s0hash;
1.11 noro 9295: struct oEGT eg0,eg1,eg_conv;
1.1 noro 9296:
9297: if ( m == 2 && nd_rref2 )
9298: return nd_f4_red_2(sp0,s0vect,col,rp0,nz);
9299:
9300: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
9301: nred = length(rp0);
9302: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
9303: rhead = (int *)MALLOC(col*sizeof(int));
9304: for ( i = 0; i < col; i++ ) rhead[i] = 0;
9305:
9306: /* construction of index arrays */
1.11 noro 9307: get_eg(&eg0);
1.1 noro 9308: if ( DP_Print ) {
1.11 noro 9309: fprintf(asir_out,"%dx%d,",nsp+nred,col);
9310: fflush(asir_out);
1.1 noro 9311: }
9312: rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
1.11 noro 9313: for ( start = 0, rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
1.1 noro 9314: rvect[i] = (NM_ind_pair)BDY(rp);
1.11 noro 9315: imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,rvect[i],start);
1.1 noro 9316: rhead[imat[i]->head] = 1;
1.11 noro 9317: start = imat[i]->head;
9318: }
1.12 noro 9319: get_eg(&eg1); init_eg(&eg_conv); add_eg(&eg_conv,&eg0,&eg1); add_eg(&f4_conv,&eg0,&eg1);
1.11 noro 9320: if ( DP_Print ) {
9321: fprintf(asir_out,"conv=%.3fsec,",eg_conv.exectime);
9322: fflush(asir_out);
1.1 noro 9323: }
9324: if ( m > 0 )
1.7 noro 9325: #if SIZEOF_LONG==8
1.1 noro 9326: r0 = nd_f4_red_mod64_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
9327: #else
9328: r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
9329: #endif
9330: else if ( m == -1 )
9331: r0 = nd_f4_red_sf_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
9332: else if ( m == -2 )
9333: r0 = nd_f4_red_lf_main(m,sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
9334: else
9335: r0 = nd_f4_red_q_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
9336: return r0;
9337: }
9338:
9339: /* for Fp, 2<=p<2^16 */
9340:
9341: NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9342: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
9343: {
9344: int spcol,sprow,a;
9345: int i,j,k,l,rank;
9346: NODE r0,r;
9347: ND_pairs sp;
9348: ND spol;
9349: UINT **spmat;
9350: UINT *svect,*v;
9351: int *colstat;
9352: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9353: int maxrs;
9354: int *spsugar;
9355: ND_pairs *spactive;
9356:
9357: spcol = col-nred;
9358: get_eg(&eg0);
9359: /* elimination (1st step) */
9360: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9361: svect = (UINT *)MALLOC(col*sizeof(UINT));
9362: spsugar = (int *)MALLOC(nsp*sizeof(int));
9363: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
9364: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9365: nd_sp(m,0,sp,&spol);
9366: if ( !spol ) continue;
9367: nd_to_vect(m,s0vect,col,spol,svect);
9368: if ( m == -1 )
9369: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
9370: else
1.40 noro 9371: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred,0);
1.1 noro 9372: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9373: if ( i < col ) {
9374: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
9375: for ( j = k = 0; j < col; j++ )
9376: if ( !rhead[j] ) v[k++] = svect[j];
9377: spsugar[sprow] = MAX(maxrs,SG(spol));
9378: if ( nz )
9379: spactive[sprow] = sp;
9380: sprow++;
9381: }
9382: nd_free(spol);
9383: }
9384: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9385: if ( DP_Print ) {
1.5 noro 9386: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9387: fflush(asir_out);
9388: }
9389: /* free index arrays */
9390: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9391:
9392: /* elimination (2nd step) */
9393: colstat = (int *)MALLOC(spcol*sizeof(int));
9394: if ( m == -1 )
9395: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
9396: else
9397: rank = nd_gauss_elim_mod(spmat,spsugar,spactive,sprow,spcol,m,colstat);
9398: r0 = 0;
9399: for ( i = 0; i < rank; i++ ) {
9400: NEXTNODE(r0,r); BDY(r) =
9401: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
9402: SG((NDV)BDY(r)) = spsugar[i];
9403: GCFREE(spmat[i]);
9404: }
9405: if ( r0 ) NEXT(r) = 0;
9406:
9407: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
9408: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9409: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9410: if ( DP_Print ) {
1.5 noro 9411: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9412: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9413: nsp,nred,sprow,spcol,rank);
1.5 noro 9414: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9415: }
9416: if ( nz ) {
9417: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
9418: if ( rank > 0 ) {
9419: NEXT(spactive[rank-1]) = 0;
9420: *nz = spactive[0];
9421: } else
9422: *nz = 0;
9423: }
9424: return r0;
9425: }
9426:
1.40 noro 9427: NODE nd_f4_red_main_s(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9428: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,NODE *syzlistp)
9429: {
9430: int spcol,sprow,a;
9431: int i,j,k,l,rank;
9432: NODE r0,r;
9433: ND_pairs sp;
9434: ND spol;
9435: UINT **spmat;
9436: UINT *svect,*cvect;
9437: UINT *v;
9438: int *colstat;
9439: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9440: int maxrs;
9441: int *spsugar;
9442: ND_pairs *spactive;
9443: SIG *spsig;
9444:
9445: get_eg(&eg0);
9446: /* elimination (1st step) */
9447: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9448: spsugar = (int *)MALLOC(nsp*sizeof(int));
9449: spsig = (SIG *)MALLOC(nsp*sizeof(SIG));
9450: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9451: nd_sp(m,0,sp,&spol);
9452: if ( !spol ) {
9453: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
9454: continue;
9455: }
9456: svect = (UINT *)MALLOC(col*sizeof(UINT));
9457: nd_to_vect(m,s0vect,col,spol,svect);
9458: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred,spol->sig);
9459: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9460: if ( i < col ) {
9461: spmat[sprow] = svect;
9462: spsugar[sprow] = MAX(maxrs,SG(spol));
9463: spsig[sprow] = sp->sig;
9464: sprow++;
9465: } else {
9466: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
9467: }
9468: nd_free(spol);
9469: }
9470: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
9471: if ( DP_Print ) {
9472: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
9473: fflush(asir_out);
9474: }
9475: /* free index arrays */
9476: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9477:
9478: /* elimination (2nd step) */
9479: colstat = (int *)MALLOC(col*sizeof(int));
9480: rank = nd_gauss_elim_mod_s(spmat,spsugar,0,sprow,col,m,colstat,spsig);
9481: r0 = 0;
9482: for ( i = 0; i < sprow; i++ ) {
9483: if ( spsugar[i] >= 0 ) {
9484: NEXTNODE(r0,r);
9485: BDY(r) = vect_to_ndv_s(spmat[i],col,s0vect);
9486: SG((NDV)BDY(r)) = spsugar[i];
9487: ((NDV)BDY(r))->sig = spsig[i];
9488: } else
9489: syzlistp[spsig[i]->pos] = insert_sig(syzlistp[spsig[i]->pos],spsig[i]);
9490: GCFREE(spmat[i]);
9491: }
9492: if ( r0 ) NEXT(r) = 0;
9493: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
9494: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9495: if ( DP_Print ) {
9496: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
9497: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9498: nsp,nred,sprow,col,rank);
9499: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
9500: }
9501: return r0;
9502: }
9503:
1.1 noro 9504:
9505: /* for small finite fields */
9506:
9507: NODE nd_f4_red_sf_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9508: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
9509: {
9510: int spcol,sprow,a;
9511: int i,j,k,l,rank;
9512: NODE r0,r;
9513: ND_pairs sp;
9514: ND spol;
9515: UINT **spmat;
9516: UINT *svect,*v;
9517: int *colstat;
9518: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9519: int maxrs;
9520: int *spsugar;
9521: ND_pairs *spactive;
9522:
9523: spcol = col-nred;
9524: get_eg(&eg0);
9525: /* elimination (1st step) */
9526: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9527: svect = (UINT *)MALLOC(col*sizeof(UINT));
9528: spsugar = (int *)MALLOC(nsp*sizeof(int));
9529: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
9530: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9531: nd_sp(m,0,sp,&spol);
9532: if ( !spol ) continue;
9533: nd_to_vect(m,s0vect,col,spol,svect);
9534: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
9535: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9536: if ( i < col ) {
9537: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
9538: for ( j = k = 0; j < col; j++ )
9539: if ( !rhead[j] ) v[k++] = svect[j];
9540: spsugar[sprow] = MAX(maxrs,SG(spol));
9541: if ( nz )
9542: spactive[sprow] = sp;
9543: sprow++;
9544: }
9545: nd_free(spol);
9546: }
9547: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9548: if ( DP_Print ) {
1.5 noro 9549: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9550: fflush(asir_out);
9551: }
9552: /* free index arrays */
9553: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9554:
9555: /* elimination (2nd step) */
9556: colstat = (int *)MALLOC(spcol*sizeof(int));
9557: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
9558: r0 = 0;
9559: for ( i = 0; i < rank; i++ ) {
9560: NEXTNODE(r0,r); BDY(r) =
9561: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
9562: SG((NDV)BDY(r)) = spsugar[i];
9563: GCFREE(spmat[i]);
9564: }
9565: if ( r0 ) NEXT(r) = 0;
9566:
9567: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
9568: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9569: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9570: if ( DP_Print ) {
1.5 noro 9571: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9572: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9573: nsp,nred,sprow,spcol,rank);
1.5 noro 9574: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9575: }
9576: if ( nz ) {
9577: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
9578: if ( rank > 0 ) {
9579: NEXT(spactive[rank-1]) = 0;
9580: *nz = spactive[0];
9581: } else
9582: *nz = 0;
9583: }
9584: return r0;
9585: }
9586:
9587: NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
9588: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
9589: {
9590: int spcol,sprow,a;
9591: int i,j,k,l,rank;
9592: NODE r0,r;
9593: ND_pairs sp;
9594: ND spol;
9595: mpz_t **spmat;
9596: mpz_t *svect,*v;
9597: int *colstat;
9598: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9599: int maxrs;
9600: int *spsugar;
9601: pointer *w;
9602:
9603: spcol = col-nred;
9604: get_eg(&eg0);
9605: /* elimination (1st step) */
9606: spmat = (mpz_t **)MALLOC(nsp*sizeof(mpz_t *));
9607: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
9608: spsugar = (int *)MALLOC(nsp*sizeof(int));
9609: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9610: nd_sp(m,trace,sp,&spol);
9611: if ( !spol ) continue;
9612: nd_to_vect_lf(s0vect,col,spol,svect);
9613: maxrs = ndv_reduce_vect_lf(svect,trace,col,imat,rvect,nred);
9614: for ( i = 0; i < col; i++ ) if ( mpz_sgn(svect[i]) ) break;
9615: if ( i < col ) {
9616: spmat[sprow] = v = (mpz_t *)MALLOC(spcol*sizeof(mpz_t));
9617: for ( j = k = 0; j < col; j++ )
9618: if ( !rhead[j] ) v[k++][0] = svect[j][0];
9619: spsugar[sprow] = MAX(maxrs,SG(spol));
9620: sprow++;
9621: }
9622: /* nd_free(spol); */
9623: }
9624: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9625: if ( DP_Print ) {
1.5 noro 9626: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9627: fflush(asir_out);
9628: }
9629: /* free index arrays */
9630: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
9631:
9632: /* elimination (2nd step) */
9633: colstat = (int *)MALLOC(spcol*sizeof(int));
9634: rank = nd_gauss_elim_lf(spmat,spsugar,sprow,spcol,colstat);
9635: w = (pointer *)MALLOC(rank*sizeof(pointer));
9636: for ( i = 0; i < rank; i++ ) {
9637: #if 0
9638: w[rank-i-1] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
9639: SG((NDV)w[rank-i-1]) = spsugar[i];
9640: #else
9641: w[i] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
9642: SG((NDV)w[i]) = spsugar[i];
9643: #endif
9644: /* GCFREE(spmat[i]); */
9645:
9646: }
9647: #if 0
9648: qsort(w,rank,sizeof(NDV),
9649: (int (*)(const void *,const void *))ndv_compare);
9650: #endif
9651: r0 = 0;
9652: for ( i = 0; i < rank; i++ ) {
9653: NEXTNODE(r0,r); BDY(r) = w[i];
9654: }
9655: if ( r0 ) NEXT(r) = 0;
9656:
9657: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
9658: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9659: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9660: if ( DP_Print ) {
1.5 noro 9661: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9662: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9663: nsp,nred,sprow,spcol,rank);
1.5 noro 9664: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9665: }
9666: return r0;
9667: }
9668:
9669: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
9670: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
9671: {
9672: int spcol,sprow,a;
9673: int i,j,k,l,rank;
9674: NODE r0,r;
9675: ND_pairs sp;
9676: ND spol;
9677: Z **spmat;
9678: Z *svect,*v;
9679: int *colstat;
9680: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9681: int maxrs;
9682: int *spsugar;
9683: pointer *w;
9684:
9685: spcol = col-nred;
9686: get_eg(&eg0);
9687: /* elimination (1st step) */
9688: spmat = (Z **)MALLOC(nsp*sizeof(Q *));
9689: svect = (Z *)MALLOC(col*sizeof(Q));
9690: spsugar = (int *)MALLOC(nsp*sizeof(int));
9691: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9692: nd_sp(0,trace,sp,&spol);
9693: if ( !spol ) continue;
9694: nd_to_vect_q(s0vect,col,spol,svect);
9695: maxrs = ndv_reduce_vect_q(svect,trace,col,imat,rvect,nred);
9696: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9697: if ( i < col ) {
9698: spmat[sprow] = v = (Z *)MALLOC(spcol*sizeof(Q));
9699: for ( j = k = 0; j < col; j++ )
9700: if ( !rhead[j] ) v[k++] = svect[j];
9701: spsugar[sprow] = MAX(maxrs,SG(spol));
9702: sprow++;
9703: }
9704: /* nd_free(spol); */
9705: }
9706: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9707: if ( DP_Print ) {
1.5 noro 9708: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9709: fflush(asir_out);
9710: }
9711: /* free index arrays */
9712: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
9713:
9714: /* elimination (2nd step) */
9715: colstat = (int *)MALLOC(spcol*sizeof(int));
9716: rank = nd_gauss_elim_q(spmat,spsugar,sprow,spcol,colstat);
9717: w = (pointer *)MALLOC(rank*sizeof(pointer));
9718: for ( i = 0; i < rank; i++ ) {
9719: #if 0
9720: w[rank-i-1] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
9721: SG((NDV)w[rank-i-1]) = spsugar[i];
9722: #else
9723: w[i] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
9724: SG((NDV)w[i]) = spsugar[i];
9725: #endif
9726: /* GCFREE(spmat[i]); */
9727: }
9728: #if 0
9729: qsort(w,rank,sizeof(NDV),
9730: (int (*)(const void *,const void *))ndv_compare);
9731: #endif
9732: r0 = 0;
9733: for ( i = 0; i < rank; i++ ) {
9734: NEXTNODE(r0,r); BDY(r) = w[i];
9735: }
9736: if ( r0 ) NEXT(r) = 0;
9737:
9738: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
9739: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9740: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9741: if ( DP_Print ) {
1.5 noro 9742: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9743: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9744: nsp,nred,sprow,spcol,rank);
1.5 noro 9745: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9746: }
9747: return r0;
9748: }
9749:
9750: FILE *nd_write,*nd_read;
9751:
9752: void nd_send_int(int a) {
9753: write_int(nd_write,(unsigned int *)&a);
9754: }
9755:
9756: void nd_send_intarray(int *p,int len) {
9757: write_intarray(nd_write,(unsigned int *)p,len);
9758: }
9759:
9760: int nd_recv_int() {
9761: int a;
9762:
9763: read_int(nd_read,(unsigned int *)&a);
9764: return a;
9765: }
9766:
9767: void nd_recv_intarray(int *p,int len) {
9768: read_intarray(nd_read,(unsigned int *)p,len);
9769: }
9770:
9771: void nd_send_ndv(NDV p) {
9772: int len,i;
9773: NMV m;
9774:
9775: if ( !p ) nd_send_int(0);
9776: else {
9777: len = LEN(p);
9778: nd_send_int(len);
9779: m = BDY(p);
9780: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
9781: nd_send_int(CM(m));
9782: nd_send_intarray((int *)DL(m),nd_wpd);
9783: }
9784: }
9785: }
9786:
9787: void nd_send_nd(ND p) {
9788: int len,i;
9789: NM m;
9790:
9791: if ( !p ) nd_send_int(0);
9792: else {
9793: len = LEN(p);
9794: nd_send_int(len);
9795: m = BDY(p);
9796: for ( i = 0; i < len; i++, m = NEXT(m) ) {
9797: nd_send_int(CM(m));
9798: nd_send_intarray((int *)DL(m),nd_wpd);
9799: }
9800: }
9801: }
9802:
9803: NDV nd_recv_ndv()
9804: {
9805: int len,i;
9806: NMV m,m0;
9807: NDV r;
9808:
9809: len = nd_recv_int();
9810: if ( !len ) return 0;
9811: else {
9812: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
9813: #if 0
9814: ndv_alloc += len*nmv_adv;
9815: #endif
9816: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
9817: CM(m) = nd_recv_int();
9818: nd_recv_intarray((int *)DL(m),nd_wpd);
9819: }
9820: MKNDV(nd_nvar,m0,len,r);
9821: return r;
9822: }
9823: }
9824:
9825: int nd_gauss_elim_q(Z **mat0,int *sugar,int row,int col,int *colstat)
9826: {
9827: int i,j,t,c,rank,inv;
9828: int *ci,*ri;
9829: Z dn;
9830: MAT m,nm;
9831:
9832: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
9833: rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci);
9834: for ( i = 0; i < row; i++ )
9835: for ( j = 0; j < col; j++ )
9836: mat0[i][j] = 0;
9837: c = col-rank;
9838: for ( i = 0; i < rank; i++ ) {
9839: mat0[i][ri[i]] = dn;
9840: for ( j = 0; j < c; j++ )
9841: mat0[i][ci[j]] = (Z)BDY(nm)[i][j];
9842: }
9843: return rank;
9844: }
9845:
9846: int nd_gauss_elim_mod(UINT **mat0,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
9847: {
9848: int i,j,k,l,inv,a,rank,s;
9849: unsigned int *t,*pivot,*pk;
9850: unsigned int **mat;
9851: ND_pairs pair;
9852:
9853: mat = (unsigned int **)mat0;
9854: for ( rank = 0, j = 0; j < col; j++ ) {
9855: for ( i = rank; i < row; i++ )
9856: mat[i][j] %= md;
9857: for ( i = rank; i < row; i++ )
9858: if ( mat[i][j] )
9859: break;
9860: if ( i == row ) {
9861: colstat[j] = 0;
9862: continue;
9863: } else
9864: colstat[j] = 1;
9865: if ( i != rank ) {
9866: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
9867: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
9868: if ( spactive ) {
9869: pair = spactive[i]; spactive[i] = spactive[rank];
9870: spactive[rank] = pair;
9871: }
9872: }
9873: pivot = mat[rank];
9874: s = sugar[rank];
9875: inv = invm(pivot[j],md);
9876: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
9877: if ( *pk ) {
9878: if ( *pk >= (unsigned int)md )
9879: *pk %= md;
9880: DMAR(*pk,inv,0,md,*pk)
9881: }
9882: for ( i = rank+1; i < row; i++ ) {
9883: t = mat[i];
9884: if ( (a = t[j]) != 0 ) {
9885: sugar[i] = MAX(sugar[i],s);
9886: red_by_vect(md,t+j,pivot+j,md-a,col-j);
9887: }
9888: }
9889: rank++;
9890: }
9891: for ( j = col-1, l = rank-1; j >= 0; j-- )
9892: if ( colstat[j] ) {
9893: pivot = mat[l];
9894: s = sugar[l];
9895: for ( i = 0; i < l; i++ ) {
9896: t = mat[i];
9897: t[j] %= md;
9898: if ( (a = t[j]) != 0 ) {
9899: sugar[i] = MAX(sugar[i],s);
9900: red_by_vect(md,t+j,pivot+j,md-a,col-j);
9901: }
9902: }
9903: l--;
9904: }
9905: for ( j = 0, l = 0; l < rank; j++ )
9906: if ( colstat[j] ) {
9907: t = mat[l];
9908: for ( k = j; k < col; k++ )
9909: if ( t[k] >= (unsigned int)md )
9910: t[k] %= md;
9911: l++;
9912: }
9913: return rank;
9914: }
9915:
1.40 noro 9916: int nd_gauss_elim_mod_s(UINT **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat,SIG *sig)
9917: {
9918: int i,j,k,l,rank,s,imin;
9919: UINT inv;
9920: UINT a;
9921: UINT *t,*pivot,*pk;
9922: UINT *ck;
9923: UINT *ct;
9924: ND_pairs pair;
9925: SIG sg;
9926: int *used;
9927:
9928: used = (int *)MALLOC(row*sizeof(int));
9929: for ( j = 0; j < col; j++ ) {
9930: for ( i = 0; i < row; i++ )
9931: a = mat[i][j] %= md;
9932: for ( i = 0; i < row; i++ )
9933: if ( !used[i] && mat[i][j] ) break;
9934: if ( i == row ) {
9935: colstat[j] = 0;
9936: continue;
9937: } else {
9938: colstat[j] = 1;
9939: used[i] = 1;
9940: }
9941: /* column j is normalized */
9942: s = sugar[i];
9943: inv = invm(mat[i][j],md);
9944: /* normalize pivot row */
9945: for ( k = j, pk = mat[i]+j; k < col; k++, pk++, ck++ ) {
9946: DMAR(*pk,inv,0,md,*pk);
9947: }
9948: for ( k = i+1; k < row; k++ ) {
9949: if ( (a = mat[k][j]) != 0 ) {
9950: sugar[k] = MAX(sugar[k],s);
9951: red_by_vect(md,mat[k]+j,mat[i]+j,(int)(md-a),col-j);
9952: Nf4_red++;
9953: }
9954: }
9955: }
9956: rank = 0;
9957: for ( i = 0; i < row; i++ ) {
9958: for ( j = 0; j < col; j++ )
9959: if ( mat[i][j] ) break;
9960: if ( j == col ) sugar[i] = -1;
9961: else rank++;
9962: }
9963: return rank;
9964: }
9965:
1.1 noro 9966:
1.7 noro 9967: int nd_gauss_elim_sf(UINT **mat0,int *sugar,int row,int col,int md,int *colstat)
1.1 noro 9968: {
1.7 noro 9969: int i,j,k,l,inv,a,rank,s;
9970: unsigned int *t,*pivot,*pk;
9971: unsigned int **mat;
9972:
9973: mat = (unsigned int **)mat0;
9974: for ( rank = 0, j = 0; j < col; j++ ) {
9975: for ( i = rank; i < row; i++ )
9976: if ( mat[i][j] )
9977: break;
9978: if ( i == row ) {
9979: colstat[j] = 0;
9980: continue;
9981: } else
9982: colstat[j] = 1;
9983: if ( i != rank ) {
9984: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
9985: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
9986: }
9987: pivot = mat[rank];
9988: s = sugar[rank];
9989: inv = _invsf(pivot[j]);
9990: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
9991: if ( *pk )
9992: *pk = _mulsf(*pk,inv);
9993: for ( i = rank+1; i < row; i++ ) {
9994: t = mat[i];
9995: if ( (a = t[j]) != 0 ) {
9996: sugar[i] = MAX(sugar[i],s);
9997: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
9998: }
9999: }
10000: rank++;
10001: }
10002: for ( j = col-1, l = rank-1; j >= 0; j-- )
10003: if ( colstat[j] ) {
10004: pivot = mat[l];
10005: s = sugar[l];
10006: for ( i = 0; i < l; i++ ) {
10007: t = mat[i];
10008: if ( (a = t[j]) != 0 ) {
10009: sugar[i] = MAX(sugar[i],s);
10010: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
10011: }
10012: }
10013: l--;
10014: }
10015: return rank;
10016: }
1.1 noro 10017:
1.7 noro 10018: int ndv_ishomo(NDV p)
10019: {
10020: NMV m;
10021: int len,h;
1.1 noro 10022:
10023: if ( !p ) return 1;
10024: len = LEN(p);
10025: m = BDY(p);
10026: h = TD(DL(m));
10027: NMV_ADV(m);
10028: for ( len--; len; len--, NMV_ADV(m) )
1.20 noro 10029: if ( TD(DL(m)) != h ) {
10030: return 0;
10031: }
1.1 noro 10032: return 1;
10033: }
10034:
10035: void ndv_save(NDV p,int index)
10036: {
10037: FILE *s;
10038: char name[BUFSIZ];
10039: short id;
10040: int nv,sugar,len,n,i,td,e,j;
10041: NMV m;
10042: unsigned int *dl;
10043: int mpos;
10044:
10045: sprintf(name,"%s/%d",Demand,index);
10046: s = fopen(name,"w");
10047: savevl(s,0);
10048: if ( !p ) {
10049: saveobj(s,0);
10050: return;
10051: }
10052: id = O_DP;
10053: nv = NV(p);
10054: sugar = SG(p);
10055: len = LEN(p);
10056: write_short(s,(unsigned short *)&id); write_int(s,(unsigned int *)&nv); write_int(s,(unsigned int *)&sugar);
10057: write_int(s,(unsigned int *)&len);
10058:
10059: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 10060: saveobj(s,(Obj)CZ(m));
1.1 noro 10061: dl = DL(m);
10062: td = TD(dl);
10063: write_int(s,(unsigned int *)&td);
10064: for ( j = 0; j < nv; j++ ) {
10065: e = GET_EXP(dl,j);
10066: write_int(s,(unsigned int *)&e);
10067: }
10068: if ( nd_module ) {
10069: mpos = MPOS(dl); write_int(s,(unsigned int *)&mpos);
10070: }
10071: }
10072: fclose(s);
10073: }
10074:
10075: void nd_save_mod(ND p,int index)
10076: {
10077: FILE *s;
10078: char name[BUFSIZ];
10079: int nv,sugar,len,c;
10080: NM m;
10081:
10082: sprintf(name,"%s/%d",Demand,index);
10083: s = fopen(name,"w");
10084: if ( !p ) {
10085: len = 0;
10086: write_int(s,(unsigned int *)&len);
10087: fclose(s);
10088: return;
10089: }
10090: nv = NV(p);
10091: sugar = SG(p);
10092: len = LEN(p);
10093: write_int(s,(unsigned int *)&nv); write_int(s,(unsigned int *)&sugar); write_int(s,(unsigned int *)&len);
10094: for ( m = BDY(p); m; m = NEXT(m) ) {
10095: c = CM(m); write_int(s,(unsigned int *)&c);
10096: write_intarray(s,(unsigned int *)DL(m),nd_wpd);
10097: }
10098: fclose(s);
10099: }
10100:
10101: NDV ndv_load(int index)
10102: {
10103: FILE *s;
10104: char name[BUFSIZ];
10105: short id;
10106: int nv,sugar,len,n,i,td,e,j;
10107: NDV d;
10108: NMV m0,m;
10109: unsigned int *dl;
10110: Obj obj;
10111: int mpos;
10112:
10113: sprintf(name,"%s/%d",Demand,index);
10114: s = fopen(name,"r");
10115: if ( !s ) return 0;
10116:
10117: skipvl(s);
10118: read_short(s,(unsigned short *)&id);
10119: if ( !id ) return 0;
10120: read_int(s,(unsigned int *)&nv);
10121: read_int(s,(unsigned int *)&sugar);
10122: read_int(s,(unsigned int *)&len);
10123:
10124: m0 = m = MALLOC(len*nmv_adv);
10125: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 10126: loadobj(s,&obj); CZ(m) = (Z)obj;
1.1 noro 10127: dl = DL(m);
10128: ndl_zero(dl);
10129: read_int(s,(unsigned int *)&td); TD(dl) = td;
10130: for ( j = 0; j < nv; j++ ) {
10131: read_int(s,(unsigned int *)&e);
10132: PUT_EXP(dl,j,e);
10133: }
10134: if ( nd_module ) {
10135: read_int(s,(unsigned int *)&mpos); MPOS(dl) = mpos;
10136: }
10137: if ( nd_blockmask ) ndl_weight_mask(dl);
10138: }
10139: fclose(s);
10140: MKNDV(nv,m0,len,d);
10141: SG(d) = sugar;
10142: return d;
10143: }
10144:
10145: ND nd_load_mod(int index)
10146: {
10147: FILE *s;
10148: char name[BUFSIZ];
10149: int nv,sugar,len,i,c;
10150: ND d;
10151: NM m0,m;
10152:
10153: sprintf(name,"%s/%d",Demand,index);
10154: s = fopen(name,"r");
10155: /* if the file does not exist, it means p[index]=0 */
10156: if ( !s ) return 0;
10157:
10158: read_int(s,(unsigned int *)&nv);
10159: if ( !nv ) { fclose(s); return 0; }
10160:
10161: read_int(s,(unsigned int *)&sugar);
10162: read_int(s,(unsigned int *)&len);
10163: for ( m0 = 0, i = 0; i < len; i++ ) {
10164: NEXTNM(m0,m);
10165: read_int(s,(unsigned int *)&c); CM(m) = c;
10166: read_intarray(s,(unsigned int *)DL(m),nd_wpd);
10167: }
10168: NEXT(m) = 0;
10169: MKND(nv,m0,len,d);
10170: SG(d) = sugar;
10171: fclose(s);
10172: return d;
10173: }
10174:
10175: void nd_det(int mod,MAT f,P *rp)
10176: {
10177: VL fv,tv;
10178: int n,i,j,max,e,nvar,sgn,k0,l0,len0,len,k,l,a;
10179: pointer **m;
10180: P **w;
10181: P mp,r;
10182: NDV **dm;
10183: NDV *t,*mi,*mj;
10184: NDV d,s,mij,mjj;
10185: ND u;
10186: NMV nmv;
10187: UINT *bound;
10188: PGeoBucket bucket;
10189: struct order_spec *ord;
10190: Z dq,dt,ds;
10191: Z mone;
10192: Z gn,qn,dn0,nm,dn;
10193:
10194: create_order_spec(0,0,&ord);
10195: nd_init_ord(ord);
10196: get_vars((Obj)f,&fv);
10197: if ( f->row != f->col )
10198: error("nd_det : non-square matrix");
10199: n = f->row;
10200: m = f->body;
10201: for ( nvar = 0, tv = fv; tv; tv = NEXT(tv), nvar++ );
10202:
10203: if ( !nvar ) {
10204: if ( !mod )
10205: detp(CO,(P **)m,n,rp);
10206: else {
10207: w = (P **)almat_pointer(n,n);
10208: for ( i = 0; i < n; i++ )
10209: for ( j = 0; j < n; j++ )
10210: ptomp(mod,(P)m[i][j],&w[i][j]);
10211: detmp(CO,mod,w,n,&mp);
10212: mptop(mp,rp);
10213: }
10214: return;
10215: }
10216:
10217: if ( !mod ) {
10218: w = (P **)almat_pointer(n,n);
10219: dq = ONE;
10220: for ( i = 0; i < n; i++ ) {
10221: dn0 = ONE;
10222: for ( j = 0; j < n; j++ ) {
10223: if ( !m[i][j] ) continue;
10224: lgp(m[i][j],&nm,&dn);
1.6 noro 10225: gcdz(dn0,dn,&gn); divsz(dn0,gn,&qn); mulz(qn,dn,&dn0);
1.1 noro 10226: }
10227: if ( !UNIZ(dn0) ) {
10228: ds = dn0;
10229: for ( j = 0; j < n; j++ )
10230: mulp(CO,(P)m[i][j],(P)ds,&w[i][j]);
10231: mulz(dq,ds,&dt); dq = dt;
10232: } else
10233: for ( j = 0; j < n; j++ )
10234: w[i][j] = (P)m[i][j];
10235: }
10236: m = (pointer **)w;
10237: }
10238:
10239: for ( i = 0, max = 1; i < n; i++ )
10240: for ( j = 0; j < n; j++ )
10241: for ( tv = fv; tv; tv = NEXT(tv) ) {
10242: e = getdeg(tv->v,(P)m[i][j]);
10243: max = MAX(e,max);
10244: }
10245: nd_setup_parameters(nvar,max);
10246: dm = (NDV **)almat_pointer(n,n);
10247: for ( i = 0, max = 1; i < n; i++ )
10248: for ( j = 0; j < n; j++ ) {
10249: dm[i][j] = ptondv(CO,fv,m[i][j]);
10250: if ( mod ) ndv_mod(mod,dm[i][j]);
10251: if ( dm[i][j] && !LEN(dm[i][j]) ) dm[i][j] = 0;
10252: }
10253: d = ptondv(CO,fv,(P)ONE);
10254: if ( mod ) ndv_mod(mod,d);
10255: chsgnz(ONE,&mone);
10256: for ( j = 0, sgn = 1; j < n; j++ ) {
10257: if ( DP_Print ) {
10258: fprintf(asir_out,".");
10259: }
10260: for ( i = j; i < n && !dm[i][j]; i++ );
10261: if ( i == n ) {
10262: *rp = 0;
10263: return;
10264: }
10265: k0 = i; l0 = j; len0 = LEN(dm[k0][l0]);
10266: for ( k = j; k < n; k++ )
10267: for ( l = j; l < n; l++ )
10268: if ( dm[k][l] && LEN(dm[k][l]) < len0 ) {
10269: k0 = k; l0 = l; len0 = LEN(dm[k][l]);
10270: }
10271: if ( k0 != j ) {
10272: t = dm[j]; dm[j] = dm[k0]; dm[k0] = t;
10273: sgn = -sgn;
10274: }
10275: if ( l0 != j ) {
10276: for ( k = j; k < n; k++ ) {
10277: s = dm[k][j]; dm[k][j] = dm[k][l0]; dm[k][l0] = s;
10278: }
10279: sgn = -sgn;
10280: }
10281: bound = nd_det_compute_bound(dm,n,j);
10282: for ( k = 0; k < nd_nvar; k++ )
10283: if ( bound[k]*2 > nd_mask0 ) break;
10284: if ( k < nd_nvar )
10285: nd_det_reconstruct(dm,n,j,d);
10286:
10287: for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) {
10288: /* if ( DP_Print ) fprintf(asir_out," i=%d\n ",i); */
10289: mi = dm[i]; mij = mi[j];
10290: if ( mod )
10291: ndv_mul_c(mod,mij,mod-1);
10292: else
10293: ndv_mul_c_q(mij,mone);
10294: for ( k = j+1; k < n; k++ ) {
10295: /* if ( DP_Print ) fprintf(asir_out,"k=%d ",k); */
10296: bucket = create_pbucket();
10297: if ( mi[k] ) {
10298: nmv = BDY(mjj); len = LEN(mjj);
10299: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
10300: u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d)));
10301: add_pbucket(mod,bucket,u);
10302: }
10303: }
10304: if ( mj[k] && mij ) {
10305: nmv = BDY(mij); len = LEN(mij);
10306: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
10307: u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d)));
10308: add_pbucket(mod,bucket,u);
10309: }
10310: }
10311: u = nd_quo(mod,bucket,d);
10312: mi[k] = ndtondv(mod,u);
10313: }
10314: /* if ( DP_Print ) fprintf(asir_out,"\n",k); */
10315: }
10316: d = mjj;
10317: }
10318: if ( DP_Print ) {
10319: fprintf(asir_out,"\n");
10320: }
10321: if ( sgn < 0 ) {
10322: if ( mod )
10323: ndv_mul_c(mod,d,mod-1);
10324: else
10325: ndv_mul_c_q(d,mone);
10326: }
10327: r = ndvtop(mod,CO,fv,d);
10328: if ( !mod && !UNIQ(dq) )
10329: divsp(CO,r,(P)dq,rp);
10330: else
10331: *rp = r;
10332: }
10333:
10334: ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d)
10335: {
10336: NM mr,mr0;
10337: NM tnm;
10338: NMV m;
10339: UINT *d0,*dt,*dm;
10340: int c,n,td,i,c1,c2,len;
10341: Z q;
10342: ND r;
10343:
10344: if ( !p ) return 0;
10345: else {
10346: n = NV(p); m = BDY(p); len = LEN(p);
10347: d0 = DL(m0);
10348: td = TD(d);
10349: mr0 = 0;
10350: NEWNM(tnm);
10351: if ( mod ) {
10352: c = CM(m0);
10353: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
10354: ndl_add(DL(m),d0,DL(tnm));
10355: if ( ndl_reducible(DL(tnm),d) ) {
10356: NEXTNM(mr0,mr);
10357: c1 = CM(m); DMAR(c1,c,0,mod,c2); CM(mr) = c2;
10358: ndl_copy(DL(tnm),DL(mr));
10359: }
10360: }
10361: } else {
1.6 noro 10362: q = CZ(m0);
1.1 noro 10363: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
10364: ndl_add(DL(m),d0,DL(tnm));
10365: if ( ndl_reducible(DL(tnm),d) ) {
10366: NEXTNM(mr0,mr);
1.6 noro 10367: mulz(CZ(m),q,&CZ(mr));
1.1 noro 10368: ndl_copy(DL(tnm),DL(mr));
10369: }
10370: }
10371: }
10372: if ( !mr0 )
10373: return 0;
10374: else {
10375: NEXT(mr) = 0;
10376: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
10377: MKND(NV(p),mr0,len,r);
10378: SG(r) = SG(p) + TD(d0);
10379: return r;
10380: }
10381: }
10382: }
10383:
10384: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d)
10385: {
10386: int i,obpe,oadv,h,k,l;
10387: static NM prev_nm_free_list;
10388: EPOS oepos;
10389:
10390: obpe = nd_bpe;
10391: oadv = nmv_adv;
10392: oepos = nd_epos;
10393: if ( obpe < 2 ) nd_bpe = 2;
10394: else if ( obpe < 3 ) nd_bpe = 3;
10395: else if ( obpe < 4 ) nd_bpe = 4;
10396: else if ( obpe < 5 ) nd_bpe = 5;
10397: else if ( obpe < 6 ) nd_bpe = 6;
10398: else if ( obpe < 8 ) nd_bpe = 8;
10399: else if ( obpe < 10 ) nd_bpe = 10;
10400: else if ( obpe < 16 ) nd_bpe = 16;
10401: else if ( obpe < 32 ) nd_bpe = 32;
10402: else error("nd_det_reconstruct : exponent too large");
10403:
10404: nd_setup_parameters(nd_nvar,0);
10405: prev_nm_free_list = _nm_free_list;
10406: _nm_free_list = 0;
10407: for ( k = j; k < n; k++ )
10408: for (l = j; l < n; l++ )
10409: ndv_realloc(dm[k][l],obpe,oadv,oepos);
10410: ndv_realloc(d,obpe,oadv,oepos);
10411: prev_nm_free_list = 0;
10412: #if 0
10413: GC_gcollect();
10414: #endif
10415: }
10416:
10417: /* returns a UINT array containing degree bounds */
10418:
10419: UINT *nd_det_compute_bound(NDV **dm,int n,int j)
10420: {
10421: UINT *d0,*d1,*d,*t,*r;
10422: int k,l,i;
10423:
10424: d0 = (UINT *)MALLOC(nd_nvar*sizeof(UINT));
10425: for ( k = 0; k < nd_nvar; k++ ) d0[k] = 0;
10426: for ( k = j; k < n; k++ )
10427: for ( l = j; l < n; l++ )
10428: if ( dm[k][l] ) {
10429: d = ndv_compute_bound(dm[k][l]);
10430: for ( i = 0; i < nd_nvar; i++ )
10431: d0[i] = MAX(d0[i],d[i]);
10432: }
10433: return d0;
10434: }
10435:
10436: DL nd_separate_d(UINT *d,UINT *trans)
10437: {
10438: int n,td,i,e,j;
10439: DL a;
10440:
10441: ndl_zero(trans);
10442: td = 0;
10443: for ( i = 0; i < nd_ntrans; i++ ) {
10444: e = GET_EXP(d,i);
10445: PUT_EXP(trans,i,e);
10446: td += MUL_WEIGHT(e,i);
10447: }
10448: if ( nd_ntrans+nd_nalg < nd_nvar ) {
10449: /* homogenized */
10450: i = nd_nvar-1;
10451: e = GET_EXP(d,i);
10452: PUT_EXP(trans,i,e);
10453: td += MUL_WEIGHT(e,i);
10454: }
10455: TD(trans) = td;
10456: if ( nd_blockmask) ndl_weight_mask(trans);
10457: NEWDL(a,nd_nalg);
10458: td = 0;
10459: for ( i = 0; i < nd_nalg; i++ ) {
10460: j = nd_ntrans+i;
10461: e = GET_EXP(d,j);
10462: a->d[i] = e;
10463: td += e;
10464: }
10465: a->td = td;
10466: return a;
10467: }
10468:
10469: int nd_monic(int mod,ND *p)
10470: {
10471: UINT *trans,*t;
10472: DL alg;
10473: MP mp0,mp;
10474: NM m,m0,m1,ma0,ma,mb,mr0,mr;
10475: ND r;
10476: DL dl;
10477: DP nm;
10478: NDV ndv;
10479: DAlg inv,cd;
10480: ND s,c;
10481: Z l,mul;
10482: Z ln;
10483: int n,ntrans,i,e,td,is_lc,len;
10484: NumberField nf;
10485: struct oEGT eg0,eg1;
10486:
10487: if ( !(nf = get_numberfield()) )
10488: error("nd_monic : current_numberfield is not set");
10489:
10490: /* Q coef -> DAlg coef */
10491: NEWNM(ma0); ma = ma0;
10492: m = BDY(*p);
10493: is_lc = 1;
10494: while ( 1 ) {
10495: NEWMP(mp0); mp = mp0;
1.6 noro 10496: mp->c = (Obj)CZ(m);
1.1 noro 10497: mp->dl = nd_separate_d(DL(m),DL(ma));
10498: NEWNM(mb);
10499: for ( m = NEXT(m); m; m = NEXT(m) ) {
10500: alg = nd_separate_d(DL(m),DL(mb));
10501: if ( !ndl_equal(DL(ma),DL(mb)) )
10502: break;
1.6 noro 10503: NEXTMP(mp0,mp); mp->c = (Obj)CZ(m); mp->dl = alg;
1.1 noro 10504: }
10505: NEXT(mp) = 0;
10506: MKDP(nd_nalg,mp0,nm);
10507: MKDAlg(nm,ONE,cd);
10508: if ( is_lc == 1 ) {
10509: /* if the lc is a rational number, we have nothing to do */
10510: if ( !mp0->dl->td )
10511: return 1;
10512:
10513: get_eg(&eg0);
10514: invdalg(cd,&inv);
10515: get_eg(&eg1); add_eg(&eg_invdalg,&eg0,&eg1);
10516: /* check the validity of inv */
10517: if ( mod && !remqi((Q)inv->dn,mod) )
10518: return 0;
10519: CA(ma) = nf->one;
10520: is_lc = 0;
10521: ln = ONE;
10522: } else {
10523: muldalg(cd,inv,&CA(ma));
10524: lcmz(ln,CA(ma)->dn,&ln);
10525: }
10526: if ( m ) {
10527: NEXT(ma) = mb; ma = mb;
10528: } else {
10529: NEXT(ma) = 0;
10530: break;
10531: }
10532: }
10533: /* l = lcm(denoms) */
10534: l = ln;
10535: for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) {
1.6 noro 10536: divsz(l,CA(m)->dn,&mul);
1.1 noro 10537: for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) {
10538: NEXTNM(mr0,mr);
1.6 noro 10539: mulz((Z)mp->c,mul,&CZ(mr));
1.1 noro 10540: dl = mp->dl;
10541: td = TD(DL(m));
10542: ndl_copy(DL(m),DL(mr));
10543: for ( i = 0; i < nd_nalg; i++ ) {
10544: e = dl->d[i];
10545: PUT_EXP(DL(mr),i+nd_ntrans,e);
10546: td += MUL_WEIGHT(e,i+nd_ntrans);
10547: }
10548: if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m));
10549: TD(DL(mr)) = td;
10550: if ( nd_blockmask) ndl_weight_mask(DL(mr));
10551: }
10552: }
10553: NEXT(mr) = 0;
10554: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
10555: MKND(NV(*p),mr0,len,r);
10556: /* XXX */
10557: SG(r) = SG(*p);
10558: nd_free(*p);
10559: *p = r;
10560: return 1;
10561: }
10562:
10563: NODE reverse_node(NODE n)
10564: {
10565: NODE t,t1;
10566:
10567: for ( t = 0; n; n = NEXT(n) ) {
10568: MKNODE(t1,BDY(n),t); t = t1;
10569: }
10570: return t;
10571: }
10572:
10573: P ndc_div(int mod,union oNDC a,union oNDC b)
10574: {
10575: union oNDC c;
10576: int inv,t;
10577:
10578: if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m));
1.10 noro 10579: else if ( mod == -2 ) divlf(a.z,b.z,&c.z);
1.1 noro 10580: else if ( mod ) {
10581: inv = invm(b.m,mod);
10582: DMAR(a.m,inv,0,mod,t); c.m = t;
10583: } else if ( nd_vc )
10584: divsp(nd_vc,a.p,b.p,&c.p);
10585: else
10586: divsz(a.z,b.z,&c.z);
10587: return ndctop(mod,c);
10588: }
10589:
10590: P ndctop(int mod,union oNDC c)
10591: {
10592: Z q;
10593: int e;
10594: GFS gfs;
10595:
10596: if ( mod == -1 ) {
10597: e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs;
10598: } else if ( mod == -2 ) {
1.10 noro 10599: q = c.z; return (P)q;
1.1 noro 10600: } else if ( mod > 0 ) {
1.6 noro 10601: STOZ(c.m,q); return (P)q;
1.1 noro 10602: } else
10603: return (P)c.p;
10604: }
10605:
10606: /* [0,0,0,cont] = p -> p/cont */
10607:
10608: void finalize_tracelist(int i,P cont)
10609: {
10610: LIST l;
10611: NODE node;
10612: Z iq;
10613:
10614: if ( !UNIQ(cont) ) {
10615: node = mknode(4,NULLP,NULLP,NULLP,cont);
10616: MKLIST(l,node); MKNODE(node,l,nd_tracelist);
10617: nd_tracelist = node;
10618: }
1.6 noro 10619: STOZ(i,iq);
1.1 noro 10620: nd_tracelist = reverse_node(nd_tracelist);
10621: MKLIST(l,nd_tracelist);
10622: node = mknode(2,iq,l); MKLIST(l,node);
10623: MKNODE(node,l,nd_alltracelist); MKLIST(l,node);
10624: nd_alltracelist = node; nd_tracelist = 0;
10625: }
10626:
10627: void conv_ilist(int demand,int trace,NODE g,int **indp)
10628: {
10629: int n,i,j;
10630: int *ind;
10631: NODE t;
10632:
10633: n = length(g);
10634: ind = (int *)MALLOC(n*sizeof(int));
10635: for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) {
10636: j = (long)BDY(t); ind[i] = j;
10637: BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j]));
10638: }
10639: if ( indp ) *indp = ind;
10640: }
10641:
1.30 noro 10642: NODE conv_ilist_s(int demand,int trace,int **indp)
10643: {
10644: int n,i,j;
10645: int *ind;
10646: NODE g0,g;
10647:
10648: n = nd_psn;
10649: ind = (int *)MALLOC(n*sizeof(int));
10650: g0 = 0;
10651: for ( i = 0; i < n; i++ ) {
10652: ind[i] = i;
10653: NEXTNODE(g0,g);
10654: BDY(g) = (pointer)(demand?ndv_load(i):(trace?nd_ps_trace[i]:nd_ps[i]));
10655: }
10656: if ( g0 ) NEXT(g) = 0;
10657: if ( indp ) *indp = ind;
10658: return g0;
10659: }
10660:
1.46 noro 10661: void parse_nd_option(VL vl,NODE opt)
1.1 noro 10662: {
1.38 noro 10663: NODE t,p,u;
1.1 noro 10664: int i,s,n;
1.38 noro 10665: char *key;
10666: Obj value;
1.46 noro 10667: VL oldvl;
1.1 noro 10668:
1.41 noro 10669: nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_norb = 0; nd_gbblock = 0;
1.1 noro 10670: nd_newelim = 0; nd_intersect = 0; nd_nzlist = 0;
10671: nd_splist = 0; nd_check_splist = 0;
1.38 noro 10672: nd_sugarweight = 0; nd_f4red =0; nd_rank0 = 0;
10673: nd_f4_td = 0; nd_sba_f4step = 2; nd_sba_pot = 0; nd_sba_largelcm = 0;
1.41 noro 10674: nd_sba_dontsort = 0; nd_top = 0; nd_sba_redundant_check = 0;
1.46 noro 10675: nd_sba_syz = 0; nd_sba_modord = 0; nd_sba_inputisgb = 0;
1.49 noro 10676: nd_hpdata = 0;
1.39 noro 10677:
1.38 noro 10678: for ( t = opt; t; t = NEXT(t) ) {
10679: p = BDY((LIST)BDY(t));
10680: key = BDY((STRING)BDY(p));
10681: value = (Obj)BDY(NEXT(p));
10682: if ( !strcmp(key,"gentrace") )
10683: nd_gentrace = value?1:0;
10684: else if ( !strcmp(key,"gensyz") )
10685: nd_gensyz = value?1:0;
10686: else if ( !strcmp(key,"nora") )
10687: nd_nora = value?1:0;
1.41 noro 10688: else if ( !strcmp(key,"norb") )
10689: nd_norb = value?1:0;
1.38 noro 10690: else if ( !strcmp(key,"gbblock") ) {
10691: if ( value && OID(value) == O_LIST ) {
1.1 noro 10692: u = BDY((LIST)value);
1.38 noro 10693: nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int));
1.1 noro 10694: for ( i = 0; u; u = NEXT(u) ) {
10695: p = BDY((LIST)BDY(u));
1.6 noro 10696: s = nd_gbblock[i++] = ZTOS((Q)BDY(p));
10697: nd_gbblock[i++] = s+ZTOS((Q)BDY(NEXT(p)))-1;
1.1 noro 10698: }
10699: nd_gbblock[i] = -1;
1.38 noro 10700: } else
10701: nd_gbblock = 0;
1.1 noro 10702: } else if ( !strcmp(key,"newelim") )
10703: nd_newelim = value?1:0;
10704: else if ( !strcmp(key,"intersect") )
10705: nd_intersect = value?1:0;
1.17 noro 10706: else if ( !strcmp(key,"syzgen") )
10707: nd_intersect = ZTOS((Q)value);
1.1 noro 10708: else if ( !strcmp(key,"lf") )
10709: nd_lf = value?1:0;
10710: else if ( !strcmp(key,"trace") ) {
1.38 noro 10711: if ( value ) {
10712: u = BDY((LIST)value);
10713: nd_nzlist = BDY((LIST)ARG2(u));
10714: nd_bpe = ZTOS((Q)ARG3(u));
10715: }
1.1 noro 10716: } else if ( !strcmp(key,"f4red") ) {
1.38 noro 10717: nd_f4red = ZTOS((Q)value);
1.1 noro 10718: } else if ( !strcmp(key,"rank0") ) {
1.38 noro 10719: nd_rank0 = value?1:0;
1.1 noro 10720: } else if ( !strcmp(key,"splist") ) {
1.38 noro 10721: nd_splist = value?1:0;
1.1 noro 10722: } else if ( !strcmp(key,"check_splist") ) {
10723: nd_check_splist = BDY((LIST)value);
1.49 noro 10724: } else if ( !strcmp(key,"hpdata") ) {
1.50 noro 10725: if ( value )
10726: nd_hpdata = BDY((LIST)value);
1.1 noro 10727: } else if ( !strcmp(key,"sugarweight") ) {
10728: u = BDY((LIST)value);
1.38 noro 10729: n = length(u);
10730: nd_sugarweight = MALLOC(n*sizeof(int));
1.1 noro 10731: for ( i = 0; i < n; i++, u = NEXT(u) )
1.38 noro 10732: nd_sugarweight[i] = ZTOS((Q)BDY(u));
10733: } else if ( !strcmp(key,"f4_td") ) {
10734: nd_f4_td = value?1:0;
10735: } else if ( !strcmp(key,"sba_f4step") ) {
10736: nd_sba_f4step = value?ZTOS((Q)value):0;
10737: } else if ( !strcmp(key,"sba_pot") ) {
1.44 noro 10738: nd_sba_pot = ZTOS((Q)value);
1.38 noro 10739: } else if ( !strcmp(key,"sba_largelcm") ) {
10740: nd_sba_largelcm = value?1:0;
1.39 noro 10741: } else if ( !strcmp(key,"sba_dontsort") ) {
10742: nd_sba_dontsort = value?1:0;
1.44 noro 10743: } else if ( !strcmp(key,"sba_syz") ) {
10744: nd_sba_syz = value?1:0;
1.46 noro 10745: } else if ( !strcmp(key,"sba_modord") ) {
10746: // value=[vlist,ordspec,weight]
10747: u = BDY((LIST)value);
10748: pltovl((LIST)ARG0(u),&oldvl);
10749: nd_sba_modord = create_comp_sig_spec(vl,oldvl,(Obj)ARG1(u),argc(u)==3?ARG2(u):0);
10750: } else if ( !strcmp(key,"sba_gbinput") ) {
10751: nd_sba_inputisgb = value?1:0;
10752: if ( nd_sba_inputisgb != 0 ) {
10753: // value=[vlist,ordspec,weight]
10754: u = BDY((LIST)value);
10755: pltovl((LIST)ARG0(u),&oldvl);
10756: nd_sba_modord = create_comp_sig_spec(vl,oldvl,(Obj)ARG1(u),argc(u)==3?ARG2(u):0);
10757: }
1.41 noro 10758: } else if ( !strcmp(key,"sba_redundant_check") ) {
10759: nd_sba_redundant_check = value?1:0;
1.39 noro 10760: } else if ( !strcmp(key,"top") ) {
10761: nd_top = value?1:0;
1.1 noro 10762: }
1.38 noro 10763: }
1.44 noro 10764: if ( nd_sba_syz ) nd_sba_dontsort = 1;
1.1 noro 10765: }
10766:
10767: ND mdptond(DP d);
10768: ND nd_mul_nm(int mod,NM m0,ND p);
10769: ND nd_mul_nm_lf(NM m0,ND p);
10770: ND *btog(NODE ti,ND **p,int nb,int mod);
10771: ND btog_one(NODE ti,ND *p,int nb,int mod);
10772: MAT nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,MAT *rp);
10773: VECT nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos,MAT *rp);
10774:
10775: /* d:monomial */
10776: ND mdptond(DP d)
10777: {
10778: NM m;
10779: ND r;
10780:
10781: if ( OID(d) == 1 )
10782: r = ptond(CO,CO,(P)d);
10783: else {
10784: NEWNM(m);
10785: dltondl(NV(d),BDY(d)->dl,DL(m));
1.6 noro 10786: CZ(m) = (Z)BDY(d)->c;
1.1 noro 10787: NEXT(m) = 0;
10788: MKND(NV(d),m,1,r);
10789: }
10790: return r;
10791: }
10792:
10793: ND nd_mul_nm(int mod,NM m0,ND p)
10794: {
10795: UINT *d0;
10796: int c0,c1,c;
10797: NM tm,mr,mr0;
10798: ND r;
10799:
10800: if ( !p ) return 0;
10801: d0 = DL(m0);
10802: c0 = CM(m0);
10803: mr0 = 0;
10804: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
10805: NEXTNM(mr0,mr);
10806: c = CM(tm); DMAR(c0,c,0,mod,c1); CM(mr) = c1;
10807: ndl_add(d0,DL(tm),DL(mr));
10808: }
10809: NEXT(mr) = 0;
10810: MKND(NV(p),mr0,LEN(p),r);
10811: return r;
10812: }
10813:
10814: ND nd_mul_nm_lf(NM m0,ND p)
10815: {
10816: UINT *d0;
10817: Z c0,c1,c;
10818: NM tm,mr,mr0;
10819: ND r;
10820:
10821: if ( !p ) return 0;
10822: d0 = DL(m0);
10823: c0 = CZ(m0);
10824: mr0 = 0;
10825: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
10826: NEXTNM(mr0,mr);
10827: c = CZ(tm); mullf(c0,CZ(tm),&c1); CZ(mr) = c1;
10828: ndl_add(d0,DL(tm),DL(mr));
10829: }
10830: NEXT(mr) = 0;
10831: MKND(NV(p),mr0,LEN(p),r);
10832: return r;
10833: }
10834:
10835: ND *btog(NODE ti,ND **p,int nb,int mod)
10836: {
10837: PGeoBucket *r;
10838: int i,ci;
10839: NODE t,s;
10840: ND m,tp;
10841: ND *pi,*rd;
10842: P c;
10843:
10844: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
10845: for ( i = 0; i < nb; i++ )
10846: r[i] = create_pbucket();
10847: for ( t = ti; t; t = NEXT(t) ) {
10848: s = BDY((LIST)BDY(t));
10849: if ( ARG0(s) ) {
10850: m = mdptond((DP)ARG2(s));
1.6 noro 10851: ptomp(mod,(P)HCZ(m),&c);
1.1 noro 10852: if ( (ci = ((MQ)c)->cont) != 0 ) {
10853: HCM(m) = ci;
1.6 noro 10854: pi = p[ZTOS((Q)ARG1(s))];
1.1 noro 10855: for ( i = 0; i < nb; i++ ) {
10856: tp = nd_mul_nm(mod,BDY(m),pi[i]);
10857: add_pbucket(mod,r[i],tp);
10858: }
10859: }
10860: ci = 1;
10861: } else {
10862: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
10863: ci = invm(ci,mod);
10864: }
10865: }
10866: rd = (ND *)MALLOC(nb*sizeof(ND));
10867: for ( i = 0; i < nb; i++ )
10868: rd[i] = normalize_pbucket(mod,r[i]);
10869: if ( ci != 1 )
10870: for ( i = 0; i < nb; i++ ) nd_mul_c(mod,rd[i],ci);
10871: return rd;
10872: }
10873:
10874: /* YYY */
10875: ND *btog_lf(NODE ti,ND **p,int nb)
10876: {
10877: PGeoBucket *r;
10878: int i;
10879: NODE t,s;
10880: ND m,tp;
10881: ND *pi,*rd;
10882: LM lm;
10883: Z lf,c;
10884:
10885: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
10886: for ( i = 0; i < nb; i++ )
10887: r[i] = create_pbucket();
10888: for ( t = ti; t; t = NEXT(t) ) {
10889: s = BDY((LIST)BDY(t));
10890: if ( ARG0(s) ) {
10891: m = mdptond((DP)ARG2(s));
1.6 noro 10892: simp_ff((Obj)HCZ(m),(Obj *)&lm);
1.1 noro 10893: if ( lm ) {
10894: lmtolf(lm,&lf); HCZ(m) = lf;
1.6 noro 10895: pi = p[ZTOS((Q)ARG1(s))];
1.1 noro 10896: for ( i = 0; i < nb; i++ ) {
10897: tp = nd_mul_nm_lf(BDY(m),pi[i]);
10898: add_pbucket(-2,r[i],tp);
10899: }
10900: }
10901: c = ONE;
10902: } else {
10903: simp_ff((Obj)ARG3(s),(Obj *)&lm); lmtolf(lm,&lf); invz(lf,current_mod_lf,&c);
10904: }
10905: }
10906: rd = (ND *)MALLOC(nb*sizeof(ND));
10907: for ( i = 0; i < nb; i++ )
10908: rd[i] = normalize_pbucket(-2,r[i]);
10909: for ( i = 0; i < nb; i++ ) nd_mul_c_lf(rd[i],c);
10910: return rd;
10911: }
10912:
10913: ND btog_one(NODE ti,ND *p,int nb,int mod)
10914: {
10915: PGeoBucket r;
10916: int i,ci,j;
10917: NODE t,s;
10918: ND m,tp;
10919: ND pi,rd;
10920: P c;
10921:
10922: r = create_pbucket();
10923: for ( t = ti; t; t = NEXT(t) ) {
10924: s = BDY((LIST)BDY(t));
10925: if ( ARG0(s) ) {
10926: m = mdptond((DP)ARG2(s));
1.6 noro 10927: ptomp(mod,(P)HCZ(m),&c);
1.1 noro 10928: if ( (ci = ((MQ)c)->cont) != 0 ) {
10929: HCM(m) = ci;
1.6 noro 10930: pi = p[j=ZTOS((Q)ARG1(s))];
1.1 noro 10931: if ( !pi ) {
10932: pi = nd_load_mod(j);
10933: tp = nd_mul_nm(mod,BDY(m),pi);
10934: nd_free(pi);
10935: add_pbucket(mod,r,tp);
10936: } else {
10937: tp = nd_mul_nm(mod,BDY(m),pi);
10938: add_pbucket(mod,r,tp);
10939: }
10940: }
10941: ci = 1;
10942: } else {
10943: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
10944: ci = invm(ci,mod);
10945: }
10946: }
10947: rd = normalize_pbucket(mod,r);
10948: free_pbucket(r);
10949: if ( ci != 1 ) nd_mul_c(mod,rd,ci);
10950: return rd;
10951: }
10952:
10953: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp);
10954:
10955: MAT nd_btog(LIST f,LIST v,int mod,struct order_spec *ord,LIST tlist,MAT *rp)
10956: {
10957: int i,j,n,m,nb,pi0,pi1,nvar;
10958: VL fv,tv,vv;
10959: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
10960: ND **p;
10961: ND *c;
10962: ND u;
10963: P inv;
10964: MAT mat;
10965:
10966: if ( mod == -2 )
10967: return nd_btog_lf(f,v,ord,tlist,rp);
10968:
10969: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 10970: parse_nd_option(vv,current_option);
1.1 noro 10971: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
10972: switch ( ord->id ) {
10973: case 1:
10974: if ( ord->nv != nvar )
10975: error("nd_check : invalid order specification");
10976: break;
10977: default:
10978: break;
10979: }
10980: nd_init_ord(ord);
10981: #if 0
1.6 noro 10982: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 10983: #else
10984: nd_bpe = 32;
10985: #endif
10986: nd_setup_parameters(nvar,0);
10987: permtrace = BDY((LIST)ARG2(BDY(tlist)));
10988: intred = BDY((LIST)ARG3(BDY(tlist)));
10989: ind = BDY((LIST)ARG4(BDY(tlist)));
10990: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
10991: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 10992: j = ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 10993: if ( j > i ) i = j;
10994: }
10995: n = i+1;
10996: nb = length(BDY(f));
10997: p = (ND **)MALLOC(n*sizeof(ND *));
10998: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
10999: pi = BDY((LIST)BDY(t));
1.6 noro 11000: pi0 = ZTOS((Q)ARG0(pi)); pi1 = ZTOS((Q)ARG1(pi));
1.1 noro 11001: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
11002: ptomp(mod,(P)ARG2(pi),&inv);
11003: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
11004: u = ptond(CO,vv,(P)ONE);
11005: HCM(u) = ((MQ)inv)->cont;
11006: c[pi1] = u;
11007: }
11008: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
11009: printf("%d ",i); fflush(stdout);
11010: ti = BDY((LIST)BDY(t));
1.6 noro 11011: p[j=ZTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11012: }
11013: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
11014: printf("%d ",i); fflush(stdout);
11015: ti = BDY((LIST)BDY(t));
1.6 noro 11016: p[j=ZTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11017: }
11018: m = length(ind);
11019: MKMAT(mat,nb,m);
11020: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
1.6 noro 11021: for ( i = 0, c = p[ZTOS((Q)BDY(t))]; i < nb; i++ )
1.1 noro 11022: BDY(mat)[i][j] = ndtodp(mod,c[i]);
11023: return mat;
11024: }
11025:
11026: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp)
11027: {
11028: int i,j,n,m,nb,pi0,pi1,nvar;
11029: VL fv,tv,vv;
11030: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
11031: ND **p;
11032: ND *c;
11033: ND u;
11034: MAT mat;
11035: LM lm;
11036: Z lf,inv;
11037:
11038: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11039: parse_nd_option(vv,current_option);
1.1 noro 11040: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11041: switch ( ord->id ) {
11042: case 1:
11043: if ( ord->nv != nvar )
11044: error("nd_check : invalid order specification");
11045: break;
11046: default:
11047: break;
11048: }
11049: nd_init_ord(ord);
11050: #if 0
1.6 noro 11051: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 11052: #else
11053: nd_bpe = 32;
11054: #endif
11055: nd_setup_parameters(nvar,0);
11056: permtrace = BDY((LIST)ARG2(BDY(tlist)));
11057: intred = BDY((LIST)ARG3(BDY(tlist)));
11058: ind = BDY((LIST)ARG4(BDY(tlist)));
11059: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
11060: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 11061: j = ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 11062: if ( j > i ) i = j;
11063: }
11064: n = i+1;
11065: nb = length(BDY(f));
11066: p = (ND **)MALLOC(n*sizeof(ND *));
11067: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
11068: pi = BDY((LIST)BDY(t));
1.6 noro 11069: pi0 = ZTOS((Q)ARG0(pi)); pi1 = ZTOS((Q)ARG1(pi));
1.1 noro 11070: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
11071: simp_ff((Obj)ARG2(pi),(Obj *)&lm); lmtolf(lm,&lf); invz(lf,current_mod_lf,&inv);
11072: u = ptond(CO,vv,(P)ONE);
11073: HCZ(u) = inv;
11074: c[pi1] = u;
11075: }
11076: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
11077: printf("%d ",i); fflush(stdout);
11078: ti = BDY((LIST)BDY(t));
1.6 noro 11079: p[j=ZTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
1.1 noro 11080: }
11081: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
11082: printf("%d ",i); fflush(stdout);
11083: ti = BDY((LIST)BDY(t));
1.6 noro 11084: p[j=ZTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
1.1 noro 11085: }
11086: m = length(ind);
11087: MKMAT(mat,nb,m);
11088: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
1.6 noro 11089: for ( i = 0, c = p[ZTOS((Q)BDY(t))]; i < nb; i++ )
1.1 noro 11090: BDY(mat)[i][j] = ndtodp(-2,c[i]);
11091: return mat;
11092: }
11093:
11094: VECT nd_btog_one(LIST f,LIST v,int mod,struct order_spec *ord,
11095: LIST tlist,int pos,MAT *rp)
11096: {
11097: int i,j,n,m,nb,pi0,pi1,nvar;
11098: VL fv,tv,vv;
11099: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
11100: ND *p;
11101: ND *c;
11102: ND u;
11103: P inv;
11104: VECT vect;
11105:
11106: if ( mod == -2 )
11107: error("nd_btog_one : not implemented yet for a large finite field");
11108:
11109: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11110: parse_nd_option(vv,current_option);
1.1 noro 11111: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11112: switch ( ord->id ) {
11113: case 1:
11114: if ( ord->nv != nvar )
11115: error("nd_check : invalid order specification");
11116: break;
11117: default:
11118: break;
11119: }
11120: nd_init_ord(ord);
11121: #if 0
1.6 noro 11122: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 11123: #else
11124: nd_bpe = 32;
11125: #endif
11126: nd_setup_parameters(nvar,0);
11127: permtrace = BDY((LIST)ARG2(BDY(tlist)));
11128: intred = BDY((LIST)ARG3(BDY(tlist)));
11129: ind = BDY((LIST)ARG4(BDY(tlist)));
11130: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
11131: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 11132: j = ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 11133: if ( j > i ) i = j;
11134: }
11135: n = i+1;
11136: nb = length(BDY(f));
11137: p = (ND *)MALLOC(n*sizeof(ND *));
11138: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
11139: pi = BDY((LIST)BDY(t));
1.6 noro 11140: pi0 = ZTOS((Q)ARG0(pi)); pi1 = ZTOS((Q)ARG1(pi));
1.1 noro 11141: if ( pi1 == pos ) {
11142: ptomp(mod,(P)ARG2(pi),&inv);
11143: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
11144: u = ptond(CO,vv,(P)ONE);
11145: HCM(u) = ((MQ)inv)->cont;
11146: p[pi0] = u;
11147: }
11148: }
11149: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
11150: printf("%d ",i); fflush(stdout);
11151: ti = BDY((LIST)BDY(t));
1.6 noro 11152: p[j=ZTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11153: if ( Demand ) {
11154: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
11155: }
11156: }
11157: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
11158: printf("%d ",i); fflush(stdout);
11159: ti = BDY((LIST)BDY(t));
1.6 noro 11160: p[j=ZTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11161: if ( Demand ) {
11162: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
11163: }
11164: }
11165: m = length(ind);
11166: MKVECT(vect,m);
11167: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) {
1.6 noro 11168: u = p[ZTOS((Q)BDY(t))];
1.1 noro 11169: if ( !u ) {
1.6 noro 11170: u = nd_load_mod(ZTOS((Q)BDY(t)));
1.1 noro 11171: BDY(vect)[j] = ndtodp(mod,u);
11172: nd_free(u);
11173: } else
11174: BDY(vect)[j] = ndtodp(mod,u);
11175: }
11176: return vect;
11177: }
11178:
11179: void ndv_print_lf(NDV p)
11180: {
11181: NMV m;
11182: int i,len;
11183:
11184: if ( !p ) printf("0\n");
11185: else {
11186: len = LEN(p);
11187: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
11188: printf("+");
11189: mpz_out_str(asir_out,10,BDY(CZ(m)));
11190: printf("*");
11191: ndl_print(DL(m));
11192: }
11193: printf("\n");
11194: }
11195: }
11196:
11197: void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp)
11198: {
11199: VL tv,fv,vv,vc,av;
11200: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
11201: int m,nocheck,nvar,mindex,e,max;
11202: NDV c;
11203: NMV a;
11204: P p,zp;
11205: Q dmy;
11206: EPOS oepos;
11207: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
11208: Alg alpha,dp;
11209: P poly;
11210: LIST f1,f2,zpl;
11211: Obj obj;
11212: NumberField nf;
11213: struct order_spec *ord1;
11214: struct oEGT eg_check,eg0,eg1;
11215: NODE tr,tl1,tl2,tl3,tl4;
11216: LIST l1,l2,l3,l4,l5;
11217: int *perm;
11218: int j,ret;
11219: NODE retn;
11220: Q jq,bpe;
11221:
11222: nd_module = 0;
11223: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11224: parse_nd_option(vv,current_option);
1.1 noro 11225: if ( nd_vc )
11226: error("nd_f4_lf_trace : computation over a rational function field is not implemented");
11227: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11228: switch ( ord->id ) {
11229: case 1:
11230: if ( ord->nv != nvar )
11231: error("nd_f4_lf_trace : invalid order specification");
11232: break;
11233: default:
11234: break;
11235: }
11236:
11237: nd_ntrans = nvar;
11238: nd_nalg = 0;
11239:
11240: nocheck = 0;
11241: mindex = 0;
11242:
11243: /* do not use on-demand load/save */
11244: nd_demand = 0;
11245: m = trace > 1 ? trace : get_lprime(mindex);
11246: nd_init_ord(ord);
11247: mrank = 0;
11248: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
11249: for ( tv = vv; tv; tv = NEXT(tv) ) {
11250: if ( nd_module ) {
11251: s = BDY((LIST)BDY(t));
11252: trank = length(s);
11253: mrank = MAX(mrank,trank);
11254: for ( ; s; s = NEXT(s) ) {
11255: e = getdeg(tv->v,(P)BDY(s));
11256: max = MAX(e,max);
11257: }
11258: } else {
11259: e = getdeg(tv->v,(P)BDY(t));
11260: max = MAX(e,max);
11261: }
11262: }
11263: nd_setup_parameters(nvar,max);
11264: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
11265: ishomo = 1;
11266: /* XXX */
11267: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
11268: if ( nd_module ) {
11269: c = (pointer)pltondv(CO,vv,(LIST)BDY(t));
11270: } else {
11271: c = (pointer)ptondv(CO,vv,(P)BDY(t));
11272: }
11273: if ( ishomo )
11274: ishomo = ishomo && ndv_ishomo(c);
11275: if ( c ) {
11276: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
11277: ndv_mod(-2,c);
11278: NEXTNODE(in0,in); BDY(in) = (pointer)c;
11279: }
11280: }
11281: if ( in0 ) NEXT(in) = 0;
11282: if ( fd0 ) NEXT(fd) = 0;
11283: if ( !ishomo && homo ) {
11284: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
11285: c = (NDV)BDY(t); len = LEN(c);
11286: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
11287: wmax = MAX(TD(DL(a)),wmax);
11288: }
11289: homogenize_order(ord,nvar,&ord1);
11290: nd_init_ord(ord1);
11291: nd_setup_parameters(nvar+1,wmax);
11292: for ( t = fd0; t; t = NEXT(t) )
11293: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
11294: }
11295: if ( MaxDeg > 0 ) nocheck = 1;
1.24 noro 11296: ret = ndv_setup(-2,m,fd0,nd_gbblock?1:0,0,0);
1.1 noro 11297: if ( ret )
11298: cand = nd_f4_lf_trace_main(m,&perm);
11299: if ( !ret || !cand ) {
11300: *rp = 0; return;
11301: }
11302: if ( !ishomo && homo ) {
11303: /* dehomogenization */
11304: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
11305: nd_init_ord(ord);
11306: nd_setup_parameters(nvar,0);
11307: }
11308: cand = ndv_reducebase(cand,perm);
11309: cand = ndv_reduceall(-2,cand);
11310: cbpe = nd_bpe;
11311: get_eg(&eg0);
11312: if ( (ret = ndv_check_membership(-2,in0,obpe,oadv,oepos,cand)) != 0 ) {
11313: /* gbcheck : cand is a GB of Id(cand) ? */
11314: retn = nd_f4(-2,0,0);
11315: }
11316: if ( !retn ) {
11317: /* failure */
11318: *rp = 0; return;
11319: }
11320: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
11321: if ( DP_Print )
1.5 noro 11322: fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime);
1.1 noro 11323: /* dp->p */
11324: nd_bpe = cbpe;
11325: nd_setup_parameters(nd_nvar,0);
11326: for ( r = cand; r; r = NEXT(r) ) {
11327: if ( nd_module ) BDY(r) = ndvtopl(-2,CO,vv,BDY(r),mrank);
11328: else BDY(r) = (pointer)ndvtop(-2,CO,vv,BDY(r));
11329: }
11330: MKLIST(*rp,cand);
11331: }
11332:
11333: NODE nd_f4_lf_trace_main(int m,int **indp)
11334: {
11335: int i,nh,stat,index;
11336: NODE r,rm,g;
11337: ND_pairs d,l,l0,t;
11338: ND spol,red;
11339: NDV nf,redv,nfqv,nfv;
11340: NM s0,s;
11341: NODE rp0,srp0,nflist,nflist_lf;
11342: int nsp,nred,col,rank,len,k,j,a;
11343: UINT c;
11344: UINT **spmat;
11345: UINT *s0vect,*svect,*p,*v;
11346: int *colstat;
11347: IndArray *imat;
11348: int *rhead;
11349: int spcol,sprow;
11350: int sugar;
11351: PGeoBucket bucket;
11352: struct oEGT eg0,eg1,eg_f4;
11353:
11354: g = 0; d = 0;
11355: for ( i = 0; i < nd_psn; i++ ) {
11356: d = update_pairs(d,g,i,0);
11357: g = update_base(g,i);
11358: }
11359: while ( d ) {
11360: get_eg(&eg0);
11361: l = nd_minsugarp(d,&d);
11362: sugar = SG(l);
11363: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
11364: bucket = create_pbucket();
11365: stat = nd_sp_f4(m,0,l,bucket);
11366: if ( !stat ) {
11367: for ( t = l; NEXT(t); t = NEXT(t) );
11368: NEXT(t) = d; d = l;
11369: d = nd_reconstruct(1,d);
11370: continue;
11371: }
11372: if ( bucket->m < 0 ) continue;
11373: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
11374: if ( !col ) {
11375: for ( t = l; NEXT(t); t = NEXT(t) );
11376: NEXT(t) = d; d = l;
11377: d = nd_reconstruct(1,d);
11378: continue;
11379: }
11380: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
11381: if ( DP_Print )
1.5 noro 11382: fprintf(asir_out,"\nsugar=%d,symb=%.3fsec,",sugar,eg_f4.exectime);
1.1 noro 11383: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
11384: if ( !l0 ) continue;
11385: l = l0;
11386:
11387: /* over LF */
11388: bucket = create_pbucket();
11389: stat = nd_sp_f4(-2,1,l,bucket);
11390: if ( !stat ) {
11391: for ( t = l; NEXT(t); t = NEXT(t) );
11392: NEXT(t) = d; d = l;
11393: d = nd_reconstruct(1,d);
11394: continue;
11395: }
11396: if ( bucket->m < 0 ) continue;
11397: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
11398: if ( !col ) {
11399: for ( t = l; NEXT(t); t = NEXT(t) );
11400: NEXT(t) = d; d = l;
11401: d = nd_reconstruct(1,d);
11402: continue;
11403: }
11404: nflist_lf = nd_f4_red(-2,l,1,s0vect,col,rp0,0);
11405: /* adding new bases */
11406: for ( rm = nflist, r = nflist_lf; r && rm; rm = NEXT(rm), r = NEXT(r) ) {
11407: nfv = (NDV)BDY(rm);
11408: nfqv = (NDV)BDY(r);
11409: if ( DL_COMPARE(HDL(nfv),HDL(nfqv)) ) return 0;
11410: ndv_removecont(m,nfv);
11411: ndv_removecont(-2,nfqv);
1.24 noro 11412: nh = ndv_newps(-2,nfv,nfqv);
1.1 noro 11413: d = update_pairs(d,g,nh,0);
11414: g = update_base(g,nh);
11415: }
11416: if ( r || rm ) return 0;
11417: }
11418: conv_ilist(nd_demand,1,g,indp);
11419: return g;
11420: }
11421:
1.7 noro 11422: #if SIZEOF_LONG==8
11423:
11424: NDV vect64_to_ndv(mp_limb_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
11425: {
11426: int j,k,len;
11427: UINT *p;
11428: UINT c;
11429: NDV r;
11430: NMV mr0,mr;
11431:
11432: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
11433: if ( !len ) return 0;
11434: else {
11435: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
11436: #if 0
11437: ndv_alloc += nmv_adv*len;
11438: #endif
11439: mr = mr0;
11440: p = s0vect;
11441: for ( j = k = 0; j < col; j++, p += nd_wpd )
11442: if ( !rhead[j] ) {
11443: if ( (c = (UINT)vect[k++]) != 0 ) {
11444: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
11445: }
11446: }
11447: MKNDV(nd_nvar,mr0,len,r);
11448: return r;
11449: }
11450: }
11451:
1.28 noro 11452: NDV vect64_to_ndv_s(mp_limb_t *vect,int col,UINT *s0vect)
11453: {
11454: int j,k,len;
11455: UINT *p;
11456: UINT c;
11457: NDV r;
11458: NMV mr0,mr;
11459:
11460: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
11461: if ( !len ) return 0;
11462: else {
11463: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
11464: mr = mr0;
11465: p = s0vect;
11466: for ( j = k = 0; j < col; j++, p += nd_wpd )
11467: if ( (c = (UINT)vect[k++]) != 0 ) {
11468: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
11469: }
11470: MKNDV(nd_nvar,mr0,len,r);
11471: return r;
11472: }
11473: }
11474:
1.7 noro 11475: int nd_to_vect64(int mod,UINT *s0,int n,ND d,mp_limb_t *r)
11476: {
11477: NM m;
1.11 noro 11478: UINT *t,*s,*u;
11479: int i,st,ed,md,prev,c;
1.7 noro 11480:
11481: for ( i = 0; i < n; i++ ) r[i] = 0;
1.11 noro 11482: prev = 0;
11483: for ( i = 0, m = BDY(d); m; m = NEXT(m) ) {
11484: t = DL(m);
11485: st = prev;
11486: ed = n;
11487: while ( ed > st ) {
11488: md = (st+ed)/2;
11489: u = s0+md*nd_wpd;
11490: c = DL_COMPARE(u,t);
11491: if ( c == 0 ) break;
11492: else if ( c > 0 ) st = md;
11493: else ed = md;
11494: }
11495: r[md] = (mp_limb_t)CM(m);
11496: prev = md;
1.7 noro 11497: }
11498: for ( i = 0; !r[i]; i++ );
11499: return i;
11500: }
11501:
11502: #define MOD128(a,c,m) ((a)=(((c)!=0||((a)>=(m)))?(((((U128)(c))<<64)+(a))%(m)):(a)))
11503:
1.28 noro 11504: int ndv_reduce_vect64(int m,mp_limb_t *svect,mp_limb_t *cvect,int col,IndArray *imat,NM_ind_pair *rp0,int nred,SIG sig)
1.7 noro 11505: {
11506: int i,j,k,len,pos,prev;
11507: mp_limb_t a,c,c1,c2;
11508: IndArray ivect;
11509: unsigned char *ivc;
11510: unsigned short *ivs;
11511: unsigned int *ivi;
11512: NDV redv;
11513: NMV mr;
11514: NODE rp;
11515: int maxrs;
11516:
11517: for ( i = 0; i < col; i++ ) cvect[i] = 0;
11518: maxrs = 0;
11519: for ( i = 0; i < nred; i++ ) {
11520: ivect = imat[i];
11521: k = ivect->head;
11522: a = svect[k]; c = cvect[k];
11523: MOD128(a,c,m);
11524: svect[k] = a; cvect[k] = 0;
1.28 noro 11525: if ( (c = svect[k]) != 0 && (sig == 0 || comp_sig(sig,rp0[i]->sig) > 0 ) ) {
1.11 noro 11526: Nf4_red++;
1.7 noro 11527: maxrs = MAX(maxrs,rp0[i]->sugar);
11528: c = m-c; redv = nd_ps[rp0[i]->index];
11529: len = LEN(redv); mr = BDY(redv);
11530: svect[k] = 0; prev = k;
11531: switch ( ivect->width ) {
11532: case 1:
11533: ivc = ivect->index.c;
11534: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11535: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.12 noro 11536: c2 = svect[pos]+c1*c;
11537: if ( c2 < svect[pos] ) cvect[pos]++;
11538: svect[pos] = c2;
1.7 noro 11539: }
11540: break;
11541: case 2:
11542: ivs = ivect->index.s;
11543: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11544: pos = prev+ivs[j]; c1 = CM(mr); prev = pos;
1.12 noro 11545: c2 = svect[pos]+c1*c;
11546: if ( c2 < svect[pos] ) cvect[pos]++;
11547: svect[pos] = c2;
1.7 noro 11548: }
11549: break;
11550: case 4:
11551: ivi = ivect->index.i;
11552: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11553: pos = prev+ivi[j]; c1 = CM(mr); prev = pos;
1.12 noro 11554: c2 = svect[pos]+c1*c;
11555: if ( c2 < svect[pos] ) cvect[pos]++;
11556: svect[pos] = c2;
1.7 noro 11557: }
11558: break;
11559: }
11560: }
11561: }
11562: for ( i = 0; i < col; i++ ) {
11563: a = svect[i]; c = cvect[i]; MOD128(a,c,m); svect[i] = a;
11564: }
11565: return maxrs;
11566: }
11567:
11568: /* for Fp, 2^15=<p<2^29 */
11569:
11570: NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
11571: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
11572: {
11573: int spcol,sprow,a;
11574: int i,j,k,l,rank;
11575: NODE r0,r;
11576: ND_pairs sp;
11577: ND spol;
11578: mp_limb_t **spmat;
11579: mp_limb_t *svect,*cvect;
11580: mp_limb_t *v;
11581: int *colstat;
11582: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
11583: int maxrs;
11584: int *spsugar;
11585: ND_pairs *spactive;
11586:
11587: spcol = col-nred;
11588: get_eg(&eg0);
11589: /* elimination (1st step) */
11590: spmat = (mp_limb_t **)MALLOC(nsp*sizeof(mp_limb_t *));
11591: svect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11592: cvect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11593: spsugar = (int *)MALLOC(nsp*sizeof(int));
11594: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
11595: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
11596: nd_sp(m,0,sp,&spol);
11597: if ( !spol ) continue;
11598: nd_to_vect64(m,s0vect,col,spol,svect);
1.28 noro 11599: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred,0);
1.7 noro 11600: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
11601: if ( i < col ) {
11602: spmat[sprow] = v = (mp_limb_t *)MALLOC_ATOMIC(spcol*sizeof(mp_limb_t));
11603: for ( j = k = 0; j < col; j++ )
11604: if ( !rhead[j] ) v[k++] = (UINT)svect[j];
11605: spsugar[sprow] = MAX(maxrs,SG(spol));
11606: if ( nz )
11607: spactive[sprow] = sp;
11608: sprow++;
11609: }
11610: nd_free(spol);
11611: }
1.12 noro 11612: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
1.7 noro 11613: if ( DP_Print ) {
11614: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
11615: fflush(asir_out);
11616: }
11617: /* free index arrays */
11618: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
11619:
11620: /* elimination (2nd step) */
11621: colstat = (int *)MALLOC(spcol*sizeof(int));
11622: rank = nd_gauss_elim_mod64(spmat,spsugar,spactive,sprow,spcol,m,colstat);
11623: r0 = 0;
11624: for ( i = 0; i < rank; i++ ) {
11625: NEXTNODE(r0,r); BDY(r) =
11626: (pointer)vect64_to_ndv(spmat[i],spcol,col,rhead,s0vect);
11627: SG((NDV)BDY(r)) = spsugar[i];
11628: GCFREE(spmat[i]);
11629: }
11630: if ( r0 ) NEXT(r) = 0;
11631:
11632: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
1.12 noro 11633: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
1.7 noro 11634: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
11635: if ( DP_Print ) {
11636: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
11637: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
11638: nsp,nred,sprow,spcol,rank);
11639: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
11640: }
11641: if ( nz ) {
11642: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
11643: if ( rank > 0 ) {
11644: NEXT(spactive[rank-1]) = 0;
11645: *nz = spactive[0];
11646: } else
11647: *nz = 0;
11648: }
11649: return r0;
11650: }
11651:
11652: int nd_gauss_elim_mod64(mp_limb_t **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
11653: {
11654: int i,j,k,l,rank,s;
11655: mp_limb_t inv;
11656: mp_limb_t a;
11657: UINT c;
11658: mp_limb_t *t,*pivot,*pk;
11659: UINT *ck;
11660: UINT **cmat;
11661: UINT *ct;
11662: ND_pairs pair;
11663:
11664: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
11665: for ( i = 0; i < row; i++ ) {
11666: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
11667: bzero(cmat[i],col*sizeof(UINT));
11668: }
11669:
11670: for ( rank = 0, j = 0; j < col; j++ ) {
11671: for ( i = rank; i < row; i++ ) {
11672: a = mat[i][j]; c = cmat[i][j];
11673: MOD128(a,c,md);
11674: mat[i][j] = a; cmat[i][j] = 0;
11675: }
11676: for ( i = rank; i < row; i++ )
11677: if ( mat[i][j] )
11678: break;
11679: if ( i == row ) {
11680: colstat[j] = 0;
11681: continue;
11682: } else
11683: colstat[j] = 1;
11684: if ( i != rank ) {
11685: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
11686: ct = cmat[i]; cmat[i] = cmat[rank]; cmat[rank] = ct;
11687: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
11688: if ( spactive ) {
11689: pair = spactive[i]; spactive[i] = spactive[rank];
11690: spactive[rank] = pair;
11691: }
11692: }
11693: /* column j is normalized */
11694: s = sugar[rank];
11695: inv = invm((UINT)mat[rank][j],md);
11696: /* normalize pivot row */
11697: for ( k = j, pk = mat[rank]+j, ck = cmat[rank]+j; k < col; k++, pk++, ck++ ) {
11698: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
11699: }
11700: for ( i = rank+1; i < row; i++ ) {
11701: if ( (a = mat[i][j]) != 0 ) {
11702: sugar[i] = MAX(sugar[i],s);
11703: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[rank]+j,(int)(md-a),col-j);
1.11 noro 11704: Nf4_red++;
1.7 noro 11705: }
11706: }
11707: rank++;
11708: }
11709: for ( j = col-1, l = rank-1; j >= 0; j-- )
11710: if ( colstat[j] ) {
11711: for ( k = j, pk = mat[l]+j, ck = cmat[l]+j; k < col; k++, pk++, ck++ ) {
11712: a = *pk; c = *ck; MOD128(a,c,md); *pk = a; *ck = 0;
11713: }
11714: s = sugar[l];
11715: for ( i = 0; i < l; i++ ) {
11716: a = mat[i][j]; c = cmat[i][j]; MOD128(a,c,md); mat[i][j] = a; cmat[i][j] = 0;
11717: if ( a ) {
11718: sugar[i] = MAX(sugar[i],s);
11719: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[l]+j,(int)(md-a),col-j);
1.11 noro 11720: Nf4_red++;
1.7 noro 11721: }
11722: }
11723: l--;
11724: }
11725: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
11726: GCFREE(cmat);
11727: return rank;
11728: }
11729:
1.28 noro 11730: int nd_gauss_elim_mod64_s(mp_limb_t **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat,SIG *sig)
11731: {
11732: int i,j,k,l,rank,s,imin;
11733: mp_limb_t inv;
11734: mp_limb_t a;
11735: UINT c;
11736: mp_limb_t *t,*pivot,*pk;
11737: UINT *ck;
11738: UINT **cmat;
11739: UINT *ct;
11740: ND_pairs pair;
11741: SIG sg;
1.31 noro 11742: int *used;
1.28 noro 11743:
1.31 noro 11744: used = (int *)MALLOC(row*sizeof(int));
1.28 noro 11745: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
11746: for ( i = 0; i < row; i++ ) {
11747: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
11748: bzero(cmat[i],col*sizeof(UINT));
11749: }
11750:
1.31 noro 11751: for ( j = 0; j < col; j++ ) {
11752: for ( i = 0; i < row; i++ ) {
1.28 noro 11753: a = mat[i][j]; c = cmat[i][j];
11754: MOD128(a,c,md);
11755: mat[i][j] = a; cmat[i][j] = 0;
11756: }
1.31 noro 11757: for ( i = 0; i < row; i++ )
11758: if ( !used[i] && mat[i][j] ) break;
11759: if ( i == row ) {
1.28 noro 11760: colstat[j] = 0;
11761: continue;
1.31 noro 11762: } else {
1.28 noro 11763: colstat[j] = 1;
1.31 noro 11764: used[i] = 1;
1.28 noro 11765: }
11766: /* column j is normalized */
1.31 noro 11767: s = sugar[i];
11768: inv = invm((UINT)mat[i][j],md);
1.28 noro 11769: /* normalize pivot row */
1.31 noro 11770: for ( k = j, pk = mat[i]+j, ck = cmat[i]+j; k < col; k++, pk++, ck++ ) {
1.28 noro 11771: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
11772: }
1.31 noro 11773: for ( k = i+1; k < row; k++ ) {
11774: if ( (a = mat[k][j]) != 0 ) {
11775: sugar[k] = MAX(sugar[k],s);
11776: red_by_vect64(md,mat[k]+j,cmat[k]+j,mat[i]+j,(int)(md-a),col-j);
1.28 noro 11777: Nf4_red++;
11778: }
11779: }
11780: }
1.31 noro 11781: rank = 0;
11782: for ( i = 0; i < row; i++ ) {
11783: for ( j = 0; j < col; j++ )
11784: if ( mat[i][j] ) break;
11785: if ( j == col ) sugar[i] = -1;
11786: else rank++;
11787: }
1.28 noro 11788: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
11789: GCFREE(cmat);
11790: return rank;
11791: }
11792:
11793: NODE nd_f4_red_mod64_main_s(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
11794: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,NODE *syzlistp)
11795: {
11796: int spcol,sprow,a;
11797: int i,j,k,l,rank;
11798: NODE r0,r;
11799: ND_pairs sp;
11800: ND spol;
11801: mp_limb_t **spmat;
11802: mp_limb_t *svect,*cvect;
11803: mp_limb_t *v;
11804: int *colstat;
11805: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
11806: int maxrs;
11807: int *spsugar;
11808: ND_pairs *spactive;
11809: SIG *spsig;
11810:
11811: get_eg(&eg0);
11812: /* elimination (1st step) */
11813: spmat = (mp_limb_t **)MALLOC(nsp*sizeof(mp_limb_t *));
11814: cvect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11815: spsugar = (int *)MALLOC(nsp*sizeof(int));
11816: spsig = (SIG *)MALLOC(nsp*sizeof(SIG));
11817: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
11818: nd_sp(m,0,sp,&spol);
11819: if ( !spol ) {
1.29 noro 11820: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
1.28 noro 11821: continue;
11822: }
11823: svect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11824: nd_to_vect64(m,s0vect,col,spol,svect);
11825: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred,spol->sig);
11826: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
11827: if ( i < col ) {
11828: spmat[sprow] = svect;
11829: spsugar[sprow] = MAX(maxrs,SG(spol));
11830: spsig[sprow] = sp->sig;
11831: sprow++;
11832: } else {
1.29 noro 11833: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
1.28 noro 11834: }
11835: nd_free(spol);
11836: }
11837: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
11838: if ( DP_Print ) {
11839: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
11840: fflush(asir_out);
11841: }
11842: /* free index arrays */
11843: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
11844:
11845: /* elimination (2nd step) */
11846: colstat = (int *)MALLOC(col*sizeof(int));
11847: rank = nd_gauss_elim_mod64_s(spmat,spsugar,0,sprow,col,m,colstat,spsig);
11848: r0 = 0;
1.31 noro 11849: for ( i = 0; i < sprow; i++ ) {
11850: if ( spsugar[i] >= 0 ) {
11851: NEXTNODE(r0,r);
11852: BDY(r) = vect64_to_ndv_s(spmat[i],col,s0vect);
11853: SG((NDV)BDY(r)) = spsugar[i];
11854: ((NDV)BDY(r))->sig = spsig[i];
11855: } else
11856: syzlistp[spsig[i]->pos] = insert_sig(syzlistp[spsig[i]->pos],spsig[i]);
1.28 noro 11857: GCFREE(spmat[i]);
11858: }
11859: if ( r0 ) NEXT(r) = 0;
11860: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
11861: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
11862: if ( DP_Print ) {
11863: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
11864: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
11865: nsp,nred,sprow,col,rank);
11866: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
11867: }
11868: return r0;
11869: }
1.40 noro 11870: #endif
1.28 noro 11871:
11872: NODE nd_f4_red_s(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,NODE *syzlistp)
11873: {
11874: IndArray *imat;
11875: int nsp,nred,i,start;
11876: int *rhead;
11877: NODE r0,rp;
11878: ND_pairs sp;
11879: NM_ind_pair *rvect;
11880: UINT *s;
11881: int *s0hash;
11882: struct oEGT eg0,eg1,eg_conv;
11883:
11884: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
11885: nred = length(rp0);
11886: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
11887: rhead = (int *)MALLOC(col*sizeof(int));
11888: for ( i = 0; i < col; i++ ) rhead[i] = 0;
11889:
11890: /* construction of index arrays */
11891: get_eg(&eg0);
11892: if ( DP_Print ) {
11893: fprintf(asir_out,"%dx%d,",nsp+nred,col);
11894: fflush(asir_out);
11895: }
11896: rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
11897: for ( start = 0, rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
11898: rvect[i] = (NM_ind_pair)BDY(rp);
11899: imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,rvect[i],start);
11900: rhead[imat[i]->head] = 1;
11901: start = imat[i]->head;
11902: }
11903: get_eg(&eg1); init_eg(&eg_conv); add_eg(&eg_conv,&eg0,&eg1); add_eg(&f4_conv,&eg0,&eg1);
11904: if ( DP_Print ) {
11905: fprintf(asir_out,"conv=%.3fsec,",eg_conv.exectime);
11906: fflush(asir_out);
11907: }
11908: if ( m > 0 )
1.40 noro 11909: #if SIZEOF_LONG==8
1.28 noro 11910: r0 = nd_f4_red_mod64_main_s(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,syzlistp);
1.40 noro 11911: #else
11912: r0 = nd_f4_red_main_s(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,syzlistp);
11913: #endif
1.28 noro 11914: else
11915: // r0 = nd_f4_red_q_main_s(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
11916: error("nd_f4_red_q_main_s : not implemented yet");
11917: return r0;
11918: }
11919:
11920: INLINE int ndl_find_reducer_minsig(UINT *dg)
11921: {
11922: RHist r;
11923: int i,singular,ret,d,k,imin;
11924: SIG t;
11925: static int wpd,nvar;
11926: static SIG quo,quomin;
11927: static UINT *tmp;
11928:
11929: if ( !quo || nvar != nd_nvar ) { NEWSIG(quo); NEWSIG(quomin); }
11930: if ( wpd != nd_wpd ) {
11931: wpd = nd_wpd;
11932: tmp = (UINT *)MALLOC(wpd*sizeof(UINT));
11933: }
11934: #if 0
11935: d = ndl_hash_value(dg);
11936: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
11937: if ( ndl_equal(dg,DL(r)) ) {
11938: return r->index;
11939: }
11940: }
11941: #endif
11942: imin = -1;
11943: for ( i = 0; i < nd_psn; i++ ) {
11944: r = nd_psh[i];
11945: if ( ndl_reducible(dg,DL(r)) ) {
11946: ndl_sub(dg,DL(r),tmp);
11947: _ndltodl(tmp,DL(quo));
11948: _addtodl(nd_nvar,DL(nd_psh[i]->sig),DL(quo));
11949: quo->pos = nd_psh[i]->sig->pos;
1.55 ! noro 11950: _adddl(nd_nvar,DL(quo),nd_sba_hm[quo->pos],DL2(quo));
1.28 noro 11951: if ( imin < 0 || comp_sig(quomin,quo) > 0 ) {
11952: t = quo; quo = quomin; quomin = t;
11953: imin = i;
11954: }
11955: }
11956: }
11957: if ( imin == -1 ) return nd_psn;
11958: else {
11959: #if 0
11960: nd_append_red(dg,i);
11961: #endif
11962: return imin;
11963: }
11964: }
11965:
11966: int nd_symbolic_preproc_s(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
11967: {
11968: NODE rp0,rp;
11969: NM mul,head,s0,s;
11970: int index,col,i,sugar;
11971: RHist h;
11972: UINT *s0v,*p;
11973: NM_ind_pair pair;
11974: ND red;
11975: NDV *ps;
11976: SIG sig;
11977:
11978: s0 = 0; rp0 = 0; col = 0;
11979: if ( nd_demand )
11980: ps = trace?nd_ps_trace_sym:nd_ps_sym;
11981: else
11982: ps = trace?nd_ps_trace:nd_ps;
11983: while ( 1 ) {
11984: head = remove_head_pbucket_symbolic(bucket);
11985: if ( !head ) break;
11986: if ( !s0 ) s0 = head;
11987: else NEXT(s) = head;
11988: s = head;
11989: index = ndl_find_reducer_minsig(DL(head));
11990: if ( index >= 0 && index < nd_psn ) {
11991: h = nd_psh[index];
11992: NEWNM(mul);
11993: ndl_sub(DL(head),DL(h),DL(mul));
11994: if ( ndl_check_bound2(index,DL(mul)) )
11995: return 0;
11996: sugar = TD(DL(mul))+SG(ps[index]);
11997: NEWSIG(sig);
11998: _ndltodl(DL(mul),DL(sig));
11999: _addtodl(nd_nvar,DL(nd_psh[index]->sig),DL(sig));
12000: sig->pos = nd_psh[index]->sig->pos;
1.55 ! noro 12001: _adddl(nd_nvar,DL(sig),nd_sba_hm[sig->pos],DL2(sig));
1.28 noro 12002: MKNM_ind_pair(pair,mul,index,sugar,sig);
12003: red = ndv_mul_nm_symbolic(mul,ps[index]);
12004: add_pbucket_symbolic(bucket,nd_remove_head(red));
12005: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
12006: }
12007: col++;
12008: }
12009: if ( rp0 ) NEXT(rp) = 0;
12010: NEXT(s) = 0;
12011: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
12012: for ( i = 0, p = s0v, s = s0; i < col;
12013: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
12014: *s0vect = s0v;
12015: *r = rp0;
12016:
12017: return col;
12018: }
12019:
12020: NODE nd_sba_f4(int m,int **indp)
12021: {
1.34 noro 12022: int i,nh,stat,index,f4red,f4step;
1.33 noro 12023: int col,rank,len,k,j,a,sugar,nbase,psugar,ms;
12024: NODE r,g,rp0,nflist;
1.41 noro 12025: ND_pairs d,l,t,l1;
1.33 noro 12026: ND h,nf;
12027: NDV nfv;
12028: union oNDC hc;
12029: UINT *s0vect;
1.28 noro 12030: UINT c;
12031: PGeoBucket bucket;
1.33 noro 12032: NODE *syzlist;
12033: SIG sig;
1.28 noro 12034: struct oEGT eg0,eg1,eg_f4;
1.33 noro 12035: struct oEGT eg2,eg_update,eg_remove,eg_large,eg_nf,eg_nfzero;
1.28 noro 12036:
12037: Nf4_red=0;
1.30 noro 12038: d = 0;
1.29 noro 12039: syzlist = (NODE *)MALLOC(nd_psn*sizeof(NODE));
1.28 noro 12040: for ( i = 0; i < nd_psn; i++ ) {
1.30 noro 12041: d = update_pairs_s(d,i,syzlist);
1.28 noro 12042: }
1.30 noro 12043: nd_nbase = nd_psn;
1.28 noro 12044: f4red = 1;
1.33 noro 12045: psugar = 0;
1.34 noro 12046: f4step = 0;
1.28 noro 12047: while ( d ) {
1.33 noro 12048: for ( t = d, ms = SG(d); t; t = NEXT(t) )
12049: if ( SG(t) < ms ) ms = SG(t);
1.38 noro 12050: if ( ms == psugar && f4step >= nd_sba_f4step ) {
1.33 noro 12051: again:
12052: l = d; d = d->next;
1.41 noro 12053: #if 0
1.33 noro 12054: if ( small_lcm(l) ) {
12055: if ( DP_Print ) fprintf(asir_out,"M");
12056: continue;
12057: }
12058: sig = l->sig;
12059: stat = nd_sp(m,0,l,&h);
1.41 noro 12060: #else
12061: l1 = find_smallest_lcm(l);
12062: if ( l1 == 0 ) {
12063: if ( DP_Print ) fprintf(asir_out,"M");
12064: continue;
12065: }
12066: sig = l1->sig;
12067: stat = nd_sp(m,0,l1,&h);
12068: #endif
1.33 noro 12069: if ( !stat ) {
12070: NEXT(l) = d; d = l;
12071: d = nd_reconstruct(0,d);
12072: goto again;
12073: }
12074: get_eg(&eg1);
12075: #if USE_GEOBUCKET
1.39 noro 12076: stat = m?nd_nf_pbucket_s(m,h,nd_ps,!nd_top&&!Top,&nf):nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.33 noro 12077: #else
1.39 noro 12078: stat = nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.33 noro 12079: #endif
12080: get_eg(&eg2);
12081: if ( !stat ) {
12082: NEXT(l) = d; d = l;
12083: d = nd_reconstruct(0,d);
12084: goto again;
12085: } else if ( stat == -1 ) {
12086: if ( DP_Print ) { printf("S"); fflush(stdout); }
12087: FREENDP(l);
12088: } else if ( nf ) {
12089: if ( DP_Print ) { printf("+"); fflush(stdout); }
12090: add_eg(&eg_nf,&eg1,&eg2);
12091: hc = HCU(nf);
12092: nd_removecont(m,nf);
12093: nfv = ndtondv(m,nf); nd_free(nf);
12094: nh = ndv_newps(m,nfv,0);
12095:
1.30 noro 12096: d = update_pairs_s(d,nh,syzlist);
12097: nd_sba_pos[sig->pos] = append_one(nd_sba_pos[sig->pos],nh);
1.33 noro 12098: FREENDP(l);
1.28 noro 12099: } else {
1.33 noro 12100: add_eg(&eg_nfzero,&eg1,&eg2);
12101: // syzygy
12102: get_eg(&eg1);
12103: d = remove_spair_s(d,sig);
12104: get_eg(&eg2); add_eg(&eg_remove,&eg1,&eg2);
1.29 noro 12105: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
1.33 noro 12106: if ( DP_Print ) { printf("."); fflush(stdout); }
12107: FREENDP(l);
12108: }
12109: } else {
1.34 noro 12110: if ( ms != psugar ) f4step = 1;
12111: else f4step++;
1.33 noro 12112: again2:
12113: psugar = ms;
12114: l = nd_minsugarp_s(d,&d);
12115: sugar = nd_sugarweight?d->sugar2:SG(d);
12116: bucket = create_pbucket();
12117: stat = nd_sp_f4(m,0,l,bucket);
12118: if ( !stat ) {
12119: for ( t = l; NEXT(t); t = NEXT(t) );
12120: NEXT(t) = d; d = l;
12121: d = nd_reconstruct(0,d);
12122: goto again2;
12123: }
12124: if ( bucket->m < 0 ) continue;
12125: col = nd_symbolic_preproc_s(bucket,0,&s0vect,&rp0);
12126: if ( !col ) {
1.37 noro 12127: for ( t = l; NEXT(t); t = NEXT(t) )
12128: ;
12129: NEXT(t) = d; d = l;
1.33 noro 12130: d = nd_reconstruct(0,d);
12131: goto again2;
12132: }
1.34 noro 12133: if ( DP_Print ) fprintf(asir_out,"\nsugar=%d,",psugar);
1.33 noro 12134: nflist = nd_f4_red_s(m,l,0,s0vect,col,rp0,syzlist);
12135: /* adding new bases */
12136: for ( r = nflist; r; r = NEXT(r) ) {
12137: nfv = (NDV)BDY(r);
1.38 noro 12138: if ( nd_f4_td ) SG(nfv) = nd_tdeg(nfv);
1.33 noro 12139: ndv_removecont(m,nfv);
12140: nh = ndv_newps(m,nfv,0);
12141: d = update_pairs_s(d,nh,syzlist);
12142: nd_sba_pos[nfv->sig->pos] = append_one(nd_sba_pos[nfv->sig->pos],nh);
12143: }
12144: for ( i = 0; i < nd_nbase; i++ )
12145: for ( r = syzlist[i]; r; r = NEXT(r) )
12146: d = remove_spair_s(d,(SIG)BDY(r));
12147: d = remove_large_lcm(d);
12148: if ( DP_Print ) {
1.34 noro 12149: fprintf(asir_out,"f4red=%d,gblen=%d",f4red,nd_psn); fflush(asir_out);
1.33 noro 12150: }
12151: f4red++;
1.28 noro 12152: }
12153: }
12154: if ( DP_Print ) {
1.34 noro 12155: fprintf(asir_out,"\nnumber of red=%d,",Nf4_red);
1.28 noro 12156: }
1.30 noro 12157: g = conv_ilist_s(nd_demand,0,indp);
1.28 noro 12158: return g;
12159: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>