Annotation of OpenXM_contrib2/asir2018/engine/nd.c, Revision 1.49
1.49 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2018/engine/nd.c,v 1.48 2021/02/18 05:35:01 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;
1304: ret = comp_sig(sig,quo);
1305: if ( ret > 0 ) { singular = 0; break; }
1.38 noro 1306: if ( ret == 0 ) { /* fprintf(asir_out,"s"); fflush(asir_out); */ singular = 1; }
1.24 noro 1307: }
1308: }
1309: if ( singular ) return -1;
1.27 noro 1310: else if ( i < nd_psn )
1311: nd_append_red(dg,i);
1312: return i;
1.24 noro 1313: }
1314:
1.1 noro 1315: ND nd_merge(ND p1,ND p2)
1316: {
1317: int n,c;
1318: int t,can,td1,td2;
1319: ND r;
1320: NM m1,m2,mr0,mr,s;
1321:
1322: if ( !p1 ) return p2;
1323: else if ( !p2 ) return p1;
1324: else {
1325: can = 0;
1326: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1327: c = DL_COMPARE(DL(m1),DL(m2));
1328: switch ( c ) {
1329: case 0:
1330: s = m1; m1 = NEXT(m1);
1331: can++; NEXTNM2(mr0,mr,s);
1332: s = m2; m2 = NEXT(m2); FREENM(s);
1333: break;
1334: case 1:
1335: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1336: break;
1337: case -1:
1338: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1339: break;
1340: }
1341: }
1342: if ( !mr0 )
1343: if ( m1 ) mr0 = m1;
1344: else if ( m2 ) mr0 = m2;
1345: else return 0;
1346: else if ( m1 ) NEXT(mr) = m1;
1347: else if ( m2 ) NEXT(mr) = m2;
1348: else NEXT(mr) = 0;
1349: BDY(p1) = mr0;
1350: SG(p1) = MAX(SG(p1),SG(p2));
1351: LEN(p1) = LEN(p1)+LEN(p2)-can;
1352: FREEND(p2);
1353: return p1;
1354: }
1355: }
1356:
1357: ND nd_add(int mod,ND p1,ND p2)
1358: {
1359: int n,c;
1360: int t,can,td1,td2;
1361: ND r;
1362: NM m1,m2,mr0,mr,s;
1363:
1.11 noro 1364: Nnd_add++;
1.1 noro 1365: if ( !p1 ) return p2;
1366: else if ( !p2 ) return p1;
1367: else if ( mod == -1 ) return nd_add_sf(p1,p2);
1368: else if ( mod == -2 ) return nd_add_lf(p1,p2);
1369: else if ( !mod ) return nd_add_q(p1,p2);
1370: else {
1371: can = 0;
1372: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1373: c = DL_COMPARE(DL(m1),DL(m2));
1374: switch ( c ) {
1375: case 0:
1376: t = ((CM(m1))+(CM(m2))) - mod;
1377: if ( t < 0 ) t += mod;
1378: s = m1; m1 = NEXT(m1);
1379: if ( t ) {
1380: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1381: } else {
1382: can += 2; FREENM(s);
1383: }
1384: s = m2; m2 = NEXT(m2); FREENM(s);
1385: break;
1386: case 1:
1387: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1388: break;
1389: case -1:
1390: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1391: break;
1392: }
1393: }
1394: if ( !mr0 )
1395: if ( m1 ) mr0 = m1;
1396: else if ( m2 ) mr0 = m2;
1397: else return 0;
1398: else if ( m1 ) NEXT(mr) = m1;
1399: else if ( m2 ) NEXT(mr) = m2;
1400: else NEXT(mr) = 0;
1401: BDY(p1) = mr0;
1402: SG(p1) = MAX(SG(p1),SG(p2));
1403: LEN(p1) = LEN(p1)+LEN(p2)-can;
1404: FREEND(p2);
1405: return p1;
1406: }
1407: }
1408:
1409: /* XXX on opteron, the inlined manipulation of destructive additon of
1410: * two NM seems to make gcc optimizer get confused, so the part is
1411: * done in a function.
1412: */
1413:
1414: int nm_destructive_add_q(NM *m1,NM *m2,NM *mr0,NM *mr)
1415: {
1416: NM s;
1417: P t;
1418: int can;
1419:
1420: addp(nd_vc,CP(*m1),CP(*m2),&t);
1421: s = *m1; *m1 = NEXT(*m1);
1422: if ( t ) {
1423: can = 1; NEXTNM2(*mr0,*mr,s); CP(*mr) = (t);
1424: } else {
1425: can = 2; FREENM(s);
1426: }
1427: s = *m2; *m2 = NEXT(*m2); FREENM(s);
1428: return can;
1429: }
1430:
1431: ND nd_add_q(ND p1,ND p2)
1432: {
1433: int n,c,can;
1434: ND r;
1435: NM m1,m2,mr0,mr,s;
1436: P t;
1437:
1438: if ( !p1 ) return p2;
1439: else if ( !p2 ) return p1;
1440: else {
1441: can = 0;
1442: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1443: c = DL_COMPARE(DL(m1),DL(m2));
1444: switch ( c ) {
1445: case 0:
1446: #if defined(__x86_64__)
1447: can += nm_destructive_add_q(&m1,&m2,&mr0,&mr);
1448: #else
1449: addp(nd_vc,CP(m1),CP(m2),&t);
1450: s = m1; m1 = NEXT(m1);
1451: if ( t ) {
1452: can++; NEXTNM2(mr0,mr,s); CP(mr) = (t);
1453: } else {
1454: can += 2; FREENM(s);
1455: }
1456: s = m2; m2 = NEXT(m2); FREENM(s);
1457: #endif
1458: break;
1459: case 1:
1460: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1461: break;
1462: case -1:
1463: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1464: break;
1465: }
1466: }
1467: if ( !mr0 )
1468: if ( m1 ) mr0 = m1;
1469: else if ( m2 ) mr0 = m2;
1470: else return 0;
1471: else if ( m1 ) NEXT(mr) = m1;
1472: else if ( m2 ) NEXT(mr) = m2;
1473: else NEXT(mr) = 0;
1474: BDY(p1) = mr0;
1475: SG(p1) = MAX(SG(p1),SG(p2));
1476: LEN(p1) = LEN(p1)+LEN(p2)-can;
1477: FREEND(p2);
1478: return p1;
1479: }
1480: }
1481:
1482: ND nd_add_sf(ND p1,ND p2)
1483: {
1484: int n,c,can;
1485: ND r;
1486: NM m1,m2,mr0,mr,s;
1487: int t;
1488:
1489: if ( !p1 ) return p2;
1490: else if ( !p2 ) return p1;
1491: else {
1492: can = 0;
1493: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1494: c = DL_COMPARE(DL(m1),DL(m2));
1495: switch ( c ) {
1496: case 0:
1497: t = _addsf(CM(m1),CM(m2));
1498: s = m1; m1 = NEXT(m1);
1499: if ( t ) {
1500: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1501: } else {
1502: can += 2; FREENM(s);
1503: }
1504: s = m2; m2 = NEXT(m2); FREENM(s);
1505: break;
1506: case 1:
1507: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1508: break;
1509: case -1:
1510: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1511: break;
1512: }
1513: }
1514: if ( !mr0 )
1515: if ( m1 ) mr0 = m1;
1516: else if ( m2 ) mr0 = m2;
1517: else return 0;
1518: else if ( m1 ) NEXT(mr) = m1;
1519: else if ( m2 ) NEXT(mr) = m2;
1520: else NEXT(mr) = 0;
1521: BDY(p1) = mr0;
1522: SG(p1) = MAX(SG(p1),SG(p2));
1523: LEN(p1) = LEN(p1)+LEN(p2)-can;
1524: FREEND(p2);
1525: return p1;
1526: }
1527: }
1528:
1529:
1530: ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp)
1531: {
1532: int c,c1,c2;
1533: Z cg,cred,gcd,tq;
1534: P cgp,credp,gcdp;
1535: Obj tr,tr1;
1536:
1537: if ( mod == -1 ) {
1538: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1539: *divp = (Obj)ONE;
1540: } else if ( mod == -2 ) {
1541: Z inv,t;
1542: divlf(ONE,HCZ(p),&inv);
1543: chsgnlf(HCZ(g),&t);
1544: mullf(inv,t,&CZ(mul));
1545: *divp = (Obj)ONE;
1546: } else if ( mod ) {
1547: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1548: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1549: *divp = (Obj)ONE;
1550: } else if ( nd_vc ) {
1551: ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp);
1552: divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp);
1553: chsgnp(cgp,&CP(mul));
1554: nd_mul_c_q(d,credp); nd_mul_c_q(g,credp);
1555: if ( dn ) {
1556: mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr);
1557: reductr(nd_vc,tr,&tr1); dn->r = (R)tr1;
1558: }
1559: *divp = (Obj)credp;
1560: } else {
1.6 noro 1561: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1562: chsgnz(cg,&CZ(mul));
1.1 noro 1563: nd_mul_c_q(d,(P)cred); nd_mul_c_q(g,(P)cred);
1564: if ( dn ) {
1565: mulz(dn->z,cred,&tq); dn->z = tq;
1566: }
1567: *divp = (Obj)cred;
1568: }
1569: return nd_add(mod,g,ndv_mul_nm(mod,mul,p));
1570: }
1571:
1572: /* ret=1 : success, ret=0 : overflow */
1.6 noro 1573: int nd_nf(int mod,ND d,ND g,NDV *ps,int full,ND *rp)
1.1 noro 1574: {
1575: NM m,mrd,tail;
1576: NM mul;
1577: int n,sugar,psugar,sugar0,stat,index;
1578: int c,c1,c2,dummy;
1579: RHist h;
1580: NDV p,red;
1581: Q cg,cred,gcd,tq,qq;
1582: Z iq;
1583: DP dmul;
1584: NODE node;
1585: LIST hist;
1586: double hmag;
1587: P tp,tp1;
1588: Obj tr,tr1,div;
1589: union oNDC hg;
1590: P cont;
1591:
1592: if ( !g ) {
1593: *rp = d;
1594: return 1;
1595: }
1596: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1597:
1598: sugar0 = sugar = SG(g);
1599: n = NV(g);
1600: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1601: if ( d )
1602: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1603: for ( ; g; ) {
1604: index = ndl_find_reducer(HDL(g));
1605: if ( index >= 0 ) {
1606: h = nd_psh[index];
1607: ndl_sub(HDL(g),DL(h),DL(mul));
1608: if ( ndl_check_bound2(index,DL(mul)) ) {
1609: nd_free(g); nd_free(d);
1610: return 0;
1611: }
1612: p = nd_demand ? ndv_load(index) : ps[index];
1613: /* d+g -> div*(d+g)+mul*p */
1.6 noro 1614: g = nd_reduce2(mod,d,g,p,mul,0,&div);
1.1 noro 1615: if ( nd_gentrace ) {
1616: /* Trace=[div,index,mul,ONE] */
1.6 noro 1617: STOZ(index,iq);
1.1 noro 1618: nmtodp(mod,mul,&dmul);
1619: node = mknode(4,div,iq,dmul,ONE);
1620: }
1621: sugar = MAX(sugar,SG(p)+TD(DL(mul)));
1622: if ( !mod && g && !nd_vc && ((double)(p_mag(HCP(g))) > hmag) ) {
1623: hg = HCU(g);
1624: nd_removecont2(d,g);
1.6 noro 1625: if ( nd_gentrace ) {
1.1 noro 1626: /* overwrite cont : Trace=[div,index,mul,cont] */
1.6 noro 1627: /* exact division */
1.1 noro 1628: cont = ndc_div(mod,hg,HCU(g));
1629: if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont;
1630: }
1631: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1632: }
1633: MKLIST(hist,node);
1634: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1635: } else if ( !full ) {
1636: *rp = g;
1637: return 1;
1638: } else {
1639: m = BDY(g);
1640: if ( NEXT(m) ) {
1641: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1642: } else {
1643: FREEND(g); g = 0;
1644: }
1645: if ( d ) {
1646: NEXT(tail)=m; tail=m; LEN(d)++;
1647: } else {
1648: MKND(n,m,1,d); tail = BDY(d);
1649: }
1650: }
1651: }
1652: if ( d ) SG(d) = sugar;
1653: *rp = d;
1654: return 1;
1655: }
1656:
1.24 noro 1657: // ret=1 => success
1658: // ret=0 => overflow
1659: // ret=-1 => singular top reducible
1660:
1661: int nd_nf_s(int mod,ND d,ND g,NDV *ps,int full,ND *rp)
1662: {
1663: NM m,mrd,tail;
1664: NM mul;
1665: int n,sugar,psugar,sugar0,stat,index;
1666: int c,c1,c2,dummy;
1667: RHist h;
1668: NDV p,red;
1669: Q cg,cred,gcd,tq,qq;
1670: Z iq;
1671: DP dmul;
1672: NODE node;
1673: LIST hist;
1674: double hmag;
1675: P tp,tp1;
1676: Obj tr,tr1,div;
1677: union oNDC hg;
1678: P cont;
1679: SIG sig;
1680:
1681: if ( !g ) {
1682: *rp = d;
1683: return 1;
1684: }
1685: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1686:
1687: sugar0 = sugar = SG(g);
1688: n = NV(g);
1689: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1690: if ( d )
1691: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1692: sig = g->sig;
1693: for ( ; g; ) {
1694: index = ndl_find_reducer_s(HDL(g),sig);
1695: if ( index >= 0 && index < nd_psn ) {
1696: // reducer found
1697: h = nd_psh[index];
1698: ndl_sub(HDL(g),DL(h),DL(mul));
1699: if ( ndl_check_bound2(index,DL(mul)) ) {
1700: nd_free(g); nd_free(d);
1701: return 0;
1702: }
1703: p = ps[index];
1704: /* d+g -> div*(d+g)+mul*p */
1705: g = nd_reduce2(mod,d,g,p,mul,0,&div);
1706: sugar = MAX(sugar,SG(p)+TD(DL(mul)));
1707: if ( !mod && g && ((double)(p_mag(HCP(g))) > hmag) ) {
1708: hg = HCU(g);
1709: nd_removecont2(d,g);
1710: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1711: }
1712: } else if ( index == -1 ) {
1713: // singular top reducible
1714: return -1;
1715: } else if ( !full ) {
1716: *rp = g;
1717: g->sig = sig;
1718: return 1;
1719: } else {
1720: m = BDY(g);
1721: if ( NEXT(m) ) {
1722: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1723: } else {
1724: FREEND(g); g = 0;
1725: }
1726: if ( d ) {
1727: NEXT(tail)=m; tail=m; LEN(d)++;
1728: } else {
1729: MKND(n,m,1,d); tail = BDY(d);
1730: }
1731: }
1732: }
1733: if ( d ) {
1734: SG(d) = sugar;
1735: d->sig = sig;
1736: }
1737: *rp = d;
1738: return 1;
1739: }
1740:
1.1 noro 1741: int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp)
1742: {
1743: int hindex,index;
1744: NDV p;
1745: ND u,d,red;
1746: NODE l;
1747: NM mul,m,mrd,tail;
1748: int sugar,psugar,n,h_reducible;
1749: PGeoBucket bucket;
1750: int c,c1,c2;
1751: Z cg,cred,gcd,zzz;
1752: RHist h;
1753: double hmag,gmag;
1754: int count = 0;
1755: int hcount = 0;
1756:
1757: if ( !g ) {
1758: *rp = 0;
1759: return 1;
1760: }
1761: sugar = SG(g);
1762: n = NV(g);
1.6 noro 1763: if ( !mod ) hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1.1 noro 1764: bucket = create_pbucket();
1765: add_pbucket(mod,bucket,g);
1766: d = 0;
1767: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1768: while ( 1 ) {
1769: if ( mod > 0 || mod == -1 )
1770: hindex = head_pbucket(mod,bucket);
1771: else if ( mod == -2 )
1772: hindex = head_pbucket_lf(bucket);
1773: else
1774: hindex = head_pbucket_q(bucket);
1775: if ( hindex < 0 ) {
1776: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1777: if ( d ) SG(d) = sugar;
1778: *rp = d;
1779: return 1;
1780: }
1781: g = bucket->body[hindex];
1782: index = ndl_find_reducer(HDL(g));
1783: if ( index >= 0 ) {
1784: count++;
1785: if ( !d ) hcount++;
1786: h = nd_psh[index];
1787: ndl_sub(HDL(g),DL(h),DL(mul));
1788: if ( ndl_check_bound2(index,DL(mul)) ) {
1789: nd_free(d);
1790: free_pbucket(bucket);
1791: *rp = 0;
1792: return 0;
1793: }
1794: p = ps[index];
1795: if ( mod == -1 )
1796: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1797: else if ( mod == -2 ) {
1798: Z inv,t;
1799: divlf(ONE,HCZ(p),&inv);
1800: chsgnlf(HCZ(g),&t);
1801: mullf(inv,t,&CZ(mul));
1802: } else if ( mod ) {
1803: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1804: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1805: } else {
1.6 noro 1806: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1807: chsgnz(cg,&CZ(mul));
1.1 noro 1808: nd_mul_c_q(d,(P)cred);
1809: mulq_pbucket(bucket,cred);
1810: g = bucket->body[hindex];
1.6 noro 1811: gmag = (double)p_mag((P)HCZ(g));
1.1 noro 1812: }
1813: red = ndv_mul_nm(mod,mul,p);
1814: bucket->body[hindex] = nd_remove_head(g);
1815: red = nd_remove_head(red);
1816: add_pbucket(mod,bucket,red);
1817: psugar = SG(p)+TD(DL(mul));
1818: sugar = MAX(sugar,psugar);
1819: if ( !mod && hmag && (gmag > hmag) ) {
1820: g = normalize_pbucket(mod,bucket);
1821: if ( !g ) {
1822: if ( d ) SG(d) = sugar;
1823: *rp = d;
1824: return 1;
1825: }
1826: nd_removecont2(d,g);
1.6 noro 1827: hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1.1 noro 1828: add_pbucket(mod,bucket,g);
1829: }
1830: } else if ( !full ) {
1831: g = normalize_pbucket(mod,bucket);
1832: if ( g ) SG(g) = sugar;
1833: *rp = g;
1834: return 1;
1835: } else {
1836: m = BDY(g);
1837: if ( NEXT(m) ) {
1838: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1839: } else {
1840: FREEND(g); g = 0;
1841: }
1842: bucket->body[hindex] = g;
1843: NEXT(m) = 0;
1844: if ( d ) {
1845: NEXT(tail)=m; tail=m; LEN(d)++;
1846: } else {
1847: MKND(n,m,1,d); tail = BDY(d);
1848: }
1849: }
1850: }
1851: }
1852:
1.25 noro 1853: int nd_nf_pbucket_s(int mod,ND g,NDV *ps,int full,ND *rp)
1854: {
1855: int hindex,index;
1856: NDV p;
1857: ND u,d,red;
1858: NODE l;
1859: NM mul,m,mrd,tail;
1860: int sugar,psugar,n,h_reducible;
1861: PGeoBucket bucket;
1862: int c,c1,c2;
1863: Z cg,cred,gcd,zzz;
1864: RHist h;
1865: double hmag,gmag;
1866: int count = 0;
1867: int hcount = 0;
1868: SIG sig;
1869:
1870: if ( !g ) {
1871: *rp = 0;
1872: return 1;
1873: }
1874: sugar = SG(g);
1875: n = NV(g);
1876: if ( !mod ) hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1877: bucket = create_pbucket();
1878: add_pbucket(mod,bucket,g);
1879: d = 0;
1880: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1881: sig = g->sig;
1882: while ( 1 ) {
1883: if ( mod > 0 || mod == -1 )
1884: hindex = head_pbucket(mod,bucket);
1885: else if ( mod == -2 )
1886: hindex = head_pbucket_lf(bucket);
1887: else
1888: hindex = head_pbucket_q(bucket);
1889: if ( hindex < 0 ) {
1890: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1891: if ( d ) {
1892: SG(d) = sugar;
1893: d->sig = sig;
1894: }
1895: *rp = d;
1896: return 1;
1897: }
1898: g = bucket->body[hindex];
1899: index = ndl_find_reducer_s(HDL(g),sig);
1900: if ( index >= 0 && index < nd_psn ) {
1901: count++;
1902: if ( !d ) hcount++;
1903: h = nd_psh[index];
1904: ndl_sub(HDL(g),DL(h),DL(mul));
1905: if ( ndl_check_bound2(index,DL(mul)) ) {
1906: nd_free(d);
1907: free_pbucket(bucket);
1908: *rp = 0;
1909: return 0;
1910: }
1911: p = ps[index];
1912: if ( mod == -1 )
1913: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1914: else if ( mod == -2 ) {
1915: Z inv,t;
1916: divlf(ONE,HCZ(p),&inv);
1917: chsgnlf(HCZ(g),&t);
1918: mullf(inv,t,&CZ(mul));
1919: } else if ( mod ) {
1920: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1921: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1922: } else {
1923: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1924: chsgnz(cg,&CZ(mul));
1925: nd_mul_c_q(d,(P)cred);
1926: mulq_pbucket(bucket,cred);
1927: g = bucket->body[hindex];
1928: gmag = (double)p_mag((P)HCZ(g));
1929: }
1930: red = ndv_mul_nm(mod,mul,p);
1931: bucket->body[hindex] = nd_remove_head(g);
1932: red = nd_remove_head(red);
1933: add_pbucket(mod,bucket,red);
1934: psugar = SG(p)+TD(DL(mul));
1935: sugar = MAX(sugar,psugar);
1936: if ( !mod && hmag && (gmag > hmag) ) {
1937: g = normalize_pbucket(mod,bucket);
1938: if ( !g ) {
1939: if ( d ) {
1940: SG(d) = sugar;
1941: d->sig = sig;
1942: }
1943: *rp = d;
1944: return 1;
1945: }
1946: nd_removecont2(d,g);
1947: hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1948: add_pbucket(mod,bucket,g);
1949: }
1950: } else if ( index == -1 ) {
1951: // singular top reducible
1952: return -1;
1953: } else if ( !full ) {
1954: g = normalize_pbucket(mod,bucket);
1955: if ( g ) {
1956: SG(g) = sugar;
1957: g->sig = sig;
1958: }
1959: *rp = g;
1960: return 1;
1961: } else {
1962: m = BDY(g);
1963: if ( NEXT(m) ) {
1964: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1965: } else {
1966: FREEND(g); g = 0;
1967: }
1968: bucket->body[hindex] = g;
1969: NEXT(m) = 0;
1970: if ( d ) {
1971: NEXT(tail)=m; tail=m; LEN(d)++;
1972: } else {
1973: MKND(n,m,1,d); tail = BDY(d);
1974: }
1975: }
1976: }
1977: }
1978:
1.1 noro 1979: /* input : list of NDV, cand : list of NDV */
1980:
1981: int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand)
1982: {
1983: int n,i,stat;
1984: ND nf,d;
1985: NDV r;
1986: NODE t,s;
1987: union oNDC dn;
1988: Z q;
1989: LIST list;
1990:
1.24 noro 1991: ndv_setup(m,0,cand,nd_gentrace?1:0,1,0);
1.1 noro 1992: n = length(cand);
1993:
1994: if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; }
1995: /* membercheck : list is a subset of Id(cand) ? */
1996: for ( t = input, i = 0; t; t = NEXT(t), i++ ) {
1997: again:
1998: nd_tracelist = 0;
1999: if ( nd_bpe > obpe )
2000: r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos);
2001: else
2002: r = (NDV)BDY(t);
2003: #if 0
2004: // moved to nd_f4_lf_trace()
2005: if ( m == -2 ) ndv_mod(m,r);
2006: #endif
2007: d = ndvtond(m,r);
1.6 noro 2008: stat = nd_nf(m,0,d,nd_ps,0,&nf);
1.1 noro 2009: if ( !stat ) {
2010: nd_reconstruct(0,0);
2011: goto again;
2012: } else if ( nf ) return 0;
2013: if ( nd_gentrace ) {
2014: nd_tracelist = reverse_node(nd_tracelist);
2015: MKLIST(list,nd_tracelist);
1.6 noro 2016: STOZ(i,q); s = mknode(2,q,list); MKLIST(list,s);
1.1 noro 2017: MKNODE(s,list,nd_alltracelist);
2018: nd_alltracelist = s; nd_tracelist = 0;
2019: }
2020: if ( DP_Print ) { printf("."); fflush(stdout); }
2021: }
2022: if ( DP_Print ) { printf("\n"); }
2023: return 1;
2024: }
2025:
2026: ND nd_remove_head(ND p)
2027: {
2028: NM m;
2029:
2030: m = BDY(p);
2031: if ( !NEXT(m) ) {
2032: FREEND(p); p = 0;
2033: } else {
2034: BDY(p) = NEXT(m); LEN(p)--;
2035: }
2036: FREENM(m);
2037: return p;
2038: }
2039:
2040: ND nd_separate_head(ND p,ND *head)
2041: {
2042: NM m,m0;
2043: ND r;
2044:
2045: m = BDY(p);
2046: if ( !NEXT(m) ) {
2047: *head = p; p = 0;
2048: } else {
2049: m0 = m;
2050: BDY(p) = NEXT(m); LEN(p)--;
2051: NEXT(m0) = 0;
2052: MKND(NV(p),m0,1,r);
2053: *head = r;
2054: }
2055: return p;
2056: }
2057:
2058: PGeoBucket create_pbucket()
2059: {
2060: PGeoBucket g;
2061:
2062: g = CALLOC(1,sizeof(struct oPGeoBucket));
2063: g->m = -1;
2064: return g;
2065: }
2066:
2067: void free_pbucket(PGeoBucket b) {
2068: int i;
2069:
2070: for ( i = 0; i <= b->m; i++ )
2071: if ( b->body[i] ) {
2072: nd_free(b->body[i]);
2073: b->body[i] = 0;
2074: }
2075: GCFREE(b);
2076: }
2077:
1.39 noro 2078: #if 0
1.1 noro 2079: void add_pbucket_symbolic(PGeoBucket g,ND d)
2080: {
2081: int l,i,k,m;
2082:
2083: if ( !d )
2084: return;
2085: l = LEN(d);
2086: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2087: /* 2^(k-1) < l <= 2^k (=m) */
2088: d = nd_merge(g->body[k],d);
2089: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
2090: g->body[k] = 0;
2091: d = nd_merge(g->body[k+1],d);
2092: }
2093: g->body[k] = d;
2094: g->m = MAX(g->m,k);
2095: }
1.39 noro 2096: #else
2097: void add_pbucket_symbolic(PGeoBucket g,ND d)
2098: {
2099: int l,i,k,m,m0;
2100:
2101: if ( !d )
2102: return;
2103: m0 = g->m;
2104: while ( 1 ) {
2105: l = LEN(d);
2106: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2107: /* 2^(k-1) < l <= 2^k (=m) */
2108: if ( g->body[k] == 0 ) {
2109: g->body[k] = d;
2110: m0 = MAX(k,m0);
2111: break;
2112: } else {
2113: d = nd_merge(g->body[k],d);
2114: g->body[k] = 0;
2115: }
2116: }
2117: g->m = m0;
2118: }
2119: #endif
1.1 noro 2120:
1.39 noro 2121: #if 0
1.1 noro 2122: void add_pbucket(int mod,PGeoBucket g,ND d)
2123: {
2124: int l,i,k,m;
2125:
2126: if ( !d )
2127: return;
2128: l = LEN(d);
2129: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2130: /* 2^(k-1) < l <= 2^k (=m) */
2131: d = nd_add(mod,g->body[k],d);
2132: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
2133: g->body[k] = 0;
2134: d = nd_add(mod,g->body[k+1],d);
2135: }
2136: g->body[k] = d;
2137: g->m = MAX(g->m,k);
2138: }
1.39 noro 2139: #else
2140: void add_pbucket(int mod,PGeoBucket g,ND d)
2141: {
2142: int l,i,k,m,m0;
2143:
2144: m0 = g->m;
2145: while ( d != 0 ) {
2146: l = LEN(d);
2147: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2148: /* 2^(k-1) < l <= 2^k (=m) */
2149: if ( g->body[k] == 0 ) {
2150: g->body[k] = d;
2151: m0 = MAX(k,m0);
2152: break;
2153: } else {
2154: d = nd_add(mod,g->body[k],d);
2155: g->body[k] = 0;
2156: }
2157: }
2158: g->m = m0;
2159: }
2160: #endif
1.1 noro 2161:
2162: void mulq_pbucket(PGeoBucket g,Z c)
2163: {
2164: int k;
2165:
2166: for ( k = 0; k <= g->m; k++ )
2167: nd_mul_c_q(g->body[k],(P)c);
2168: }
2169:
2170: NM remove_head_pbucket_symbolic(PGeoBucket g)
2171: {
2172: int j,i,k,c;
2173: NM head;
2174:
2175: k = g->m;
2176: j = -1;
2177: for ( i = 0; i <= k; i++ ) {
2178: if ( !g->body[i] ) continue;
2179: if ( j < 0 ) j = i;
2180: else {
2181: c = DL_COMPARE(HDL(g->body[i]),HDL(g->body[j]));
2182: if ( c > 0 )
2183: j = i;
2184: else if ( c == 0 )
2185: g->body[i] = nd_remove_head(g->body[i]);
2186: }
2187: }
2188: if ( j < 0 ) return 0;
2189: else {
2190: head = BDY(g->body[j]);
2191: if ( !NEXT(head) ) {
2192: FREEND(g->body[j]);
2193: g->body[j] = 0;
2194: } else {
2195: BDY(g->body[j]) = NEXT(head);
2196: LEN(g->body[j])--;
2197: }
2198: return head;
2199: }
2200: }
2201:
2202: int head_pbucket(int mod,PGeoBucket g)
2203: {
2204: int j,i,c,k,nv,sum;
2205: UINT *di,*dj;
2206: ND gi,gj;
2207:
2208: k = g->m;
2209: while ( 1 ) {
2210: j = -1;
2211: for ( i = 0; i <= k; i++ ) {
2212: if ( !(gi = g->body[i]) )
2213: continue;
2214: if ( j < 0 ) {
2215: j = i;
2216: gj = g->body[j];
2217: dj = HDL(gj);
2218: sum = HCM(gj);
2219: } else {
2220: c = DL_COMPARE(HDL(gi),dj);
2221: if ( c > 0 ) {
2222: if ( sum ) HCM(gj) = sum;
2223: else g->body[j] = nd_remove_head(gj);
2224: j = i;
2225: gj = g->body[j];
2226: dj = HDL(gj);
2227: sum = HCM(gj);
2228: } else if ( c == 0 ) {
2229: if ( mod == -1 )
2230: sum = _addsf(sum,HCM(gi));
2231: else {
2232: sum = sum+HCM(gi)-mod;
2233: if ( sum < 0 ) sum += mod;
2234: }
2235: g->body[i] = nd_remove_head(gi);
2236: }
2237: }
2238: }
2239: if ( j < 0 ) return -1;
2240: else if ( sum ) {
2241: HCM(gj) = sum;
2242: return j;
2243: } else
2244: g->body[j] = nd_remove_head(gj);
2245: }
2246: }
2247:
2248: int head_pbucket_q(PGeoBucket g)
2249: {
2250: int j,i,c,k,nv;
2251: Z sum,t;
2252: ND gi,gj;
2253:
2254: k = g->m;
2255: while ( 1 ) {
2256: j = -1;
2257: for ( i = 0; i <= k; i++ ) {
2258: if ( !(gi = g->body[i]) ) continue;
2259: if ( j < 0 ) {
2260: j = i;
2261: gj = g->body[j];
1.6 noro 2262: sum = HCZ(gj);
1.1 noro 2263: } else {
2264: nv = NV(gi);
2265: c = DL_COMPARE(HDL(gi),HDL(gj));
2266: if ( c > 0 ) {
1.6 noro 2267: if ( sum ) HCZ(gj) = sum;
1.1 noro 2268: else g->body[j] = nd_remove_head(gj);
2269: j = i;
2270: gj = g->body[j];
1.6 noro 2271: sum = HCZ(gj);
1.1 noro 2272: } else if ( c == 0 ) {
1.6 noro 2273: addz(sum,HCZ(gi),&t);
1.1 noro 2274: sum = t;
2275: g->body[i] = nd_remove_head(gi);
2276: }
2277: }
2278: }
2279: if ( j < 0 ) return -1;
2280: else if ( sum ) {
1.6 noro 2281: HCZ(gj) = sum;
1.1 noro 2282: return j;
2283: } else
2284: g->body[j] = nd_remove_head(gj);
2285: }
2286: }
2287:
2288: int head_pbucket_lf(PGeoBucket g)
2289: {
2290: int j,i,c,k,nv;
2291: Z sum,t;
2292: ND gi,gj;
2293:
2294: k = g->m;
2295: while ( 1 ) {
2296: j = -1;
2297: for ( i = 0; i <= k; i++ ) {
2298: if ( !(gi = g->body[i]) ) continue;
2299: if ( j < 0 ) {
2300: j = i;
2301: gj = g->body[j];
2302: sum = HCZ(gj);
2303: } else {
2304: nv = NV(gi);
2305: c = DL_COMPARE(HDL(gi),HDL(gj));
2306: if ( c > 0 ) {
2307: if ( sum ) HCZ(gj) = sum;
2308: else g->body[j] = nd_remove_head(gj);
2309: j = i;
2310: gj = g->body[j];
2311: sum = HCZ(gj);
2312: } else if ( c == 0 ) {
2313: addlf(sum,HCZ(gi),&t);
2314: sum = t;
2315: g->body[i] = nd_remove_head(gi);
2316: }
2317: }
2318: }
2319: if ( j < 0 ) return -1;
2320: else if ( sum ) {
2321: HCZ(gj) = sum;
2322: return j;
2323: } else
2324: g->body[j] = nd_remove_head(gj);
2325: }
2326: }
2327:
2328: ND normalize_pbucket(int mod,PGeoBucket g)
2329: {
2330: int i;
2331: ND r,t;
2332:
2333: r = 0;
2334: for ( i = 0; i <= g->m; i++ ) {
2335: r = nd_add(mod,r,g->body[i]);
2336: g->body[i] = 0;
2337: }
2338: g->m = -1;
2339: return r;
2340: }
2341:
2342: #if 0
2343: void register_hcf(NDV p)
2344: {
2345: DCP dc,t;
2346: P hc,h;
2347: int c;
2348: NODE l,l1,prev;
2349:
2350: hc = p->body->c.p;
2351: if ( !nd_vc || NUM(hc) ) return;
2352: fctrp(nd_vc,hc,&dc);
2353: for ( t = dc; t; t = NEXT(t) ) {
2354: h = t->c;
2355: if ( NUM(h) ) continue;
2356: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2357: c = compp(nd_vc,h,(P)BDY(l));
2358: if ( c >= 0 ) break;
2359: }
2360: if ( !l || c > 0 ) {
2361: MKNODE(l1,h,l);
2362: if ( !prev )
2363: nd_hcf = l1;
2364: else
2365: NEXT(prev) = l1;
2366: }
2367: }
2368: }
2369: #else
2370: void register_hcf(NDV p)
2371: {
2372: DCP dc,t;
2373: P hc,h,q;
2374: Q dmy;
2375: int c;
2376: NODE l,l1,prev;
2377:
2378: hc = p->body->c.p;
2379: if ( NUM(hc) ) return;
2380: ptozp(hc,1,&dmy,&h);
2381: #if 1
2382: for ( l = nd_hcf; l; l = NEXT(l) ) {
2383: while ( 1 ) {
2384: if ( divtpz(nd_vc,h,(P)BDY(l),&q) ) h = q;
2385: else break;
2386: }
2387: }
2388: if ( NUM(h) ) return;
2389: #endif
2390: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2391: c = compp(nd_vc,h,(P)BDY(l));
2392: if ( c >= 0 ) break;
2393: }
2394: if ( !l || c > 0 ) {
2395: MKNODE(l1,h,l);
2396: if ( !prev )
2397: nd_hcf = l1;
2398: else
2399: NEXT(prev) = l1;
2400: }
2401: }
2402: #endif
2403:
2404: int do_diagonalize(int sugar,int m)
2405: {
1.6 noro 2406: int i,nh,stat;
2407: NODE r,g,t;
2408: ND h,nf,s,head;
2409: NDV nfv;
2410: Q q;
2411: P nm,nmp,dn,mnp,dnp,cont,cont1;
2412: union oNDC hc;
2413: NODE node;
2414: LIST l;
2415: Z iq;
1.1 noro 2416:
1.6 noro 2417: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
2418: if ( nd_gentrace ) {
2419: /* Trace = [1,index,1,1] */
2420: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2421: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2422: }
2423: if ( nd_demand )
2424: nfv = ndv_load(i);
2425: else
2426: nfv = nd_ps[i];
2427: s = ndvtond(m,nfv);
2428: s = nd_separate_head(s,&head);
2429: stat = nd_nf(m,head,s,nd_ps,1,&nf);
2430: if ( !stat ) return 0;
2431: ndv_free(nfv);
2432: hc = HCU(nf); nd_removecont(m,nf);
2433: /* exact division */
2434: cont = ndc_div(m,hc,HCU(nf));
1.1 noro 2435: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.6 noro 2436: nfv = ndtondv(m,nf);
2437: nd_free(nf);
2438: nd_bound[i] = ndv_compute_bound(nfv);
2439: if ( !m ) register_hcf(nfv);
2440: if ( nd_demand ) {
2441: ndv_save(nfv,i);
2442: ndv_free(nfv);
2443: } else
2444: nd_ps[i] = nfv;
2445: }
2446: return 1;
1.1 noro 2447: }
2448:
2449: LIST compute_splist()
2450: {
2451: NODE g,tn0,tn,node;
2452: LIST l0;
2453: ND_pairs d,t;
2454: int i;
2455: Z i1,i2;
2456:
2457: g = 0; d = 0;
2458: for ( i = 0; i < nd_psn; i++ ) {
2459: d = update_pairs(d,g,i,0);
2460: g = update_base(g,i);
2461: }
2462: for ( t = d, tn0 = 0; t; t = NEXT(t) ) {
2463: NEXTNODE(tn0,tn);
1.6 noro 2464: STOZ(t->i1,i1); STOZ(t->i2,i2);
1.1 noro 2465: node = mknode(2,i1,i2); MKLIST(l0,node);
2466: BDY(tn) = l0;
2467: }
2468: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
2469: return l0;
2470: }
2471:
1.49 ! noro 2472: typedef struct oHPDATA {
! 2473: P hn; // HP(t)=hn(t)/(1-t)^n
! 2474: int len;
! 2475: P *head; // hp(i)=head[i] (i=0,...,len-1)
! 2476: P hp; // dim Hm(i)=hp(i) (i >= len)
! 2477: VECT x; // BDY(x)[i] = <<0,...,1,...,0>>
! 2478: P *plist; // plist[i]=(1-t)^i
! 2479: } *HPDATA;
! 2480:
! 2481: void make_reduced(VECT b,int nv);
! 2482: void mhp_rec(VECT b,VECT x,P t,P *r);
! 2483: P mhp_ctop(P *r,P *plist,int n);
! 2484: void mhp_to_hf(VL vl,P hp,int n,P *plist,VECT *head,P *hf);
! 2485: DL monomial_colon(DL a,DL b,int n);
! 2486: LIST dp_monomial_hilbert_poincare(VECT b,VECT x,P *plist);
! 2487:
! 2488: int hpvalue(HPDATA data,int d)
! 2489: {
! 2490: P *head;
! 2491: int len;
! 2492: P hp,val;
! 2493: Z dz;
! 2494:
! 2495: head = data->head;
! 2496: len = data->len;
! 2497: hp = data->hp;
! 2498: if ( d < len )
! 2499: return ZTOS((Z)head[d]);
! 2500: else {
! 2501: STOZ(d,dz);
! 2502: substp(CO,hp,hp->v,(P)dz,&val);
! 2503: return ZTOS((Z)val);
! 2504: }
! 2505: }
! 2506:
! 2507: void setup_hpdata(HPDATA final,HPDATA current)
! 2508: {
! 2509: int n,i;
! 2510: P *r;
! 2511: DL *p;
! 2512: P tv;
! 2513: VECT b,x,head;
! 2514: DL dl;
! 2515:
! 2516: n = nd_nvar;
! 2517: final->hn = (P)ARG0(nd_hpdata);
! 2518: head = (VECT)ARG2(nd_hpdata);
! 2519: final->len = head->len;
! 2520: final->head = (P *)BDY(head);
! 2521: final->hp = (P)ARG3(nd_hpdata);
! 2522: final->plist = (P *)BDY((VECT)ARG4(nd_hpdata));
! 2523: MKVECT(x,n);
! 2524: for ( i = 0; i < n; i++ ) {
! 2525: NEWDL(dl,n); dl->d[i] = 1; dl->td = 1; BDY(x)[i] = dl;
! 2526: }
! 2527: final->x = x;
! 2528:
! 2529: r = (P *)CALLOC(n+1,sizeof(P));
! 2530: MKVECT(b,nd_psn); p = (DL *)BDY(b);
! 2531: for ( i = 0; i < nd_psn; i++ ) {
! 2532: p[i] = ndltodl(n,nd_psh[i]->dl);
! 2533: }
! 2534: make_reduced(b,n);
! 2535: makevar("t",&tv);
! 2536: mhp_rec(b,x,tv,r);
! 2537: current->hn = mhp_ctop(r,final->plist,n);
! 2538: mhp_to_hf(CO,current->hn,n,final->plist,&head,¤t->hp);
! 2539: current->head = (P *)BDY(head);
! 2540: current->len = head->len;
! 2541: current->x = x;
! 2542: current->plist = final->plist;
! 2543: }
! 2544:
! 2545: void update_hpdata(HPDATA current,int nh,int do_hf)
! 2546: {
! 2547: NODE data1,nd,t;
! 2548: DL new,dl;
! 2549: int len,i,n;
! 2550: Z dz;
! 2551: DL *p;
! 2552: VECT b,head;
! 2553: P tv,td,s,hn,hpoly;
! 2554: LIST list1;
! 2555:
! 2556: n = nd_nvar;
! 2557: new = ndltodl(n,nd_psh[nh]->dl);
! 2558: MKVECT(b,nh); p = (DL *)BDY(b);
! 2559: for ( i = 0; i < nh; i++ ) {
! 2560: p[i] = monomial_colon(ndltodl(n,nd_psh[i]->dl),new,n);
! 2561: }
! 2562: // compute HP(I:new)
! 2563: list1 = dp_monomial_hilbert_poincare(b,current->x,current->plist);
! 2564: data1 = BDY((LIST)list1);
! 2565: // HP(I+<new>) = H(I)-t^d*H(I:new), d=tdeg(new)
! 2566: makevar("t",&tv); UTOZ(new->td,dz);
! 2567: pwrp(CO,tv,dz,&td);
! 2568: mulp(CO,(P)ARG0(data1),td,&s);
! 2569: subp(CO,current->hn,s,&hn);
! 2570: current->hn = hn;
! 2571: if ( do_hf ) {
! 2572: mhp_to_hf(CO,hn,n,current->plist,&head,&hpoly);
! 2573: current->head = (P *)BDY(head);
! 2574: current->len = head->len;
! 2575: current->hp = hpoly;
! 2576: }
! 2577: }
! 2578:
! 2579: ND_pairs nd_remove_same_sugar( ND_pairs d, int sugar)
! 2580: {
! 2581: struct oND_pairs root;
! 2582: ND_pairs prev,cur;
! 2583:
! 2584: root.next = d;
! 2585: prev = &root; cur = d;
! 2586: while ( cur ) {
! 2587: if ( SG(cur) == sugar )
! 2588: prev->next = cur->next;
! 2589: else
! 2590: prev = cur;
! 2591: cur = cur->next;
! 2592: }
! 2593: return root.next;
! 2594: }
! 2595:
1.1 noro 2596: /* return value = 0 => input is not a GB */
2597:
2598: NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp)
2599: {
1.6 noro 2600: int i,nh,sugar,stat;
2601: NODE r,g,t;
2602: ND_pairs d;
2603: ND_pairs l;
2604: ND h,nf,s,head,nf1;
2605: NDV nfv;
2606: Z q;
2607: union oNDC dn,hc;
2608: int diag_count = 0;
1.41 noro 2609: int Nnfnz = 0,Nnfz = 0;
1.6 noro 2610: P cont;
2611: LIST list;
1.49 ! noro 2612: struct oHPDATA current_hpdata,final_hpdata;
! 2613: int final_hpvalue;
! 2614:
1.27 noro 2615: struct oEGT eg1,eg2,eg_update;
1.6 noro 2616:
1.27 noro 2617: init_eg(&eg_update);
1.11 noro 2618: Nnd_add = 0;
1.6 noro 2619: g = 0; d = 0;
2620: for ( i = 0; i < nd_psn; i++ ) {
2621: d = update_pairs(d,g,i,gensyz);
2622: g = update_base(g,i);
2623: }
2624: sugar = 0;
1.49 ! noro 2625: if ( nd_hpdata ) {
! 2626: setup_hpdata(&final_hpdata,¤t_hpdata);
! 2627: }
1.6 noro 2628: while ( d ) {
1.1 noro 2629: again:
1.6 noro 2630: l = nd_minp(d,&d);
2631: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
2632: if ( SG(l) != sugar ) {
2633: if ( ishomo ) {
2634: diag_count = 0;
2635: stat = do_diagonalize(sugar,m);
1.1 noro 2636: if ( !stat ) {
1.6 noro 2637: NEXT(l) = d; d = l;
2638: d = nd_reconstruct(0,d);
2639: goto again;
1.1 noro 2640: }
1.6 noro 2641: }
2642: sugar = SG(l);
2643: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
1.49 ! noro 2644: if ( nd_hpdata ) {
! 2645: if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) )
! 2646: break;
! 2647: else {
! 2648: final_hpvalue = hpvalue(&final_hpdata,sugar);
! 2649: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
! 2650: if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
! 2651: d = nd_remove_same_sugar(d,sugar);
! 2652: continue;
! 2653: }
! 2654: }
! 2655: }
1.6 noro 2656: }
2657: stat = nd_sp(m,0,l,&h);
2658: if ( !stat ) {
2659: NEXT(l) = d; d = l;
2660: d = nd_reconstruct(0,d);
2661: goto again;
2662: }
1.1 noro 2663: #if USE_GEOBUCKET
1.39 noro 2664: stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!nd_top&&!Top,&nf)
2665: :nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 2666: #else
1.39 noro 2667: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 2668: #endif
1.6 noro 2669: if ( !stat ) {
2670: NEXT(l) = d; d = l;
2671: d = nd_reconstruct(0,d);
2672: goto again;
2673: } else if ( nf ) {
1.41 noro 2674: Nnfnz++;
1.6 noro 2675: if ( checkonly || gensyz ) return 0;
1.1 noro 2676: if ( nd_newelim ) {
2677: if ( nd_module ) {
2678: if ( MPOS(HDL(nf)) > 1 ) return 0;
2679: } else if ( !(HDL(nf)[nd_exporigin] & nd_mask[0]) ) return 0;
2680: }
1.6 noro 2681: if ( DP_Print ) { printf("+"); fflush(stdout); }
2682: hc = HCU(nf);
2683: nd_removecont(m,nf);
2684: if ( !m && nd_nalg ) {
2685: nd_monic(0,&nf);
2686: nd_removecont(m,nf);
2687: }
2688: if ( nd_gentrace ) {
2689: /* exact division */
1.1 noro 2690: cont = ndc_div(m,hc,HCU(nf));
2691: if ( m || !UNIQ(cont) ) {
1.6 noro 2692: t = mknode(4,NULLP,NULLP,NULLP,cont);
2693: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
1.1 noro 2694: nd_tracelist = t;
2695: }
2696: }
1.6 noro 2697: nfv = ndtondv(m,nf); nd_free(nf);
1.24 noro 2698: nh = ndv_newps(m,nfv,0);
1.6 noro 2699: if ( !m && (ishomo && ++diag_count == diag_period) ) {
2700: diag_count = 0;
2701: stat = do_diagonalize(sugar,m);
2702: if ( !stat ) {
2703: NEXT(l) = d; d = l;
2704: d = nd_reconstruct(1,d);
2705: goto again;
1.1 noro 2706: }
1.6 noro 2707: }
1.27 noro 2708: get_eg(&eg1);
1.6 noro 2709: d = update_pairs(d,g,nh,0);
1.27 noro 2710: get_eg(&eg2); add_eg(&eg_update,&eg1,&eg2);
1.6 noro 2711: g = update_base(g,nh);
2712: FREENDP(l);
1.49 ! noro 2713: if ( nd_hpdata ) {
! 2714: update_hpdata(¤t_hpdata,nh,1);
! 2715: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
! 2716: if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
! 2717: d = nd_remove_same_sugar(d,sugar);
! 2718: }
! 2719: }
1.41 noro 2720: } else {
2721: Nnfz++;
2722: if ( nd_gentrace && gensyz ) {
2723: nd_tracelist = reverse_node(nd_tracelist);
2724: MKLIST(list,nd_tracelist);
2725: STOZ(-1,q); t = mknode(2,q,list); MKLIST(list,t);
2726: MKNODE(t,list,nd_alltracelist);
2727: nd_alltracelist = t; nd_tracelist = 0;
2728: }
2729: if ( DP_Print ) { printf("."); fflush(stdout); }
2730: FREENDP(l);
2731: }
1.36 noro 2732: }
2733: conv_ilist(nd_demand,0,g,indp);
1.41 noro 2734: if ( !checkonly && DP_Print ) {
2735: printf("\nnd_gb done. Nnd_add=%d,Npairs=%d, Nnfnz=%d,Nnfz=%d,",Nnd_add,Npairs,Nnfnz,Nnfz);
2736: printf("Nremoved=%d\n",NcriB+NcriMF+Ncri2);
2737: fflush(asir_out);
2738: }
2739: if ( DP_Print ) {
2740: print_eg("update",&eg_update); fprintf(asir_out,"\n");
2741: }
1.36 noro 2742: return g;
1.1 noro 2743: }
2744:
1.30 noro 2745: ND_pairs update_pairs_s(ND_pairs d,int t,NODE *syz);
1.47 noro 2746: int update_pairs_array_s(ND_pairs *d,int t,NODE *syz);
1.30 noro 2747: ND_pairs nd_newpairs_s(int t ,NODE *syz);
1.47 noro 2748: ND_pairs *nd_newpairs_array_s(int t ,NODE *syz);
1.24 noro 2749:
2750: int nd_nf_pbucket_s(int mod,ND g,NDV *ps,int full,ND *nf);
2751: int nd_nf_s(int mod,ND d,ND g,NDV *ps,int full,ND *nf);
2752:
2753: void _copydl(int n,DL d1,DL d2);
2754: void _subfromdl(int n,DL d1,DL d2);
2755: extern int (*cmpdl)(int n,DL d1,DL d2);
2756:
2757: NODE insert_sig(NODE l,SIG s)
2758: {
2759: int pos;
2760: DL sig;
2761: struct oNODE root;
2762: NODE p,prev,r;
2763: SIG t;
2764:
2765: pos = s->pos; sig = DL(s);
2766: root.next = l; prev = &root;
2767: for ( p = l; p; p = p->next ) {
2768: t = (SIG)p->body;
2769: if ( t->pos == pos ) {
2770: if ( _dl_redble(DL(t),sig,nd_nvar) )
2771: return root.next;
2772: else if ( _dl_redble(sig,DL(t),nd_nvar) )
2773: // remove p
2774: prev->next = p->next;
1.45 noro 2775: else
2776: prev = p;
1.24 noro 2777: } else
2778: prev = p;
2779: }
1.27 noro 2780: NEWNODE(r); r->body = (pointer)s; r->next = 0;
2781: for ( p = &root; p->next; p = p->next );
2782: p->next = r;
2783: // r->next = root.next;
2784: // return r;
2785: return root.next;
1.24 noro 2786: }
2787:
2788: ND_pairs remove_spair_s(ND_pairs d,SIG sig)
2789: {
2790: struct oND_pairs root;
2791: ND_pairs prev,p;
2792: SIG spsig;
2793:
2794: root.next = d;
2795: prev = &root; p = d;
2796: while ( p ) {
2797: spsig = p->sig;
1.26 noro 2798: if ( sig->pos == spsig->pos && _dl_redble(DL(sig),DL(spsig),nd_nvar) ) {
1.24 noro 2799: // remove p
2800: prev->next = p->next;
1.26 noro 2801: Nsyz++;
2802: } else
1.24 noro 2803: prev = p;
2804: p = p->next;
2805: }
2806: return (ND_pairs)root.next;
2807: }
2808:
1.29 noro 2809: int _dl_redble_ext(DL,DL,DL,int);
2810:
1.28 noro 2811: int small_lcm(ND_pairs l)
2812: {
2813: SIG sig;
2814: int i;
1.29 noro 2815: NODE t;
1.28 noro 2816: static DL lcm,mul,quo;
1.44 noro 2817: static int nvar = 0;
1.28 noro 2818:
1.38 noro 2819: if ( nd_sba_largelcm ) return 0;
1.28 noro 2820: if ( nvar < nd_nvar ) {
2821: nvar = nd_nvar; NEWDL(lcm,nvar); NEWDL(quo,nvar); NEWDL(mul,nvar);
2822: }
2823: sig = l->sig;
2824: _ndltodl(l->lcm,lcm);
1.29 noro 2825: #if 0
1.28 noro 2826: for ( i = 0; i < nd_psn; i++ ) {
2827: if ( sig->pos == nd_psh[i]->sig->pos &&
1.29 noro 2828: _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
1.28 noro 2829: _ndltodl(DL(nd_psh[i]),mul);
2830: _addtodl(nd_nvar,quo,mul);
2831: if ( (*cmpdl)(nd_nvar,lcm,mul) > 0 )
2832: break;
2833: }
2834: }
2835: if ( i < nd_psn ) return 1;
2836: else return 0;
1.29 noro 2837: #else
2838: for ( t = nd_sba_pos[sig->pos]; t; t = t->next ) {
2839: i = (long)BDY(t);
2840: if ( _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
2841: _ndltodl(DL(nd_psh[i]),mul);
2842: _addtodl(nd_nvar,quo,mul);
2843: if ( (*cmpdl)(nd_nvar,lcm,mul) > 0 )
2844: break;
2845: }
2846: }
2847: if ( t ) return 1;
2848: else return 0;
2849: #endif
1.28 noro 2850: }
2851:
1.41 noro 2852: ND_pairs find_smallest_lcm(ND_pairs l)
2853: {
2854: SIG sig;
2855: int i,minindex;
2856: NODE t;
2857: ND_pairs r;
2858: struct oSIG sig1;
2859: static DL mul,quo,minlm;
1.44 noro 2860: static int nvar = 0;
1.41 noro 2861:
2862: if ( nvar < nd_nvar ) {
2863: nvar = nd_nvar;
2864: NEWDL(quo,nvar); NEWDL(mul,nvar);
2865: NEWDL(minlm,nvar);
2866: }
2867: sig = l->sig;
2868: // find mg s.t. m*s(g)=sig and m*lm(g) is minimal
2869: _ndltodl(l->lcm,minlm); minindex = -1;
2870: for ( t = nd_sba_pos[sig->pos]; t; t = t->next ) {
2871: i = (long)BDY(t);
2872: if ( _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
2873: _ndltodl(DL(nd_psh[i]),mul);
2874: _addtodl(nd_nvar,quo,mul);
2875: if ( (*cmpdl)(nd_nvar,minlm,mul) > 0 ) {
2876: minindex = i;
1.47 noro 2877: break;
1.41 noro 2878: _copydl(nd_nvar,mul,minlm);
2879: }
2880: }
2881: }
2882: // l->lcm is minimal; return l itself
2883: if ( minindex < 0 ) return l;
1.47 noro 2884: else return 0;
1.41 noro 2885: for ( i = 0; i < nd_psn; i++ ) {
2886: if ( i == minindex ) continue;
2887: _ndltodl(DL(nd_psh[i]),mul);
2888: if ( _dl_redble_ext(mul,minlm,quo,nd_nvar) ) {
2889: _addtodl(nd_nvar,nd_ps[i]->sig->dl,quo);
2890: sig1.pos = nd_ps[i]->sig->pos;
2891: sig1.dl = quo;
2892: if ( comp_sig(sig,&sig1) > 0 ) {
2893: // printf("X");
2894: NEWND_pairs(r);
2895: r->sig = sig;
2896: r->i1 = minindex;
2897: r->i2 = i;
2898: dltondl(nd_nvar,minlm,r->lcm);
2899: r->next = 0;
2900: return r;
2901: }
2902: }
2903: }
2904: // there is no suitable spair
2905: return 0;
2906: }
2907:
1.28 noro 2908: ND_pairs remove_large_lcm(ND_pairs d)
2909: {
2910: struct oND_pairs root;
2911: ND_pairs prev,p;
2912:
2913: root.next = d;
2914: prev = &root; p = d;
2915: while ( p ) {
1.41 noro 2916: #if 0
1.28 noro 2917: if ( small_lcm(p) ) {
2918: // remove p
2919: prev->next = p->next;
2920: } else
1.41 noro 2921: #else
2922: if ( find_smallest_lcm(p) == 0 ) {
2923: // remove p
2924: prev->next = p->next;
2925: } else
2926: #endif
1.28 noro 2927: prev = p;
2928: p = p->next;
2929: }
2930: return (ND_pairs)root.next;
2931: }
2932:
1.26 noro 2933: struct oEGT eg_create,eg_newpairs,eg_merge;
2934:
1.30 noro 2935: NODE conv_ilist_s(int demand,int trace,int **indp);
2936:
1.44 noro 2937: // S(fj*ei-fi*ej)
2938:
1.45 noro 2939: void _subdl(int,DL,DL,DL);
2940:
1.44 noro 2941: SIG trivial_sig(int i,int j)
2942: {
1.45 noro 2943: static DL lcm;
1.44 noro 2944: static struct oSIG sigi,sigj;
2945: static int nvar = 0;
2946: SIG sig;
2947:
2948: if ( nvar != nd_nvar ) {
1.45 noro 2949: nvar = nd_nvar; NEWDL(lcm,nvar); NEWDL(sigi.dl,nvar); NEWDL(sigj.dl,nvar);
2950: }
1.46 noro 2951: if ( nd_sba_inputisgb != 0 ) {
1.45 noro 2952: lcm_of_DL(nd_nvar,nd_sba_hm[i],nd_sba_hm[j],lcm);
2953: sigi.pos = i; _subdl(nd_nvar,lcm,nd_sba_hm[i],sigi.dl);
2954: sigj.pos = j; _subdl(nd_nvar,lcm,nd_sba_hm[j],sigj.dl);
2955: if ( comp_sig(&sigi,&sigj) > 0 ) sig = dup_sig(&sigi);
2956: else sig = dup_sig(&sigj);
2957: } else {
2958: sigi.pos = i; _copydl(nd_nvar,nd_sba_hm[j],sigi.dl);
2959: sigj.pos = j; _copydl(nd_nvar,nd_sba_hm[i],sigj.dl);
2960: if ( comp_sig(&sigi,&sigj) > 0 ) sig = dup_sig(&sigi);
2961: else sig = dup_sig(&sigj);
1.44 noro 2962: }
2963: return sig;
2964: }
2965:
1.47 noro 2966: int nd_minsig(ND_pairs *d)
2967: {
2968: int min,i,ret;
2969:
2970: min = -1;
2971: for ( i = 0; i < nd_nbase; i++ ) {
2972: if ( d[i] != 0 ) {
2973: if ( min < 0 ) min = i;
2974: else {
2975: ret = comp_sig(d[i]->sig,d[min]->sig);
2976: if ( ret < 0 ) min = i;
2977: }
2978: }
2979: }
2980: return min;
2981: }
2982:
2983: int dlength(ND_pairs d)
2984: {
2985: int i;
2986: for ( i = 0; d; d = d->next, i++ );
2987: return i;
2988: }
2989:
1.44 noro 2990: NODE nd_sba_buch(int m,int ishomo,int **indp,NODE *syzp)
1.24 noro 2991: {
1.39 noro 2992: int i,j,nh,sugar,stat,pos;
1.30 noro 2993: NODE r,t,g;
1.47 noro 2994: ND_pairs *d;
1.41 noro 2995: ND_pairs l,l1;
1.24 noro 2996: ND h,nf,s,head,nf1;
2997: NDV nfv;
2998: Z q;
2999: union oNDC dn,hc;
3000: P cont;
3001: LIST list;
3002: SIG sig;
1.29 noro 3003: NODE *syzlist;
1.47 noro 3004: int ngen,ind;
1.41 noro 3005: int Nnominimal,Nredundant;
1.28 noro 3006: DL lcm,quo,mul;
1.49 ! noro 3007: struct oHPDATA final_hpdata,current_hpdata;
1.47 noro 3008: struct oEGT eg1,eg2,eg_update,eg_remove,eg_large,eg_nf,eg_nfzero,eg_minsig,eg_smallest;
3009: int Nnfs=0,Nnfz=0,Nnfnz=0,dlen,nsyz;
1.24 noro 3010:
1.27 noro 3011: init_eg(&eg_remove);
1.29 noro 3012: syzlist = (NODE *)MALLOC(nd_psn*sizeof(NODE));
1.47 noro 3013: d = (ND_pairs *)MALLOC(nd_psn*sizeof(ND_pairs));
3014: nd_nbase = nd_psn;
1.26 noro 3015: Nsyz = 0;
1.24 noro 3016: Nnd_add = 0;
1.41 noro 3017: Nnominimal = 0;
1.26 noro 3018: Nredundant = 0;
1.44 noro 3019: ngen = nd_psn;
1.48 noro 3020: if ( !do_weyl ) {
3021: for ( i = 0; i < nd_psn; i++ )
3022: for ( j = i+1; j < nd_psn; j++ ) {
3023: sig = trivial_sig(i,j);
3024: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
3025: }
1.29 noro 3026: }
1.47 noro 3027: dlen = 0;
1.41 noro 3028: for ( i = 0; i < nd_psn; i++ ) {
1.47 noro 3029: dlen += update_pairs_array_s(d,i,syzlist);
1.41 noro 3030: }
1.24 noro 3031: sugar = 0;
1.39 noro 3032: pos = 0;
1.49 ! noro 3033: if ( nd_hpdata ) {
! 3034: setup_hpdata(&final_hpdata,¤t_hpdata);
! 3035: }
1.26 noro 3036: NEWDL(lcm,nd_nvar); NEWDL(quo,nd_nvar); NEWDL(mul,nd_nvar);
3037: init_eg(&eg_create);
3038: init_eg(&eg_merge);
1.47 noro 3039: init_eg(&eg_minsig);
3040: init_eg(&eg_smallest);
1.29 noro 3041: init_eg(&eg_large);
1.31 noro 3042: init_eg(&eg_nf);
3043: init_eg(&eg_nfzero);
1.47 noro 3044: while ( 1 ) {
3045: if ( DP_Print && dlen%100 == 0 ) fprintf(asir_out,"(%d)",dlen);
3046: again :
3047: get_eg(&eg1);
3048: ind = nd_minsig(d);
3049: get_eg(&eg2); add_eg(&eg_minsig,&eg1,&eg2);
3050: if ( ind < 0 ) break;
3051: l = d[ind];
3052: // printf("(%d,%d)",l->i1,l->i2); print_sig(l->sig); printf("\n");
3053: get_eg(&eg1);
1.41 noro 3054: l1 = find_smallest_lcm(l);
1.47 noro 3055: get_eg(&eg2); add_eg(&eg_smallest,&eg1,&eg2);
1.41 noro 3056: if ( l1 == 0 ) {
1.47 noro 3057: d[ind] = d[ind]->next; dlen--;
1.41 noro 3058: if ( DP_Print ) fprintf(asir_out,"M");
3059: Nnominimal++;
3060: continue;
3061: }
3062: if ( SG(l1) != sugar ) {
3063: sugar = SG(l1);
3064: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
3065: }
3066: sig = l1->sig;
3067: if ( DP_Print && nd_sba_pot ) {
3068: if ( sig->pos != pos ) {
3069: fprintf(asir_out,"[%d]",sig->pos);
3070: pos = sig->pos;
3071: }
3072: }
3073: stat = nd_sp(m,0,l1,&h);
1.24 noro 3074: if ( !stat ) {
1.47 noro 3075: nd_reconstruct_s(0,d);
1.24 noro 3076: goto again;
3077: }
1.31 noro 3078: get_eg(&eg1);
1.25 noro 3079: #if USE_GEOBUCKET
1.39 noro 3080: 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.24 noro 3081: #else
1.39 noro 3082: stat = nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.24 noro 3083: #endif
1.31 noro 3084: get_eg(&eg2);
1.24 noro 3085: if ( !stat ) {
1.47 noro 3086: nd_reconstruct_s(0,d);
1.24 noro 3087: goto again;
3088: } else if ( stat == -1 ) {
1.47 noro 3089: d[ind] = d[ind]->next; dlen--;
1.41 noro 3090: Nnfs++;
1.24 noro 3091: if ( DP_Print ) { printf("S"); fflush(stdout); }
3092: } else if ( nf ) {
1.47 noro 3093: d[ind] = d[ind]->next; dlen--;
1.41 noro 3094: Nnfnz++;
3095: if ( DP_Print ) {
3096: if ( nd_sba_redundant_check ) {
3097: if ( ndl_find_reducer_nonsig(HDL(nf)) >= 0 ) {
3098: Nredundant++;
3099: printf("R");
3100: } else
3101: printf("+");
3102: } else
3103: printf("+");
3104: fflush(stdout);
3105: }
1.31 noro 3106: add_eg(&eg_nf,&eg1,&eg2);
1.24 noro 3107: hc = HCU(nf);
3108: nd_removecont(m,nf);
3109: nfv = ndtondv(m,nf); nd_free(nf);
3110: nh = ndv_newps(m,nfv,0);
1.26 noro 3111:
1.47 noro 3112: dlen += update_pairs_array_s(d,nh,syzlist);
1.29 noro 3113: nd_sba_pos[sig->pos] = append_one(nd_sba_pos[sig->pos],nh);
1.49 ! noro 3114: if ( nd_hpdata ) {
! 3115: update_hpdata(¤t_hpdata,nh,0);
! 3116: if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) ) {
! 3117: if ( DP_Print ) { printf("\nWe found a gb.\n"); }
! 3118: break;
! 3119: }
! 3120: }
1.24 noro 3121: } else {
1.47 noro 3122: d[ind] = d[ind]->next; dlen--;
1.41 noro 3123: Nnfz++;
1.31 noro 3124: add_eg(&eg_nfzero,&eg1,&eg2);
1.24 noro 3125: // syzygy
1.27 noro 3126: get_eg(&eg1);
1.47 noro 3127: nsyz = Nsyz;
3128: d[sig->pos] = remove_spair_s(d[sig->pos],sig);
3129: dlen -= Nsyz-nsyz;
1.27 noro 3130: get_eg(&eg2); add_eg(&eg_remove,&eg1,&eg2);
1.29 noro 3131: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
1.24 noro 3132: if ( DP_Print ) { printf("."); fflush(stdout); }
3133: }
3134: }
1.30 noro 3135: g = conv_ilist_s(nd_demand,0,indp);
1.26 noro 3136: if ( DP_Print ) {
1.47 noro 3137: 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 3138: printf("Nnfnz=%d,Nnfz=%d,Nnfsingular=%d\n",Nnfnz,Nnfz,Nnfs);
3139: fflush(stdout);
3140: if ( nd_sba_redundant_check )
3141: printf("Nredundant=%d\n",Nredundant);
1.26 noro 3142: fflush(stdout);
3143: print_eg("create",&eg_create);
3144: print_eg("merge",&eg_merge);
1.47 noro 3145: print_eg("minsig",&eg_minsig);
3146: print_eg("smallest",&eg_smallest);
3147: print_eg("remove",&eg_remove);
3148: print_eg("nf",&eg_nf);
3149: print_eg("nfzero",&eg_nfzero);
3150: printf("\n");
3151: }
3152: if ( nd_sba_syz ) {
1.27 noro 3153: print_eg("remove",&eg_remove);
1.31 noro 3154: print_eg("nf",&eg_nf);
3155: print_eg("nfzero",&eg_nfzero);
1.27 noro 3156: printf("\n");
1.26 noro 3157: }
1.44 noro 3158: if ( nd_sba_syz ) {
3159: NODE hsyz,tsyz,prev;
3160:
3161: hsyz = 0;
3162: for ( i = 0; i < ngen; i++ ) {
3163: tsyz = syzlist[i];
3164: for ( prev = 0; tsyz != 0; prev = tsyz, tsyz = NEXT(tsyz))
3165: BDY(tsyz) = (pointer)sigtodpm((SIG)BDY(tsyz));
3166: if ( prev != 0 ) {
3167: prev->next = hsyz; hsyz = syzlist[i];
3168: }
3169: }
3170: *syzp = hsyz;
3171: } else *syzp = 0;
1.24 noro 3172: return g;
3173: }
3174:
1.1 noro 3175: /* splist = [[i1,i2],...] */
3176:
3177: int check_splist(int m,NODE splist)
3178: {
3179: NODE t,p;
3180: ND_pairs d,r,l;
3181: int stat;
3182: ND h,nf;
3183:
3184: for ( d = 0, t = splist; t; t = NEXT(t) ) {
3185: p = BDY((LIST)BDY(t));
1.6 noro 3186: NEXTND_pairs(d,r);
3187: r->i1 = ZTOS((Q)ARG0(p)); r->i2 = ZTOS((Q)ARG1(p));
3188: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.1 noro 3189: SG(r) = TD(LCM(r)); /* XXX */
3190: }
3191: if ( d ) NEXT(r) = 0;
3192:
1.6 noro 3193: while ( d ) {
1.1 noro 3194: again:
1.6 noro 3195: l = nd_minp(d,&d);
3196: stat = nd_sp(m,0,l,&h);
3197: if ( !stat ) {
3198: NEXT(l) = d; d = l;
3199: d = nd_reconstruct(0,d);
3200: goto again;
3201: }
1.39 noro 3202: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.6 noro 3203: if ( !stat ) {
3204: NEXT(l) = d; d = l;
3205: d = nd_reconstruct(0,d);
3206: goto again;
3207: } else if ( nf ) return 0;
1.1 noro 3208: if ( DP_Print) { printf("."); fflush(stdout); }
1.6 noro 3209: }
1.1 noro 3210: if ( DP_Print) { printf("done.\n"); fflush(stdout); }
3211: return 1;
3212: }
3213:
3214: int check_splist_f4(int m,NODE splist)
3215: {
3216: UINT *s0vect;
1.6 noro 3217: PGeoBucket bucket;
1.1 noro 3218: NODE p,rp0,t;
3219: ND_pairs d,r,l,ll;
3220: int col,stat;
3221:
3222: for ( d = 0, t = splist; t; t = NEXT(t) ) {
3223: p = BDY((LIST)BDY(t));
1.6 noro 3224: NEXTND_pairs(d,r);
3225: r->i1 = ZTOS((Q)ARG0(p)); r->i2 = ZTOS((Q)ARG1(p));
3226: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.1 noro 3227: SG(r) = TD(LCM(r)); /* XXX */
3228: }
3229: if ( d ) NEXT(r) = 0;
3230:
1.6 noro 3231: while ( d ) {
3232: l = nd_minsugarp(d,&d);
3233: bucket = create_pbucket();
3234: stat = nd_sp_f4(m,0,l,bucket);
3235: if ( !stat ) {
3236: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
3237: NEXT(ll) = d; d = l;
3238: d = nd_reconstruct(0,d);
3239: continue;
3240: }
3241: if ( bucket->m < 0 ) continue;
3242: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
3243: if ( !col ) {
3244: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
3245: NEXT(ll) = d; d = l;
3246: d = nd_reconstruct(0,d);
3247: continue;
1.1 noro 3248: }
1.6 noro 3249: if ( nd_f4_red(m,l,0,s0vect,col,rp0,0) ) return 0;
3250: }
3251: return 1;
1.1 noro 3252: }
3253:
3254: int do_diagonalize_trace(int sugar,int m)
3255: {
1.6 noro 3256: int i,nh,stat;
3257: NODE r,g,t;
3258: ND h,nf,nfq,s,head;
3259: NDV nfv,nfqv;
3260: Q q,den,num;
3261: union oNDC hc;
3262: NODE node;
3263: LIST l;
3264: Z iq;
3265: P cont,cont1;
1.1 noro 3266:
1.6 noro 3267: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
3268: if ( nd_gentrace ) {
3269: /* Trace = [1,index,1,1] */
3270: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
3271: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
3272: }
3273: /* for nd_ps */
3274: s = ndvtond(m,nd_ps[i]);
3275: s = nd_separate_head(s,&head);
3276: stat = nd_nf_pbucket(m,s,nd_ps,1,&nf);
3277: if ( !stat ) return 0;
3278: nf = nd_add(m,head,nf);
3279: ndv_free(nd_ps[i]);
3280: nd_ps[i] = ndtondv(m,nf);
3281: nd_free(nf);
3282:
3283: /* for nd_ps_trace */
3284: if ( nd_demand )
3285: nfv = ndv_load(i);
3286: else
3287: nfv = nd_ps_trace[i];
3288: s = ndvtond(0,nfv);
3289: s = nd_separate_head(s,&head);
3290: stat = nd_nf(0,head,s,nd_ps_trace,1,&nf);
3291: if ( !stat ) return 0;
3292: ndv_free(nfv);
3293: hc = HCU(nf); nd_removecont(0,nf);
3294: /* exact division */
1.1 noro 3295: cont = ndc_div(0,hc,HCU(nf));
1.6 noro 3296: if ( nd_gentrace ) finalize_tracelist(i,cont);
3297: nfv = ndtondv(0,nf);
3298: nd_free(nf);
3299: nd_bound[i] = ndv_compute_bound(nfv);
3300: register_hcf(nfv);
3301: if ( nd_demand ) {
3302: ndv_save(nfv,i);
3303: ndv_free(nfv);
3304: } else
3305: nd_ps_trace[i] = nfv;
3306: }
3307: return 1;
1.1 noro 3308: }
3309:
3310: static struct oEGT eg_invdalg;
3311: struct oEGT eg_le;
3312:
3313: void nd_subst_vector(VL vl,P p,NODE subst,P *r)
3314: {
3315: NODE tn;
3316: P p1;
3317:
3318: for ( tn = subst; tn; tn = NEXT(NEXT(tn)) ) {
3319: substp(vl,p,BDY(tn),BDY(NEXT(tn)),&p1); p = p1;
3320: }
3321: *r = p;
3322: }
3323:
3324: NODE nd_gb_trace(int m,int ishomo,int **indp)
3325: {
1.6 noro 3326: int i,nh,sugar,stat;
3327: NODE r,g,t;
3328: ND_pairs d;
3329: ND_pairs l;
3330: ND h,nf,nfq,s,head;
3331: NDV nfv,nfqv;
3332: Z q,den,num;
3333: P hc;
3334: union oNDC dn,hnfq;
3335: struct oEGT eg_monic,egm0,egm1;
3336: int diag_count = 0;
3337: P cont;
3338: LIST list;
1.49 ! noro 3339: struct oHPDATA current_hpdata,final_hpdata;
! 3340: int final_hpvalue;
1.6 noro 3341:
3342: init_eg(&eg_monic);
3343: init_eg(&eg_invdalg);
3344: init_eg(&eg_le);
3345: g = 0; d = 0;
3346: for ( i = 0; i < nd_psn; i++ ) {
3347: d = update_pairs(d,g,i,0);
3348: g = update_base(g,i);
3349: }
3350: sugar = 0;
1.49 ! noro 3351: if ( nd_hpdata ) {
! 3352: setup_hpdata(&final_hpdata,¤t_hpdata);
! 3353: }
! 3354:
1.6 noro 3355: while ( d ) {
1.1 noro 3356: again:
1.6 noro 3357: l = nd_minp(d,&d);
3358: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
3359: if ( SG(l) != sugar ) {
1.1 noro 3360: #if 1
1.6 noro 3361: if ( ishomo ) {
3362: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3363: stat = do_diagonalize_trace(sugar,m);
3364: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3365: diag_count = 0;
1.1 noro 3366: if ( !stat ) {
1.6 noro 3367: NEXT(l) = d; d = l;
3368: d = nd_reconstruct(1,d);
3369: goto again;
1.1 noro 3370: }
1.6 noro 3371: }
3372: #endif
3373: sugar = SG(l);
3374: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
1.49 ! noro 3375: if ( nd_hpdata ) {
! 3376: if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) )
! 3377: break;
! 3378: else {
! 3379: final_hpvalue = hpvalue(&final_hpdata,sugar);
! 3380: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
! 3381: if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
! 3382: d = nd_remove_same_sugar(d,sugar);
! 3383: continue;
! 3384: }
! 3385: }
! 3386: }
1.6 noro 3387: }
3388: stat = nd_sp(m,0,l,&h);
3389: if ( !stat ) {
3390: NEXT(l) = d; d = l;
3391: d = nd_reconstruct(1,d);
3392: goto again;
3393: }
1.1 noro 3394: #if USE_GEOBUCKET
1.39 noro 3395: stat = nd_nf_pbucket(m,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 3396: #else
1.39 noro 3397: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 3398: #endif
1.6 noro 3399: if ( !stat ) {
3400: NEXT(l) = d; d = l;
3401: d = nd_reconstruct(1,d);
3402: goto again;
3403: } else if ( nf ) {
3404: if ( nd_demand ) {
3405: nfqv = ndv_load(nd_psn);
3406: nfq = ndvtond(0,nfqv);
3407: } else
3408: nfq = 0;
3409: if ( !nfq ) {
1.39 noro 3410: if ( !nd_sp(0,1,l,&h) || !nd_nf(0,0,h,nd_ps_trace,!nd_top&&!Top,&nfq) ) {
1.6 noro 3411: NEXT(l) = d; d = l;
3412: d = nd_reconstruct(1,d);
3413: goto again;
3414: }
3415: }
3416: if ( nfq ) {
3417: /* m|HC(nfq) => failure */
3418: if ( nd_vc ) {
3419: nd_subst_vector(nd_vc,HCP(nfq),nd_subst,&hc); q = (Z)hc;
3420: } else
3421: q = HCZ(nfq);
3422: if ( !remqi((Q)q,m) ) return 0;
3423:
3424: if ( DP_Print ) { printf("+"); fflush(stdout); }
3425: hnfq = HCU(nfq);
3426: if ( nd_nalg ) {
3427: /* m|DN(HC(nf)^(-1)) => failure */
3428: get_eg(&egm0);
3429: if ( !nd_monic(m,&nfq) ) return 0;
3430: get_eg(&egm1); add_eg(&eg_monic,&egm0,&egm1);
3431: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
3432: nfv = ndv_dup(0,nfqv); ndv_mod(m,nfv); nd_free(nf);
3433: } else {
3434: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
3435: nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf);
3436: }
3437: if ( nd_gentrace ) {
3438: /* exact division */
3439: cont = ndc_div(0,hnfq,HCU(nfqv));
3440: if ( !UNIQ(cont) ) {
3441: t = mknode(4,NULLP,NULLP,NULLP,cont);
3442: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
3443: nd_tracelist = t;
3444: }
3445: }
1.24 noro 3446: nh = ndv_newps(0,nfv,nfqv);
1.6 noro 3447: if ( ishomo && ++diag_count == diag_period ) {
3448: diag_count = 0;
3449: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3450: stat = do_diagonalize_trace(sugar,m);
3451: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3452: if ( !stat ) {
1.1 noro 3453: NEXT(l) = d; d = l;
3454: d = nd_reconstruct(1,d);
3455: goto again;
1.6 noro 3456: }
1.1 noro 3457: }
1.6 noro 3458: d = update_pairs(d,g,nh,0);
3459: g = update_base(g,nh);
1.49 ! noro 3460: if ( nd_hpdata ) {
! 3461: update_hpdata(¤t_hpdata,nh,1);
! 3462: if ( final_hpvalue == hpvalue(¤t_hpdata,sugar) ) {
! 3463: if ( DP_Print ) fprintf(asir_out,"sugar=%d done.\n",sugar);
! 3464: d = nd_remove_same_sugar(d,sugar);
! 3465: }
! 3466: }
1.6 noro 3467: } else {
3468: if ( DP_Print ) { printf("*"); fflush(stdout); }
3469: }
3470: } else {
3471: if ( DP_Print ) { printf("."); fflush(stdout); }
1.1 noro 3472: }
1.6 noro 3473: FREENDP(l);
3474: }
3475: if ( nd_nalg ) {
3476: if ( DP_Print ) {
3477: print_eg("monic",&eg_monic);
3478: print_eg("invdalg",&eg_invdalg);
3479: print_eg("le",&eg_le);
1.1 noro 3480: }
1.6 noro 3481: }
1.1 noro 3482: conv_ilist(nd_demand,1,g,indp);
1.41 noro 3483: if ( DP_Print ) { printf("\nnd_gb_trace done.\n"); fflush(stdout); }
1.6 noro 3484: return g;
1.1 noro 3485: }
3486:
3487: int ndv_compare(NDV *p1,NDV *p2)
3488: {
3489: return DL_COMPARE(HDL(*p1),HDL(*p2));
3490: }
3491:
3492: int ndv_compare_rev(NDV *p1,NDV *p2)
3493: {
3494: return -DL_COMPARE(HDL(*p1),HDL(*p2));
3495: }
3496:
3497: int ndvi_compare(NDVI p1,NDVI p2)
3498: {
3499: return DL_COMPARE(HDL(p1->p),HDL(p2->p));
3500: }
3501:
3502: int ndvi_compare_rev(NDVI p1,NDVI p2)
3503: {
3504: return -DL_COMPARE(HDL(p1->p),HDL(p2->p));
3505: }
3506:
3507: NODE ndv_reduceall(int m,NODE f)
3508: {
3509: int i,j,n,stat;
3510: ND nf,g,head;
3511: NODE t,a0,a;
3512: union oNDC dn;
3513: Q q,num,den;
3514: NODE node;
3515: LIST l;
3516: Z iq,jq;
3517: int *perm;
3518: union oNDC hc;
3519: P cont,cont1;
3520:
3521: if ( nd_nora ) return f;
3522: n = length(f);
1.24 noro 3523: ndv_setup(m,0,f,0,1,0);
1.1 noro 3524: perm = (int *)MALLOC(n*sizeof(int));
3525: if ( nd_gentrace ) {
3526: for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) )
1.6 noro 3527: perm[i] = ZTOS((Q)ARG1(BDY((LIST)BDY(t))));
1.1 noro 3528: }
3529: for ( i = 0; i < n; ) {
3530: if ( nd_gentrace ) {
3531: /* Trace = [1,index,1,1] */
1.6 noro 3532: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
1.1 noro 3533: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
3534: }
3535: g = ndvtond(m,nd_ps[i]);
3536: g = nd_separate_head(g,&head);
1.6 noro 3537: stat = nd_nf(m,head,g,nd_ps,1,&nf);
1.1 noro 3538: if ( !stat )
3539: nd_reconstruct(0,0);
3540: else {
3541: if ( DP_Print ) { printf("."); fflush(stdout); }
3542: ndv_free(nd_ps[i]);
3543: hc = HCU(nf); nd_removecont(m,nf);
3544: if ( nd_gentrace ) {
3545: for ( t = nd_tracelist; t; t = NEXT(t) ) {
1.6 noro 3546: jq = ARG1(BDY((LIST)BDY(t))); j = ZTOS(jq);
3547: STOZ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq;
1.1 noro 3548: }
1.6 noro 3549: /* exact division */
1.1 noro 3550: cont = ndc_div(m,hc,HCU(nf));
3551: finalize_tracelist(perm[i],cont);
3552: }
3553: nd_ps[i] = ndtondv(m,nf); nd_free(nf);
3554: nd_bound[i] = ndv_compute_bound(nd_ps[i]);
3555: i++;
3556: }
3557: }
3558: if ( DP_Print ) { printf("\n"); }
3559: for ( a0 = 0, i = 0; i < n; i++ ) {
3560: NEXTNODE(a0,a);
3561: if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i];
3562: else {
3563: for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break;
3564: BDY(a) = (pointer)nd_ps[j];
3565: }
3566: }
3567: NEXT(a) = 0;
3568: return a0;
3569: }
3570:
1.41 noro 3571: int ndplength(ND_pairs d)
3572: {
3573: int i;
3574: for ( i = 0; d; i++ ) d = NEXT(d);
3575: return i;
3576: }
3577:
1.1 noro 3578: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz)
3579: {
3580: ND_pairs d1,nd,cur,head,prev,remove;
1.41 noro 3581: int len0;
1.1 noro 3582:
3583: if ( !g ) return d;
3584: /* for testing */
3585: if ( gensyz && nd_gensyz == 2 ) {
3586: d1 = nd_newpairs(g,t);
3587: if ( !d )
3588: return d1;
3589: else {
3590: nd = d;
3591: while ( NEXT(nd) ) nd = NEXT(nd);
3592: NEXT(nd) = d1;
3593: return d;
3594: }
3595: }
3596: d = crit_B(d,t);
3597: d1 = nd_newpairs(g,t);
1.41 noro 3598: len0 = ndplength(d1);
1.1 noro 3599: d1 = crit_M(d1);
3600: d1 = crit_F(d1);
1.41 noro 3601: NcriMF += len0-ndplength(d1);
1.1 noro 3602: if ( gensyz || do_weyl )
3603: head = d1;
3604: else {
3605: prev = 0; cur = head = d1;
3606: while ( cur ) {
3607: if ( crit_2( cur->i1,cur->i2 ) ) {
3608: remove = cur;
3609: if ( !prev ) head = cur = NEXT(cur);
3610: else cur = NEXT(prev) = NEXT(cur);
1.41 noro 3611: FREENDP(remove); Ncri2++;
1.1 noro 3612: } else {
3613: prev = cur; cur = NEXT(cur);
3614: }
3615: }
3616: }
3617: if ( !d )
3618: return head;
3619: else {
3620: nd = d;
3621: while ( NEXT(nd) ) nd = NEXT(nd);
3622: NEXT(nd) = head;
3623: return d;
3624: }
3625: }
3626:
1.24 noro 3627: ND_pairs merge_pairs_s(ND_pairs d,ND_pairs d1);
3628:
1.30 noro 3629: ND_pairs update_pairs_s( ND_pairs d, int t,NODE *syz)
1.24 noro 3630: {
3631: ND_pairs d1;
1.26 noro 3632: struct oEGT eg1,eg2,eg3;
1.24 noro 3633:
1.30 noro 3634: if ( !t ) return d;
1.26 noro 3635: get_eg(&eg1);
1.30 noro 3636: d1 = nd_newpairs_s(t,syz);
1.26 noro 3637: get_eg(&eg2); add_eg(&eg_create,&eg1,&eg2);
1.24 noro 3638: d = merge_pairs_s(d,d1);
1.26 noro 3639: get_eg(&eg3); add_eg(&eg_merge,&eg2,&eg3);
1.24 noro 3640: return d;
3641: }
1.1 noro 3642:
1.47 noro 3643: int update_pairs_array_s( ND_pairs *d, int t,NODE *syz)
3644: {
3645: ND_pairs *d1;
3646: struct oEGT eg1,eg2,eg3;
3647: int i;
3648:
3649: if ( !t ) return 0;
3650: get_eg(&eg1);
3651: Nnewpair = 0;
3652: d1 = nd_newpairs_array_s(t,syz);
3653: get_eg(&eg2); add_eg(&eg_create,&eg1,&eg2);
3654: for ( i = 0; i < nd_nbase; i++ )
3655: d[i] = merge_pairs_s(d[i],d1[i]);
3656: get_eg(&eg3); add_eg(&eg_merge,&eg2,&eg3);
3657: return Nnewpair;
3658: }
3659:
1.1 noro 3660: ND_pairs nd_newpairs( NODE g, int t )
3661: {
3662: NODE h;
3663: UINT *dl;
3664: int ts,s,i,t0,min,max;
3665: ND_pairs r,r0;
3666:
3667: dl = DL(nd_psh[t]);
3668: ts = SG(nd_psh[t]) - TD(dl);
1.17 noro 3669: if ( nd_module && nd_intersect && (MPOS(dl) > nd_intersect) ) return 0;
1.1 noro 3670: for ( r0 = 0, h = g; h; h = NEXT(h) ) {
3671: if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) )
3672: continue;
3673: if ( nd_gbblock ) {
3674: t0 = (long)BDY(h);
3675: for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) {
3676: min = nd_gbblock[i]; max = nd_gbblock[i+1];
3677: if ( t0 >= min && t0 <= max && t >= min && t <= max )
3678: break;
3679: }
3680: if ( nd_gbblock[i] >= 0 )
3681: continue;
3682: }
1.41 noro 3683: NEXTND_pairs(r0,r); Npairs++;
1.1 noro 3684: r->i1 = (long)BDY(h);
3685: r->i2 = t;
3686: ndl_lcm(DL(nd_psh[r->i1]),dl,r->lcm);
3687: s = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
3688: SG(r) = MAX(s,ts) + TD(LCM(r));
3689: /* experimental */
3690: if ( nd_sugarweight )
3691: r->sugar2 = ndl_weight2(r->lcm);
3692: }
3693: if ( r0 ) NEXT(r) = 0;
3694: return r0;
3695: }
3696:
1.46 noro 3697: int sig_cmpdl_op(int n,DL d1,DL d2)
3698: {
3699: int e1,e2,i,j,l;
3700: int *t1,*t2;
3701: int len,head;
3702: struct order_pair *pair;
3703:
3704: len = nd_sba_modord->block_length;
3705: pair = nd_sba_modord->order_pair;
3706:
3707: head = 0;
3708: for ( i = 0, t1 = d1->d, t2 = d2->d; i < len; i++ ) {
3709: l = pair[i].length;
3710: switch ( pair[i].order ) {
3711: case 0:
3712: for ( j = 0, e1 = e2 = 0; j < l; j++ ) {
3713: e1 += t1[j];
3714: e2 += t2[j];
3715: }
3716: if ( e1 > e2 )
3717: return 1;
3718: else if ( e1 < e2 )
3719: return -1;
3720: else {
3721: for ( j = l - 1; j >= 0 && t1[j] == t2[j]; j-- );
3722: if ( j >= 0 )
3723: return t1[j] < t2[j] ? 1 : -1;
3724: }
3725: break;
3726: case 1:
3727: for ( j = 0, e1 = e2 = 0; j < l; j++ ) {
3728: e1 += t1[j];
3729: e2 += t2[j];
3730: }
3731: if ( e1 > e2 )
3732: return 1;
3733: else if ( e1 < e2 )
3734: return -1;
3735: else {
3736: for ( j = 0; j < l && t1[j] == t2[j]; j++ );
3737: if ( j < l )
3738: return t1[j] > t2[j] ? 1 : -1;
3739: }
3740: break;
3741: case 2:
3742: for ( j = 0; j < l && t1[j] == t2[j]; j++ );
3743: if ( j < l )
3744: return t1[j] > t2[j] ? 1 : -1;
3745: break;
3746: default:
3747: error("sig_cmpdl_op : invalid order"); break;
3748: }
3749: t1 += l; t2 += l; head += l;
3750: }
3751: return 0;
3752: }
3753:
3754: int sig_cmpdl_mat(int n,DL d1,DL d2)
3755: {
3756: int *v,*t1,*t2;
3757: int s,i,j,len;
3758: int **matrix;
3759: static int *w;
3760: static int nvar = 0;
3761:
3762: if ( nvar != n ) {
3763: nvar = n; w = (int *)MALLOC(n*sizeof(int));
3764: }
3765: for ( i = 0, t1 = d1->d, t2 = d2->d; i < n; i++ )
3766: w[i] = t1[i]-t2[i];
3767: len = nd_sba_modord->row;
3768: matrix = nd_sba_modord->matrix;
3769: for ( j = 0; j < len; j++ ) {
3770: v = matrix[j];
3771: for ( i = 0, s = 0; i < n; i++ )
3772: s += v[i]*w[i];
3773: if ( s > 0 )
3774: return 1;
3775: else if ( s < 0 )
3776: return -1;
3777: }
3778: return 0;
3779: }
3780:
3781: struct comp_sig_spec *create_comp_sig_spec(VL current_vl,VL old_vl,Obj ord,Obj weight)
3782: {
3783: struct comp_sig_spec *spec;
3784: VL ovl,vl;
3785: V ov;
3786: int i,j,n,nvar,s;
3787: NODE node,t,tn;
3788: struct order_pair *l;
3789: MAT m;
3790: Obj **b;
3791: int **w;
3792: int *a;
3793:
3794: spec = (struct comp_sig_spec *)MALLOC(sizeof(struct comp_sig_spec));
3795: for ( i = 0, vl = current_vl; vl; vl = NEXT(vl), i++ );
3796: spec->n = nvar = i;
3797: if ( old_vl != 0 ) {
3798: spec->oldv = (int *)MALLOC(nvar*sizeof(int));
3799: for ( i = 0, ovl = old_vl; i < nvar; ovl = NEXT(ovl), i++ ) {
3800: ov = ovl->v;
3801: for ( j = 0, vl = current_vl; vl; vl = NEXT(vl), j++ )
3802: if ( ov == vl->v ) break;
3803: spec->oldv[i] = j;
3804: }
3805: } else
3806: spec->oldv = 0;
3807: if ( !ord || NUM(ord) ) {
3808: switch ( ZTOS((Z)ord) ) {
3809: case 0:
3810: spec->cmpdl = cmpdl_revgradlex; break;
3811: case 1:
3812: spec->cmpdl = cmpdl_gradlex; break;
3813: case 2:
3814: spec->cmpdl = cmpdl_lex; break;
3815: default:
3816: error("create_comp_sig_spec : invalid spec"); break;
3817: }
3818: } else if ( OID(ord) == O_LIST ) {
3819: node = BDY((LIST)ord);
3820: for ( n = 0, t = node; t; t = NEXT(t), n++ );
3821: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
3822: for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {
3823: tn = BDY((LIST)BDY(t)); l[i].order = ZTOS((Q)BDY(tn));
3824: tn = NEXT(tn); l[i].length = ZTOS((Q)BDY(tn));
3825: s += l[i].length;
3826: }
3827: if ( s != nvar )
3828: error("create_comp_sig_spec : invalid spec");
3829: spec->order_pair = l;
3830: spec->block_length = n;
3831: spec->cmpdl = sig_cmpdl_op;
3832: } else if ( OID(ord) == O_MAT ) {
3833: m = (MAT)ord; b = (Obj **)BDY(m);
3834: if ( m->col != nvar )
3835: error("create_comp_sig_spec : invalid spec");
3836: w = almat(m->row,m->col);
3837: for ( i = 0; i < m->row; i++ )
3838: for ( j = 0; j < m->col; j++ )
3839: w[i][j] = ZTOS((Q)b[i][j]);
3840: spec->row = m->row;
3841: spec->matrix = w;
3842: spec->cmpdl = sig_cmpdl_mat;
3843: } else
3844: error("create_comp_sig_spec : invalid spec");
3845: if ( weight != 0 ) {
3846: node = BDY((LIST)weight);
3847: a = (int *)MALLOC(nvar*sizeof(int));
3848: for ( i = 0; i < nvar; i++, node = NEXT(node) )
3849: a[i] = ZTOS((Z)BDY(node));
3850: spec->weight = a;
3851: }
3852: return spec;
3853: }
3854:
3855: #define SIG_MUL_WEIGHT(a,i) (weight?(a)*weight[i]:(a))
3856:
3857: int comp_sig_monomial(int n,DL d1,DL d2)
3858: {
3859: static DL m1,m2;
3860: static int nvar = 0;
3861: int *oldv,*weight;
3862: int i,w1,w2;
3863:
3864: if ( nvar != n ) {
3865: nvar = n; NEWDL(m1,nvar); NEWDL(m2,nvar);
3866: }
3867: if ( !nd_sba_modord )
3868: return (*cmpdl)(n,d1,d2);
3869: else {
3870: weight = nd_sba_modord->weight;
3871: oldv = nd_sba_modord->oldv;
3872: if ( oldv ) {
3873: for ( i = 0; i < n; i++ ) {
3874: m1->d[i] = d1->d[oldv[i]]; m2->d[i] = d2->d[oldv[i]];
3875: }
3876: } else {
3877: for ( i = 0; i < n; i++ ) {
3878: m1->d[i] = d1->d[i]; m2->d[i] = d2->d[i];
3879: }
3880: }
3881: for ( i = 0, w1 = w2 = 0; i < n; i++ ) {
3882: w1 += SIG_MUL_WEIGHT(m1->d[i],i);
3883: w2 += SIG_MUL_WEIGHT(m2->d[i],i);
3884: }
3885: m1->td = w1; m2->td = w2;
3886: return (*nd_sba_modord->cmpdl)(n,m1,m2);
3887: }
3888: }
3889:
1.24 noro 3890: int comp_sig(SIG s1,SIG s2)
3891: {
1.38 noro 3892: if ( nd_sba_pot ) {
3893: if ( s1->pos > s2->pos ) return 1;
3894: else if ( s1->pos < s2->pos ) return -1;
1.46 noro 3895: else return comp_sig_monomial(nd_nvar,s1->dl,s2->dl);
1.38 noro 3896: } else {
3897: static DL m1,m2;
1.44 noro 3898: static int nvar = 0;
1.38 noro 3899: int ret;
3900:
3901: if ( nvar != nd_nvar ) {
3902: nvar = nd_nvar; NEWDL(m1,nvar); NEWDL(m2,nvar);
3903: }
3904: _adddl(nd_nvar,s1->dl,nd_sba_hm[s1->pos],m1);
3905: _adddl(nd_nvar,s2->dl,nd_sba_hm[s2->pos],m2);
1.47 noro 3906: if ( !nd_sba_modord )
3907: ret = (*cmpdl)(nd_nvar,m1,m2);
3908: else
3909: ret = comp_sig_monomial(nd_nvar,m1,m2);
1.38 noro 3910: if ( ret != 0 ) return ret;
3911: else if ( s1->pos > s2->pos ) return 1;
3912: else if ( s1->pos < s2->pos ) return -1;
3913: else return 0;
1.24 noro 3914: }
3915: }
3916:
3917: int _create_spair_s(int i1,int i2,ND_pairs sp,SIG sig1,SIG sig2)
3918: {
3919: int ret,s1,s2;
3920: RHist p1,p2;
3921: static int wpd;
3922: static UINT *lcm;
3923:
3924: sp->i1 = i1;
3925: sp->i2 = i2;
3926: p1 = nd_psh[i1];
3927: p2 = nd_psh[i2];
3928: ndl_lcm(DL(p1),DL(p2),sp->lcm);
1.49 ! noro 3929: #if 0
1.24 noro 3930: s1 = SG(p1)-TD(DL(p1));
3931: s2 = SG(p2)-TD(DL(p2));
3932: SG(sp) = MAX(s1,s2) + TD(sp->lcm);
1.49 ! noro 3933: #endif
1.24 noro 3934:
1.26 noro 3935: if ( wpd != nd_wpd ) {
1.24 noro 3936: wpd = nd_wpd;
3937: lcm = (UINT *)MALLOC(wpd*sizeof(UINT));
3938: }
3939: // DL(sig1) <- sp->lcm
3940: // DL(sig1) -= DL(p1)
3941: // DL(sig1) += DL(p1->sig)
1.27 noro 3942: ndl_sub(sp->lcm,DL(p1),lcm);
1.24 noro 3943: _ndltodl(lcm,DL(sig1));
3944: _addtodl(nd_nvar,DL(p1->sig),DL(sig1));
3945: sig1->pos = p1->sig->pos;
3946:
3947: // DL(sig2) <- sp->lcm
3948: // DL(sig2) -= DL(p2)
3949: // DL(sig2) += DL(p2->sig)
1.27 noro 3950: ndl_sub(sp->lcm,DL(p2),lcm);
1.24 noro 3951: _ndltodl(lcm,DL(sig2));
3952: _addtodl(nd_nvar,DL(p2->sig),DL(sig2));
3953: sig2->pos = p2->sig->pos;
3954:
3955: ret = comp_sig(sig1,sig2);
3956: if ( ret == 0 ) return 0;
3957: else if ( ret > 0 ) sp->sig = sig1;
3958: else sp->sig = sig2;
1.49 ! noro 3959:
! 3960: s1 = DL(sig1)->td+nd_sba_hm[p1->sig->pos]->td;
! 3961: s2 = DL(sig2)->td+nd_sba_hm[p2->sig->pos]->td;
! 3962: SG(sp) = MAX(s1,s2);
! 3963:
1.24 noro 3964: return 1;
3965: }
3966:
3967: SIG dup_sig(SIG sig)
3968: {
3969: SIG r;
3970:
3971: if ( !sig ) return 0;
3972: else {
3973: NEWSIG(r);
3974: _copydl(nd_nvar,DL(sig),DL(r));
3975: r->pos = sig->pos;
3976: return r;
3977: }
3978: }
3979:
3980: void dup_ND_pairs(ND_pairs to,ND_pairs from)
3981: {
3982: to->i1 = from->i1;
3983: to->i2 = from->i2;
3984: to->sugar = from->sugar;
3985: to->sugar2 = from->sugar2;
3986: ndl_copy(from->lcm,to->lcm);
3987: to->sig = dup_sig(from->sig);
3988: }
3989:
3990: ND_pairs merge_pairs_s(ND_pairs p1,ND_pairs p2)
3991: {
3992: struct oND_pairs root;
3993: ND_pairs q1,q2,r0,r;
3994: int ret;
3995:
3996: r = &root;
3997: for ( q1 = p1, q2 = p2; q1 != 0 && q2 != 0; ) {
3998: ret = comp_sig(q1->sig,q2->sig);
3999: if ( ret < 0 ) {
4000: r->next = q1; r = q1; q1 = q1->next;
4001: } else if ( ret > 0 ) {
4002: r->next = q2; r = q2; q2 = q2->next;
4003: } else {
1.47 noro 4004: Nnewpair--;
1.24 noro 4005: ret = DL_COMPARE(q1->lcm,q2->lcm);
1.35 noro 4006: Nsamesig++;
1.24 noro 4007: if ( ret < 0 ) {
4008: r->next = q1; r = q1; q1 = q1->next;
4009: q2 = q2->next;
4010: } else {
4011: r->next = q2; r = q2; q2 = q2->next;
4012: q1 = q1->next;
4013: }
4014: }
4015: }
4016: if ( q1 ) {
4017: r->next = q1;
4018: } else {
4019: r->next = q2;
4020: }
4021: return root.next;
4022: }
4023:
4024: ND_pairs insert_pair_s(ND_pairs l,ND_pairs s)
4025: {
4026: ND_pairs p,prev;
1.47 noro 4027: int ret=1;
1.24 noro 4028:
4029: for ( p = l, prev = 0; p != 0; prev = p, p = p->next ) {
4030: if ( (ret = comp_sig(s->sig,p->sig)) <= 0 )
4031: break;
4032: }
4033: if ( ret == 0 ) {
4034: ret = DL_COMPARE(s->lcm,p->lcm);
4035: if ( ret < 0 ) {
4036: // replace p with s
4037: s->next = p->next;
4038: if ( prev == 0 ) {
4039: return s;
4040: } else {
4041: prev->next = s;
4042: return l;
4043: }
4044: } else
4045: return l;
4046: } else {
4047: // insert s between prev and p
1.47 noro 4048: Nnewpair++;
1.24 noro 4049: s->next = p;
4050: if ( prev == 0 ) {
4051: return s;
4052: } else {
4053: prev->next = s;
4054: return l;
4055: }
4056: }
4057: }
4058:
1.29 noro 4059: INLINE int __dl_redble(DL d1,DL d2,int nvar)
4060: {
4061: int i;
4062:
4063: if ( d1->td > d2->td )
4064: return 0;
4065: for ( i = nvar-1; i >= 0; i-- )
4066: if ( d1->d[i] > d2->d[i] )
4067: break;
4068: if ( i >= 0 )
4069: return 0;
4070: else
4071: return 1;
4072: }
4073:
1.30 noro 4074: ND_pairs nd_newpairs_s(int t, NODE *syz)
1.24 noro 4075: {
4076: NODE h,s;
4077: UINT *dl;
1.27 noro 4078: int ts,ret,i;
1.24 noro 4079: ND_pairs r,r0,_sp,sp;
1.29 noro 4080: SIG spsig,tsig;
1.44 noro 4081: static int nvar = 0;
1.29 noro 4082: static SIG _sig1,_sig2;
1.26 noro 4083: struct oEGT eg1,eg2,eg3,eg4;
1.24 noro 4084:
4085: NEWND_pairs(_sp);
1.29 noro 4086: if ( !_sig1 || nvar != nd_nvar ) {
4087: nvar = nd_nvar; NEWSIG(_sig1); NEWSIG(_sig2);
4088: }
1.24 noro 4089: r0 = 0;
1.27 noro 4090: for ( i = 0; i < t; i++ ) {
4091: ret = _create_spair_s(i,t,_sp,_sig1,_sig2);
1.24 noro 4092: if ( ret ) {
4093: spsig = _sp->sig;
1.29 noro 4094: for ( s = syz[spsig->pos]; s; s = s->next ) {
1.24 noro 4095: tsig = (SIG)s->body;
1.29 noro 4096: if ( _dl_redble(DL(tsig),DL(spsig),nd_nvar) )
1.24 noro 4097: break;
4098: }
4099: if ( s == 0 ) {
4100: NEWND_pairs(sp);
4101: dup_ND_pairs(sp,_sp);
4102: r0 = insert_pair_s(r0,sp);
1.26 noro 4103: } else
4104: Nsyz++;
1.24 noro 4105: }
4106: }
4107: return r0;
4108: }
4109:
1.47 noro 4110: ND_pairs *nd_newpairs_array_s(int t, NODE *syz)
4111: {
4112: NODE h,s;
4113: UINT *dl;
4114: int ts,ret,i;
4115: ND_pairs r,r0,_sp,sp;
4116: ND_pairs *d;
4117: SIG spsig,tsig;
4118: static int nvar = 0;
4119: static SIG _sig1,_sig2;
4120: struct oEGT eg1,eg2,eg3,eg4;
4121:
4122: NEWND_pairs(_sp);
4123: if ( !_sig1 || nvar != nd_nvar ) {
4124: nvar = nd_nvar; NEWSIG(_sig1); NEWSIG(_sig2);
4125: }
4126: d = (ND_pairs *)MALLOC(nd_nbase*sizeof(ND_pairs));
4127: Nnewpair = 0;
4128: for ( i = 0; i < t; i++ ) {
4129: ret = _create_spair_s(i,t,_sp,_sig1,_sig2);
4130: if ( ret ) {
4131: spsig = _sp->sig;
4132: for ( s = syz[spsig->pos]; s; s = s->next ) {
4133: tsig = (SIG)s->body;
4134: if ( _dl_redble(DL(tsig),DL(spsig),nd_nvar) )
4135: break;
4136: }
4137: if ( s == 0 ) {
4138: NEWND_pairs(sp);
4139: dup_ND_pairs(sp,_sp);
4140: d[spsig->pos] = insert_pair_s(d[spsig->pos],sp);
4141: } else
4142: Nsyz++;
4143: }
4144: }
4145: return d;
4146: }
4147:
1.1 noro 4148: /* ipair = [i1,i2],[i1,i2],... */
4149: ND_pairs nd_ipairtospair(NODE ipair)
4150: {
4151: int s1,s2;
4152: NODE tn,t;
4153: ND_pairs r,r0;
4154:
4155: for ( r0 = 0, t = ipair; t; t = NEXT(t) ) {
4156: NEXTND_pairs(r0,r);
4157: tn = BDY((LIST)BDY(t));
1.6 noro 4158: r->i1 = ZTOS((Q)ARG0(tn));
4159: r->i2 = ZTOS((Q)ARG1(tn));
1.1 noro 4160: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
4161: s1 = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
4162: s2 = SG(nd_psh[r->i2])-TD(DL(nd_psh[r->i2]));
4163: SG(r) = MAX(s1,s2) + TD(LCM(r));
4164: /* experimental */
4165: if ( nd_sugarweight )
4166: r->sugar2 = ndl_weight2(r->lcm);
4167: }
4168: if ( r0 ) NEXT(r) = 0;
4169: return r0;
4170: }
4171:
4172: /* kokokara */
4173:
4174: ND_pairs crit_B( ND_pairs d, int s )
4175: {
4176: ND_pairs cur,head,prev,remove;
4177: UINT *t,*tl,*lcm;
4178: int td,tdl;
4179:
4180: if ( !d ) return 0;
4181: t = DL(nd_psh[s]);
4182: prev = 0;
4183: head = cur = d;
4184: lcm = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
4185: while ( cur ) {
4186: tl = cur->lcm;
4187: if ( ndl_reducible(tl,t) ) {
4188: ndl_lcm(DL(nd_psh[cur->i1]),t,lcm);
4189: if ( !ndl_equal(lcm,tl) ) {
4190: ndl_lcm(DL(nd_psh[cur->i2]),t,lcm);
4191: if (!ndl_equal(lcm,tl)) {
4192: remove = cur;
4193: if ( !prev ) {
4194: head = cur = NEXT(cur);
4195: } else {
4196: cur = NEXT(prev) = NEXT(cur);
4197: }
1.41 noro 4198: FREENDP(remove); NcriB++;
1.1 noro 4199: } else {
4200: prev = cur; cur = NEXT(cur);
4201: }
4202: } else {
4203: prev = cur; cur = NEXT(cur);
4204: }
4205: } else {
4206: prev = cur; cur = NEXT(cur);
4207: }
4208: }
4209: return head;
4210: }
4211:
4212: ND_pairs crit_M( ND_pairs d1 )
4213: {
4214: ND_pairs e,d2,d3,dd,p;
4215: UINT *id,*jd;
4216:
4217: if ( !d1 ) return d1;
4218: for ( dd = 0, e = d1; e; e = d3 ) {
4219: if ( !(d2 = NEXT(e)) ) {
4220: NEXT(e) = dd;
4221: return e;
4222: }
4223: id = LCM(e);
4224: for ( d3 = 0; d2; d2 = p ) {
4225: p = NEXT(d2);
4226: jd = LCM(d2);
4227: if ( ndl_equal(jd,id) )
4228: ;
4229: else if ( TD(jd) > TD(id) )
4230: if ( ndl_reducible(jd,id) ) continue;
4231: else ;
4232: else if ( ndl_reducible(id,jd) ) goto delit;
4233: NEXT(d2) = d3;
4234: d3 = d2;
4235: }
4236: NEXT(e) = dd;
4237: dd = e;
4238: continue;
4239: /**/
4240: delit: NEXT(d2) = d3;
4241: d3 = d2;
4242: for ( ; p; p = d2 ) {
4243: d2 = NEXT(p);
4244: NEXT(p) = d3;
4245: d3 = p;
4246: }
4247: FREENDP(e);
4248: }
4249: return dd;
4250: }
4251:
4252: ND_pairs crit_F( ND_pairs d1 )
4253: {
4254: ND_pairs rest, head,remove;
4255: ND_pairs last, p, r, w;
4256: int s;
4257:
4258: if ( !d1 ) return d1;
4259: for ( head = last = 0, p = d1; NEXT(p); ) {
4260: r = w = equivalent_pairs(p,&rest);
4261: s = SG(r);
4262: w = NEXT(w);
4263: while ( w ) {
4264: if ( crit_2(w->i1,w->i2) ) {
4265: r = w;
4266: w = NEXT(w);
4267: while ( w ) {
4268: remove = w;
4269: w = NEXT(w);
4270: FREENDP(remove);
4271: }
4272: break;
4273: } else if ( SG(w) < s ) {
4274: FREENDP(r);
4275: r = w;
4276: s = SG(r);
4277: w = NEXT(w);
4278: } else {
4279: remove = w;
4280: w = NEXT(w);
4281: FREENDP(remove);
4282: }
4283: }
4284: if ( last ) NEXT(last) = r;
4285: else head = r;
4286: NEXT(last = r) = 0;
4287: p = rest;
4288: if ( !p ) return head;
4289: }
4290: if ( !last ) return p;
4291: NEXT(last) = p;
4292: return head;
4293: }
4294:
4295: int crit_2( int dp1, int dp2 )
4296: {
4297: return ndl_disjoint(DL(nd_psh[dp1]),DL(nd_psh[dp2]));
4298: }
4299:
4300: ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest )
4301: {
4302: ND_pairs w,p,r,s;
4303: UINT *d;
4304:
4305: w = d1;
4306: d = LCM(w);
4307: s = NEXT(w);
4308: NEXT(w) = 0;
4309: for ( r = 0; s; s = p ) {
4310: p = NEXT(s);
4311: if ( ndl_equal(d,LCM(s)) ) {
4312: NEXT(s) = w; w = s;
4313: } else {
4314: NEXT(s) = r; r = s;
4315: }
4316: }
4317: *prest = r;
4318: return w;
4319: }
4320:
4321: NODE update_base(NODE nd,int ndp)
4322: {
4323: UINT *dl, *dln;
4324: NODE last, p, head;
4325:
4326: dl = DL(nd_psh[ndp]);
4327: for ( head = last = 0, p = nd; p; ) {
4328: dln = DL(nd_psh[(long)BDY(p)]);
4329: if ( ndl_reducible( dln, dl ) ) {
4330: p = NEXT(p);
4331: if ( last ) NEXT(last) = p;
4332: } else {
4333: if ( !last ) head = p;
4334: p = NEXT(last = p);
4335: }
4336: }
4337: head = append_one(head,ndp);
4338: return head;
4339: }
4340:
4341: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest )
4342: {
4343: ND_pairs m,ml,p,l;
4344: UINT *lcm;
4345: int s,td,len,tlen,c,c1;
4346:
4347: if ( !(p = NEXT(m = d)) ) {
4348: *prest = p;
4349: NEXT(m) = 0;
4350: return m;
4351: }
4352: if ( !NoSugar ) {
4353: if ( nd_sugarweight ) {
4354: s = m->sugar2;
4355: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4356: if ( (p->sugar2 < s)
4357: || ((p->sugar2 == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
4358: ml = l; m = p; s = m->sugar2;
4359: }
4360: } else {
4361: s = SG(m);
4362: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4363: if ( (SG(p) < s)
4364: || ((SG(p) == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
4365: ml = l; m = p; s = SG(m);
4366: }
4367: }
4368: } else {
4369: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4370: if ( DL_COMPARE(LCM(p),LCM(m)) < 0 ) {
4371: ml = l; m = p; s = SG(m);
4372: }
4373: }
4374: if ( !ml ) *prest = NEXT(m);
4375: else {
4376: NEXT(ml) = NEXT(m);
4377: *prest = d;
4378: }
4379: NEXT(m) = 0;
4380: return m;
4381: }
4382:
4383: ND_pairs nd_minsugarp( ND_pairs d, ND_pairs *prest )
4384: {
4385: int msugar,i;
4386: ND_pairs t,dm0,dm,dr0,dr;
4387:
4388: if ( nd_sugarweight ) {
4389: for ( msugar = d->sugar2, t = NEXT(d); t; t = NEXT(t) )
4390: if ( t->sugar2 < msugar ) msugar = t->sugar2;
4391: dm0 = 0; dr0 = 0;
4392: for ( i = 0, t = d; t; t = NEXT(t) )
4393: if ( i < nd_f4_nsp && t->sugar2 == msugar ) {
4394: if ( dm0 ) NEXT(dm) = t;
4395: else dm0 = t;
4396: dm = t;
4397: i++;
4398: } else {
4399: if ( dr0 ) NEXT(dr) = t;
4400: else dr0 = t;
4401: dr = t;
4402: }
4403: } else {
4404: for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) )
4405: if ( SG(t) < msugar ) msugar = SG(t);
4406: dm0 = 0; dr0 = 0;
4407: for ( i = 0, t = d; t; t = NEXT(t) )
4408: if ( i < nd_f4_nsp && SG(t) == msugar ) {
4409: if ( dm0 ) NEXT(dm) = t;
4410: else dm0 = t;
4411: dm = t;
4412: i++;
4413: } else {
4414: if ( dr0 ) NEXT(dr) = t;
4415: else dr0 = t;
4416: dr = t;
4417: }
4418: }
4419: NEXT(dm) = 0;
4420: if ( dr0 ) NEXT(dr) = 0;
4421: *prest = dr0;
4422: return dm0;
4423: }
4424:
1.28 noro 4425: ND_pairs nd_minsugarp_s( ND_pairs d, ND_pairs *prest )
4426: {
4427: int msugar;
4428: ND_pairs t,last;
4429:
4430: for ( msugar = SG(d), t = d; t; t = NEXT(t) )
4431: if ( SG(t) == msugar ) last = t;
4432: *prest = last->next;
4433: last->next = 0;
4434: return d;
4435: }
4436:
1.1 noro 4437: int nd_tdeg(NDV c)
4438: {
4439: int wmax = 0;
4440: int i,len;
4441: NMV a;
4442:
4443: len = LEN(c);
4444: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
4445: wmax = MAX(TD(DL(a)),wmax);
4446: return wmax;
4447: }
4448:
1.24 noro 4449: int ndv_newps(int m,NDV a,NDV aq)
1.1 noro 4450: {
4451: int len;
4452: RHist r;
4453: NDV b;
4454: NODE tn;
4455: LIST l;
4456: Z iq;
4457:
4458: if ( nd_psn == nd_pslen ) {
4459: nd_pslen *= 2;
4460: nd_ps = (NDV *)REALLOC((char *)nd_ps,nd_pslen*sizeof(NDV));
4461: nd_ps_trace = (NDV *)REALLOC((char *)nd_ps_trace,nd_pslen*sizeof(NDV));
4462: nd_psh = (RHist *)REALLOC((char *)nd_psh,nd_pslen*sizeof(RHist));
4463: nd_bound = (UINT **)
4464: REALLOC((char *)nd_bound,nd_pslen*sizeof(UINT *));
4465: nd_ps_sym = (NDV *)REALLOC((char *)nd_ps_sym,nd_pslen*sizeof(NDV));
4466: nd_ps_trace_sym = (NDV *)REALLOC((char *)nd_ps_trace_sym,nd_pslen*sizeof(NDV));
4467: }
4468: NEWRHist(r); nd_psh[nd_psn] = r;
4469: nd_ps[nd_psn] = a;
4470: if ( aq ) {
4471: nd_ps_trace[nd_psn] = aq;
4472: if ( !m ) {
4473: register_hcf(aq);
4474: } else if ( m == -2 ) {
4475: /* do nothing */
4476: } else
4477: error("ndv_newps : invalud modulus");
4478: nd_bound[nd_psn] = ndv_compute_bound(aq);
4479: #if 1
4480: SG(r) = SG(aq);
4481: #else
4482: SG(r) = nd_tdeg(aq);
4483: #endif
4484: ndl_copy(HDL(aq),DL(r));
1.24 noro 4485: r->sig = dup_sig(aq->sig);
1.1 noro 4486: } else {
4487: if ( !m ) register_hcf(a);
4488: nd_bound[nd_psn] = ndv_compute_bound(a);
4489: #if 1
4490: SG(r) = SG(a);
4491: #else
4492: SG(r) = nd_tdeg(a);
4493: #endif
4494: ndl_copy(HDL(a),DL(r));
1.24 noro 4495: r->sig = dup_sig(a->sig);
1.1 noro 4496: }
4497: if ( nd_demand ) {
4498: if ( aq ) {
4499: ndv_save(nd_ps_trace[nd_psn],nd_psn);
4500: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
4501: nd_ps_trace_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
4502: nd_ps_trace[nd_psn] = 0;
4503: } else {
4504: ndv_save(nd_ps[nd_psn],nd_psn);
4505: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps[nd_psn]);
4506: nd_ps[nd_psn] = 0;
4507: }
4508: }
4509: if ( nd_gentrace ) {
4510: /* reverse the tracelist and append it to alltracelist */
4511: nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist);
1.6 noro 4512: STOZ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn);
1.1 noro 4513: MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0;
4514: }
4515: return nd_psn++;
4516: }
4517:
1.46 noro 4518: // find LM wrt the specified modord
4519: void ndv_lm_modord(NDV p,DL d)
1.45 noro 4520: {
4521: NMV m;
4522: DL tmp;
4523: int len,i,ret;
4524:
4525: NEWDL(tmp,nd_nvar);
4526: m = BDY(p); len = LEN(p);
1.46 noro 4527: _ndltodl(DL(m),d); // printdl(d); printf("->");
1.45 noro 4528: for ( i = 1, NMV_ADV(m); i < len; i++, NMV_ADV(m) ) {
4529: _ndltodl(DL(m),tmp);
1.46 noro 4530: ret = comp_sig_monomial(nd_nvar,tmp,d);
1.45 noro 4531: if ( ret > 0 ) _copydl(nd_nvar,tmp,d);
4532: }
1.46 noro 4533: // printdl(d); printf("\n");
1.45 noro 4534: }
4535:
1.1 noro 4536: /* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */
4537: /* return 1 if success, 0 if failure (HC(a mod p)) */
4538:
1.24 noro 4539: int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont,int sba)
1.1 noro 4540: {
1.6 noro 4541: int i,j,td,len,max;
4542: NODE s,s0,f0,tn;
4543: UINT *d;
4544: RHist r;
4545: NDVI w;
4546: NDV a,am;
4547: union oNDC hc;
4548: NODE node;
4549: P hcp;
4550: Z iq,jq;
4551: LIST l;
4552:
4553: nd_found = 0; nd_notfirst = 0; nd_create = 0;
4554: /* initialize the tracelist */
4555: nd_tracelist = 0;
4556:
4557: for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++;
4558: w = (NDVI)MALLOC(nd_psn*sizeof(struct oNDVI));
4559: for ( i = j = 0, s = f; s; s = NEXT(s), j++ )
4560: if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; }
4561: if ( !dont_sort ) {
4562: /* XXX heuristic */
1.26 noro 4563: if ( !sba && !nd_ord->id && (nd_ord->ord.simple<2) )
1.6 noro 4564: qsort(w,nd_psn,sizeof(struct oNDVI),
4565: (int (*)(const void *,const void *))ndvi_compare_rev);
4566: else
4567: qsort(w,nd_psn,sizeof(struct oNDVI),
4568: (int (*)(const void *,const void *))ndvi_compare);
4569: }
4570: nd_pslen = 2*nd_psn;
4571: nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4572: nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4573: nd_ps_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4574: nd_ps_trace_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4575: nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist));
4576: nd_bound = (UINT **)MALLOC(nd_pslen*sizeof(UINT *));
4577: nd_hcf = 0;
1.1 noro 4578:
1.6 noro 4579: if ( trace && nd_vc )
4580: makesubst(nd_vc,&nd_subst);
4581: else
4582: nd_subst = 0;
1.1 noro 4583:
1.6 noro 4584: if ( !nd_red )
4585: nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
4586: for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0;
4587: for ( i = 0; i < nd_psn; i++ ) {
4588: hc = HCU(w[i].p);
4589: if ( trace ) {
4590: if ( mod == -2 ) {
4591: /* over a large finite field */
4592: /* trace = small modulus */
4593: a = nd_ps_trace[i] = ndv_dup(-2,w[i].p);
4594: ndv_mod(-2,a);
4595: if ( !dont_removecont) ndv_removecont(-2,a);
4596: am = nd_ps[i] = ndv_dup(trace,w[i].p);
4597: ndv_mod(trace,am);
4598: if ( DL_COMPARE(HDL(am),HDL(a)) )
4599: return 0;
4600: ndv_removecont(trace,am);
4601: } else {
4602: a = nd_ps_trace[i] = ndv_dup(0,w[i].p);
4603: if ( !dont_removecont) ndv_removecont(0,a);
4604: register_hcf(a);
4605: am = nd_ps[i] = ndv_dup(mod,a);
4606: ndv_mod(mod,am);
4607: if ( DL_COMPARE(HDL(am),HDL(a)) )
4608: return 0;
4609: ndv_removecont(mod,am);
4610: }
4611: } else {
4612: a = nd_ps[i] = ndv_dup(mod,w[i].p);
4613: if ( mod || !dont_removecont ) ndv_removecont(mod,a);
4614: if ( !mod ) register_hcf(a);
1.1 noro 4615: }
1.6 noro 4616: if ( nd_gentrace ) {
4617: STOZ(i,iq); STOZ(w[i].i,jq); node = mknode(3,iq,jq,ONE);
4618: /* exact division */
1.1 noro 4619: if ( !dont_removecont )
1.6 noro 4620: ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a));
4621: MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l;
4622: }
4623: NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r));
4624: nd_bound[i] = ndv_compute_bound(a);
4625: nd_psh[i] = r;
4626: if ( nd_demand ) {
4627: if ( trace ) {
4628: ndv_save(nd_ps_trace[i],i);
4629: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
4630: nd_ps_trace_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
4631: nd_ps_trace[i] = 0;
4632: } else {
4633: ndv_save(nd_ps[i],i);
4634: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps[i]);
4635: nd_ps[i] = 0;
4636: }
1.1 noro 4637: }
1.6 noro 4638: }
1.24 noro 4639: if ( sba ) {
1.27 noro 4640: nd_sba_hm = (DL *)MALLOC(nd_psn*sizeof(DL));
1.24 noro 4641: // setup signatures
1.27 noro 4642: for ( i = 0; i < nd_psn; i++ ) {
4643: SIG sig;
1.24 noro 4644:
1.27 noro 4645: NEWSIG(sig); sig->pos = i;
4646: nd_ps[i]->sig = sig;
4647: if ( nd_demand ) nd_ps_sym[i]->sig = sig;
4648: nd_psh[i]->sig = sig;
4649: if ( trace ) {
4650: nd_ps_trace[i]->sig = sig;
4651: if ( nd_demand ) nd_ps_trace_sym[i]->sig = sig;
4652: }
4653: NEWDL(nd_sba_hm[i],nd_nvar);
1.46 noro 4654: if ( nd_sba_modord )
4655: ndv_lm_modord(nd_ps[i],nd_sba_hm[i]);
1.45 noro 4656: else
4657: _ndltodl(DL(nd_psh[i]),nd_sba_hm[i]);
1.27 noro 4658: }
1.29 noro 4659: nd_sba_pos = (NODE *)MALLOC(nd_psn*sizeof(NODE));
4660: for ( i = 0; i < nd_psn; i++ ) {
4661: j = nd_psh[i]->sig->pos;
4662: nd_sba_pos[j] = append_one(nd_sba_pos[j],i);
4663: }
1.24 noro 4664: }
1.6 noro 4665: if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0;
4666: return 1;
1.1 noro 4667: }
4668:
4669: struct order_spec *append_block(struct order_spec *spec,
4670: int nv,int nalg,int ord);
4671:
4672: extern VECT current_dl_weight_vector_obj;
4673: static VECT prev_weight_vector_obj;
4674:
4675: void preprocess_algcoef(VL vv,VL av,struct order_spec *ord,LIST f,
4676: struct order_spec **ord1p,LIST *f1p,NODE *alistp)
4677: {
4678: NODE alist,t,s,r0,r,arg;
4679: VL tv;
4680: P poly;
4681: DP d;
4682: Alg alpha,dp;
4683: DAlg inv,da,hc;
4684: MP m;
4685: int i,nvar,nalg,n;
4686: NumberField nf;
4687: LIST f1,f2;
4688: struct order_spec *current_spec;
4689: VECT obj,obj0;
4690: VECT tmp;
4691:
4692: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++);
4693: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++);
4694:
4695: for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) {
4696: NEXTNODE(alist,t); MKV(tv->v,poly);
4697: MKAlg(poly,alpha); BDY(t) = (pointer)alpha;
4698: tv->v = tv->v->priv;
4699: }
4700: NEXT(t) = 0;
4701:
4702: /* simplification, making polynomials monic */
4703: setfield_dalg(alist);
4704: obj_algtodalg((Obj)f,(Obj *)&f1);
4705: for ( t = BDY(f); t; t = NEXT(t) ) {
4706: initd(ord); ptod(vv,vv,(P)BDY(t),&d);
4707: hc = (DAlg)BDY(d)->c;
4708: if ( NID(hc) == N_DA ) {
4709: invdalg(hc,&inv);
4710: for ( m = BDY(d); m; m = NEXT(m) ) {
4711: muldalg(inv,(DAlg)m->c,&da); m->c = (Obj)da;
4712: }
4713: }
4714: initd(ord); dtop(vv,vv,d,(Obj *)&poly); BDY(f) = (pointer)poly;
4715: }
4716: obj_dalgtoalg((Obj)f1,(Obj *)&f);
4717:
4718: /* append alg vars to the var list */
4719: for ( tv = vv; NEXT(tv); tv = NEXT(tv) );
4720: NEXT(tv) = av;
4721:
4722: /* append a block to ord */
4723: *ord1p = append_block(ord,nvar,nalg,2);
4724:
4725: /* create generator list */
4726: nf = get_numberfield();
4727: for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) {
4728: MKAlg(nf->defpoly[i],dp);
4729: MKNODE(s,dp,t); t = s;
4730: }
4731: MKLIST(f1,t);
4732: *alistp = alist;
4733: algobjtorat((Obj)f1,(Obj *)f1p);
4734:
4735: /* creating a new weight vector */
4736: prev_weight_vector_obj = obj0 = current_dl_weight_vector_obj;
4737: n = nvar+nalg+1;
4738: MKVECT(obj,n);
4739: if ( obj0 && obj0->len == nvar )
4740: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = BDY(obj0)[i];
4741: else
4742: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = (pointer)ONE;
4743: for ( i = 0; i < nalg; i++ ) BDY(obj)[i+nvar] = 0;
4744: BDY(obj)[n-1] = (pointer)ONE;
4745: arg = mknode(1,obj);
4746: Pdp_set_weight(arg,&tmp);
4747: }
4748:
4749: NODE postprocess_algcoef(VL av,NODE alist,NODE r)
4750: {
4751: NODE s,t,u0,u;
4752: P p;
4753: VL tv;
4754: Obj obj;
4755: VECT tmp;
4756: NODE arg;
4757:
4758: u0 = 0;
4759: for ( t = r; t; t = NEXT(t) ) {
4760: p = (P)BDY(t);
4761: for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) {
4762: substr(CO,0,(Obj)p,tv->v,(Obj)BDY(s),&obj); p = (P)obj;
4763: }
4764: if ( OID(p) == O_P || (OID(p) == O_N && NID((Num)p) != N_A) ) {
4765: NEXTNODE(u0,u);
4766: BDY(u) = (pointer)p;
4767: }
4768: }
4769: arg = mknode(1,prev_weight_vector_obj);
4770: Pdp_set_weight(arg,&tmp);
4771:
4772: return u0;
4773: }
4774:
4775: void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
4776: {
4777: VL tv,fv,vv,vc,av;
4778: NODE fd,fd0,r,r0,t,x,s,xx,alist;
4779: int e,max,nvar,i;
4780: NDV b;
4781: int ishomo,nalg,mrank,trank,wmax,len;
4782: NMV a;
4783: Alg alpha,dp;
4784: P p,zp;
4785: Q dmy;
4786: LIST f1,f2,zpl;
4787: Obj obj;
4788: NumberField nf;
4789: struct order_spec *ord1;
4790: NODE tr,tl1,tl2,tl3,tl4,nzlist;
4791: LIST l1,l2,l3,l4,l5;
4792: int j;
4793: Z jq,bpe,last_nonzero;
4794: int *perm;
4795: EPOS oepos;
4796: int obpe,oadv,ompos,cbpe;
1.15 noro 4797: VECT hvect;
1.1 noro 4798:
1.41 noro 4799: NcriB = NcriMF = Ncri2 = 0;
1.1 noro 4800: nd_module = 0;
4801: if ( !m && Demand ) nd_demand = 1;
4802: else nd_demand = 0;
4803:
4804: if ( DP_Multiple )
4805: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
4806: #if 0
4807: ndv_alloc = 0;
4808: #endif
4809: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 4810: parse_nd_option(vv,current_option);
1.1 noro 4811: if ( m && nd_vc )
4812: error("nd_{gr,f4} : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
4813: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
4814: switch ( ord->id ) {
4815: case 1:
4816: if ( ord->nv != nvar )
4817: error("nd_{gr,f4} : invalid order specification");
4818: break;
4819: default:
4820: break;
4821: }
4822: nd_nalg = 0;
4823: av = 0;
4824: if ( !m ) {
4825: get_algtree((Obj)f,&av);
4826: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
4827: nd_ntrans = nvar;
4828: nd_nalg = nalg;
4829: /* #i -> t#i */
4830: if ( nalg ) {
4831: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
4832: ord = ord1;
4833: f = f1;
4834: }
4835: nvar += nalg;
4836: }
4837: nd_init_ord(ord);
4838: mrank = 0;
4839: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
4840: for ( tv = vv; tv; tv = NEXT(tv) ) {
4841: if ( nd_module ) {
1.16 noro 4842: if ( OID(BDY(t)) == O_DPM ) {
4843: e = dpm_getdeg((DPM)BDY(t),&trank);
4844: max = MAX(e,max);
4845: mrank = MAX(mrank,trank);
4846: } else {
4847: s = BDY((LIST)BDY(t));
4848: trank = length(s);
4849: mrank = MAX(mrank,trank);
4850: for ( ; s; s = NEXT(s) ) {
4851: e = getdeg(tv->v,(P)BDY(s));
4852: max = MAX(e,max);
4853: }
1.1 noro 4854: }
4855: } else {
1.43 noro 4856: if ( OID(BDY(t)) == O_DP ) {
4857: e = dp_getdeg((DP)BDY(t));
4858: max = MAX(e,max);
4859: } else {
4860: e = getdeg(tv->v,(P)BDY(t));
4861: max = MAX(e,max);
4862: }
1.1 noro 4863: }
4864: }
4865: nd_setup_parameters(nvar,nd_nzlist?0:max);
4866: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
4867: ishomo = 1;
4868: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
4869: if ( nd_module ) {
1.16 noro 4870: if ( OID(BDY(t)) == O_DPM ) {
4871: Z cont;
4872: DPM zdpm;
4873:
4874: if ( !m && !nd_gentrace ) dpm_ptozp((DPM)BDY(t),&cont,&zdpm);
4875: else zdpm = (DPM)BDY(t);
4876: b = (pointer)dpmtondv(m,zdpm);
4877: } else {
4878: if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
4879: else zpl = (LIST)BDY(t);
1.1 noro 4880: b = (pointer)pltondv(CO,vv,zpl);
1.16 noro 4881: }
1.1 noro 4882: } else {
1.43 noro 4883: if ( OID(BDY(t)) == O_DP ) {
4884: DP zdp;
4885:
4886: if ( !m && !nd_gentrace ) dp_ptozp((DP)BDY(t),&zdp);
4887: else zdp = (DP)BDY(t);
4888: b = (pointer)dptondv(m,zdp);
4889: } else {
4890: if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
4891: else zp = (P)BDY(t);
4892: b = (pointer)ptondv(CO,vv,zp);
4893: }
1.1 noro 4894: }
4895: if ( ishomo )
4896: ishomo = ishomo && ndv_ishomo(b);
4897: if ( m ) ndv_mod(m,b);
4898: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
4899: }
4900: if ( fd0 ) NEXT(fd) = 0;
4901:
4902: if ( !ishomo && homo ) {
4903: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
4904: b = (NDV)BDY(t); len = LEN(b);
4905: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
4906: wmax = MAX(TD(DL(a)),wmax);
4907: }
4908: homogenize_order(ord,nvar,&ord1);
4909: nd_init_ord(ord1);
4910: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
4911: for ( t = fd0; t; t = NEXT(t) )
4912: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
4913: }
4914:
1.24 noro 4915: ndv_setup(m,0,fd0,(nd_gbblock||nd_splist||nd_check_splist)?1:0,0,0);
1.1 noro 4916: if ( nd_gentrace ) {
4917: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
4918: }
4919: if ( nd_splist ) {
4920: *rp = compute_splist();
4921: return;
4922: }
4923: if ( nd_check_splist ) {
4924: if ( f4 ) {
4925: if ( check_splist_f4(m,nd_check_splist) ) *rp = (LIST)ONE;
4926: else *rp = 0;
4927: } else {
4928: if ( check_splist(m,nd_check_splist) ) *rp = (LIST)ONE;
4929: else *rp = 0;
4930: }
4931: return;
4932: }
4933: x = f4?nd_f4(m,0,&perm):nd_gb(m,ishomo || homo,0,0,&perm);
4934: if ( !x ) {
4935: *rp = 0; return;
4936: }
1.15 noro 4937: if ( nd_gentrace ) {
4938: MKVECT(hvect,nd_psn);
4939: for ( i = 0; i < nd_psn; i++ )
4940: ndltodp(nd_psh[i]->dl,(DP *)&BDY(hvect)[i]);
4941: }
1.1 noro 4942: if ( !ishomo && homo ) {
4943: /* dehomogenization */
4944: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
4945: nd_init_ord(ord);
4946: nd_setup_parameters(nvar,0);
4947: }
4948: nd_demand = 0;
4949: if ( nd_module && nd_intersect ) {
4950: for ( j = nd_psn-1, x = 0; j >= 0; j-- )
1.17 noro 4951: if ( MPOS(DL(nd_psh[j])) > nd_intersect ) {
1.1 noro 4952: MKNODE(xx,(pointer)((unsigned long)j),x); x = xx;
4953: }
4954: conv_ilist(nd_demand,0,x,0);
4955: goto FINAL;
4956: }
4957: if ( nd_gentrace && f4 ) { nzlist = nd_alltracelist; }
4958: x = ndv_reducebase(x,perm);
4959: if ( nd_gentrace && !f4 ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
4960: x = ndv_reduceall(m,x);
4961: cbpe = nd_bpe;
4962: if ( nd_gentrace && !f4 ) {
4963: tl2 = nd_alltracelist; nd_alltracelist = 0;
4964: ndv_check_membership(m,fd0,obpe,oadv,oepos,x);
4965: tl3 = nd_alltracelist; nd_alltracelist = 0;
4966: if ( nd_gensyz ) {
4967: nd_gb(m,0,1,1,0);
4968: tl4 = nd_alltracelist; nd_alltracelist = 0;
4969: } else tl4 = 0;
4970: }
4971: nd_bpe = cbpe;
4972: nd_setup_parameters(nd_nvar,0);
4973: FINAL:
4974: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
1.16 noro 4975: NEXTNODE(r0,r);
4976: if ( nd_module ) {
4977: if ( retdp ) BDY(r) = ndvtodpm(m,BDY(t));
4978: else BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank);
4979: } else if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
4980: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.1 noro 4981: }
4982: if ( r0 ) NEXT(r) = 0;
4983: if ( !m && nd_nalg )
4984: r0 = postprocess_algcoef(av,alist,r0);
4985: MKLIST(*rp,r0);
4986: if ( nd_gentrace ) {
4987: if ( f4 ) {
1.6 noro 4988: STOZ(16,bpe);
4989: STOZ(nd_last_nonzero,last_nonzero);
1.15 noro 4990: tr = mknode(6,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe,last_nonzero,hvect); MKLIST(*rp,tr);
1.1 noro 4991: } else {
4992: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
4993: tl3 = reverse_node(tl3);
4994: /* tl2 = [[i,[[*,j,*,*],...]],...] */
4995: for ( t = tl2; t; t = NEXT(t) ) {
4996: /* s = [i,[*,j,*,*],...] */
4997: s = BDY((LIST)BDY(t));
1.6 noro 4998: j = perm[ZTOS((Q)ARG0(s))]; STOZ(j,jq); ARG0(s) = (pointer)jq;
1.1 noro 4999: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.6 noro 5000: j = perm[ZTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOZ(j,jq);
1.1 noro 5001: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
5002: }
5003: }
5004: for ( j = length(x)-1, t = 0; j >= 0; j-- ) {
1.6 noro 5005: STOZ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.1 noro 5006: }
5007: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
5008: MKLIST(l5,tl4);
1.6 noro 5009: STOZ(nd_bpe,bpe);
1.15 noro 5010: tr = mknode(9,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe,hvect); MKLIST(*rp,tr);
1.1 noro 5011: }
5012: }
5013: #if 0
5014: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
5015: #endif
5016: }
5017:
1.28 noro 5018: NODE nd_sba_f4(int m,int **indp);
5019:
5020: void nd_sba(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
1.24 noro 5021: {
5022: VL tv,fv,vv,vc,av;
1.44 noro 5023: NODE fd,fd0,r,r0,t,x,s,xx,nd,syz;
1.24 noro 5024: int e,max,nvar,i;
5025: NDV b;
5026: int ishomo,nalg,wmax,len;
5027: NMV a;
5028: P p,zp;
5029: Q dmy;
5030: struct order_spec *ord1;
5031: int j;
5032: int *perm;
5033: EPOS oepos;
5034: int obpe,oadv,ompos,cbpe;
1.29 noro 5035: struct oEGT eg0,eg1,egconv;
1.24 noro 5036:
5037: nd_module = 0;
5038: nd_demand = 0;
1.35 noro 5039: Nsamesig = 0;
1.24 noro 5040: if ( DP_Multiple )
5041: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
5042: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5043: parse_nd_option(vv,current_option);
1.24 noro 5044: if ( m && nd_vc )
5045: error("nd_sba : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
5046: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5047: switch ( ord->id ) {
5048: case 1:
5049: if ( ord->nv != nvar )
5050: error("nd_sba : invalid order specification");
5051: break;
5052: default:
5053: break;
5054: }
5055: nd_nalg = 0;
5056: nd_init_ord(ord);
5057: // for SIG comparison
5058: initd(ord);
5059: for ( t = BDY(f), max = 1; t; t = NEXT(t) ) {
5060: for ( tv = vv; tv; tv = NEXT(tv) ) {
1.43 noro 5061: if ( OID(BDY(t)) == O_DP ) {
5062: e = dp_getdeg((DP)BDY(t));
5063: max = MAX(e,max);
5064: } else {
5065: e = getdeg(tv->v,(P)BDY(t));
5066: max = MAX(e,max);
5067: }
1.24 noro 5068: }
5069: }
1.25 noro 5070: nd_setup_parameters(nvar,max);
1.24 noro 5071: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
5072: ishomo = 1;
5073: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.43 noro 5074: if ( OID(BDY(t)) == O_DP ) {
5075: DP zdp;
5076:
5077: if ( !m ) dp_ptozp((DP)BDY(t),&zdp);
5078: else zdp = (DP)BDY(t);
5079: b = (pointer)dptondv(m,zdp);
5080: } else {
5081: if ( !m ) ptozp((P)BDY(t),1,&dmy,&zp);
5082: else zp = (P)BDY(t);
5083: b = (pointer)ptondv(CO,vv,zp);
5084: }
1.24 noro 5085: if ( ishomo )
5086: ishomo = ishomo && ndv_ishomo(b);
5087: if ( m ) ndv_mod(m,b);
5088: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
5089: }
5090: if ( fd0 ) NEXT(fd) = 0;
5091:
5092: if ( !ishomo && homo ) {
5093: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
5094: b = (NDV)BDY(t); len = LEN(b);
5095: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
5096: wmax = MAX(TD(DL(a)),wmax);
5097: }
5098: homogenize_order(ord,nvar,&ord1);
5099: nd_init_ord(ord1);
1.42 noro 5100: // for SIG comparison
5101: initd(ord1);
1.24 noro 5102: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
5103: for ( t = fd0; t; t = NEXT(t) )
5104: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
5105: }
5106:
1.39 noro 5107: ndv_setup(m,0,fd0,nd_sba_dontsort,0,1);
1.44 noro 5108: x = f4 ? nd_sba_f4(m,&perm) : nd_sba_buch(m,ishomo || homo,&perm,&syz);
1.24 noro 5109: if ( !x ) {
5110: *rp = 0; return;
5111: }
5112: if ( !ishomo && homo ) {
5113: /* dehomogenization */
5114: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5115: nd_init_ord(ord);
1.42 noro 5116: // for SIG comparison
5117: initd(ord);
1.24 noro 5118: nd_setup_parameters(nvar,0);
5119: }
5120: nd_demand = 0;
5121: x = ndv_reducebase(x,perm);
5122: x = ndv_reduceall(m,x);
5123: nd_setup_parameters(nd_nvar,0);
1.29 noro 5124: get_eg(&eg0);
1.24 noro 5125: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5126: NEXTNODE(r0,r);
5127: if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
1.34 noro 5128: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.24 noro 5129: }
5130: if ( r0 ) NEXT(r) = 0;
1.44 noro 5131: if ( nd_sba_syz ) {
5132: LIST gb,hsyz;
5133: NODE nd;
5134:
5135: MKLIST(gb,r0);
5136: MKLIST(hsyz,syz);
5137: nd = mknode(2,gb,hsyz);
5138: MKLIST(*rp,nd);
5139: } else
5140: MKLIST(*rp,r0);
1.29 noro 5141: get_eg(&eg1); init_eg(&egconv); add_eg(&egconv,&eg0,&eg1);
5142: print_eg("conv",&egconv); fprintf(asir_out,"\n");
1.24 noro 5143: }
5144:
1.1 noro 5145: void nd_gr_postproc(LIST f,LIST v,int m,struct order_spec *ord,int do_check,LIST *rp)
5146: {
5147: VL tv,fv,vv,vc,av;
5148: NODE fd,fd0,r,r0,t,x,s,xx,alist;
5149: int e,max,nvar,i;
5150: NDV b;
5151: int ishomo,nalg;
5152: Alg alpha,dp;
5153: P p,zp;
5154: Q dmy;
5155: LIST f1,f2;
5156: Obj obj;
5157: NumberField nf;
5158: struct order_spec *ord1;
5159: int *perm;
5160:
5161: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5162: parse_nd_option(vv,current_option);
1.1 noro 5163: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5164: switch ( ord->id ) {
5165: case 1:
5166: if ( ord->nv != nvar )
5167: error("nd_check : invalid order specification");
5168: break;
5169: default:
5170: break;
5171: }
5172: nd_nalg = 0;
5173: av = 0;
5174: if ( !m ) {
5175: get_algtree((Obj)f,&av);
5176: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
5177: nd_ntrans = nvar;
5178: nd_nalg = nalg;
5179: /* #i -> t#i */
5180: if ( nalg ) {
5181: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
5182: ord = ord1;
5183: f = f1;
5184: }
5185: nvar += nalg;
5186: }
5187: nd_init_ord(ord);
5188: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
5189: for ( tv = vv; tv; tv = NEXT(tv) ) {
5190: e = getdeg(tv->v,(P)BDY(t));
5191: max = MAX(e,max);
5192: }
5193: nd_setup_parameters(nvar,max);
5194: ishomo = 1;
5195: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
5196: ptozp((P)BDY(t),1,&dmy,&zp);
5197: b = (pointer)ptondv(CO,vv,zp);
5198: if ( ishomo )
5199: ishomo = ishomo && ndv_ishomo(b);
5200: if ( m ) ndv_mod(m,b);
5201: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
5202: }
5203: if ( fd0 ) NEXT(fd) = 0;
1.24 noro 5204: ndv_setup(m,0,fd0,0,1,0);
1.1 noro 5205: for ( x = 0, i = 0; i < nd_psn; i++ )
5206: x = update_base(x,i);
5207: if ( do_check ) {
5208: x = nd_gb(m,ishomo,1,0,&perm);
5209: if ( !x ) {
5210: *rp = 0;
5211: return;
5212: }
5213: } else {
5214: #if 0
5215: /* bug ? */
5216: for ( t = x; t; t = NEXT(t) )
5217: BDY(t) = (pointer)nd_ps[(long)BDY(t)];
5218: #else
5219: conv_ilist(0,0,x,&perm);
5220: #endif
5221: }
5222: x = ndv_reducebase(x,perm);
5223: x = ndv_reduceall(m,x);
5224: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5225: NEXTNODE(r0,r);
5226: BDY(r) = ndvtop(m,CO,vv,BDY(t));
5227: }
5228: if ( r0 ) NEXT(r) = 0;
5229: if ( !m && nd_nalg )
5230: r0 = postprocess_algcoef(av,alist,r0);
5231: MKLIST(*rp,r0);
5232: }
5233:
5234: NDV recompute_trace(NODE trace,NDV *p,int m);
5235: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp);
5236:
5237: NDV recompute_trace(NODE ti,NDV *p,int mod)
5238: {
5239: int c,c1,c2,i;
5240: NM mul,m,tail;
5241: ND d,r,rm;
5242: NODE sj;
5243: NDV red;
5244: Obj mj;
5245:
5246: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
5247: CM(mul) = 1;
5248: tail = 0;
5249: for ( i = 0, d = r = 0; ti; ti = NEXT(ti), i++ ) {
5250: sj = BDY((LIST)BDY(ti));
5251: if ( ARG0(sj) ) {
1.6 noro 5252: red = p[ZTOS((Q)ARG1(sj))];
1.1 noro 5253: mj = (Obj)ARG2(sj);
5254: if ( OID(mj) != O_DP ) ndl_zero(DL(mul));
5255: else dltondl(nd_nvar,BDY((DP)mj)->dl,DL(mul));
5256: rm = ndv_mul_nm(mod,mul,red);
5257: if ( !r ) r = rm;
5258: else {
5259: for ( m = BDY(r); m && !ndl_equal(m->dl,BDY(rm)->dl); m = NEXT(m), LEN(r)-- ) {
5260: if ( d ) {
5261: NEXT(tail) = m; tail = m; LEN(d)++;
5262: } else {
5263: MKND(nd_nvar,m,1,d); tail = BDY(d);
5264: }
5265: }
5266: if ( !m ) return 0; /* failure */
5267: else {
5268: BDY(r) = m;
5269: if ( mod > 0 || mod == -1 ) {
5270: c1 = invm(HCM(rm),mod); c2 = mod-HCM(r);
5271: DMAR(c1,c2,0,mod,c);
5272: nd_mul_c(mod,rm,c);
5273: } else {
5274: Z t,u;
5275:
5276: chsgnlf(HCZ(r),&t);
5277: divlf(t,HCZ(rm),&u);
5278: nd_mul_c_lf(rm,u);
5279: }
5280: r = nd_add(mod,r,rm);
5281: }
5282: }
5283: }
5284: }
5285: if ( tail ) NEXT(tail) = 0;
5286: d = nd_add(mod,d,r);
5287: nd_mul_c(mod,d,invm(HCM(d),mod));
5288: return ndtondv(mod,d);
5289: }
5290:
5291: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp)
5292: {
5293: VL tv,fv,vv,vc,av;
5294: NODE fd,fd0,r,r0,t,x,s,xx,alist;
5295: int e,max,nvar,i;
5296: NDV b;
5297: int ishomo,nalg;
5298: Alg alpha,dp;
5299: P p,zp;
5300: Q dmy;
5301: LIST f1,f2;
5302: Obj obj;
5303: NumberField nf;
5304: struct order_spec *ord1;
5305: NODE permtrace,intred,ind,perm,trace,ti;
5306: int len,n,j;
5307: NDV *db,*pb;
5308:
5309: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5310: parse_nd_option(vv,current_option);
1.1 noro 5311: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5312: switch ( ord->id ) {
5313: case 1:
5314: if ( ord->nv != nvar )
5315: error("nd_check : invalid order specification");
5316: break;
5317: default:
5318: break;
5319: }
5320: nd_init_ord(ord);
1.6 noro 5321: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 5322: nd_setup_parameters(nvar,0);
5323:
5324: len = length(BDY(f));
5325: db = (NDV *)MALLOC(len*sizeof(NDV *));
5326: for ( i = 0, t = BDY(f); t; i++, t = NEXT(t) ) {
5327: ptozp((P)BDY(t),1,&dmy,&zp);
5328: b = ptondv(CO,vv,zp);
5329: ndv_mod(m,b);
5330: ndv_mul_c(m,b,invm(HCM(b),m));
5331: db[i] = b;
5332: }
5333:
5334: permtrace = BDY((LIST)ARG2(BDY(tlist)));
5335: intred = BDY((LIST)ARG3(BDY(tlist)));
5336: ind = BDY((LIST)ARG4(BDY(tlist)));
5337: perm = BDY((LIST)ARG0(permtrace));
5338: trace = NEXT(permtrace);
5339:
5340: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 5341: j = ZTOS((Q)ARG0(BDY((LIST)BDY(t))));
1.1 noro 5342: if ( j > i ) i = j;
5343: }
5344: n = i+1;
5345: pb = (NDV *)MALLOC(n*sizeof(NDV *));
5346: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
5347: ti = BDY((LIST)BDY(t));
1.6 noro 5348: pb[ZTOS((Q)ARG0(ti))] = db[ZTOS((Q)ARG1(ti))];
1.1 noro 5349: }
5350: for ( t = trace; t; t = NEXT(t) ) {
5351: ti = BDY((LIST)BDY(t));
1.6 noro 5352: pb[ZTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
5353: if ( !pb[ZTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
1.1 noro 5354: if ( DP_Print ) {
5355: fprintf(asir_out,"."); fflush(asir_out);
5356: }
5357: }
5358: for ( t = intred; t; t = NEXT(t) ) {
5359: ti = BDY((LIST)BDY(t));
1.6 noro 5360: pb[ZTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
5361: if ( !pb[ZTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
1.1 noro 5362: if ( DP_Print ) {
5363: fprintf(asir_out,"*"); fflush(asir_out);
5364: }
5365: }
5366: for ( r0 = 0, t = ind; t; t = NEXT(t) ) {
5367: NEXTNODE(r0,r);
1.6 noro 5368: b = pb[ZTOS((Q)BDY(t))];
1.1 noro 5369: ndv_mul_c(m,b,invm(HCM(b),m));
5370: #if 0
1.6 noro 5371: BDY(r) = ndvtop(m,CO,vv,pb[ZTOS((Q)BDY(t))]);
1.1 noro 5372: #else
1.6 noro 5373: BDY(r) = ndvtodp(m,pb[ZTOS((Q)BDY(t))]);
1.1 noro 5374: #endif
5375: }
5376: if ( r0 ) NEXT(r) = 0;
5377: MKLIST(*rp,r0);
5378: if ( DP_Print ) fprintf(asir_out,"\n");
5379: }
5380:
1.16 noro 5381: 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 5382: {
5383: VL tv,fv,vv,vc,av;
5384: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
5385: int m,nocheck,nvar,mindex,e,max;
5386: NDV c;
5387: NMV a;
5388: P p,zp;
5389: Q dmy;
5390: EPOS oepos;
5391: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
5392: Alg alpha,dp;
5393: P poly;
5394: LIST f1,f2,zpl;
5395: Obj obj;
5396: NumberField nf;
5397: struct order_spec *ord1;
5398: struct oEGT eg_check,eg0,eg1;
5399: NODE tr,tl1,tl2,tl3,tl4;
5400: LIST l1,l2,l3,l4,l5;
5401: int *perm;
5402: int j,ret;
5403: Z jq,bpe;
1.15 noro 5404: VECT hvect;
1.1 noro 5405:
1.41 noro 5406: NcriB = NcriMF = Ncri2 = 0;
1.1 noro 5407: nd_module = 0;
5408: nd_lf = 0;
1.46 noro 5409: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
5410: parse_nd_option(vv,current_option);
1.1 noro 5411: if ( nd_lf ) {
5412: if ( f4 )
5413: nd_f4_lf_trace(f,v,trace,homo,ord,rp);
5414: else
5415: error("nd_gr_trace is not implemented yet over a large finite field");
5416: return;
5417: }
5418: if ( DP_Multiple )
5419: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
5420:
5421: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5422: switch ( ord->id ) {
5423: case 1:
5424: if ( ord->nv != nvar )
5425: error("nd_gr_trace : invalid order specification");
5426: break;
5427: default:
5428: break;
5429: }
5430:
5431: get_algtree((Obj)f,&av);
5432: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
5433: nd_ntrans = nvar;
5434: nd_nalg = nalg;
5435: /* #i -> t#i */
5436: if ( nalg ) {
5437: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
5438: ord = ord1;
5439: f = f1;
5440: }
5441: nvar += nalg;
5442:
5443: nocheck = 0;
5444: mindex = 0;
5445:
5446: if ( Demand ) nd_demand = 1;
5447: else nd_demand = 0;
5448:
5449: /* setup modulus */
5450: if ( trace < 0 ) {
5451: trace = -trace;
5452: nocheck = 1;
5453: }
5454: m = trace > 1 ? trace : get_lprime(mindex);
5455: nd_init_ord(ord);
5456: mrank = 0;
5457: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
5458: for ( tv = vv; tv; tv = NEXT(tv) ) {
5459: if ( nd_module ) {
1.16 noro 5460: if ( OID(BDY(t)) == O_DPM ) {
5461: e = dpm_getdeg((DPM)BDY(t),&trank);
5462: max = MAX(e,max);
5463: mrank = MAX(mrank,trank);
5464: } else {
1.1 noro 5465: s = BDY((LIST)BDY(t));
5466: trank = length(s);
5467: mrank = MAX(mrank,trank);
5468: for ( ; s; s = NEXT(s) ) {
5469: e = getdeg(tv->v,(P)BDY(s));
5470: max = MAX(e,max);
5471: }
1.16 noro 5472: }
1.1 noro 5473: } else {
1.43 noro 5474: if ( OID(BDY(t)) == O_DP ) {
5475: e = dp_getdeg((DP)BDY(t));
5476: max = MAX(e,max);
5477: } else {
1.1 noro 5478: e = getdeg(tv->v,(P)BDY(t));
5479: max = MAX(e,max);
1.43 noro 5480: }
1.1 noro 5481: }
5482: }
5483: nd_setup_parameters(nvar,max);
5484: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
5485: ishomo = 1;
5486: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
5487: if ( nd_module ) {
1.16 noro 5488: if ( OID(BDY(t)) == O_DPM ) {
5489: Z cont;
5490: DPM zdpm;
5491:
1.17 noro 5492: if ( !nd_gentrace ) dpm_ptozp((DPM)BDY(t),&cont,&zdpm);
1.16 noro 5493: else zdpm = (DPM)BDY(t);
5494: c = (pointer)dpmtondv(m,zdpm);
5495: } else {
5496: if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
5497: else zpl = (LIST)BDY(t);
1.1 noro 5498: c = (pointer)pltondv(CO,vv,zpl);
1.16 noro 5499: }
1.1 noro 5500: } else {
1.43 noro 5501: if ( OID(BDY(t)) == O_DP ) {
5502: DP zdp;
5503:
5504: if ( !nd_gentrace ) dp_ptozp((DP)BDY(t),&zdp);
5505: else zdp = (DP)BDY(t);
5506: c = (pointer)dptondv(m,zdp);
5507: } else {
5508: if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
5509: else zp = (P)BDY(t);
5510: c = (pointer)ptondv(CO,vv,zp);
5511: }
1.1 noro 5512: }
5513: if ( ishomo )
5514: ishomo = ishomo && ndv_ishomo(c);
5515: if ( c ) {
5516: NEXTNODE(in0,in); BDY(in) = (pointer)c;
5517: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
5518: }
5519: }
5520: if ( in0 ) NEXT(in) = 0;
5521: if ( fd0 ) NEXT(fd) = 0;
5522: if ( !ishomo && homo ) {
5523: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
5524: c = (NDV)BDY(t); len = LEN(c);
5525: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
5526: wmax = MAX(TD(DL(a)),wmax);
5527: }
5528: homogenize_order(ord,nvar,&ord1);
5529: nd_init_ord(ord1);
5530: nd_setup_parameters(nvar+1,wmax);
5531: for ( t = fd0; t; t = NEXT(t) )
5532: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
5533: }
5534: if ( MaxDeg > 0 ) nocheck = 1;
5535: while ( 1 ) {
5536: tl1 = tl2 = tl3 = tl4 = 0;
5537: if ( Demand )
5538: nd_demand = 1;
1.24 noro 5539: ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0,0);
1.1 noro 5540: if ( nd_gentrace ) {
5541: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
5542: }
5543: if ( ret )
5544: cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm);
5545: if ( !ret || !cand ) {
5546: /* failure */
5547: if ( trace > 1 ) { *rp = 0; return; }
5548: else m = get_lprime(++mindex);
5549: continue;
5550: }
1.15 noro 5551: if ( nd_gentrace ) {
5552: MKVECT(hvect,nd_psn);
5553: for ( i = 0; i < nd_psn; i++ )
5554: ndltodp(nd_psh[i]->dl,(DP *)&BDY(hvect)[i]);
5555: }
1.1 noro 5556: if ( !ishomo && homo ) {
5557: /* dehomogenization */
5558: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5559: nd_init_ord(ord);
5560: nd_setup_parameters(nvar,0);
5561: }
5562: nd_demand = 0;
5563: cand = ndv_reducebase(cand,perm);
5564: if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
5565: cand = ndv_reduceall(0,cand);
5566: cbpe = nd_bpe;
5567: if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; }
5568: get_eg(&eg0);
5569: if ( nocheck )
5570: break;
5571: if ( (ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand)) != 0 ) {
5572: if ( nd_gentrace ) {
5573: tl3 = nd_alltracelist; nd_alltracelist = 0;
5574: } else tl3 = 0;
5575: /* gbcheck : cand is a GB of Id(cand) ? */
5576: if ( nd_vc || nd_gentrace || nd_gensyz )
5577: ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0;
5578: else
5579: ret = nd_f4(0,1,0)!=0;
5580: if ( nd_gentrace && nd_gensyz ) {
5581: tl4 = nd_alltracelist; nd_alltracelist = 0;
5582: } else tl4 = 0;
5583: }
5584: if ( ret ) break;
5585: else if ( trace > 1 ) {
5586: /* failure */
5587: *rp = 0; return;
5588: } else {
5589: /* try the next modulus */
5590: m = get_lprime(++mindex);
5591: /* reset the parameters */
5592: if ( !ishomo && homo ) {
5593: nd_init_ord(ord1);
5594: nd_setup_parameters(nvar+1,wmax);
5595: } else {
5596: nd_init_ord(ord);
5597: nd_setup_parameters(nvar,max);
5598: }
5599: }
5600: }
5601: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
5602: if ( DP_Print )
1.6 noro 5603: fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime);
1.1 noro 5604: /* dp->p */
5605: nd_bpe = cbpe;
5606: nd_setup_parameters(nd_nvar,0);
5607: for ( r = cand; r; r = NEXT(r) ) {
1.16 noro 5608: if ( nd_module ) {
1.17 noro 5609: if ( retdp ) BDY(r) = ndvtodpm(0,BDY(r));
1.16 noro 5610: else BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank);
1.17 noro 5611: } else if ( retdp ) BDY(r) = ndvtodp(0,BDY(r));
5612: else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r));
1.1 noro 5613: }
5614: if ( nd_nalg )
5615: cand = postprocess_algcoef(av,alist,cand);
5616: MKLIST(*rp,cand);
5617: if ( nd_gentrace ) {
5618: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
5619: tl3 = reverse_node(tl3);
5620: /* tl2 = [[i,[[*,j,*,*],...]],...] */
5621: for ( t = tl2; t; t = NEXT(t) ) {
5622: /* s = [i,[*,j,*,*],...] */
5623: s = BDY((LIST)BDY(t));
1.6 noro 5624: j = perm[ZTOS((Q)ARG0(s))]; STOZ(j,jq); ARG0(s) = (pointer)jq;
1.1 noro 5625: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.6 noro 5626: j = perm[ZTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOZ(j,jq);
1.1 noro 5627: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
5628: }
5629: }
5630: for ( j = length(cand)-1, t = 0; j >= 0; j-- ) {
1.6 noro 5631: STOZ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.1 noro 5632: }
5633: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
5634: MKLIST(l5,tl4);
1.6 noro 5635: STOZ(nd_bpe,bpe);
1.15 noro 5636: tr = mknode(9,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe,hvect); MKLIST(*rp,tr);
1.1 noro 5637: }
5638: }
5639:
5640: /* XXX : module element is not considered */
5641:
5642: void dltondl(int n,DL dl,UINT *r)
5643: {
5644: UINT *d;
5645: int i,j,l,s,ord_l;
5646: struct order_pair *op;
5647:
5648: d = (unsigned int *)dl->d;
5649: for ( i = 0; i < nd_wpd; i++ ) r[i] = 0;
5650: if ( nd_blockmask ) {
5651: l = nd_blockmask->n;
5652: op = nd_blockmask->order_pair;
5653: for ( j = 0, s = 0; j < l; j++ ) {
5654: ord_l = op[j].length;
5655: for ( i = 0; i < ord_l; i++, s++ ) PUT_EXP(r,s,d[s]);
5656: }
5657: TD(r) = ndl_weight(r);
5658: ndl_weight_mask(r);
5659: } else {
5660: for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]);
5661: TD(r) = ndl_weight(r);
5662: }
5663: }
5664:
5665: DL ndltodl(int n,UINT *ndl)
5666: {
5667: DL dl;
5668: int *d;
5669: int i,j,l,s,ord_l;
5670: struct order_pair *op;
5671:
1.33 noro 5672: NEWDL_NOINIT(dl,n);
1.1 noro 5673: dl->td = TD(ndl);
5674: d = dl->d;
5675: if ( nd_blockmask ) {
5676: l = nd_blockmask->n;
5677: op = nd_blockmask->order_pair;
5678: for ( j = 0, s = 0; j < l; j++ ) {
5679: ord_l = op[j].length;
5680: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
5681: }
5682: } else {
5683: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
5684: }
5685: return dl;
5686: }
5687:
1.24 noro 5688: void _ndltodl(UINT *ndl,DL dl)
5689: {
5690: int *d;
5691: int i,j,l,s,ord_l,n;
5692: struct order_pair *op;
5693:
5694: n = nd_nvar;
5695: dl->td = TD(ndl);
5696: d = dl->d;
5697: if ( nd_blockmask ) {
5698: l = nd_blockmask->n;
5699: op = nd_blockmask->order_pair;
5700: for ( j = 0, s = 0; j < l; j++ ) {
5701: ord_l = op[j].length;
5702: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
5703: }
5704: } else {
5705: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
5706: }
5707: }
5708:
1.1 noro 5709: void nmtodp(int mod,NM m,DP *r)
5710: {
5711: DP dp;
5712: MP mr;
5713:
5714: NEWMP(mr);
5715: mr->dl = ndltodl(nd_nvar,DL(m));
5716: mr->c = (Obj)ndctop(mod,m->c);
5717: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
5718: *r = dp;
5719: }
5720:
1.15 noro 5721: void ndltodp(UINT *d,DP *r)
5722: {
5723: DP dp;
5724: MP mr;
5725:
5726: NEWMP(mr);
5727: mr->dl = ndltodl(nd_nvar,d);
5728: mr->c = (Obj)ONE;
5729: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
5730: *r = dp;
5731: }
5732:
1.1 noro 5733: void ndl_print(UINT *dl)
5734: {
5735: int n;
5736: int i,j,l,ord_l,s,s0;
5737: struct order_pair *op;
5738:
5739: n = nd_nvar;
5740: printf("<<");
5741: if ( nd_blockmask ) {
5742: l = nd_blockmask->n;
5743: op = nd_blockmask->order_pair;
5744: for ( j = 0, s = s0 = 0; j < l; j++ ) {
5745: ord_l = op[j].length;
5746: for ( i = 0; i < ord_l; i++, s++ )
5747: printf(s==n-1?"%d":"%d,",GET_EXP(dl,s));
5748: }
5749: } else {
5750: for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i));
5751: }
5752: printf(">>");
5753: if ( nd_module && MPOS(dl) )
5754: printf("*e%d",MPOS(dl));
5755: }
5756:
5757: void nd_print(ND p)
5758: {
5759: NM m;
5760:
5761: if ( !p )
5762: printf("0\n");
5763: else {
5764: for ( m = BDY(p); m; m = NEXT(m) ) {
5765: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
1.28 noro 5766: else printf("+%ld*",CM(m));
1.1 noro 5767: ndl_print(DL(m));
5768: }
5769: printf("\n");
5770: }
5771: }
5772:
5773: void nd_print_q(ND p)
5774: {
5775: NM m;
5776:
5777: if ( !p )
5778: printf("0\n");
5779: else {
5780: for ( m = BDY(p); m; m = NEXT(m) ) {
5781: printf("+");
1.6 noro 5782: printexpr(CO,(Obj)CZ(m));
1.1 noro 5783: printf("*");
5784: ndl_print(DL(m));
5785: }
5786: printf("\n");
5787: }
5788: }
5789:
5790: void ndp_print(ND_pairs d)
5791: {
5792: ND_pairs t;
5793:
5794: for ( t = d; t; t = NEXT(t) ) printf("%d,%d ",t->i1,t->i2);
5795: printf("\n");
5796: }
5797:
5798: void nd_removecont(int mod,ND p)
5799: {
5800: int i,n;
5801: Z *w;
5802: NM m;
5803: struct oVECT v;
5804:
5805: if ( mod == -1 ) nd_mul_c(mod,p,_invsf(HCM(p)));
5806: else if ( mod == -2 ) {
5807: Z inv;
5808: divlf(ONE,HCZ(p),&inv);
5809: nd_mul_c_lf(p,inv);
5810: } else if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod));
5811: else {
5812: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
5813: w = (Z *)MALLOC(n*sizeof(Q));
5814: v.len = n;
5815: v.body = (pointer *)w;
1.6 noro 5816: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5817: removecont_array((P *)w,n,1);
1.6 noro 5818: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5819: }
5820: }
5821:
5822: void nd_removecont2(ND p1,ND p2)
5823: {
5824: int i,n1,n2,n;
5825: Z *w;
5826: NM m;
5827: struct oVECT v;
5828:
5829: n1 = nd_length(p1);
5830: n2 = nd_length(p2);
5831: n = n1+n2;
5832: w = (Z *)MALLOC(n*sizeof(Q));
5833: v.len = n;
5834: v.body = (pointer *)w;
5835: i = 0;
5836: if ( p1 )
1.6 noro 5837: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5838: if ( p2 )
1.6 noro 5839: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5840: removecont_array((P *)w,n,1);
5841: i = 0;
5842: if ( p1 )
1.6 noro 5843: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5844: if ( p2 )
1.6 noro 5845: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5846: }
5847:
5848: void ndv_removecont(int mod,NDV p)
5849: {
5850: int i,len,all_p;
5851: Z *c;
5852: P *w;
5853: Z dvr,t;
5854: P g,cont,tp;
5855: NMV m;
5856:
5857: if ( mod == -1 )
5858: ndv_mul_c(mod,p,_invsf(HCM(p)));
5859: else if ( mod == -2 ) {
5860: Z inv;
5861: divlf(ONE,HCZ(p),&inv);
5862: ndv_mul_c_lf(p,inv);
5863: } else if ( mod )
5864: ndv_mul_c(mod,p,invm(HCM(p),mod));
5865: else {
5866: len = p->len;
5867: w = (P *)MALLOC(len*sizeof(P));
5868: c = (Z *)MALLOC(len*sizeof(Q));
5869: for ( m = BDY(p), all_p = 1, i = 0; i < len; NMV_ADV(m), i++ ) {
5870: ptozp(CP(m),1,(Q *)&c[i],&w[i]);
5871: all_p = all_p && !NUM(w[i]);
5872: }
5873: if ( all_p ) {
5874: qltozl((Q *)c,len,&dvr); nd_heu_nezgcdnpz(nd_vc,w,len,1,&g);
5875: mulp(nd_vc,(P)dvr,g,&cont);
5876: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
5877: divsp(nd_vc,CP(m),cont,&tp); CP(m) = tp;
5878: }
5879: } else {
5880: sortbynm((Q *)c,len);
5881: qltozl((Q *)c,len,&dvr);
5882: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
5883: divsp(nd_vc,CP(m),(P)dvr,&tp); CP(m) = tp;
5884: }
5885: }
5886: }
5887: }
5888:
5889: /* koko */
5890:
5891: void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos,int ompos)
5892: {
5893: int len,i,max;
5894: NMV m,mr0,mr,t;
5895:
5896: len = p->len;
1.14 noro 5897: for ( m = BDY(p), i = 0, max = 0; i < len; NMV_OADV(m), i++ )
1.1 noro 5898: max = MAX(max,TD(DL(m)));
5899: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
5900: m = (NMV)((char *)mr0+(len-1)*oadv);
5901: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
5902: t = (NMV)MALLOC(nmv_adv);
5903: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
5904: ndl_homogenize(DL(m),DL(t),obpe,oepos,ompos,max);
1.6 noro 5905: CZ(mr) = CZ(m);
1.1 noro 5906: ndl_copy(DL(t),DL(mr));
5907: }
5908: NV(p)++;
5909: BDY(p) = mr0;
5910: }
5911:
5912: void ndv_dehomogenize(NDV p,struct order_spec *ord)
5913: {
5914: int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos;
5915: int pos;
5916: Q *w;
5917: Q dvr,t;
5918: NMV m,r;
5919:
5920: len = p->len;
5921: newnvar = nd_nvar-1;
5922: newexporigin = nd_get_exporigin(ord);
5923: if ( nd_module ) newmpos = newexporigin-1;
5924: newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin;
5925: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ )
5926: ndl_dehomogenize(DL(m));
5927: if ( newwpd != nd_wpd ) {
5928: newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT));
5929: for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) {
1.6 noro 5930: CZ(r) = CZ(m);
1.1 noro 5931: if ( nd_module ) pos = MPOS(DL(m));
5932: for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j];
5933: adj = nd_exporigin-newexporigin;
5934: for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj];
5935: if ( nd_module ) {
5936: DL(r)[newmpos] = pos;
5937: }
5938: }
5939: }
5940: NV(p)--;
5941: }
5942:
5943: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr)
5944: {
5945: int i;
5946: P *tpl,*tpl1;
5947: NODE l;
5948: P h,gcd,t;
5949:
5950: tpl = (P *)MALLOC(m*sizeof(P));
5951: tpl1 = (P *)MALLOC(m*sizeof(P));
5952: bcopy(pl,tpl,m*sizeof(P));
5953: gcd = (P)ONE;
5954: for ( l = nd_hcf; l; l = NEXT(l) ) {
5955: h = (P)BDY(l);
5956: while ( 1 ) {
5957: for ( i = 0; i < m; i++ )
5958: if ( !divtpz(vl,tpl[i],h,&tpl1[i]) )
5959: break;
5960: if ( i == m ) {
5961: bcopy(tpl1,tpl,m*sizeof(P));
5962: mulp(vl,gcd,h,&t); gcd = t;
5963: } else
5964: break;
5965: }
5966: }
5967: if ( DP_Print > 2 ){fprintf(asir_out,"[%d]",nmonop(gcd)); fflush(asir_out);}
5968: if ( full ) {
5969: heu_nezgcdnpz(vl,tpl,m,&t);
5970: mulp(vl,gcd,t,pr);
5971: } else
5972: *pr = gcd;
5973: }
5974:
5975: void removecont_array(P *p,int n,int full)
5976: {
5977: int all_p,all_q,i;
5978: Z *c;
5979: P *w;
5980: P t,s;
5981:
5982: for ( all_q = 1, i = 0; i < n; i++ )
5983: all_q = all_q && NUM(p[i]);
5984: if ( all_q ) {
5985: removecont_array_q((Z *)p,n);
5986: } else {
5987: c = (Z *)MALLOC(n*sizeof(Z));
5988: w = (P *)MALLOC(n*sizeof(P));
5989: for ( i = 0; i < n; i++ ) {
5990: ptozp(p[i],1,(Q *)&c[i],&w[i]);
5991: }
5992: removecont_array_q(c,n);
5993: nd_heu_nezgcdnpz(nd_vc,w,n,full,&t);
5994: for ( i = 0; i < n; i++ ) {
5995: divsp(nd_vc,w[i],t,&s); mulp(nd_vc,s,(P)c[i],&p[i]);
5996: }
5997: }
5998: }
5999:
6000: /* c is an int array */
6001:
6002: void removecont_array_q(Z *c,int n)
6003: {
6004: struct oVECT v;
6005: Z d0,d1,a,u,u1,gcd;
6006: int i,j;
6007: Z *q,*r;
6008:
6009: q = (Z *)MALLOC(n*sizeof(Z));
6010: r = (Z *)MALLOC(n*sizeof(Z));
6011: v.id = O_VECT; v.len = n; v.body = (pointer *)c;
6012: gcdvz_estimate(&v,&d0);
6013: for ( i = 0; i < n; i++ ) {
6014: divqrz(c[i],d0,&q[i],&r[i]);
6015: }
6016: for ( i = 0; i < n; i++ ) if ( r[i] ) break;
6017: if ( i < n ) {
6018: v.id = O_VECT; v.len = n; v.body = (pointer *)r;
6019: gcdvz(&v,&d1);
6020: gcdz(d0,d1,&gcd);
1.6 noro 6021: /* exact division */
6022: divsz(d0,gcd,&a);
1.1 noro 6023: for ( i = 0; i < n; i++ ) {
6024: mulz(a,q[i],&u);
6025: if ( r[i] ) {
1.6 noro 6026: /* exact division */
6027: divsz(r[i],gcd,&u1);
1.1 noro 6028: addz(u,u1,&q[i]);
6029: } else
6030: q[i] = u;
6031: }
6032: }
6033: for ( i = 0; i < n; i++ ) c[i] = q[i];
6034: }
6035:
1.4 noro 6036: void gcdv_mpz_estimate(mpz_t d0,mpz_t *c,int n);
6037:
6038: void mpz_removecont_array(mpz_t *c,int n)
6039: {
6040: mpz_t d0,a,u,u1,gcd;
6041: int i,j;
1.13 noro 6042: static mpz_t *q,*r;
6043: static int c_len = 0;
1.4 noro 6044:
6045: for ( i = 0; i < n; i++ )
6046: if ( mpz_sgn(c[i]) ) break;
6047: if ( i == n ) return;
6048: gcdv_mpz_estimate(d0,c,n);
1.13 noro 6049: if ( n > c_len ) {
6050: q = (mpz_t *)MALLOC(n*sizeof(mpz_t));
6051: r = (mpz_t *)MALLOC(n*sizeof(mpz_t));
6052: c_len = n;
6053: }
1.4 noro 6054: for ( i = 0; i < n; i++ ) {
6055: mpz_init(q[i]); mpz_init(r[i]);
6056: mpz_fdiv_qr(q[i],r[i],c[i],d0);
6057: }
6058: for ( i = 0; i < n; i++ )
6059: if ( mpz_sgn(r[i]) ) break;
6060: mpz_init(gcd); mpz_init(a); mpz_init(u); mpz_init(u1);
6061: if ( i < n ) {
6062: mpz_gcd(gcd,d0,r[i]);
6063: for ( j = i+1; j < n; j++ ) mpz_gcd(gcd,gcd,r[j]);
6064: mpz_div(a,d0,gcd);
6065: for ( i = 0; i < n; i++ ) {
6066: mpz_mul(u,a,q[i]);
6067: if ( mpz_sgn(r[i]) ) {
6068: mpz_div(u1,r[i],gcd);
6069: mpz_add(q[i],u,u1);
6070: } else
6071: mpz_set(q[i],u);
6072: }
6073: }
6074: for ( i = 0; i < n; i++ )
6075: mpz_set(c[i],q[i]);
6076: }
6077:
1.1 noro 6078: void nd_mul_c(int mod,ND p,int mul)
6079: {
6080: NM m;
6081: int c,c1;
6082:
6083: if ( !p ) return;
6084: if ( mul == 1 ) return;
6085: if ( mod == -1 )
6086: for ( m = BDY(p); m; m = NEXT(m) )
6087: CM(m) = _mulsf(CM(m),mul);
6088: else
6089: for ( m = BDY(p); m; m = NEXT(m) ) {
6090: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
6091: }
6092: }
6093:
6094: void nd_mul_c_lf(ND p,Z mul)
6095: {
6096: NM m;
6097: Z c;
6098:
6099: if ( !p ) return;
6100: if ( UNIZ(mul) ) return;
6101: for ( m = BDY(p); m; m = NEXT(m) ) {
6102: mullf(CZ(m),mul,&c); CZ(m) = c;
6103: }
6104: }
6105:
6106: void nd_mul_c_q(ND p,P mul)
6107: {
6108: NM m;
6109: P c;
6110:
6111: if ( !p ) return;
6112: if ( UNIQ(mul) ) return;
6113: for ( m = BDY(p); m; m = NEXT(m) ) {
6114: mulp(nd_vc,CP(m),mul,&c); CP(m) = c;
6115: }
6116: }
6117:
6118: void nd_mul_c_p(VL vl,ND p,P mul)
6119: {
6120: NM m;
6121: P c;
6122:
6123: if ( !p ) return;
6124: for ( m = BDY(p); m; m = NEXT(m) ) {
6125: mulp(vl,CP(m),mul,&c); CP(m) = c;
6126: }
6127: }
6128:
6129: void nd_free(ND p)
6130: {
6131: NM t,s;
6132:
6133: if ( !p ) return;
6134: t = BDY(p);
6135: while ( t ) {
6136: s = NEXT(t);
6137: FREENM(t);
6138: t = s;
6139: }
6140: FREEND(p);
6141: }
6142:
6143: void ndv_free(NDV p)
6144: {
6145: GCFREE(BDY(p));
6146: }
6147:
6148: void nd_append_red(UINT *d,int i)
6149: {
6150: RHist m,m0;
6151: int h;
6152:
6153: NEWRHist(m);
6154: h = ndl_hash_value(d);
6155: m->index = i;
6156: ndl_copy(d,DL(m));
6157: NEXT(m) = nd_red[h];
6158: nd_red[h] = m;
6159: }
6160:
6161: UINT *ndv_compute_bound(NDV p)
6162: {
6163: UINT *d1,*d2,*t;
6164: UINT u;
6165: int i,j,k,l,len,ind;
6166: NMV m;
6167:
6168: if ( !p )
6169: return 0;
6170: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6171: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6172: len = LEN(p);
6173: m = BDY(p); ndl_copy(DL(m),d1); NMV_ADV(m);
6174: for ( i = 1; i < len; i++, NMV_ADV(m) ) {
6175: ndl_max(DL(m),d1,d2);
6176: t = d1; d1 = d2; d2 = t;
6177: }
6178: l = nd_nvar+31;
6179: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
6180: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
6181: u = d1[i];
6182: k = (nd_epw-1)*nd_bpe;
6183: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
6184: t[ind] = (u>>k)&nd_mask0;
6185: }
6186: for ( ; ind < l; ind++ ) t[ind] = 0;
6187: return t;
6188: }
6189:
6190: UINT *nd_compute_bound(ND p)
6191: {
6192: UINT *d1,*d2,*t;
6193: UINT u;
6194: int i,j,k,l,len,ind;
6195: NM m;
6196:
6197: if ( !p )
6198: return 0;
6199: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6200: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6201: len = LEN(p);
6202: m = BDY(p); ndl_copy(DL(m),d1); m = NEXT(m);
6203: for ( m = NEXT(m); m; m = NEXT(m) ) {
6204: ndl_lcm(DL(m),d1,d2);
6205: t = d1; d1 = d2; d2 = t;
6206: }
6207: l = nd_nvar+31;
6208: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
6209: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
6210: u = d1[i];
6211: k = (nd_epw-1)*nd_bpe;
6212: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
6213: t[ind] = (u>>k)&nd_mask0;
6214: }
6215: for ( ; ind < l; ind++ ) t[ind] = 0;
6216: return t;
6217: }
6218:
6219: /* if nd_module == 1 then d[nd_exporigin-1] indicates the position */
6220: /* of a term. In this case we need additional 1 word. */
6221:
6222: int nd_get_exporigin(struct order_spec *ord)
6223: {
6224: switch ( ord->id ) {
1.21 noro 6225: case 0: case 2: case 256: case 258: case 300:
1.1 noro 6226: return 1+nd_module;
6227: case 1: case 257:
6228: /* block order */
6229: /* poly ring d[0]:weight d[1]:w0,...,d[nd_exporigin-1]:w(n-1) */
6230: /* module d[0]:weight d[1]:w0,...,d[nd_exporigin-2]:w(n-1) */
6231: return ord->ord.block.length+1+nd_module;
6232: case 3: case 259:
6233: #if 0
6234: error("nd_get_exporigin : composite order is not supported yet.");
6235: #else
6236: return 1+nd_module;
6237: #endif
6238: default:
6239: error("nd_get_exporigin : ivalid argument.");
6240: return 0;
6241: }
6242: }
6243:
6244: void nd_setup_parameters(int nvar,int max) {
6245: int i,j,n,elen,ord_o,ord_l,l,s,wpd;
6246: struct order_pair *op;
1.45 noro 6247: extern int CNVars;
1.1 noro 6248:
6249: nd_nvar = nvar;
1.45 noro 6250: CNVars = nvar;
1.1 noro 6251: if ( max ) {
6252: /* XXX */
6253: if ( do_weyl ) nd_bpe = 32;
6254: else if ( max < 2 ) nd_bpe = 1;
6255: else if ( max < 4 ) nd_bpe = 2;
6256: else if ( max < 8 ) nd_bpe = 3;
6257: else if ( max < 16 ) nd_bpe = 4;
6258: else if ( max < 32 ) nd_bpe = 5;
6259: else if ( max < 64 ) nd_bpe = 6;
6260: else if ( max < 256 ) nd_bpe = 8;
6261: else if ( max < 1024 ) nd_bpe = 10;
6262: else if ( max < 65536 ) nd_bpe = 16;
6263: else nd_bpe = 32;
6264: }
6265: if ( !do_weyl && weight_check && (current_dl_weight_vector || nd_matrix) ) {
6266: UINT t;
6267: int st;
6268: int *v;
6269: /* t = max(weights) */
6270: t = 0;
6271: if ( current_dl_weight_vector )
6272: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
6273: if ( (st=current_dl_weight_vector[i]) < 0 ) st = -st;
6274: if ( t < st ) t = st;
6275: }
6276: if ( nd_matrix )
6277: for ( i = 0; i < nd_matrix_len; i++ )
6278: for ( j = 0, v = nd_matrix[i]; j < nd_nvar; j++ ) {
6279: if ( (st=v[j]) < 0 ) st = -st;
6280: if ( t < st ) t = st;
6281: }
6282: /* i = bitsize of t */
6283: for ( i = 0; t; t >>=1, i++ );
6284: /* i += bitsize of nd_nvar */
6285: for ( t = nd_nvar; t; t >>=1, i++);
6286: /* nd_bpe+i = bitsize of max(weights)*max(exp)*nd_nvar */
6287: if ( (nd_bpe+i) >= 31 )
6288: error("nd_setup_parameters : too large weight");
6289: }
6290: nd_epw = (sizeof(UINT)*8)/nd_bpe;
6291: elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0);
6292: nd_exporigin = nd_get_exporigin(nd_ord);
6293: wpd = nd_exporigin+elen;
6294: if ( nd_module )
6295: nd_mpos = nd_exporigin-1;
6296: else
6297: nd_mpos = -1;
6298: if ( wpd != nd_wpd ) {
6299: nd_free_private_storage();
6300: nd_wpd = wpd;
6301: }
6302: if ( nd_bpe < 32 ) {
6303: nd_mask0 = (1<<nd_bpe)-1;
6304: } else {
6305: nd_mask0 = 0xffffffff;
6306: }
6307: bzero(nd_mask,sizeof(nd_mask));
6308: nd_mask1 = 0;
6309: for ( i = 0; i < nd_epw; i++ ) {
6310: nd_mask[nd_epw-i-1] = (nd_mask0<<(i*nd_bpe));
6311: nd_mask1 |= (1<<(nd_bpe-1))<<(i*nd_bpe);
6312: }
6313: nmv_adv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(nd_wpd-1)*sizeof(UINT));
6314: nd_epos = nd_create_epos(nd_ord);
6315: nd_blockmask = nd_create_blockmask(nd_ord);
6316: nd_work_vector = (int *)REALLOC(nd_work_vector,nd_nvar*sizeof(int));
6317: }
6318:
6319: ND_pairs nd_reconstruct(int trace,ND_pairs d)
6320: {
6321: int i,obpe,oadv,h;
6322: static NM prev_nm_free_list;
6323: static ND_pairs prev_ndp_free_list;
6324: RHist mr0,mr;
6325: RHist r;
6326: RHist *old_red;
6327: ND_pairs s0,s,t;
6328: EPOS oepos;
6329:
6330: obpe = nd_bpe;
6331: oadv = nmv_adv;
6332: oepos = nd_epos;
6333: if ( obpe < 2 ) nd_bpe = 2;
6334: else if ( obpe < 3 ) nd_bpe = 3;
6335: else if ( obpe < 4 ) nd_bpe = 4;
6336: else if ( obpe < 5 ) nd_bpe = 5;
6337: else if ( obpe < 6 ) nd_bpe = 6;
6338: else if ( obpe < 8 ) nd_bpe = 8;
6339: else if ( obpe < 10 ) nd_bpe = 10;
6340: else if ( obpe < 16 ) nd_bpe = 16;
6341: else if ( obpe < 32 ) nd_bpe = 32;
6342: else error("nd_reconstruct : exponent too large");
6343:
6344: nd_setup_parameters(nd_nvar,0);
6345: prev_nm_free_list = _nm_free_list;
6346: prev_ndp_free_list = _ndp_free_list;
6347: _nm_free_list = 0;
6348: _ndp_free_list = 0;
6349: for ( i = nd_psn-1; i >= 0; i-- ) {
6350: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
6351: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
6352: }
6353: if ( trace )
6354: for ( i = nd_psn-1; i >= 0; i-- ) {
6355: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
6356: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
6357: }
6358: s0 = 0;
6359: for ( t = d; t; t = NEXT(t) ) {
6360: NEXTND_pairs(s0,s);
6361: s->i1 = t->i1;
6362: s->i2 = t->i2;
1.24 noro 6363: s->sig = t->sig;
1.1 noro 6364: SG(s) = SG(t);
6365: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
6366: }
6367:
6368: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
6369: for ( i = 0; i < REDTAB_LEN; i++ ) {
6370: old_red[i] = nd_red[i];
6371: nd_red[i] = 0;
6372: }
6373: for ( i = 0; i < REDTAB_LEN; i++ )
6374: for ( r = old_red[i]; r; r = NEXT(r) ) {
6375: NEWRHist(mr);
6376: mr->index = r->index;
6377: SG(mr) = SG(r);
6378: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
6379: h = ndl_hash_value(DL(mr));
6380: NEXT(mr) = nd_red[h];
6381: nd_red[h] = mr;
1.24 noro 6382: mr->sig = r->sig;
1.1 noro 6383: }
6384: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
6385: old_red = 0;
6386: for ( i = 0; i < nd_psn; i++ ) {
6387: NEWRHist(r); SG(r) = SG(nd_psh[i]);
6388: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
1.24 noro 6389: r->sig = nd_psh[i]->sig;
1.1 noro 6390: nd_psh[i] = r;
6391: }
6392: if ( s0 ) NEXT(s) = 0;
6393: prev_nm_free_list = 0;
6394: prev_ndp_free_list = 0;
6395: #if 0
6396: GC_gcollect();
6397: #endif
6398: return s0;
6399: }
6400:
1.30 noro 6401: void nd_reconstruct_s(int trace,ND_pairs *d)
6402: {
6403: int i,obpe,oadv,h;
6404: static NM prev_nm_free_list;
6405: static ND_pairs prev_ndp_free_list;
6406: RHist mr0,mr;
6407: RHist r;
6408: RHist *old_red;
6409: ND_pairs s0,s,t;
6410: EPOS oepos;
6411:
6412: obpe = nd_bpe;
6413: oadv = nmv_adv;
6414: oepos = nd_epos;
6415: if ( obpe < 2 ) nd_bpe = 2;
6416: else if ( obpe < 3 ) nd_bpe = 3;
6417: else if ( obpe < 4 ) nd_bpe = 4;
6418: else if ( obpe < 5 ) nd_bpe = 5;
6419: else if ( obpe < 6 ) nd_bpe = 6;
6420: else if ( obpe < 8 ) nd_bpe = 8;
6421: else if ( obpe < 10 ) nd_bpe = 10;
6422: else if ( obpe < 16 ) nd_bpe = 16;
6423: else if ( obpe < 32 ) nd_bpe = 32;
6424: else error("nd_reconstruct_s : exponent too large");
6425:
6426: nd_setup_parameters(nd_nvar,0);
6427: prev_nm_free_list = _nm_free_list;
6428: prev_ndp_free_list = _ndp_free_list;
6429: _nm_free_list = 0;
6430: _ndp_free_list = 0;
6431: for ( i = nd_psn-1; i >= 0; i-- ) {
6432: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
6433: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
6434: }
6435: if ( trace )
6436: for ( i = nd_psn-1; i >= 0; i-- ) {
6437: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
6438: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
6439: }
6440:
6441: for ( i = 0; i < nd_nbase; i++ ) {
6442: s0 = 0;
6443: for ( t = d[i]; t; t = NEXT(t) ) {
6444: NEXTND_pairs(s0,s);
6445: s->i1 = t->i1;
6446: s->i2 = t->i2;
6447: s->sig = t->sig;
6448: SG(s) = SG(t);
6449: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
6450: }
1.47 noro 6451: if ( s0 ) NEXT(s) = 0;
1.30 noro 6452: d[i] = s0;
6453: }
6454:
6455: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
6456: for ( i = 0; i < REDTAB_LEN; i++ ) {
6457: old_red[i] = nd_red[i];
6458: nd_red[i] = 0;
6459: }
6460: for ( i = 0; i < REDTAB_LEN; i++ )
6461: for ( r = old_red[i]; r; r = NEXT(r) ) {
6462: NEWRHist(mr);
6463: mr->index = r->index;
6464: SG(mr) = SG(r);
6465: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
6466: h = ndl_hash_value(DL(mr));
6467: NEXT(mr) = nd_red[h];
6468: nd_red[h] = mr;
6469: mr->sig = r->sig;
6470: }
6471: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
6472: old_red = 0;
6473: for ( i = 0; i < nd_psn; i++ ) {
6474: NEWRHist(r); SG(r) = SG(nd_psh[i]);
6475: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
6476: r->sig = nd_psh[i]->sig;
6477: nd_psh[i] = r;
6478: }
6479: if ( s0 ) NEXT(s) = 0;
6480: prev_nm_free_list = 0;
6481: prev_ndp_free_list = 0;
6482: #if 0
6483: GC_gcollect();
6484: #endif
6485: }
6486:
1.1 noro 6487: void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos)
6488: {
6489: int n,i,ei,oepw,omask0,j,s,ord_l,l;
6490: struct order_pair *op;
6491:
6492: n = nd_nvar;
6493: oepw = (sizeof(UINT)*8)/obpe;
6494: omask0 = (1<<obpe)-1;
6495: TD(r) = TD(d);
6496: for ( i = nd_exporigin; i < nd_wpd; i++ ) r[i] = 0;
6497: if ( nd_blockmask ) {
6498: l = nd_blockmask->n;
6499: op = nd_blockmask->order_pair;
6500: for ( i = 1; i < nd_exporigin; i++ )
6501: r[i] = d[i];
6502: for ( j = 0, s = 0; j < l; j++ ) {
6503: ord_l = op[j].length;
6504: for ( i = 0; i < ord_l; i++, s++ ) {
6505: ei = GET_EXP_OLD(d,s);
6506: PUT_EXP(r,s,ei);
6507: }
6508: }
6509: } else {
6510: for ( i = 0; i < n; i++ ) {
6511: ei = GET_EXP_OLD(d,i);
6512: PUT_EXP(r,i,ei);
6513: }
6514: }
6515: if ( nd_module ) MPOS(r) = MPOS(d);
6516: }
6517:
6518: ND nd_copy(ND p)
6519: {
6520: NM m,mr,mr0;
6521: int c,n;
6522: ND r;
6523:
6524: if ( !p )
6525: return 0;
6526: else {
6527: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
6528: NEXTNM(mr0,mr);
6529: CM(mr) = CM(m);
6530: ndl_copy(DL(m),DL(mr));
6531: }
6532: NEXT(mr) = 0;
6533: MKND(NV(p),mr0,LEN(p),r);
6534: SG(r) = SG(p);
6535: return r;
6536: }
6537: }
6538:
6539: int nd_sp(int mod,int trace,ND_pairs p,ND *rp)
6540: {
6541: NM m1,m2;
6542: NDV p1,p2;
6543: ND t1,t2;
6544: UINT *lcm;
6545: P gp,tp;
6546: Z g,t;
6547: Z iq;
6548: int td;
6549: LIST hist;
6550: NODE node;
6551: DP d;
6552:
6553: if ( !mod && nd_demand ) {
6554: p1 = ndv_load(p->i1); p2 = ndv_load(p->i2);
6555: } else {
6556: if ( trace ) {
6557: p1 = nd_ps_trace[p->i1]; p2 = nd_ps_trace[p->i2];
6558: } else {
6559: p1 = nd_ps[p->i1]; p2 = nd_ps[p->i2];
6560: }
6561: }
6562: lcm = LCM(p);
6563: NEWNM(m1); ndl_sub(lcm,HDL(p1),DL(m1));
6564: if ( ndl_check_bound2(p->i1,DL(m1)) ) {
6565: FREENM(m1); return 0;
6566: }
6567: NEWNM(m2); ndl_sub(lcm,HDL(p2),DL(m2));
6568: if ( ndl_check_bound2(p->i2,DL(m2)) ) {
6569: FREENM(m1); FREENM(m2); return 0;
6570: }
6571:
6572: if ( mod == -1 ) {
6573: CM(m1) = HCM(p2); CM(m2) = _chsgnsf(HCM(p1));
6574: } else if ( mod > 0 ) {
6575: CM(m1) = HCM(p2); CM(m2) = mod-HCM(p1);
6576: } else if ( mod == -2 ) {
6577: CZ(m1) = HCZ(p2); chsgnlf(HCZ(p1),&CZ(m2));
6578: } else if ( nd_vc ) {
6579: ezgcdpz(nd_vc,HCP(p1),HCP(p2),&gp);
6580: divsp(nd_vc,HCP(p2),gp,&CP(m1));
6581: divsp(nd_vc,HCP(p1),gp,&tp); chsgnp(tp,&CP(m2));
6582: } else {
1.6 noro 6583: igcd_cofactor(HCZ(p1),HCZ(p2),&g,&t,&CZ(m1)); chsgnz(t,&CZ(m2));
1.1 noro 6584: }
6585: t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2);
6586: *rp = nd_add(mod,t1,t2);
6587: if ( nd_gentrace ) {
6588: /* nd_tracelist is initialized */
1.6 noro 6589: STOZ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE);
1.1 noro 6590: MKLIST(hist,node); MKNODE(nd_tracelist,hist,0);
1.6 noro 6591: STOZ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE);
1.1 noro 6592: MKLIST(hist,node); MKNODE(node,hist,nd_tracelist);
6593: nd_tracelist = node;
6594: }
1.24 noro 6595: if ( *rp )
6596: (*rp)->sig = p->sig;
1.1 noro 6597: FREENM(m1); FREENM(m2);
6598: return 1;
6599: }
6600:
6601: void ndv_mul_c(int mod,NDV p,int mul)
6602: {
6603: NMV m;
6604: int c,c1,len,i;
6605:
6606: if ( !p ) return;
6607: len = LEN(p);
6608: if ( mod == -1 )
6609: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) )
6610: CM(m) = _mulsf(CM(m),mul);
6611: else
6612: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
6613: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
6614: }
6615: }
6616:
6617: void ndv_mul_c_lf(NDV p,Z mul)
6618: {
6619: NMV m;
6620: Z c;
6621: int len,i;
6622:
6623: if ( !p ) return;
6624: len = LEN(p);
6625: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
6626: mullf(CZ(m),mul,&c); CZ(m) = c;
6627: }
6628: }
6629:
6630: /* for nd_det */
6631: void ndv_mul_c_q(NDV p,Z mul)
6632: {
6633: NMV m;
6634: Z c;
6635: int len,i;
6636:
6637: if ( !p ) return;
6638: len = LEN(p);
6639: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 6640: mulz(CZ(m),mul,&c); CZ(m) = c;
1.1 noro 6641: }
6642: }
6643:
6644: ND weyl_ndv_mul_nm(int mod,NM m0,NDV p) {
6645: int n2,i,j,l,n,tlen;
6646: UINT *d0;
6647: NM *tab,*psum;
6648: ND s,r;
6649: NM t;
6650: NMV m1;
6651:
6652: if ( !p ) return 0;
6653: n = NV(p); n2 = n>>1;
6654: d0 = DL(m0);
6655: l = LEN(p);
6656: for ( i = 0, tlen = 1; i < n2; i++ ) tlen *= (GET_EXP(d0,n2+i)+1);
6657: tab = (NM *)MALLOC(tlen*sizeof(NM));
6658: psum = (NM *)MALLOC(tlen*sizeof(NM));
6659: for ( i = 0; i < tlen; i++ ) psum[i] = 0;
6660: m1 = (NMV)(((char *)BDY(p))+nmv_adv*(l-1));
6661: for ( i = l-1; i >= 0; i--, NMV_PREV(m1) ) {
6662: /* m0(NM) * m1(NMV) => tab(NM) */
6663: weyl_mul_nm_nmv(n,mod,m0,m1,tab,tlen);
6664: for ( j = 0; j < tlen; j++ ) {
6665: if ( tab[j] ) {
6666: NEXT(tab[j]) = psum[j]; psum[j] = tab[j];
6667: }
6668: }
6669: }
6670: for ( i = tlen-1, r = 0; i >= 0; i-- )
6671: if ( psum[i] ) {
6672: for ( j = 0, t = psum[i]; t; t = NEXT(t), j++ );
6673: MKND(n,psum[i],j,s);
6674: r = nd_add(mod,r,s);
6675: }
6676: if ( r ) SG(r) = SG(p)+TD(d0);
6677: return r;
6678: }
6679:
6680: /* product of monomials */
6681: /* XXX block order is not handled correctly */
6682:
6683: void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *tab,int tlen)
6684: {
6685: int i,n2,j,s,curlen,homo,h,a,b,k,l,u,min;
6686: UINT *d0,*d1,*d,*dt,*ctab;
6687: Z *ctab_q;
6688: Z q,q1;
6689: UINT c0,c1,c;
6690: NM *p;
6691: NM m,t;
6692: int mpos;
6693:
6694: for ( i = 0; i < tlen; i++ ) tab[i] = 0;
6695: if ( !m0 || !m1 ) return;
6696: d0 = DL(m0); d1 = DL(m1); n2 = n>>1;
6697: if ( nd_module )
6698: if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation");
6699:
6700: NEWNM(m); d = DL(m);
6701: if ( mod ) {
6702: c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c;
6703: } else if ( nd_vc )
6704: mulp(nd_vc,CP(m0),CP(m1),&CP(m));
6705: else
1.6 noro 6706: mulz(CZ(m0),CZ(m1),&CZ(m));
1.1 noro 6707: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
6708: homo = n&1 ? 1 : 0;
6709: if ( homo ) {
6710: /* offset of h-degree */
6711: h = GET_EXP(d0,n-1)+GET_EXP(d1,n-1);
6712: PUT_EXP(DL(m),n-1,h);
6713: TD(DL(m)) = h;
6714: if ( nd_blockmask ) ndl_weight_mask(DL(m));
6715: }
6716: tab[0] = m;
6717: NEWNM(m); d = DL(m);
6718: for ( i = 0, curlen = 1; i < n2; i++ ) {
6719: a = GET_EXP(d0,i); b = GET_EXP(d1,n2+i);
6720: k = GET_EXP(d0,n2+i); l = GET_EXP(d1,i);
6721: /* xi^a*(Di^k*xi^l)*Di^b */
6722: a += l; b += k;
6723: s = MUL_WEIGHT(a,i)+MUL_WEIGHT(b,n2+i);
6724: if ( !k || !l ) {
6725: for ( j = 0; j < curlen; j++ )
6726: if ( (t = tab[j]) != 0 ) {
6727: dt = DL(t);
6728: PUT_EXP(dt,i,a); PUT_EXP(dt,n2+i,b); TD(dt) += s;
6729: if ( nd_blockmask ) ndl_weight_mask(dt);
6730: }
6731: curlen *= k+1;
6732: continue;
6733: }
6734: min = MIN(k,l);
6735: if ( mod ) {
6736: ctab = (UINT *)MALLOC((min+1)*sizeof(UINT));
6737: mkwcm(k,l,mod,(int *)ctab);
6738: } else {
6739: ctab_q = (Z *)MALLOC((min+1)*sizeof(Z));
6740: mkwc(k,l,ctab_q);
6741: }
6742: for ( j = min; j >= 0; j-- ) {
6743: for ( u = 0; u < nd_wpd; u++ ) d[u] = 0;
6744: PUT_EXP(d,i,a-j); PUT_EXP(d,n2+i,b-j);
6745: h = MUL_WEIGHT(a-j,i)+MUL_WEIGHT(b-j,n2+i);
6746: if ( homo ) {
6747: TD(d) = s;
6748: PUT_EXP(d,n-1,s-h);
6749: } else TD(d) = h;
6750: if ( nd_blockmask ) ndl_weight_mask(d);
6751: if ( mod ) c = ctab[j];
6752: else q = ctab_q[j];
6753: p = tab+curlen*j;
6754: if ( j == 0 ) {
6755: for ( u = 0; u < curlen; u++, p++ ) {
6756: if ( tab[u] ) {
6757: ndl_addto(DL(tab[u]),d);
6758: if ( mod ) {
6759: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1;
6760: } else if ( nd_vc )
6761: mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u]));
6762: else {
1.6 noro 6763: mulz(CZ(tab[u]),q,&q1); CZ(tab[u]) = q1;
1.1 noro 6764: }
6765: }
6766: }
6767: } else {
6768: for ( u = 0; u < curlen; u++, p++ ) {
6769: if ( tab[u] ) {
6770: NEWNM(t);
6771: ndl_add(DL(tab[u]),d,DL(t));
6772: if ( mod ) {
6773: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1;
6774: } else if ( nd_vc )
6775: mulp(nd_vc,CP(tab[u]),(P)q,&CP(t));
6776: else
1.6 noro 6777: mulz(CZ(tab[u]),q,&CZ(t));
1.1 noro 6778: *p = t;
6779: }
6780: }
6781: }
6782: }
6783: curlen *= k+1;
6784: }
6785: FREENM(m);
6786: if ( nd_module ) {
6787: mpos = MPOS(d1);
6788: for ( i = 0; i < tlen; i++ )
6789: if ( tab[i] ) {
6790: d = DL(tab[i]);
6791: MPOS(d) = mpos;
6792: TD(d) = ndl_weight(d);
6793: }
6794: }
6795: }
6796:
6797: ND ndv_mul_nm_symbolic(NM m0,NDV p)
6798: {
6799: NM mr,mr0;
6800: NMV m;
6801: UINT *d,*dt,*dm;
6802: int c,n,td,i,c1,c2,len;
6803: Q q;
6804: ND r;
6805:
6806: if ( !p ) return 0;
6807: else {
6808: n = NV(p); m = BDY(p);
6809: d = DL(m0);
6810: len = LEN(p);
6811: mr0 = 0;
6812: td = TD(d);
6813: c = CM(m0);
6814: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6815: NEXTNM(mr0,mr);
6816: CM(mr) = 1;
6817: ndl_add(DL(m),d,DL(mr));
6818: }
6819: NEXT(mr) = 0;
6820: MKND(NV(p),mr0,len,r);
6821: SG(r) = SG(p) + TD(d);
6822: return r;
6823: }
6824: }
6825:
6826: ND ndv_mul_nm(int mod,NM m0,NDV p)
6827: {
6828: NM mr,mr0;
6829: NMV m;
6830: UINT *d,*dt,*dm;
6831: int c,n,td,i,c1,c2,len;
6832: P q;
6833: ND r;
6834:
6835: if ( !p ) return 0;
6836: else if ( do_weyl ) {
6837: if ( mod < 0 ) {
6838: error("ndv_mul_nm : not implemented (weyl)");
6839: return 0;
6840: } else
6841: return weyl_ndv_mul_nm(mod,m0,p);
6842: } else {
6843: n = NV(p); m = BDY(p);
6844: d = DL(m0);
6845: len = LEN(p);
6846: mr0 = 0;
6847: td = TD(d);
6848: if ( mod == -1 ) {
6849: c = CM(m0);
6850: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6851: NEXTNM(mr0,mr);
6852: CM(mr) = _mulsf(CM(m),c);
6853: ndl_add(DL(m),d,DL(mr));
6854: }
6855: } else if ( mod == -2 ) {
6856: Z cl;
6857: cl = CZ(m0);
6858: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6859: NEXTNM(mr0,mr);
6860: mullf(CZ(m),cl,&CZ(mr));
6861: ndl_add(DL(m),d,DL(mr));
6862: }
6863: } else if ( mod ) {
6864: c = CM(m0);
6865: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6866: NEXTNM(mr0,mr);
6867: c1 = CM(m);
6868: DMAR(c1,c,0,mod,c2);
6869: CM(mr) = c2;
6870: ndl_add(DL(m),d,DL(mr));
6871: }
6872: } else {
6873: q = CP(m0);
6874: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6875: NEXTNM(mr0,mr);
6876: mulp(nd_vc,CP(m),q,&CP(mr));
6877: ndl_add(DL(m),d,DL(mr));
6878: }
6879: }
6880: NEXT(mr) = 0;
6881: MKND(NV(p),mr0,len,r);
6882: SG(r) = SG(p) + TD(d);
6883: return r;
6884: }
6885: }
6886:
6887: ND nd_quo(int mod,PGeoBucket bucket,NDV d)
6888: {
6889: NM mq0,mq;
6890: NMV tm;
6891: Q q;
6892: int i,nv,sg,c,c1,c2,hindex;
6893: ND p,t,r;
6894:
6895: if ( bucket->m < 0 ) return 0;
6896: else {
6897: nv = NV(d);
6898: mq0 = 0;
6899: tm = (NMV)MALLOC(nmv_adv);
6900: while ( 1 ) {
6901: if ( mod > 0 || mod == -1 )
6902: hindex = head_pbucket(mod,bucket);
6903: else if ( mod == -2 )
6904: hindex = head_pbucket_lf(bucket);
6905: else
6906: hindex = head_pbucket_q(bucket);
6907: if ( hindex < 0 ) break;
6908: p = bucket->body[hindex];
6909: NEXTNM(mq0,mq);
6910: ndl_sub(HDL(p),HDL(d),DL(mq));
6911: ndl_copy(DL(mq),DL(tm));
6912: if ( mod ) {
6913: c1 = invm(HCM(d),mod); c2 = HCM(p);
6914: DMAR(c1,c2,0,mod,c); CM(mq) = c;
6915: CM(tm) = mod-c;
6916: } else {
1.6 noro 6917: divsz(HCZ(p),HCZ(d),&CZ(mq));
6918: chsgnz(CZ(mq),&CZ(tm));
1.1 noro 6919: }
6920: t = ndv_mul_nmv_trunc(mod,tm,d,HDL(d));
6921: bucket->body[hindex] = nd_remove_head(p);
6922: t = nd_remove_head(t);
6923: add_pbucket(mod,bucket,t);
6924: }
6925: if ( !mq0 )
6926: r = 0;
6927: else {
6928: NEXT(mq) = 0;
6929: for ( i = 0, mq = mq0; mq; mq = NEXT(mq), i++ );
6930: MKND(nv,mq0,i,r);
6931: /* XXX */
6932: SG(r) = HTD(r);
6933: }
6934: return r;
6935: }
6936: }
6937:
6938: void ndv_realloc(NDV p,int obpe,int oadv,EPOS oepos)
6939: {
6940: NMV m,mr,mr0,t;
6941: int len,i,k;
6942:
6943: if ( !p ) return;
6944: m = BDY(p); len = LEN(p);
6945: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
6946: m = (NMV)((char *)mr0+(len-1)*oadv);
6947: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
6948: t = (NMV)MALLOC(nmv_adv);
6949: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
1.6 noro 6950: CZ(t) = CZ(m);
1.1 noro 6951: for ( k = 0; k < nd_wpd; k++ ) DL(t)[k] = 0;
6952: ndl_reconstruct(DL(m),DL(t),obpe,oepos);
1.6 noro 6953: CZ(mr) = CZ(t);
1.1 noro 6954: ndl_copy(DL(t),DL(mr));
6955: }
6956: BDY(p) = mr0;
6957: }
6958:
6959: NDV ndv_dup_realloc(NDV p,int obpe,int oadv,EPOS oepos)
6960: {
6961: NMV m,mr,mr0;
6962: int len,i;
6963: NDV r;
6964:
6965: if ( !p ) return 0;
6966: m = BDY(p); len = LEN(p);
6967: mr0 = mr = (NMV)MALLOC(len*nmv_adv);
6968: for ( i = 0; i < len; i++, NMV_OADV(m), NMV_ADV(mr) ) {
6969: ndl_zero(DL(mr));
6970: ndl_reconstruct(DL(m),DL(mr),obpe,oepos);
1.6 noro 6971: CZ(mr) = CZ(m);
1.1 noro 6972: }
6973: MKNDV(NV(p),mr0,len,r);
6974: SG(r) = SG(p);
1.24 noro 6975: r->sig = p->sig;
1.1 noro 6976: return r;
6977: }
6978:
6979: /* duplicate p */
6980:
6981: NDV ndv_dup(int mod,NDV p)
6982: {
6983: NDV d;
6984: NMV t,m,m0;
6985: int i,len;
6986:
6987: if ( !p ) return 0;
6988: len = LEN(p);
6989: m0 = m = (NMV)((mod>0 || mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
6990: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
6991: ndl_copy(DL(t),DL(m));
1.6 noro 6992: CZ(m) = CZ(t);
1.1 noro 6993: }
6994: MKNDV(NV(p),m0,len,d);
6995: SG(d) = SG(p);
6996: return d;
6997: }
6998:
6999: NDV ndv_symbolic(int mod,NDV p)
7000: {
7001: NDV d;
7002: NMV t,m,m0;
7003: int i,len;
7004:
7005: if ( !p ) return 0;
7006: len = LEN(p);
7007: m0 = m = (NMV)((mod>0||mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
7008: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
7009: ndl_copy(DL(t),DL(m));
1.6 noro 7010: CZ(m) = ONE;
1.1 noro 7011: }
7012: MKNDV(NV(p),m0,len,d);
7013: SG(d) = SG(p);
7014: return d;
7015: }
7016:
7017: ND nd_dup(ND p)
7018: {
7019: ND d;
7020: NM t,m,m0;
7021:
7022: if ( !p ) return 0;
7023: for ( m0 = 0, t = BDY(p); t; t = NEXT(t) ) {
7024: NEXTNM(m0,m);
7025: ndl_copy(DL(t),DL(m));
1.6 noro 7026: CZ(m) = CZ(t);
1.1 noro 7027: }
7028: if ( m0 ) NEXT(m) = 0;
7029: MKND(NV(p),m0,LEN(p),d);
7030: SG(d) = SG(p);
7031: return d;
7032: }
7033:
7034: /* XXX if p->len == 0 then it represents 0 */
7035:
7036: void ndv_mod(int mod,NDV p)
7037: {
7038: NMV t,d;
7039: int r,s,u;
7040: int i,len,dlen;
7041: P cp;
7042: Z c;
7043: Obj gfs;
7044:
7045: if ( !p ) return;
7046: len = LEN(p);
7047: dlen = 0;
7048: if ( mod == -1 )
7049: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7050: simp_ff((Obj)CP(t),&gfs);
7051: if ( gfs ) {
7052: r = FTOIF(CONT((GFS)gfs));
7053: CM(d) = r;
7054: ndl_copy(DL(t),DL(d));
7055: NMV_ADV(d);
7056: dlen++;
7057: }
7058: }
7059: else if ( mod == -2 )
7060: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7061: simp_ff((Obj)CP(t),&gfs);
7062: if ( gfs ) {
7063: lmtolf((LM)gfs,&CZ(d));
7064: ndl_copy(DL(t),DL(d));
7065: NMV_ADV(d);
7066: dlen++;
7067: }
7068: }
7069: else
7070: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7071: if ( nd_vc ) {
7072: nd_subst_vector(nd_vc,CP(t),nd_subst,&cp);
7073: c = (Z)cp;
7074: } else
1.6 noro 7075: c = CZ(t);
1.1 noro 7076: r = remqi((Q)c,mod);
7077: if ( r ) {
7078: CM(d) = r;
7079: ndl_copy(DL(t),DL(d));
7080: NMV_ADV(d);
7081: dlen++;
7082: }
7083: }
7084: LEN(p) = dlen;
7085: }
7086:
7087: NDV ptondv(VL vl,VL dvl,P p)
7088: {
7089: ND nd;
7090:
7091: nd = ptond(vl,dvl,p);
7092: return ndtondv(0,nd);
7093: }
7094:
7095: void pltozpl(LIST l,Q *cont,LIST *pp)
7096: {
1.16 noro 7097: NODE nd,nd1;
7098: int n;
7099: P *pl;
7100: Q *cl;
7101: int i;
7102: P dmy;
7103: Z dvr,inv;
7104: LIST r;
7105:
7106: nd = BDY(l); n = length(nd);
7107: pl = (P *)MALLOC(n*sizeof(P));
7108: cl = (Q *)MALLOC(n*sizeof(Q));
7109: for ( i = 0; i < n; i++, nd = NEXT(nd) ) {
7110: ptozp((P)BDY(nd),1,&cl[i],&dmy);
7111: }
7112: qltozl(cl,n,&dvr);
7113: divz(ONE,dvr,&inv);
7114: nd = BDY(l);
7115: for ( i = 0; i < n; i++, nd = NEXT(nd) )
7116: divsp(CO,(P)BDY(nd),(P)dvr,&pl[i]);
7117: nd = 0;
7118: for ( i = n-1; i >= 0; i-- ) {
7119: MKNODE(nd1,pl[i],nd); nd = nd1;
7120: }
7121: MKLIST(r,nd);
7122: *pp = r;
1.1 noro 7123: }
7124:
7125: /* (a1,a2,...,an) -> a1*e(1)+...+an*e(n) */
7126:
7127: NDV pltondv(VL vl,VL dvl,LIST p)
7128: {
7129: int i;
7130: NODE t;
7131: ND r,ri;
7132: NM m;
7133:
7134: if ( !nd_module ) error("pltond : module order must be set");
7135: r = 0;
7136: for ( i = 1, t = BDY(p); t; t = NEXT(t), i++ ) {
7137: ri = ptond(vl,dvl,(P)BDY(t));
7138: if ( ri )
7139: for ( m = BDY(ri); m; m = NEXT(m) ) {
7140: MPOS(DL(m)) = i;
7141: TD(DL(m)) = ndl_weight(DL(m));
7142: if ( nd_blockmask ) ndl_weight_mask(DL(m));
7143: }
7144: r = nd_add(0,r,ri);
7145: }
7146: return ndtondv(0,r);
7147: }
7148:
7149: ND ptond(VL vl,VL dvl,P p)
7150: {
7151: int n,i,j,k,e;
7152: VL tvl;
7153: V v;
7154: DCP dc;
7155: DCP *w;
7156: ND r,s,t,u;
7157: P x;
7158: int c;
7159: UINT *d;
7160: NM m,m0;
7161:
7162: if ( !p )
7163: return 0;
7164: else if ( NUM(p) ) {
7165: NEWNM(m);
7166: ndl_zero(DL(m));
1.48 noro 7167: if ( RATN(p) && !INT((Q)p) )
1.1 noro 7168: error("ptond : input must be integer-coefficient");
1.6 noro 7169: CZ(m) = (Z)p;
1.1 noro 7170: NEXT(m) = 0;
7171: MKND(nd_nvar,m,1,r);
7172: SG(r) = 0;
7173: return r;
7174: } else {
7175: for ( dc = DC(p), k = 0; dc; dc = NEXT(dc), k++ );
7176: w = (DCP *)MALLOC(k*sizeof(DCP));
7177: for ( dc = DC(p), j = 0; j < k; dc = NEXT(dc), j++ ) w[j] = dc;
7178: for ( i = 0, tvl = dvl, v = VR(p);
7179: tvl && tvl->v != v; tvl = NEXT(tvl), i++ );
7180: if ( !tvl ) {
7181: for ( j = k-1, s = 0, MKV(v,x); j >= 0; j-- ) {
7182: t = ptond(vl,dvl,COEF(w[j]));
7183: pwrp(vl,x,DEG(w[j]),&p);
7184: nd_mul_c_p(CO,t,p); s = nd_add(0,s,t);
7185: }
7186: return s;
7187: } else {
7188: NEWNM(m0); d = DL(m0);
7189: for ( j = k-1, s = 0; j >= 0; j-- ) {
1.6 noro 7190: ndl_zero(d); e = ZTOS(DEG(w[j])); PUT_EXP(d,i,e);
1.1 noro 7191: TD(d) = MUL_WEIGHT(e,i);
7192: if ( nd_blockmask) ndl_weight_mask(d);
7193: if ( nd_module ) MPOS(d) = 0;
7194: t = ptond(vl,dvl,COEF(w[j]));
7195: for ( m = BDY(t); m; m = NEXT(m) )
7196: ndl_addto(DL(m),d);
7197: SG(t) += TD(d);
7198: s = nd_add(0,s,t);
7199: }
7200: FREENM(m0);
7201: return s;
7202: }
7203: }
7204: }
7205:
7206: P ndvtop(int mod,VL vl,VL dvl,NDV p)
7207: {
7208: VL tvl;
7209: int len,n,j,i,e;
7210: NMV m;
7211: Z q;
7212: P c;
7213: UINT *d;
7214: P s,r,u,t,w;
7215: GFS gfs;
7216:
7217: if ( !p ) return 0;
7218: else {
7219: len = LEN(p);
7220: n = NV(p);
7221: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
7222: for ( j = len-1, s = 0; j >= 0; j--, NMV_PREV(m) ) {
7223: if ( mod == -1 ) {
7224: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
7225: } else if ( mod == -2 ) {
7226: c = (P)CZ(m);
7227: } else if ( mod > 0 ) {
1.6 noro 7228: STOZ(CM(m),q); c = (P)q;
1.1 noro 7229: } else
7230: c = CP(m);
7231: d = DL(m);
7232: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
1.6 noro 7233: MKV(tvl->v,r); e = GET_EXP(d,i); STOZ(e,q);
1.1 noro 7234: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
7235: }
7236: addp(vl,s,t,&u); s = u;
7237: }
7238: return s;
7239: }
7240: }
7241:
7242: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank)
7243: {
7244: VL tvl;
7245: int len,n,j,i,e;
7246: NMV m;
7247: Z q;
7248: P c;
7249: UINT *d;
7250: P s,r,u,t,w;
7251: GFS gfs;
7252: P *a;
7253: LIST l;
7254: NODE nd,nd1;
7255:
7256: if ( !p ) return 0;
7257: else {
7258: a = (P *)MALLOC((rank+1)*sizeof(P));
7259: for ( i = 0; i <= rank; i++ ) a[i] = 0;
7260: len = LEN(p);
7261: n = NV(p);
7262: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
7263: for ( j = len-1; j >= 0; j--, NMV_PREV(m) ) {
7264: if ( mod == -1 ) {
7265: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
7266: } else if ( mod ) {
1.6 noro 7267: STOZ(CM(m),q); c = (P)q;
1.1 noro 7268: } else
7269: c = CP(m);
7270: d = DL(m);
7271: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
1.6 noro 7272: MKV(tvl->v,r); e = GET_EXP(d,i); STOZ(e,q);
1.1 noro 7273: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
7274: }
7275: addp(vl,a[MPOS(d)],t,&u); a[MPOS(d)] = u;
7276: }
7277: nd = 0;
7278: for ( i = rank; i > 0; i-- ) {
7279: MKNODE(nd1,a[i],nd); nd = nd1;
7280: }
7281: MKLIST(l,nd);
7282: return l;
7283: }
7284: }
7285:
7286: NDV ndtondv(int mod,ND p)
7287: {
7288: NDV d;
7289: NMV m,m0;
7290: NM t;
7291: int i,len;
7292:
7293: if ( !p ) return 0;
7294: len = LEN(p);
7295: if ( mod > 0 || mod == -1 )
7296: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7297: else
7298: m0 = m = MALLOC(len*nmv_adv);
7299: #if 0
7300: ndv_alloc += nmv_adv*len;
7301: #endif
7302: for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, NMV_ADV(m) ) {
7303: ndl_copy(DL(t),DL(m));
1.6 noro 7304: CZ(m) = CZ(t);
1.1 noro 7305: }
7306: MKNDV(NV(p),m0,len,d);
7307: SG(d) = SG(p);
1.24 noro 7308: d->sig = p->sig;
1.1 noro 7309: return d;
7310: }
7311:
1.16 noro 7312: static int dmm_comp_nv;
7313:
7314: int dmm_comp(DMM *a,DMM *b)
7315: {
7316: return -compdmm(dmm_comp_nv,*a,*b);
7317: }
7318:
7319: void dmm_sort_by_ord(DMM *a,int len,int nv)
7320: {
7321: dmm_comp_nv = nv;
7322: qsort(a,len,sizeof(DMM),(int (*)(const void *,const void *))dmm_comp);
7323: }
7324:
7325: void dpm_sort(DPM p,DPM *rp)
7326: {
7327: DMM t,t1;
7328: int len,i,n;
7329: DMM *a;
7330: DPM d;
7331:
7332: if ( !p ) *rp = 0;
7333: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7334: a = (DMM *)MALLOC(len*sizeof(DMM));
7335: for ( i = 0, t = BDY(p); i < len; i++, t = NEXT(t) ) a[i] = t;
7336: n = p->nv;
7337: dmm_sort_by_ord(a,len,n);
7338: t = 0;
7339: for ( i = len-1; i >= 0; i-- ) {
7340: NEWDMM(t1);
7341: t1->c = a[i]->c;
7342: t1->dl = a[i]->dl;
7343: t1->pos = a[i]->pos;
7344: t1->next = t;
7345: t = t1;
7346: }
7347: MKDPM(n,t,d);
7348: SG(d) = SG(p);
7349: *rp = d;
7350: }
7351:
1.18 noro 7352: int dpm_comp(DPM *a,DPM *b)
7353: {
1.22 noro 7354: return -compdpm(CO,*a,*b);
1.18 noro 7355: }
7356:
7357: NODE dpm_sort_list(NODE l)
7358: {
7359: int i,len;
7360: NODE t,t1;
7361: DPM *a;
7362:
7363: len = length(l);
7364: a = (DPM *)MALLOC(len*sizeof(DPM));
7365: for ( t = l, i = 0; i < len; i++, t = NEXT(t) ) a[i] = (DPM)BDY(t);
7366: qsort(a,len,sizeof(DPM),(int (*)(const void *,const void *))dpm_comp);
7367: t = 0;
7368: for ( i = len-1; i >= 0; i-- ) {
7369: MKNODE(t1,(pointer)a[i],t); t = t1;
7370: }
7371: return t;
7372: }
7373:
1.20 noro 7374: int nmv_comp(NMV a,NMV b)
7375: {
1.21 noro 7376: int t;
7377: t = DL_COMPARE(a->dl,b->dl);
7378: return -t;
1.20 noro 7379: }
7380:
1.43 noro 7381: NDV dptondv(int mod,DP p)
7382: {
7383: NDV d;
7384: NMV m,m0;
7385: MP t;
7386: MP *a;
7387: int i,len,n;
7388:
7389: if ( !p ) return 0;
7390: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7391: n = p->nv;
7392: if ( mod > 0 || mod == -1 )
7393: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7394: else
7395: m0 = m = MALLOC(len*nmv_adv);
7396: for ( i = 0, t = BDY(p); i < len; i++, NMV_ADV(m), t = NEXT(t) ) {
7397: dltondl(n,t->dl,DL(m));
7398: TD(DL(m)) = ndl_weight(DL(m));
7399: CZ(m) = (Z)t->c;
7400: }
7401: qsort(m0,len,nmv_adv,(int (*)(const void *,const void *))nmv_comp);
7402: MKNDV(NV(p),m0,len,d);
7403: SG(d) = SG(p);
7404: return d;
7405: }
7406:
1.16 noro 7407: NDV dpmtondv(int mod,DPM p)
7408: {
7409: NDV d;
7410: NMV m,m0;
7411: DMM t;
7412: DMM *a;
7413: int i,len,n;
7414:
7415: if ( !p ) return 0;
7416: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7417: a = (DMM *)MALLOC(len*sizeof(DMM));
7418: for ( i = 0, t = BDY(p); i < len; i++, t = NEXT(t) ) a[i] = t;
7419: n = p->nv;
7420: dmm_sort_by_ord(a,len,n);
7421: if ( mod > 0 || mod == -1 )
7422: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7423: else
7424: m0 = m = MALLOC(len*nmv_adv);
7425: #if 0
7426: ndv_alloc += nmv_adv*len;
7427: #endif
7428: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7429: dltondl(n,a[i]->dl,DL(m));
7430: MPOS(DL(m)) = a[i]->pos;
1.20 noro 7431: TD(DL(m)) = ndl_weight(DL(m));
1.16 noro 7432: CZ(m) = (Z)a[i]->c;
7433: }
1.20 noro 7434: qsort(m0,len,nmv_adv,(int (*)(const void *,const void *))nmv_comp);
1.16 noro 7435: MKNDV(NV(p),m0,len,d);
7436: SG(d) = SG(p);
7437: return d;
7438: }
7439:
1.1 noro 7440: ND ndvtond(int mod,NDV p)
7441: {
7442: ND d;
7443: NM m,m0;
7444: NMV t;
7445: int i,len;
7446:
7447: if ( !p ) return 0;
7448: m0 = 0;
7449: len = p->len;
7450: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7451: NEXTNM(m0,m);
7452: ndl_copy(DL(t),DL(m));
1.6 noro 7453: CZ(m) = CZ(t);
1.1 noro 7454: }
7455: NEXT(m) = 0;
7456: MKND(NV(p),m0,len,d);
7457: SG(d) = SG(p);
1.28 noro 7458: d->sig = p->sig;
1.1 noro 7459: return d;
7460: }
7461:
7462: DP ndvtodp(int mod,NDV p)
7463: {
7464: MP m,m0;
7465: DP d;
7466: NMV t;
7467: int i,len;
7468:
7469: if ( !p ) return 0;
7470: m0 = 0;
7471: len = p->len;
7472: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7473: NEXTMP(m0,m);
7474: m->dl = ndltodl(nd_nvar,DL(t));
7475: m->c = (Obj)ndctop(mod,t->c);
7476: }
7477: NEXT(m) = 0;
7478: MKDP(nd_nvar,m0,d);
7479: SG(d) = SG(p);
7480: return d;
7481: }
7482:
1.44 noro 7483: DPM sigtodpm(SIG s)
7484: {
7485: DMM m;
7486: DPM d;
7487:
7488: NEWDMM(m);
7489: m->c = (Obj)ONE;
7490: m->dl = s->dl;
7491: m->pos = s->pos+1;
7492: m->next = 0;
7493: MKDPM(nd_nvar,m,d);
7494: SG(d) = s->dl->td;
7495: return d;
7496: }
7497:
1.16 noro 7498: DPM ndvtodpm(int mod,NDV p)
7499: {
7500: DMM m,m0;
7501: DPM d;
7502: NMV t;
7503: int i,len;
7504:
7505: if ( !p ) return 0;
7506: m0 = 0;
7507: len = p->len;
7508: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7509: NEXTDMM(m0,m);
7510: m->dl = ndltodl(nd_nvar,DL(t));
7511: m->c = (Obj)ndctop(mod,t->c);
7512: m->pos = MPOS(DL(t));
7513: }
7514: NEXT(m) = 0;
7515: MKDPM(nd_nvar,m0,d);
7516: SG(d) = SG(p);
7517: return d;
7518: }
7519:
7520:
1.1 noro 7521: DP ndtodp(int mod,ND p)
7522: {
7523: MP m,m0;
7524: DP d;
7525: NM t;
7526: int i,len;
7527:
7528: if ( !p ) return 0;
7529: m0 = 0;
7530: len = p->len;
7531: for ( t = BDY(p); t; t = NEXT(t) ) {
7532: NEXTMP(m0,m);
7533: m->dl = ndltodl(nd_nvar,DL(t));
7534: m->c = (Obj)ndctop(mod,t->c);
7535: }
7536: NEXT(m) = 0;
7537: MKDP(nd_nvar,m0,d);
7538: SG(d) = SG(p);
7539: return d;
7540: }
7541:
7542: void ndv_print(NDV p)
7543: {
7544: NMV m;
7545: int i,len;
7546:
7547: if ( !p ) printf("0\n");
7548: else {
7549: len = LEN(p);
7550: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7551: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
1.28 noro 7552: else printf("+%ld*",CM(m));
1.1 noro 7553: ndl_print(DL(m));
7554: }
7555: printf("\n");
7556: }
7557: }
7558:
7559: void ndv_print_q(NDV p)
7560: {
7561: NMV m;
7562: int i,len;
7563:
7564: if ( !p ) printf("0\n");
7565: else {
7566: len = LEN(p);
7567: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7568: printf("+");
1.6 noro 7569: printexpr(CO,(Obj)CZ(m));
1.1 noro 7570: printf("*");
7571: ndl_print(DL(m));
7572: }
7573: printf("\n");
7574: }
7575: }
7576:
7577: NODE ndv_reducebase(NODE x,int *perm)
7578: {
7579: int len,i,j;
7580: NDVI w;
7581: NODE t,t0;
7582:
1.41 noro 7583: if ( nd_norb ) return x;
1.1 noro 7584: len = length(x);
7585: w = (NDVI)MALLOC(len*sizeof(struct oNDVI));
7586: for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) {
7587: w[i].p = BDY(t); w[i].i = perm[i];
7588: }
7589: for ( i = 0; i < len; i++ ) {
7590: for ( j = 0; j < i; j++ ) {
7591: if ( w[i].p && w[j].p ) {
7592: if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0;
7593: else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0;
7594: }
7595: }
7596: }
7597: for ( i = j = 0, t0 = 0; i < len; i++ ) {
7598: if ( w[i].p ) {
7599: NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p;
7600: perm[j++] = w[i].i;
7601: }
7602: }
7603: NEXT(t) = 0; x = t0;
7604: return x;
7605: }
7606:
7607: /* XXX incomplete */
7608:
1.21 noro 7609: extern DMMstack dmm_stack;
7610: int ndl_module_schreyer_compare(UINT *a,UINT *b);
1.16 noro 7611:
1.1 noro 7612: void nd_init_ord(struct order_spec *ord)
7613: {
7614: nd_module = (ord->id >= 256);
7615: if ( nd_module ) {
7616: nd_dcomp = -1;
1.21 noro 7617: nd_module_ordtype = ord->module_ordtype;
1.1 noro 7618: nd_pot_nelim = ord->pot_nelim;
7619: nd_poly_weight_len = ord->nv;
7620: nd_poly_weight = ord->top_weight;
7621: nd_module_rank = ord->module_rank;
7622: nd_module_weight = ord->module_top_weight;
7623: }
7624: nd_matrix = 0;
7625: nd_matrix_len = 0;
7626: switch ( ord->id ) {
7627: case 0:
7628: switch ( ord->ord.simple ) {
7629: case 0:
7630: nd_dcomp = 1;
7631: nd_isrlex = 1;
7632: break;
7633: case 1:
7634: nd_dcomp = 1;
7635: nd_isrlex = 0;
7636: break;
7637: case 2:
7638: nd_dcomp = 0;
7639: nd_isrlex = 0;
7640: ndl_compare_function = ndl_lex_compare;
7641: break;
7642: case 11:
7643: /* XXX */
7644: nd_dcomp = 0;
7645: nd_isrlex = 1;
7646: ndl_compare_function = ndl_ww_lex_compare;
7647: break;
7648: default:
7649: error("nd_gr : unsupported order");
7650: }
7651: break;
7652: case 1:
7653: /* block order */
7654: /* XXX */
7655: nd_dcomp = -1;
7656: nd_isrlex = 0;
7657: ndl_compare_function = ndl_block_compare;
7658: break;
7659: case 2:
7660: /* matrix order */
7661: /* XXX */
7662: nd_dcomp = -1;
7663: nd_isrlex = 0;
7664: nd_matrix_len = ord->ord.matrix.row;
7665: nd_matrix = ord->ord.matrix.matrix;
7666: ndl_compare_function = ndl_matrix_compare;
7667: break;
7668: case 3:
7669: /* composite order */
7670: nd_dcomp = -1;
7671: nd_isrlex = 0;
7672: nd_worb_len = ord->ord.composite.length;
7673: nd_worb = ord->ord.composite.w_or_b;
7674: ndl_compare_function = ndl_composite_compare;
7675: break;
7676:
7677: /* module order */
7678: case 256:
7679: switch ( ord->ord.simple ) {
7680: case 0:
1.21 noro 7681: nd_dcomp = 0;
1.1 noro 7682: nd_isrlex = 1;
1.21 noro 7683: ndl_compare_function = ndl_module_glex_compare;
1.1 noro 7684: break;
7685: case 1:
1.21 noro 7686: nd_dcomp = 0;
1.1 noro 7687: nd_isrlex = 0;
7688: ndl_compare_function = ndl_module_glex_compare;
7689: break;
7690: case 2:
1.21 noro 7691: nd_dcomp = 0;
1.1 noro 7692: nd_isrlex = 0;
1.21 noro 7693: ndl_compare_function = ndl_module_compare;
7694: ndl_base_compare_function = ndl_lex_compare;
1.1 noro 7695: break;
7696: default:
1.21 noro 7697: error("nd_init_ord : unsupported order");
1.1 noro 7698: }
7699: break;
7700: case 257:
7701: /* block order */
7702: nd_isrlex = 0;
1.21 noro 7703: ndl_compare_function = ndl_module_compare;
7704: ndl_base_compare_function = ndl_block_compare;
1.1 noro 7705: break;
7706: case 258:
7707: /* matrix order */
7708: nd_isrlex = 0;
7709: nd_matrix_len = ord->ord.matrix.row;
7710: nd_matrix = ord->ord.matrix.matrix;
1.21 noro 7711: ndl_compare_function = ndl_module_compare;
7712: ndl_base_compare_function = ndl_matrix_compare;
1.1 noro 7713: break;
7714: case 259:
7715: /* composite order */
7716: nd_isrlex = 0;
7717: nd_worb_len = ord->ord.composite.length;
7718: nd_worb = ord->ord.composite.w_or_b;
1.21 noro 7719: ndl_compare_function = ndl_module_compare;
7720: ndl_base_compare_function = ndl_composite_compare;
7721: break;
7722: case 300:
7723: /* schreyer order */
7724: if ( ord->base->id != 256 )
7725: error("nd_init_ord : unsupported base order");
7726: ndl_compare_function = ndl_module_schreyer_compare;
7727: dmm_stack = ord->dmmstack;
7728: switch ( ord->base->ord.simple ) {
7729: case 0:
7730: nd_isrlex = 1;
7731: ndl_base_compare_function = ndl_glex_compare;
7732: dl_base_compare_function = cmpdl_revgradlex;
7733: break;
7734: case 1:
7735: nd_isrlex = 0;
7736: ndl_base_compare_function = ndl_glex_compare;
7737: dl_base_compare_function = cmpdl_gradlex;
7738: break;
7739: case 2:
7740: nd_isrlex = 0;
7741: ndl_base_compare_function = ndl_lex_compare;
7742: dl_base_compare_function = cmpdl_lex;
7743: break;
7744: default:
7745: error("nd_init_ord : unsupported order");
7746: }
1.1 noro 7747: break;
7748: }
7749: nd_ord = ord;
7750: }
7751:
7752: BlockMask nd_create_blockmask(struct order_spec *ord)
7753: {
7754: int n,i,j,s,l;
7755: UINT *t;
7756: BlockMask bm;
7757:
7758: /* we only create mask table for block order */
7759: if ( ord->id != 1 && ord->id != 257 )
7760: return 0;
7761: n = ord->ord.block.length;
7762: bm = (BlockMask)MALLOC(sizeof(struct oBlockMask));
7763: bm->n = n;
7764: bm->order_pair = ord->ord.block.order_pair;
7765: bm->mask = (UINT **)MALLOC(n*sizeof(UINT *));
7766: for ( i = 0, s = 0; i < n; i++ ) {
7767: bm->mask[i] = t = (UINT *)MALLOC_ATOMIC(nd_wpd*sizeof(UINT));
7768: for ( j = 0; j < nd_wpd; j++ ) t[j] = 0;
7769: l = bm->order_pair[i].length;
7770: for ( j = 0; j < l; j++, s++ ) PUT_EXP(t,s,nd_mask0);
7771: }
7772: return bm;
7773: }
7774:
7775: EPOS nd_create_epos(struct order_spec *ord)
7776: {
7777: int i,j,l,s,ord_l,ord_o;
7778: EPOS epos;
7779: struct order_pair *op;
7780:
7781: epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS));
7782: switch ( ord->id ) {
1.21 noro 7783: case 0: case 256: case 300:
1.1 noro 7784: if ( nd_isrlex ) {
7785: for ( i = 0; i < nd_nvar; i++ ) {
7786: epos[i].i = nd_exporigin + (nd_nvar-1-i)/nd_epw;
7787: epos[i].s = (nd_epw-((nd_nvar-1-i)%nd_epw)-1)*nd_bpe;
7788: }
7789: } else {
7790: for ( i = 0; i < nd_nvar; i++ ) {
7791: epos[i].i = nd_exporigin + i/nd_epw;
7792: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
7793: }
7794: }
7795: break;
7796: case 1: case 257:
7797: /* block order */
7798: l = ord->ord.block.length;
7799: op = ord->ord.block.order_pair;
7800: for ( j = 0, s = 0; j < l; j++ ) {
7801: ord_o = op[j].order;
7802: ord_l = op[j].length;
7803: if ( !ord_o )
7804: for ( i = 0; i < ord_l; i++ ) {
7805: epos[s+i].i = nd_exporigin + (s+ord_l-i-1)/nd_epw;
7806: epos[s+i].s = (nd_epw-((s+ord_l-i-1)%nd_epw)-1)*nd_bpe;
7807: }
7808: else
7809: for ( i = 0; i < ord_l; i++ ) {
7810: epos[s+i].i = nd_exporigin + (s+i)/nd_epw;
7811: epos[s+i].s = (nd_epw-((s+i)%nd_epw)-1)*nd_bpe;
7812: }
7813: s += ord_l;
7814: }
7815: break;
7816: case 2:
7817: /* matrix order */
7818: case 3:
7819: /* composite order */
7820: default:
7821: for ( i = 0; i < nd_nvar; i++ ) {
7822: epos[i].i = nd_exporigin + i/nd_epw;
7823: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
7824: }
7825: break;
7826: }
7827: return epos;
7828: }
7829:
7830: /* external interface */
7831:
7832: void nd_nf_p(Obj f,LIST g,LIST v,int m,struct order_spec *ord,Obj *rp)
7833: {
7834: NODE t,in0,in;
7835: ND ndf,nf;
7836: NDV ndvf;
7837: VL vv,tv;
7838: int stat,nvar,max,mrank;
7839: union oNDC dn;
7840: Q cont;
7841: P pp;
7842: LIST ppl;
7843:
7844: if ( !f ) {
7845: *rp = 0;
7846: return;
7847: }
7848: pltovl(v,&vv);
7849: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
7850:
7851: /* max=65536 implies nd_bpe=32 */
7852: max = 65536;
7853:
7854: nd_module = 0;
7855: /* nd_module will be set if ord is a module ordering */
7856: nd_init_ord(ord);
7857: nd_setup_parameters(nvar,max);
7858: if ( nd_module && OID(f) != O_LIST )
7859: error("nd_nf_p : the first argument must be a list");
7860: if ( nd_module ) mrank = length(BDY((LIST)f));
7861: /* conversion to ndv */
7862: for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) {
7863: NEXTNODE(in0,in);
7864: if ( nd_module ) {
7865: if ( !BDY(t) || OID(BDY(t)) != O_LIST
7866: || length(BDY((LIST)BDY(t))) != mrank )
7867: error("nd_nf_p : inconsistent basis element");
7868: if ( !m ) pltozpl((LIST)BDY(t),&cont,&ppl);
7869: else ppl = (LIST)BDY(t);
7870: BDY(in) = (pointer)pltondv(CO,vv,ppl);
7871: } else {
7872: if ( !m ) ptozp((P)BDY(t),1,&cont,&pp);
7873: else pp = (P)BDY(t);
7874: BDY(in) = (pointer)ptondv(CO,vv,pp);
7875: }
7876: if ( m ) ndv_mod(m,(NDV)BDY(in));
7877: }
7878: if ( in0 ) NEXT(in) = 0;
7879:
7880: if ( nd_module ) ndvf = pltondv(CO,vv,(LIST)f);
7881: else ndvf = ptondv(CO,vv,(P)f);
7882: if ( m ) ndv_mod(m,ndvf);
7883: ndf = (pointer)ndvtond(m,ndvf);
7884:
7885: /* dont sort, dont removecont */
1.24 noro 7886: ndv_setup(m,0,in0,1,1,0);
1.1 noro 7887: nd_scale=2;
1.6 noro 7888: stat = nd_nf(m,0,ndf,nd_ps,1,&nf);
1.1 noro 7889: if ( !stat )
7890: error("nd_nf_p : exponent too large");
7891: if ( nd_module ) *rp = (Obj)ndvtopl(m,CO,vv,ndtondv(m,nf),mrank);
7892: else *rp = (Obj)ndvtop(m,CO,vv,ndtondv(m,nf));
7893: }
7894:
7895: int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r)
7896: {
7897: NM m;
7898: UINT *t,*s;
7899: int i;
7900:
7901: for ( i = 0; i < n; i++ ) r[i] = 0;
7902: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7903: t = DL(m);
7904: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
7905: r[i] = CM(m);
7906: }
7907: for ( i = 0; !r[i]; i++ );
7908: return i;
7909: }
7910:
7911: int nd_to_vect_q(UINT *s0,int n,ND d,Z *r)
7912: {
7913: NM m;
7914: UINT *t,*s;
7915: int i;
7916:
7917: for ( i = 0; i < n; i++ ) r[i] = 0;
7918: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7919: t = DL(m);
7920: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.6 noro 7921: r[i] = CZ(m);
1.1 noro 7922: }
7923: for ( i = 0; !r[i]; i++ );
7924: return i;
7925: }
7926:
7927: int nd_to_vect_lf(UINT *s0,int n,ND d,mpz_t *r)
7928: {
7929: NM m;
7930: UINT *t,*s;
7931: int i;
7932:
7933: for ( i = 0; i < n; i++ ) { mpz_init(r[i]); mpz_set_ui(r[i],0); }
7934: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7935: t = DL(m);
7936: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
7937: mpz_set(r[i],BDY(CZ(m)));
7938: }
7939: for ( i = 0; !mpz_sgn(r[i]); i++ );
7940: return i;
7941: }
7942:
7943: unsigned long *nd_to_vect_2(UINT *s0,int n,int *s0hash,ND p)
7944: {
7945: NM m;
7946: unsigned long *v;
7947: int i,j,h,size;
7948: UINT *s,*t;
7949:
7950: size = sizeof(unsigned long)*(n+BLEN-1)/BLEN;
7951: v = (unsigned long *)MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
7952: bzero(v,size);
7953: for ( i = j = 0, s = s0, m = BDY(p); m; j++, m = NEXT(m) ) {
7954: t = DL(m);
7955: h = ndl_hash_value(t);
7956: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
7957: v[i/BLEN] |= 1L <<(i%BLEN);
7958: }
7959: return v;
7960: }
7961:
7962: int nd_nm_to_vect_2(UINT *s0,int n,int *s0hash,NDV p,NM m,unsigned long *v)
7963: {
7964: NMV mr;
7965: UINT *d,*t,*s;
7966: int i,j,len,h,head;
7967:
7968: d = DL(m);
7969: len = LEN(p);
7970: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
7971: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
7972: ndl_add(d,DL(mr),t);
7973: h = ndl_hash_value(t);
7974: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
7975: if ( j == 0 ) head = i;
7976: v[i/BLEN] |= 1L <<(i%BLEN);
7977: }
7978: return head;
7979: }
7980:
7981: Z *nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_pair pair)
7982: {
7983: NM m;
7984: NMV mr;
7985: UINT *d,*t,*s;
7986: NDV p;
7987: int i,j,len;
7988: Z *r;
7989:
7990: m = pair->mul;
7991: d = DL(m);
7992: p = nd_ps[pair->index];
7993: len = LEN(p);
7994: r = (Z *)CALLOC(n,sizeof(Q));
7995: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
7996: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
7997: ndl_add(d,DL(mr),t);
7998: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.6 noro 7999: r[i] = CZ(mr);
1.1 noro 8000: }
8001: return r;
8002: }
8003:
1.11 noro 8004: IndArray nm_ind_pair_to_vect_compress(int trace,UINT *s0,int n,NM_ind_pair pair,int start)
1.1 noro 8005: {
8006: NM m;
8007: NMV mr;
1.11 noro 8008: UINT *d,*t,*s,*u;
1.1 noro 8009: NDV p;
8010: unsigned char *ivc;
8011: unsigned short *ivs;
8012: UINT *v,*ivi,*s0v;
1.11 noro 8013: int i,j,len,prev,diff,cdiff,h,st,ed,md,c;
1.1 noro 8014: IndArray r;
8015:
8016: m = pair->mul;
8017: d = DL(m);
8018: if ( trace )
8019: p = nd_demand?nd_ps_trace_sym[pair->index]:nd_ps_trace[pair->index];
8020: else
8021: p = nd_demand?nd_ps_sym[pair->index]:nd_ps[pair->index];
8022:
8023: len = LEN(p);
8024: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8025: v = (unsigned int *)MALLOC(len*sizeof(unsigned int));
1.11 noro 8026: for ( prev = start, mr = BDY(p), j = 0; j < len; j++, NMV_ADV(mr) ) {
8027: ndl_add(d,DL(mr),t);
8028: st = prev;
8029: ed = n;
8030: while ( ed > st ) {
8031: md = (st+ed)/2;
8032: u = s0+md*nd_wpd;
8033: c = DL_COMPARE(u,t);
8034: if ( c == 0 ) break;
8035: else if ( c > 0 ) st = md;
8036: else ed = md;
8037: }
8038: prev = v[j] = md;
1.1 noro 8039: }
8040: r = (IndArray)MALLOC(sizeof(struct oIndArray));
8041: r->head = v[0];
8042: diff = 0;
8043: for ( i = 1; i < len; i++ ) {
8044: cdiff = v[i]-v[i-1]; diff = MAX(cdiff,diff);
8045: }
8046: if ( diff < 256 ) {
8047: r->width = 1;
8048: ivc = (unsigned char *)MALLOC_ATOMIC(len*sizeof(unsigned char));
8049: r->index.c = ivc;
8050: for ( i = 1, ivc[0] = 0; i < len; i++ ) ivc[i] = v[i]-v[i-1];
8051: } else if ( diff < 65536 ) {
8052: r->width = 2;
8053: ivs = (unsigned short *)MALLOC_ATOMIC(len*sizeof(unsigned short));
8054: r->index.s = ivs;
8055: for ( i = 1, ivs[0] = 0; i < len; i++ ) ivs[i] = v[i]-v[i-1];
8056: } else {
8057: r->width = 4;
8058: ivi = (unsigned int *)MALLOC_ATOMIC(len*sizeof(unsigned int));
8059: r->index.i = ivi;
8060: for ( i = 1, ivi[0] = 0; i < len; i++ ) ivi[i] = v[i]-v[i-1];
8061: }
8062: return r;
8063: }
8064:
8065: int compress_array(Z *svect,Z *cvect,int n)
8066: {
8067: int i,j;
8068:
8069: for ( i = j = 0; i < n; i++ )
8070: if ( svect[i] ) cvect[j++] = svect[i];
8071: return j;
8072: }
8073:
8074: void expand_array(Z *svect,Z *cvect,int n)
8075: {
8076: int i,j;
8077:
8078: for ( i = j = 0; j < n; i++ )
8079: if ( svect[i] ) svect[i] = cvect[j++];
8080: }
8081:
1.8 noro 8082: #if 0
1.1 noro 8083: int ndv_reduce_vect_q(Z *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8084: {
8085: int i,j,k,len,pos,prev,nz;
8086: Z cs,mcs,c1,c2,cr,gcd,t;
8087: IndArray ivect;
8088: unsigned char *ivc;
8089: unsigned short *ivs;
8090: unsigned int *ivi;
8091: NDV redv;
8092: NMV mr;
8093: NODE rp;
8094: int maxrs;
8095: double hmag;
8096: Z *cvect;
1.3 noro 8097: int l;
1.1 noro 8098:
8099: maxrs = 0;
8100: for ( i = 0; i < col && !svect[i]; i++ );
8101: if ( i == col ) return maxrs;
8102: hmag = p_mag((P)svect[i])*nd_scale;
8103: cvect = (Z *)MALLOC(col*sizeof(Q));
8104: for ( i = 0; i < nred; i++ ) {
8105: ivect = imat[i];
8106: k = ivect->head;
8107: if ( svect[k] ) {
8108: maxrs = MAX(maxrs,rp0[i]->sugar);
8109: redv = nd_demand?ndv_load(rp0[i]->index)
8110: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
8111: len = LEN(redv); mr = BDY(redv);
1.6 noro 8112: igcd_cofactor(svect[k],CZ(mr),&gcd,&cs,&cr);
1.1 noro 8113: chsgnz(cs,&mcs);
8114: if ( !UNIQ(cr) ) {
8115: for ( j = 0; j < col; j++ ) {
8116: mulz(svect[j],cr,&c1); svect[j] = c1;
8117: }
8118: }
8119: svect[k] = 0; prev = k;
8120: switch ( ivect->width ) {
8121: case 1:
8122: ivc = ivect->index.c;
8123: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8124: pos = prev+ivc[j]; prev = pos;
1.6 noro 8125: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8126: }
8127: break;
8128: case 2:
8129: ivs = ivect->index.s;
8130: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8131: pos = prev+ivs[j]; prev = pos;
1.6 noro 8132: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8133: }
8134: break;
8135: case 4:
8136: ivi = ivect->index.i;
8137: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8138: pos = prev+ivi[j]; prev = pos;
1.6 noro 8139: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8140: }
8141: break;
8142: }
8143: for ( j = k+1; j < col && !svect[j]; j++ );
8144: if ( j == col ) break;
8145: if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) {
8146: nz = compress_array(svect,cvect,col);
8147: removecont_array((P *)cvect,nz,1);
8148: expand_array(svect,cvect,nz);
8149: hmag = ((double)p_mag((P)svect[j]))*nd_scale;
8150: }
8151: }
8152: }
8153: nz = compress_array(svect,cvect,col);
8154: removecont_array((P *)cvect,nz,1);
8155: expand_array(svect,cvect,nz);
8156: if ( DP_Print ) {
8157: fprintf(asir_out,"-"); fflush(asir_out);
8158: }
8159: return maxrs;
8160: }
1.4 noro 8161: #else
1.9 noro 8162:
1.4 noro 8163: /* direct mpz version */
8164: int ndv_reduce_vect_q(Z *svect0,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8165: {
8166: int i,j,k,len,pos,prev;
8167: mpz_t cs,cr,gcd;
8168: IndArray ivect;
8169: unsigned char *ivc;
8170: unsigned short *ivs;
8171: unsigned int *ivi;
8172: NDV redv;
8173: NMV mr;
8174: NODE rp;
8175: int maxrs;
8176: double hmag;
8177: int l;
1.13 noro 8178: static mpz_t *svect;
8179: static int svect_len=0;
1.4 noro 8180:
8181: maxrs = 0;
8182: for ( i = 0; i < col && !svect0[i]; i++ );
8183: if ( i == col ) return maxrs;
8184: hmag = p_mag((P)svect0[i])*nd_scale;
1.13 noro 8185: if ( col > svect_len ) {
8186: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
8187: svect_len = col;
8188: }
1.4 noro 8189: for ( i = 0; i < col; i++ ) {
8190: mpz_init(svect[i]);
8191: if ( svect0[i] )
8192: mpz_set(svect[i],BDY(svect0[i]));
8193: else
8194: mpz_set_ui(svect[i],0);
8195: }
8196: mpz_init(gcd); mpz_init(cs); mpz_init(cr);
8197: for ( i = 0; i < nred; i++ ) {
8198: ivect = imat[i];
8199: k = ivect->head;
8200: if ( mpz_sgn(svect[k]) ) {
8201: maxrs = MAX(maxrs,rp0[i]->sugar);
8202: redv = nd_demand?ndv_load(rp0[i]->index)
8203: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
8204: len = LEN(redv); mr = BDY(redv);
1.6 noro 8205: mpz_gcd(gcd,svect[k],BDY(CZ(mr)));
1.4 noro 8206: mpz_div(cs,svect[k],gcd);
1.6 noro 8207: mpz_div(cr,BDY(CZ(mr)),gcd);
1.4 noro 8208: mpz_neg(cs,cs);
1.9 noro 8209: if ( MUNIMPZ(cr) )
8210: for ( j = 0; j < col; j++ ) mpz_neg(svect[j],svect[j]);
8211: else if ( !UNIMPZ(cr) )
8212: for ( j = 0; j < col; j++ ) {
8213: if ( mpz_sgn(svect[j]) ) mpz_mul(svect[j],svect[j],cr);
8214: }
1.4 noro 8215: mpz_set_ui(svect[k],0);
8216: prev = k;
8217: switch ( ivect->width ) {
8218: case 1:
8219: ivc = ivect->index.c;
8220: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8221: pos = prev+ivc[j]; prev = pos;
1.6 noro 8222: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8223: }
8224: break;
8225: case 2:
8226: ivs = ivect->index.s;
8227: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8228: pos = prev+ivs[j]; prev = pos;
1.6 noro 8229: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8230: }
8231: break;
8232: case 4:
8233: ivi = ivect->index.i;
8234: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8235: pos = prev+ivi[j]; prev = pos;
1.6 noro 8236: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8237: }
8238: break;
8239: }
8240: for ( j = k+1; j < col && !svect[j]; j++ );
8241: if ( j == col ) break;
8242: if ( hmag && ((double)mpz_sizeinbase(svect[j],2) > hmag) ) {
8243: mpz_removecont_array(svect,col);
8244: hmag = ((double)mpz_sizeinbase(svect[j],2))*nd_scale;
8245: }
8246: }
8247: }
8248: mpz_removecont_array(svect,col);
8249: if ( DP_Print ) {
8250: fprintf(asir_out,"-"); fflush(asir_out);
8251: }
8252: for ( i = 0; i < col; i++ )
8253: if ( mpz_sgn(svect[i]) ) MPZTOZ(svect[i],svect0[i]);
8254: else svect0[i] = 0;
8255: return maxrs;
8256: }
8257: #endif
1.1 noro 8258:
1.40 noro 8259: int ndv_reduce_vect(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred,SIG sig)
1.1 noro 8260: {
8261: int i,j,k,len,pos,prev;
8262: UINT c,c1,c2,c3,up,lo,dmy;
8263: IndArray ivect;
8264: unsigned char *ivc;
8265: unsigned short *ivs;
8266: unsigned int *ivi;
8267: NDV redv;
8268: NMV mr;
8269: NODE rp;
8270: int maxrs;
8271:
8272: maxrs = 0;
8273: for ( i = 0; i < nred; i++ ) {
8274: ivect = imat[i];
8275: k = ivect->head; svect[k] %= m;
1.40 noro 8276: if ( (c = svect[k]) != 0 && (sig == 0 || comp_sig(sig,rp0[i]->sig) > 0 ) ) {
1.1 noro 8277: maxrs = MAX(maxrs,rp0[i]->sugar);
8278: c = m-c; redv = nd_ps[rp0[i]->index];
8279: len = LEN(redv); mr = BDY(redv);
8280: svect[k] = 0; prev = k;
8281: switch ( ivect->width ) {
8282: case 1:
8283: ivc = ivect->index.c;
8284: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8285: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.40 noro 8286: if ( c1 ) {
8287: c2 = svect[pos];
1.1 noro 8288: DMA(c1,c,c2,up,lo);
8289: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8290: } else svect[pos] = lo;
1.40 noro 8291: }
1.1 noro 8292: }
8293: break;
8294: case 2:
8295: ivs = ivect->index.s;
8296: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8297: pos = prev+ivs[j]; c1 = CM(mr);
8298: prev = pos;
1.40 noro 8299: if ( c1 ) {
8300: c2 = svect[pos];
1.1 noro 8301: DMA(c1,c,c2,up,lo);
8302: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8303: } else svect[pos] = lo;
1.40 noro 8304: }
1.1 noro 8305: }
8306: break;
8307: case 4:
8308: ivi = ivect->index.i;
8309: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8310: pos = prev+ivi[j]; c1 = CM(mr);
8311: prev = pos;
1.40 noro 8312: if ( c1 ) {
8313: c2 = svect[pos];
1.1 noro 8314: DMA(c1,c,c2,up,lo);
8315: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8316: } else svect[pos] = lo;
1.40 noro 8317: }
1.1 noro 8318: }
8319: break;
8320: }
8321: }
8322: }
8323: for ( i = 0; i < col; i++ )
8324: if ( svect[i] >= (UINT)m ) svect[i] %= m;
8325: return maxrs;
8326: }
8327:
8328: int ndv_reduce_vect_sf(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8329: {
8330: int i,j,k,len,pos,prev;
8331: UINT c,c1,c2,c3,up,lo,dmy;
8332: IndArray ivect;
8333: unsigned char *ivc;
8334: unsigned short *ivs;
8335: unsigned int *ivi;
8336: NDV redv;
8337: NMV mr;
8338: NODE rp;
8339: int maxrs;
8340:
8341: maxrs = 0;
8342: for ( i = 0; i < nred; i++ ) {
8343: ivect = imat[i];
8344: k = ivect->head;
8345: if ( (c = svect[k]) != 0 ) {
8346: maxrs = MAX(maxrs,rp0[i]->sugar);
8347: c = _chsgnsf(c); redv = nd_ps[rp0[i]->index];
8348: len = LEN(redv); mr = BDY(redv);
8349: svect[k] = 0; prev = k;
8350: switch ( ivect->width ) {
8351: case 1:
8352: ivc = ivect->index.c;
8353: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8354: pos = prev+ivc[j]; prev = pos;
8355: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8356: }
8357: break;
8358: case 2:
8359: ivs = ivect->index.s;
8360: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8361: pos = prev+ivs[j]; prev = pos;
8362: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8363: }
8364: break;
8365: case 4:
8366: ivi = ivect->index.i;
8367: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8368: pos = prev+ivi[j]; prev = pos;
8369: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8370: }
8371: break;
8372: }
8373: }
8374: }
8375: return maxrs;
8376: }
8377:
8378: ND nd_add_lf(ND p1,ND p2)
8379: {
8380: int n,c,can;
8381: ND r;
8382: NM m1,m2,mr0,mr,s;
8383: Z t;
8384:
8385: if ( !p1 ) return p2;
8386: else if ( !p2 ) return p1;
8387: else {
8388: can = 0;
8389: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
8390: c = DL_COMPARE(DL(m1),DL(m2));
8391: switch ( c ) {
8392: case 0:
8393: addlf(CZ(m1),CZ(m2),&t);
8394: s = m1; m1 = NEXT(m1);
8395: if ( t ) {
8396: can++; NEXTNM2(mr0,mr,s); CZ(mr) = (t);
8397: } else {
8398: can += 2; FREENM(s);
8399: }
8400: s = m2; m2 = NEXT(m2); FREENM(s);
8401: break;
8402: case 1:
8403: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
8404: break;
8405: case -1:
8406: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
8407: break;
8408: }
8409: }
8410: if ( !mr0 )
8411: if ( m1 ) mr0 = m1;
8412: else if ( m2 ) mr0 = m2;
8413: else return 0;
8414: else if ( m1 ) NEXT(mr) = m1;
8415: else if ( m2 ) NEXT(mr) = m2;
8416: else NEXT(mr) = 0;
8417: BDY(p1) = mr0;
8418: SG(p1) = MAX(SG(p1),SG(p2));
8419: LEN(p1) = LEN(p1)+LEN(p2)-can;
8420: FREEND(p2);
8421: return p1;
8422: }
8423: }
8424:
8425: int ndv_reduce_vect_lf(mpz_t *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8426: {
8427: int i,j,k,len,pos,prev;
8428: mpz_t c,mc,c1;
8429: IndArray ivect;
8430: unsigned char *ivc;
8431: unsigned short *ivs;
8432: unsigned int *ivi;
8433: NDV redv;
8434: NMV mr;
8435: NODE rp;
8436: int maxrs;
8437:
8438: maxrs = 0;
8439: lf_lazy = 1;
8440: for ( i = 0; i < nred; i++ ) {
8441: ivect = imat[i];
8442: k = ivect->head;
8443: mpz_mod(svect[k],svect[k],BDY(current_mod_lf));
8444: if ( mpz_sgn(svect[k]) ) {
8445: maxrs = MAX(maxrs,rp0[i]->sugar);
8446: mpz_neg(svect[k],svect[k]);
8447: redv = trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index];
8448: len = LEN(redv); mr = BDY(redv);
8449: prev = k;
8450: switch ( ivect->width ) {
8451: case 1:
8452: ivc = ivect->index.c;
8453: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8454: pos = prev+ivc[j]; prev = pos;
8455: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8456: }
8457: break;
8458: case 2:
8459: ivs = ivect->index.s;
8460: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8461: pos = prev+ivs[j]; prev = pos;
8462: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8463: }
8464: break;
8465: case 4:
8466: ivi = ivect->index.i;
8467: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8468: pos = prev+ivi[j]; prev = pos;
8469: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8470: }
8471: break;
8472: }
8473: mpz_set_ui(svect[k],0);
8474: }
8475: }
8476: lf_lazy=0;
8477: for ( i = 0; i < col; i++ ) {
8478: mpz_mod(svect[i],svect[i],BDY(current_mod_lf));
8479: }
8480: return maxrs;
8481: }
8482:
8483: int nd_gauss_elim_lf(mpz_t **mat0,int *sugar,int row,int col,int *colstat)
8484: {
8485: int i,j,k,l,rank,s;
8486: mpz_t a,a1,inv;
8487: mpz_t *t,*pivot,*pk;
8488: mpz_t **mat;
8489: struct oEGT eg0,eg1,eg_forward,eg_mod,eg_back;
8490: int size,size1;
8491:
8492: mpz_init(inv);
8493: mpz_init(a);
8494: mat = (mpz_t **)mat0;
8495: size = 0;
8496: for ( rank = 0, j = 0; j < col; j++ ) {
8497: for ( i = rank; i < row; i++ ) {
8498: mpz_mod(mat[i][j],mat[i][j],BDY(current_mod_lf));
8499: }
8500: for ( i = rank; i < row; i++ )
8501: if ( mpz_sgn(mat[i][j]) )
8502: break;
8503: if ( i == row ) {
8504: colstat[j] = 0;
8505: continue;
8506: } else
8507: colstat[j] = 1;
8508: if ( i != rank ) {
8509: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
8510: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
8511: }
8512: pivot = mat[rank];
8513: s = sugar[rank];
8514: mpz_invert(inv,pivot[j],BDY(current_mod_lf));
8515: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
8516: if ( mpz_sgn(*pk) ) {
8517: mpz_mul(a,*pk,inv); mpz_mod(*pk,a,BDY(current_mod_lf));
8518: }
8519: for ( i = rank+1; i < row; i++ ) {
8520: t = mat[i];
8521: if ( mpz_sgn(t[j]) ) {
8522: sugar[i] = MAX(sugar[i],s);
8523: mpz_neg(a,t[j]);
8524: red_by_vect_lf(t+j,pivot+j,a,col-j);
8525: }
8526: }
8527: rank++;
8528: }
8529: for ( j = col-1, l = rank-1; j >= 0; j-- )
8530: if ( colstat[j] ) {
8531: pivot = mat[l];
8532: s = sugar[l];
8533: for ( k = j; k < col; k++ )
8534: mpz_mod(pivot[k],pivot[k],BDY(current_mod_lf));
8535: for ( i = 0; i < l; i++ ) {
8536: t = mat[i];
8537: if ( mpz_sgn(t[j]) ) {
8538: sugar[i] = MAX(sugar[i],s);
8539: mpz_neg(a,t[j]);
8540: red_by_vect_lf(t+j,pivot+j,a,col-j);
8541: }
8542: }
8543: l--;
8544: }
8545: for ( j = 0, l = 0; l < rank; j++ )
8546: if ( colstat[j] ) {
8547: t = mat[l];
8548: for ( k = j; k < col; k++ ) {
8549: mpz_mod(t[k],t[k],BDY(current_mod_lf));
8550: }
8551: l++;
8552: }
8553: return rank;
8554: }
8555:
8556:
8557: NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhead,UINT *s0vect)
8558: {
8559: int j,k,len;
8560: UINT *p;
8561: UINT c;
8562: NDV r;
8563: NMV mr0,mr;
8564:
8565: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
8566: if ( !len ) return 0;
8567: else {
8568: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8569: #if 0
8570: ndv_alloc += nmv_adv*len;
8571: #endif
8572: mr = mr0;
8573: p = s0vect;
8574: for ( j = k = 0; j < col; j++, p += nd_wpd )
8575: if ( !rhead[j] ) {
8576: if ( (c = vect[k++]) != 0 ) {
8577: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
8578: }
8579: }
8580: MKNDV(nd_nvar,mr0,len,r);
8581: return r;
8582: }
8583: }
8584:
1.40 noro 8585: NDV vect_to_ndv_s(UINT *vect,int col,UINT *s0vect)
8586: {
8587: int j,k,len;
8588: UINT *p;
8589: UINT c;
8590: NDV r;
8591: NMV mr0,mr;
8592:
8593: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
8594: if ( !len ) return 0;
8595: else {
8596: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8597: mr = mr0;
8598: p = s0vect;
8599: for ( j = k = 0; j < col; j++, p += nd_wpd )
8600: if ( (c = vect[k++]) != 0 ) {
8601: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
8602: }
8603: MKNDV(nd_nvar,mr0,len,r);
8604: return r;
8605: }
8606: }
8607:
1.1 noro 8608: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect)
8609: {
8610: int j,k,len;
8611: UINT *p;
8612: NDV r;
8613: NMV mr0,mr;
8614:
8615: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) len++;
8616: if ( !len ) return 0;
8617: else {
8618: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8619: mr = mr0;
8620: p = s0vect;
8621: for ( j = 0; j < col; j++, p += nd_wpd )
8622: if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) {
8623: ndl_copy(p,DL(mr)); CM(mr) = 1; NMV_ADV(mr);
8624: }
8625: MKNDV(nd_nvar,mr0,len,r);
8626: return r;
8627: }
8628: }
8629:
8630: /* for preprocessed vector */
8631:
8632: NDV vect_to_ndv_q(Z *vect,int spcol,int col,int *rhead,UINT *s0vect)
8633: {
1.6 noro 8634: int j,k,len;
8635: UINT *p;
8636: Z c;
8637: NDV r;
8638: NMV mr0,mr;
1.1 noro 8639:
1.6 noro 8640: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
8641: if ( !len ) return 0;
8642: else {
8643: mr0 = (NMV)MALLOC(nmv_adv*len);
1.1 noro 8644: #if 0
1.6 noro 8645: ndv_alloc += nmv_adv*len;
1.1 noro 8646: #endif
1.6 noro 8647: mr = mr0;
8648: p = s0vect;
8649: for ( j = k = 0; j < col; j++, p += nd_wpd ) {
8650: if ( !rhead[j] ) {
8651: if ( (c = vect[k++]) != 0 ) {
8652: if ( !INT(c) )
8653: error("vect_to_ndv_q : components must be integers");
8654: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
8655: }
8656: }
1.1 noro 8657: }
1.6 noro 8658: MKNDV(nd_nvar,mr0,len,r);
8659: return r;
8660: }
1.1 noro 8661: }
8662:
8663: NDV vect_to_ndv_lf(mpz_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
8664: {
8665: int j,k,len;
8666: UINT *p;
8667: mpz_t c;
8668: NDV r;
8669: NMV mr0,mr;
8670:
8671: for ( j = 0, len = 0; j < spcol; j++ ) if ( mpz_sgn(vect[j]) ) len++;
8672: if ( !len ) return 0;
8673: else {
8674: mr0 = (NMV)MALLOC(nmv_adv*len);
8675: #if 0
8676: ndv_alloc += nmv_adv*len;
8677: #endif
8678: mr = mr0;
8679: p = s0vect;
8680: for ( j = k = 0; j < col; j++, p += nd_wpd )
8681: if ( !rhead[j] ) {
8682: c[0] = vect[k++][0];
8683: if ( mpz_sgn(c) ) {
8684: ndl_copy(p,DL(mr)); MPZTOZ(c,CZ(mr)); NMV_ADV(mr);
8685: }
8686: }
8687: MKNDV(nd_nvar,mr0,len,r);
8688: return r;
8689: }
8690: }
8691:
8692: /* for plain vector */
8693:
8694: NDV plain_vect_to_ndv_q(Z *vect,int col,UINT *s0vect)
8695: {
8696: int j,k,len;
8697: UINT *p;
8698: Z c;
8699: NDV r;
8700: NMV mr0,mr;
8701:
8702: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
8703: if ( !len ) return 0;
8704: else {
8705: mr0 = (NMV)MALLOC(nmv_adv*len);
8706: #if 0
8707: ndv_alloc += nmv_adv*len;
8708: #endif
8709: mr = mr0;
8710: p = s0vect;
8711: for ( j = k = 0; j < col; j++, p += nd_wpd, k++ )
8712: if ( (c = vect[k]) != 0 ) {
8713: if ( !INT(c) )
1.6 noro 8714: error("plain_vect_to_ndv_q : components must be integers");
8715: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
1.1 noro 8716: }
8717: MKNDV(nd_nvar,mr0,len,r);
8718: return r;
8719: }
8720: }
8721:
8722: int nd_sp_f4(int m,int trace,ND_pairs l,PGeoBucket bucket)
8723: {
8724: ND_pairs t;
8725: NODE sp0,sp;
8726: int stat;
8727: ND spol;
8728:
8729: for ( t = l; t; t = NEXT(t) ) {
8730: stat = nd_sp(m,trace,t,&spol);
8731: if ( !stat ) return 0;
8732: if ( spol ) {
8733: add_pbucket_symbolic(bucket,spol);
8734: }
8735: }
8736: return 1;
8737: }
8738:
8739: int nd_symbolic_preproc(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
8740: {
8741: NODE rp0,rp;
8742: NM mul,head,s0,s;
8743: int index,col,i,sugar;
8744: RHist h;
8745: UINT *s0v,*p;
8746: NM_ind_pair pair;
8747: ND red;
8748: NDV *ps;
8749:
8750: s0 = 0; rp0 = 0; col = 0;
8751: if ( nd_demand )
8752: ps = trace?nd_ps_trace_sym:nd_ps_sym;
8753: else
8754: ps = trace?nd_ps_trace:nd_ps;
8755: while ( 1 ) {
8756: head = remove_head_pbucket_symbolic(bucket);
8757: if ( !head ) break;
8758: if ( !s0 ) s0 = head;
8759: else NEXT(s) = head;
8760: s = head;
8761: index = ndl_find_reducer(DL(head));
8762: if ( index >= 0 ) {
8763: h = nd_psh[index];
8764: NEWNM(mul);
8765: ndl_sub(DL(head),DL(h),DL(mul));
8766: if ( ndl_check_bound2(index,DL(mul)) )
8767: return 0;
8768: sugar = TD(DL(mul))+SG(ps[index]);
1.28 noro 8769: MKNM_ind_pair(pair,mul,index,sugar,0);
1.1 noro 8770: red = ndv_mul_nm_symbolic(mul,ps[index]);
8771: add_pbucket_symbolic(bucket,nd_remove_head(red));
8772: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
8773: }
8774: col++;
8775: }
8776: if ( rp0 ) NEXT(rp) = 0;
8777: NEXT(s) = 0;
8778: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
8779: for ( i = 0, p = s0v, s = s0; i < col;
8780: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
8781: *s0vect = s0v;
8782: *r = rp0;
8783: return col;
8784: }
8785:
8786: void print_ndp(ND_pairs l)
8787: {
8788: ND_pairs t;
8789:
8790: for ( t = l; t; t = NEXT(t) )
8791: printf("[%d,%d] ",t->i1,t->i2);
8792: printf("\n");
8793: }
8794:
8795: NODE nd_f4(int m,int checkonly,int **indp)
8796: {
8797: int i,nh,stat,index,f4red;
8798: NODE r,g,tn0,tn,node;
8799: ND_pairs d,l,t,ll0,ll,lh;
8800: LIST l0,l1;
8801: ND spol,red;
8802: NDV nf,redv;
8803: NM s0,s;
8804: NODE rp0,srp0,nflist,nzlist,nzlist_t;
8805: int nsp,nred,col,rank,len,k,j,a,i1s,i2s;
8806: UINT c;
8807: UINT **spmat;
8808: UINT *s0vect,*svect,*p,*v;
8809: int *colstat;
8810: IndArray *imat;
8811: int *rhead;
8812: int spcol,sprow;
8813: int sugar,sugarh;
8814: PGeoBucket bucket;
8815: struct oEGT eg0,eg1,eg_f4;
8816: Z i1,i2,sugarq;
1.12 noro 8817:
8818: init_eg(&f4_symb); init_eg(&f4_conv); init_eg(&f4_conv); init_eg(&f4_elim1); init_eg(&f4_elim2);
1.1 noro 8819: #if 0
8820: ndv_alloc = 0;
8821: #endif
1.11 noro 8822: Nf4_red=0;
1.1 noro 8823: g = 0; d = 0;
8824: for ( i = 0; i < nd_psn; i++ ) {
8825: d = update_pairs(d,g,i,0);
8826: g = update_base(g,i);
8827: }
8828: nzlist = 0;
8829: nzlist_t = nd_nzlist;
8830: f4red = 1;
8831: nd_last_nonzero = 0;
8832: while ( d ) {
8833: get_eg(&eg0);
8834: l = nd_minsugarp(d,&d);
8835: sugar = nd_sugarweight?l->sugar2:SG(l);
8836: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
8837: if ( nzlist_t ) {
8838: node = BDY((LIST)BDY(nzlist_t));
1.6 noro 8839: sugarh = ZTOS((Q)ARG0(node));
1.1 noro 8840: tn = BDY((LIST)ARG1(node));
8841: if ( !tn ) {
8842: nzlist_t = NEXT(nzlist_t);
8843: continue;
8844: }
8845: /* tn = [[i1,i2],...] */
8846: lh = nd_ipairtospair(tn);
8847: }
8848: bucket = create_pbucket();
8849: stat = nd_sp_f4(m,0,l,bucket);
8850: if ( !stat ) {
8851: for ( t = l; NEXT(t); t = NEXT(t) );
8852: NEXT(t) = d; d = l;
8853: d = nd_reconstruct(0,d);
8854: continue;
8855: }
8856: if ( bucket->m < 0 ) continue;
8857: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
8858: if ( !col ) {
8859: for ( t = l; NEXT(t); t = NEXT(t) );
8860: NEXT(t) = d; d = l;
8861: d = nd_reconstruct(0,d);
8862: continue;
8863: }
1.12 noro 8864: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); add_eg(&f4_symb,&eg0,&eg1);
1.1 noro 8865: if ( DP_Print )
1.6 noro 8866: fprintf(asir_out,"sugar=%d,symb=%.3fsec,",
1.5 noro 8867: sugar,eg_f4.exectime);
1.1 noro 8868: nflist = nd_f4_red(m,nd_nzlist?lh:l,0,s0vect,col,rp0,nd_gentrace?&ll:0);
8869: if ( checkonly && nflist ) return 0;
8870: /* adding new bases */
8871: if ( nflist ) nd_last_nonzero = f4red;
8872: for ( r = nflist; r; r = NEXT(r) ) {
8873: nf = (NDV)BDY(r);
1.38 noro 8874: if ( nd_f4_td ) SG(nf) = nd_tdeg(nf);
1.1 noro 8875: ndv_removecont(m,nf);
8876: if ( !m && nd_nalg ) {
8877: ND nf1;
8878:
8879: nf1 = ndvtond(m,nf);
8880: nd_monic(0,&nf1);
8881: nd_removecont(m,nf1);
8882: nf = ndtondv(m,nf1);
8883: }
1.24 noro 8884: nh = ndv_newps(m,nf,0);
1.1 noro 8885: d = update_pairs(d,g,nh,0);
8886: g = update_base(g,nh);
8887: }
8888: if ( DP_Print ) {
8889: fprintf(asir_out,"f4red=%d,gblen=%d\n",f4red,length(g)); fflush(asir_out);
8890: }
8891: if ( nd_gentrace ) {
8892: for ( t = ll, tn0 = 0; t; t = NEXT(t) ) {
8893: NEXTNODE(tn0,tn);
1.6 noro 8894: STOZ(t->i1,i1); STOZ(t->i2,i2);
1.1 noro 8895: node = mknode(2,i1,i2); MKLIST(l0,node);
8896: BDY(tn) = l0;
8897: }
8898: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
1.6 noro 8899: STOZ(sugar,sugarq); node = mknode(2,sugarq,l0); MKLIST(l1,node);
1.1 noro 8900: MKNODE(node,l1,nzlist); nzlist = node;
8901: }
8902: if ( nd_nzlist ) nzlist_t = NEXT(nzlist_t);
8903: f4red++;
8904: if ( nd_f4red && f4red > nd_f4red ) break;
8905: if ( nd_rank0 && !nflist ) break;
8906: }
8907: if ( nd_gentrace ) {
8908: MKLIST(l0,reverse_node(nzlist));
8909: MKNODE(nd_alltracelist,l0,0);
8910: }
8911: #if 0
8912: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
8913: #endif
1.12 noro 8914: if ( DP_Print ) {
8915: fprintf(asir_out,"number of red=%d,",Nf4_red);
8916: fprintf(asir_out,"symb=%.3fsec,conv=%.3fsec,elim1=%.3fsec,elim2=%.3fsec\n",
8917: f4_symb.exectime,f4_conv.exectime,f4_elim1.exectime,f4_elim2.exectime);
1.41 noro 8918: fprintf(asir_out,"number of removed pairs=%d\n,",NcriB+NcriMF+Ncri2);
1.12 noro 8919: }
1.1 noro 8920: conv_ilist(nd_demand,0,g,indp);
8921: return g;
8922: }
8923:
8924: NODE nd_f4_trace(int m,int **indp)
8925: {
8926: int i,nh,stat,index;
8927: NODE r,g;
8928: ND_pairs d,l,l0,t;
8929: ND spol,red;
8930: NDV nf,redv,nfqv,nfv;
8931: NM s0,s;
8932: NODE rp0,srp0,nflist;
8933: int nsp,nred,col,rank,len,k,j,a;
8934: UINT c;
8935: UINT **spmat;
8936: UINT *s0vect,*svect,*p,*v;
8937: int *colstat;
8938: IndArray *imat;
8939: int *rhead;
8940: int spcol,sprow;
8941: int sugar;
8942: PGeoBucket bucket;
8943: struct oEGT eg0,eg1,eg_f4;
8944:
8945: g = 0; d = 0;
8946: for ( i = 0; i < nd_psn; i++ ) {
8947: d = update_pairs(d,g,i,0);
8948: g = update_base(g,i);
8949: }
8950: while ( d ) {
8951: get_eg(&eg0);
8952: l = nd_minsugarp(d,&d);
8953: sugar = SG(l);
8954: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
8955: bucket = create_pbucket();
8956: stat = nd_sp_f4(m,0,l,bucket);
8957: if ( !stat ) {
8958: for ( t = l; NEXT(t); t = NEXT(t) );
8959: NEXT(t) = d; d = l;
8960: d = nd_reconstruct(1,d);
8961: continue;
8962: }
8963: if ( bucket->m < 0 ) continue;
8964: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
8965: if ( !col ) {
8966: for ( t = l; NEXT(t); t = NEXT(t) );
8967: NEXT(t) = d; d = l;
8968: d = nd_reconstruct(1,d);
8969: continue;
8970: }
8971: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
8972: if ( DP_Print )
1.3 noro 8973: fprintf(asir_out,"\nsugar=%d,symb=%.3fsec,",
1.5 noro 8974: sugar,eg_f4.exectime);
1.1 noro 8975: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
8976: if ( !l0 ) continue;
8977: l = l0;
8978:
8979: /* over Q */
8980: bucket = create_pbucket();
8981: stat = nd_sp_f4(0,1,l,bucket);
8982: if ( !stat ) {
8983: for ( t = l; NEXT(t); t = NEXT(t) );
8984: NEXT(t) = d; d = l;
8985: d = nd_reconstruct(1,d);
8986: continue;
8987: }
8988: if ( bucket->m < 0 ) continue;
8989: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
8990: if ( !col ) {
8991: for ( t = l; NEXT(t); t = NEXT(t) );
8992: NEXT(t) = d; d = l;
8993: d = nd_reconstruct(1,d);
8994: continue;
8995: }
8996: nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0);
8997: /* adding new bases */
8998: for ( r = nflist; r; r = NEXT(r) ) {
8999: nfqv = (NDV)BDY(r);
9000: ndv_removecont(0,nfqv);
1.6 noro 9001: if ( !remqi((Q)HCZ(nfqv),m) ) return 0;
1.1 noro 9002: if ( nd_nalg ) {
9003: ND nf1;
9004:
9005: nf1 = ndvtond(m,nfqv);
9006: nd_monic(0,&nf1);
9007: nd_removecont(0,nf1);
9008: nfqv = ndtondv(0,nf1); nd_free(nf1);
9009: }
9010: nfv = ndv_dup(0,nfqv);
9011: ndv_mod(m,nfv);
9012: ndv_removecont(m,nfv);
1.24 noro 9013: nh = ndv_newps(0,nfv,nfqv);
1.1 noro 9014: d = update_pairs(d,g,nh,0);
9015: g = update_base(g,nh);
9016: }
9017: }
9018: #if 0
9019: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
9020: #endif
9021: conv_ilist(nd_demand,1,g,indp);
9022: return g;
9023: }
9024:
9025: int rref(matrix mat,int *sugar)
9026: {
9027: int row,col,i,j,k,l,s,wcol,wj;
9028: unsigned long bj;
9029: unsigned long **a;
9030: unsigned long *ai,*ak,*as,*t;
9031: int *pivot;
9032:
9033: row = mat->row;
9034: col = mat->col;
9035: a = mat->a;
9036: wcol = (col+BLEN-1)/BLEN;
9037: pivot = (int *)MALLOC_ATOMIC(row*sizeof(int));
9038: i = 0;
9039: for ( j = 0; j < col; j++ ) {
9040: wj = j/BLEN; bj = 1L<<(j%BLEN);
9041: for ( k = i; k < row; k++ )
9042: if ( a[k][wj] & bj ) break;
9043: if ( k == row ) continue;
9044: pivot[i] = j;
9045: if ( k != i ) {
9046: t = a[i]; a[i] = a[k]; a[k] = t;
9047: s = sugar[i]; sugar[i] = sugar[k]; sugar[k] = s;
9048: }
9049: ai = a[i];
9050: for ( k = i+1; k < row; k++ ) {
9051: ak = a[k];
9052: if ( ak[wj] & bj ) {
9053: for ( l = wj; l < wcol; l++ )
9054: ak[l] ^= ai[l];
9055: sugar[k] = MAX(sugar[k],sugar[i]);
9056: }
9057: }
9058: i++;
9059: }
9060: for ( k = i-1; k >= 0; k-- ) {
9061: j = pivot[k]; wj = j/BLEN; bj = 1L<<(j%BLEN);
9062: ak = a[k];
9063: for ( s = 0; s < k; s++ ) {
9064: as = a[s];
9065: if ( as[wj] & bj ) {
9066: for ( l = wj; l < wcol; l++ )
9067: as[l] ^= ak[l];
9068: sugar[s] = MAX(sugar[s],sugar[k]);
9069: }
9070: }
9071: }
9072: return i;
9073: }
9074:
9075: void print_matrix(matrix mat)
9076: {
9077: int row,col,i,j;
9078: unsigned long *ai;
9079:
9080: row = mat->row;
9081: col = mat->col;
9082: printf("%d x %d\n",row,col);
9083: for ( i = 0; i < row; i++ ) {
9084: ai = mat->a[i];
9085: for ( j = 0; j < col; j++ ) {
9086: if ( ai[j/BLEN] & (1L<<(j%BLEN)) ) putchar('1');
9087: else putchar('0');
9088: }
9089: putchar('\n');
9090: }
9091: }
9092:
9093: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect);
9094:
9095: void red_by_vect_2(matrix mat,int *sugar,unsigned long *v,int rhead,int rsugar)
9096: {
9097: int row,col,wcol,wj,i,j;
9098: unsigned long bj;
9099: unsigned long *ai;
9100: unsigned long **a;
9101: int len;
9102: int *pos;
9103:
9104: row = mat->row;
9105: col = mat->col;
9106: wcol = (col+BLEN-1)/BLEN;
9107: pos = (int *)MALLOC(wcol*sizeof(int));
9108: bzero(pos,wcol*sizeof(int));
9109: for ( i = j = 0; i < wcol; i++ )
9110: if ( v[i] ) pos[j++] = i;;
9111: len = j;
9112: wj = rhead/BLEN;
9113: bj = 1L<<rhead%BLEN;
9114: a = mat->a;
9115: for ( i = 0; i < row; i++ ) {
9116: ai = a[i];
9117: if ( ai[wj]&bj ) {
9118: for ( j = 0; j < len; j++ )
9119: ai[pos[j]] ^= v[pos[j]];
9120: sugar[i] = MAX(sugar[i],rsugar);
9121: }
9122: }
9123: }
9124:
9125: NODE nd_f4_red_2(ND_pairs sp0,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
9126: {
9127: int nsp,nred,i,i0,k,rank,row;
9128: NODE r0,rp;
9129: ND_pairs sp;
9130: ND spol;
9131: NM_ind_pair rt;
9132: int *s0hash;
9133: UINT *s;
9134: int *pivot,*sugar,*head;
9135: matrix mat;
9136: NM m;
9137: NODE r;
9138: struct oEGT eg0,eg1,eg2,eg_elim1,eg_elim2;
9139: int rhead,rsugar,size;
9140: unsigned long *v;
9141:
9142: get_eg(&eg0);
9143: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
9144: nred = length(rp0);
9145: mat = alloc_matrix(nsp,col);
9146: s0hash = (int *)MALLOC(col*sizeof(int));
9147: for ( i = 0, s = s0vect; i < col; i++, s += nd_wpd )
9148: s0hash[i] = ndl_hash_value(s);
9149:
9150: sugar = (int *)MALLOC(nsp*sizeof(int));
9151: for ( i = 0, sp = sp0; sp; sp = NEXT(sp) ) {
9152: nd_sp(2,0,sp,&spol);
9153: if ( spol ) {
9154: mat->a[i] = nd_to_vect_2(s0vect,col,s0hash,spol);
9155: sugar[i] = SG(spol);
9156: i++;
9157: }
9158: }
9159: mat->row = i;
9160: if ( DP_Print ) {
9161: fprintf(asir_out,"%dx%d,",mat->row,mat->col); fflush(asir_out);
9162: }
9163: size = ((col+BLEN-1)/BLEN)*sizeof(unsigned long);
9164: v = CALLOC((col+BLEN-1)/BLEN,sizeof(unsigned long));
9165: for ( rp = rp0, i = 0; rp; rp = NEXT(rp), i++ ) {
9166: rt = (NM_ind_pair)BDY(rp);
9167: bzero(v,size);
9168: rhead = nd_nm_to_vect_2(s0vect,col,s0hash,nd_ps[rt->index],rt->mul,v);
9169: rsugar = SG(nd_ps[rt->index])+TD(DL(rt->mul));
9170: red_by_vect_2(mat,sugar,v,rhead,rsugar);
9171: }
9172:
9173: get_eg(&eg1);
9174: init_eg(&eg_elim1); add_eg(&eg_elim1,&eg0,&eg1);
9175: rank = rref(mat,sugar);
9176:
9177: for ( i = 0, r0 = 0; i < rank; i++ ) {
9178: NEXTNODE(r0,r);
9179: BDY(r) = (pointer)vect_to_ndv_2(mat->a[i],col,s0vect);
9180: SG((NDV)BDY(r)) = sugar[i];
9181: }
9182: if ( r0 ) NEXT(r) = 0;
9183: get_eg(&eg2);
9184: init_eg(&eg_elim2); add_eg(&eg_elim2,&eg1,&eg2);
9185: if ( DP_Print ) {
9186: fprintf(asir_out,"elim1=%.3fsec,elim2=%.3fsec,",
1.5 noro 9187: eg_elim1.exectime,eg_elim2.exectime);
1.1 noro 9188: fflush(asir_out);
9189: }
9190: return r0;
9191: }
9192:
9193:
9194: NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
9195: {
9196: IndArray *imat;
1.11 noro 9197: int nsp,nred,i,start;
1.1 noro 9198: int *rhead;
9199: NODE r0,rp;
9200: ND_pairs sp;
9201: NM_ind_pair *rvect;
9202: UINT *s;
9203: int *s0hash;
1.11 noro 9204: struct oEGT eg0,eg1,eg_conv;
1.1 noro 9205:
9206: if ( m == 2 && nd_rref2 )
9207: return nd_f4_red_2(sp0,s0vect,col,rp0,nz);
9208:
9209: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
9210: nred = length(rp0);
9211: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
9212: rhead = (int *)MALLOC(col*sizeof(int));
9213: for ( i = 0; i < col; i++ ) rhead[i] = 0;
9214:
9215: /* construction of index arrays */
1.11 noro 9216: get_eg(&eg0);
1.1 noro 9217: if ( DP_Print ) {
1.11 noro 9218: fprintf(asir_out,"%dx%d,",nsp+nred,col);
9219: fflush(asir_out);
1.1 noro 9220: }
9221: rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
1.11 noro 9222: for ( start = 0, rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
1.1 noro 9223: rvect[i] = (NM_ind_pair)BDY(rp);
1.11 noro 9224: imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,rvect[i],start);
1.1 noro 9225: rhead[imat[i]->head] = 1;
1.11 noro 9226: start = imat[i]->head;
9227: }
1.12 noro 9228: get_eg(&eg1); init_eg(&eg_conv); add_eg(&eg_conv,&eg0,&eg1); add_eg(&f4_conv,&eg0,&eg1);
1.11 noro 9229: if ( DP_Print ) {
9230: fprintf(asir_out,"conv=%.3fsec,",eg_conv.exectime);
9231: fflush(asir_out);
1.1 noro 9232: }
9233: if ( m > 0 )
1.7 noro 9234: #if SIZEOF_LONG==8
1.1 noro 9235: r0 = nd_f4_red_mod64_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
9236: #else
9237: r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
9238: #endif
9239: else if ( m == -1 )
9240: r0 = nd_f4_red_sf_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz);
9241: else if ( m == -2 )
9242: r0 = nd_f4_red_lf_main(m,sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
9243: else
9244: r0 = nd_f4_red_q_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
9245: return r0;
9246: }
9247:
9248: /* for Fp, 2<=p<2^16 */
9249:
9250: NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9251: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
9252: {
9253: int spcol,sprow,a;
9254: int i,j,k,l,rank;
9255: NODE r0,r;
9256: ND_pairs sp;
9257: ND spol;
9258: UINT **spmat;
9259: UINT *svect,*v;
9260: int *colstat;
9261: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9262: int maxrs;
9263: int *spsugar;
9264: ND_pairs *spactive;
9265:
9266: spcol = col-nred;
9267: get_eg(&eg0);
9268: /* elimination (1st step) */
9269: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9270: svect = (UINT *)MALLOC(col*sizeof(UINT));
9271: spsugar = (int *)MALLOC(nsp*sizeof(int));
9272: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
9273: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9274: nd_sp(m,0,sp,&spol);
9275: if ( !spol ) continue;
9276: nd_to_vect(m,s0vect,col,spol,svect);
9277: if ( m == -1 )
9278: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
9279: else
1.40 noro 9280: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred,0);
1.1 noro 9281: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9282: if ( i < col ) {
9283: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
9284: for ( j = k = 0; j < col; j++ )
9285: if ( !rhead[j] ) v[k++] = svect[j];
9286: spsugar[sprow] = MAX(maxrs,SG(spol));
9287: if ( nz )
9288: spactive[sprow] = sp;
9289: sprow++;
9290: }
9291: nd_free(spol);
9292: }
9293: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9294: if ( DP_Print ) {
1.5 noro 9295: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9296: fflush(asir_out);
9297: }
9298: /* free index arrays */
9299: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9300:
9301: /* elimination (2nd step) */
9302: colstat = (int *)MALLOC(spcol*sizeof(int));
9303: if ( m == -1 )
9304: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
9305: else
9306: rank = nd_gauss_elim_mod(spmat,spsugar,spactive,sprow,spcol,m,colstat);
9307: r0 = 0;
9308: for ( i = 0; i < rank; i++ ) {
9309: NEXTNODE(r0,r); BDY(r) =
9310: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
9311: SG((NDV)BDY(r)) = spsugar[i];
9312: GCFREE(spmat[i]);
9313: }
9314: if ( r0 ) NEXT(r) = 0;
9315:
9316: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
9317: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9318: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9319: if ( DP_Print ) {
1.5 noro 9320: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9321: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9322: nsp,nred,sprow,spcol,rank);
1.5 noro 9323: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9324: }
9325: if ( nz ) {
9326: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
9327: if ( rank > 0 ) {
9328: NEXT(spactive[rank-1]) = 0;
9329: *nz = spactive[0];
9330: } else
9331: *nz = 0;
9332: }
9333: return r0;
9334: }
9335:
1.40 noro 9336: NODE nd_f4_red_main_s(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9337: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,NODE *syzlistp)
9338: {
9339: int spcol,sprow,a;
9340: int i,j,k,l,rank;
9341: NODE r0,r;
9342: ND_pairs sp;
9343: ND spol;
9344: UINT **spmat;
9345: UINT *svect,*cvect;
9346: UINT *v;
9347: int *colstat;
9348: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9349: int maxrs;
9350: int *spsugar;
9351: ND_pairs *spactive;
9352: SIG *spsig;
9353:
9354: get_eg(&eg0);
9355: /* elimination (1st step) */
9356: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9357: spsugar = (int *)MALLOC(nsp*sizeof(int));
9358: spsig = (SIG *)MALLOC(nsp*sizeof(SIG));
9359: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9360: nd_sp(m,0,sp,&spol);
9361: if ( !spol ) {
9362: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
9363: continue;
9364: }
9365: svect = (UINT *)MALLOC(col*sizeof(UINT));
9366: nd_to_vect(m,s0vect,col,spol,svect);
9367: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred,spol->sig);
9368: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9369: if ( i < col ) {
9370: spmat[sprow] = svect;
9371: spsugar[sprow] = MAX(maxrs,SG(spol));
9372: spsig[sprow] = sp->sig;
9373: sprow++;
9374: } else {
9375: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
9376: }
9377: nd_free(spol);
9378: }
9379: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
9380: if ( DP_Print ) {
9381: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
9382: fflush(asir_out);
9383: }
9384: /* free index arrays */
9385: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9386:
9387: /* elimination (2nd step) */
9388: colstat = (int *)MALLOC(col*sizeof(int));
9389: rank = nd_gauss_elim_mod_s(spmat,spsugar,0,sprow,col,m,colstat,spsig);
9390: r0 = 0;
9391: for ( i = 0; i < sprow; i++ ) {
9392: if ( spsugar[i] >= 0 ) {
9393: NEXTNODE(r0,r);
9394: BDY(r) = vect_to_ndv_s(spmat[i],col,s0vect);
9395: SG((NDV)BDY(r)) = spsugar[i];
9396: ((NDV)BDY(r))->sig = spsig[i];
9397: } else
9398: syzlistp[spsig[i]->pos] = insert_sig(syzlistp[spsig[i]->pos],spsig[i]);
9399: GCFREE(spmat[i]);
9400: }
9401: if ( r0 ) NEXT(r) = 0;
9402: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
9403: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9404: if ( DP_Print ) {
9405: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
9406: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9407: nsp,nred,sprow,col,rank);
9408: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
9409: }
9410: return r0;
9411: }
9412:
1.1 noro 9413:
9414: /* for small finite fields */
9415:
9416: NODE nd_f4_red_sf_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9417: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
9418: {
9419: int spcol,sprow,a;
9420: int i,j,k,l,rank;
9421: NODE r0,r;
9422: ND_pairs sp;
9423: ND spol;
9424: UINT **spmat;
9425: UINT *svect,*v;
9426: int *colstat;
9427: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9428: int maxrs;
9429: int *spsugar;
9430: ND_pairs *spactive;
9431:
9432: spcol = col-nred;
9433: get_eg(&eg0);
9434: /* elimination (1st step) */
9435: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9436: svect = (UINT *)MALLOC(col*sizeof(UINT));
9437: spsugar = (int *)MALLOC(nsp*sizeof(int));
9438: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
9439: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9440: nd_sp(m,0,sp,&spol);
9441: if ( !spol ) continue;
9442: nd_to_vect(m,s0vect,col,spol,svect);
9443: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
9444: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9445: if ( i < col ) {
9446: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
9447: for ( j = k = 0; j < col; j++ )
9448: if ( !rhead[j] ) v[k++] = svect[j];
9449: spsugar[sprow] = MAX(maxrs,SG(spol));
9450: if ( nz )
9451: spactive[sprow] = sp;
9452: sprow++;
9453: }
9454: nd_free(spol);
9455: }
9456: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9457: if ( DP_Print ) {
1.5 noro 9458: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9459: fflush(asir_out);
9460: }
9461: /* free index arrays */
9462: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9463:
9464: /* elimination (2nd step) */
9465: colstat = (int *)MALLOC(spcol*sizeof(int));
9466: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
9467: r0 = 0;
9468: for ( i = 0; i < rank; i++ ) {
9469: NEXTNODE(r0,r); BDY(r) =
9470: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
9471: SG((NDV)BDY(r)) = spsugar[i];
9472: GCFREE(spmat[i]);
9473: }
9474: if ( r0 ) NEXT(r) = 0;
9475:
9476: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
9477: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9478: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9479: if ( DP_Print ) {
1.5 noro 9480: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9481: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9482: nsp,nred,sprow,spcol,rank);
1.5 noro 9483: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9484: }
9485: if ( nz ) {
9486: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
9487: if ( rank > 0 ) {
9488: NEXT(spactive[rank-1]) = 0;
9489: *nz = spactive[0];
9490: } else
9491: *nz = 0;
9492: }
9493: return r0;
9494: }
9495:
9496: NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
9497: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
9498: {
9499: int spcol,sprow,a;
9500: int i,j,k,l,rank;
9501: NODE r0,r;
9502: ND_pairs sp;
9503: ND spol;
9504: mpz_t **spmat;
9505: mpz_t *svect,*v;
9506: int *colstat;
9507: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9508: int maxrs;
9509: int *spsugar;
9510: pointer *w;
9511:
9512: spcol = col-nred;
9513: get_eg(&eg0);
9514: /* elimination (1st step) */
9515: spmat = (mpz_t **)MALLOC(nsp*sizeof(mpz_t *));
9516: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
9517: spsugar = (int *)MALLOC(nsp*sizeof(int));
9518: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9519: nd_sp(m,trace,sp,&spol);
9520: if ( !spol ) continue;
9521: nd_to_vect_lf(s0vect,col,spol,svect);
9522: maxrs = ndv_reduce_vect_lf(svect,trace,col,imat,rvect,nred);
9523: for ( i = 0; i < col; i++ ) if ( mpz_sgn(svect[i]) ) break;
9524: if ( i < col ) {
9525: spmat[sprow] = v = (mpz_t *)MALLOC(spcol*sizeof(mpz_t));
9526: for ( j = k = 0; j < col; j++ )
9527: if ( !rhead[j] ) v[k++][0] = svect[j][0];
9528: spsugar[sprow] = MAX(maxrs,SG(spol));
9529: sprow++;
9530: }
9531: /* nd_free(spol); */
9532: }
9533: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9534: if ( DP_Print ) {
1.5 noro 9535: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9536: fflush(asir_out);
9537: }
9538: /* free index arrays */
9539: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
9540:
9541: /* elimination (2nd step) */
9542: colstat = (int *)MALLOC(spcol*sizeof(int));
9543: rank = nd_gauss_elim_lf(spmat,spsugar,sprow,spcol,colstat);
9544: w = (pointer *)MALLOC(rank*sizeof(pointer));
9545: for ( i = 0; i < rank; i++ ) {
9546: #if 0
9547: w[rank-i-1] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
9548: SG((NDV)w[rank-i-1]) = spsugar[i];
9549: #else
9550: w[i] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
9551: SG((NDV)w[i]) = spsugar[i];
9552: #endif
9553: /* GCFREE(spmat[i]); */
9554:
9555: }
9556: #if 0
9557: qsort(w,rank,sizeof(NDV),
9558: (int (*)(const void *,const void *))ndv_compare);
9559: #endif
9560: r0 = 0;
9561: for ( i = 0; i < rank; i++ ) {
9562: NEXTNODE(r0,r); BDY(r) = w[i];
9563: }
9564: if ( r0 ) NEXT(r) = 0;
9565:
9566: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
9567: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9568: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9569: if ( DP_Print ) {
1.5 noro 9570: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9571: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9572: nsp,nred,sprow,spcol,rank);
1.5 noro 9573: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9574: }
9575: return r0;
9576: }
9577:
9578: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
9579: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
9580: {
9581: int spcol,sprow,a;
9582: int i,j,k,l,rank;
9583: NODE r0,r;
9584: ND_pairs sp;
9585: ND spol;
9586: Z **spmat;
9587: Z *svect,*v;
9588: int *colstat;
9589: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9590: int maxrs;
9591: int *spsugar;
9592: pointer *w;
9593:
9594: spcol = col-nred;
9595: get_eg(&eg0);
9596: /* elimination (1st step) */
9597: spmat = (Z **)MALLOC(nsp*sizeof(Q *));
9598: svect = (Z *)MALLOC(col*sizeof(Q));
9599: spsugar = (int *)MALLOC(nsp*sizeof(int));
9600: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9601: nd_sp(0,trace,sp,&spol);
9602: if ( !spol ) continue;
9603: nd_to_vect_q(s0vect,col,spol,svect);
9604: maxrs = ndv_reduce_vect_q(svect,trace,col,imat,rvect,nred);
9605: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9606: if ( i < col ) {
9607: spmat[sprow] = v = (Z *)MALLOC(spcol*sizeof(Q));
9608: for ( j = k = 0; j < col; j++ )
9609: if ( !rhead[j] ) v[k++] = svect[j];
9610: spsugar[sprow] = MAX(maxrs,SG(spol));
9611: sprow++;
9612: }
9613: /* nd_free(spol); */
9614: }
9615: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9616: if ( DP_Print ) {
1.5 noro 9617: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9618: fflush(asir_out);
9619: }
9620: /* free index arrays */
9621: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
9622:
9623: /* elimination (2nd step) */
9624: colstat = (int *)MALLOC(spcol*sizeof(int));
9625: rank = nd_gauss_elim_q(spmat,spsugar,sprow,spcol,colstat);
9626: w = (pointer *)MALLOC(rank*sizeof(pointer));
9627: for ( i = 0; i < rank; i++ ) {
9628: #if 0
9629: w[rank-i-1] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
9630: SG((NDV)w[rank-i-1]) = spsugar[i];
9631: #else
9632: w[i] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
9633: SG((NDV)w[i]) = spsugar[i];
9634: #endif
9635: /* GCFREE(spmat[i]); */
9636: }
9637: #if 0
9638: qsort(w,rank,sizeof(NDV),
9639: (int (*)(const void *,const void *))ndv_compare);
9640: #endif
9641: r0 = 0;
9642: for ( i = 0; i < rank; i++ ) {
9643: NEXTNODE(r0,r); BDY(r) = w[i];
9644: }
9645: if ( r0 ) NEXT(r) = 0;
9646:
9647: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
9648: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9649: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9650: if ( DP_Print ) {
1.5 noro 9651: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9652: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9653: nsp,nred,sprow,spcol,rank);
1.5 noro 9654: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9655: }
9656: return r0;
9657: }
9658:
9659: FILE *nd_write,*nd_read;
9660:
9661: void nd_send_int(int a) {
9662: write_int(nd_write,(unsigned int *)&a);
9663: }
9664:
9665: void nd_send_intarray(int *p,int len) {
9666: write_intarray(nd_write,(unsigned int *)p,len);
9667: }
9668:
9669: int nd_recv_int() {
9670: int a;
9671:
9672: read_int(nd_read,(unsigned int *)&a);
9673: return a;
9674: }
9675:
9676: void nd_recv_intarray(int *p,int len) {
9677: read_intarray(nd_read,(unsigned int *)p,len);
9678: }
9679:
9680: void nd_send_ndv(NDV p) {
9681: int len,i;
9682: NMV m;
9683:
9684: if ( !p ) nd_send_int(0);
9685: else {
9686: len = LEN(p);
9687: nd_send_int(len);
9688: m = BDY(p);
9689: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
9690: nd_send_int(CM(m));
9691: nd_send_intarray((int *)DL(m),nd_wpd);
9692: }
9693: }
9694: }
9695:
9696: void nd_send_nd(ND p) {
9697: int len,i;
9698: NM m;
9699:
9700: if ( !p ) nd_send_int(0);
9701: else {
9702: len = LEN(p);
9703: nd_send_int(len);
9704: m = BDY(p);
9705: for ( i = 0; i < len; i++, m = NEXT(m) ) {
9706: nd_send_int(CM(m));
9707: nd_send_intarray((int *)DL(m),nd_wpd);
9708: }
9709: }
9710: }
9711:
9712: NDV nd_recv_ndv()
9713: {
9714: int len,i;
9715: NMV m,m0;
9716: NDV r;
9717:
9718: len = nd_recv_int();
9719: if ( !len ) return 0;
9720: else {
9721: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
9722: #if 0
9723: ndv_alloc += len*nmv_adv;
9724: #endif
9725: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
9726: CM(m) = nd_recv_int();
9727: nd_recv_intarray((int *)DL(m),nd_wpd);
9728: }
9729: MKNDV(nd_nvar,m0,len,r);
9730: return r;
9731: }
9732: }
9733:
9734: int nd_gauss_elim_q(Z **mat0,int *sugar,int row,int col,int *colstat)
9735: {
9736: int i,j,t,c,rank,inv;
9737: int *ci,*ri;
9738: Z dn;
9739: MAT m,nm;
9740:
9741: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
9742: rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci);
9743: for ( i = 0; i < row; i++ )
9744: for ( j = 0; j < col; j++ )
9745: mat0[i][j] = 0;
9746: c = col-rank;
9747: for ( i = 0; i < rank; i++ ) {
9748: mat0[i][ri[i]] = dn;
9749: for ( j = 0; j < c; j++ )
9750: mat0[i][ci[j]] = (Z)BDY(nm)[i][j];
9751: }
9752: return rank;
9753: }
9754:
9755: int nd_gauss_elim_mod(UINT **mat0,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
9756: {
9757: int i,j,k,l,inv,a,rank,s;
9758: unsigned int *t,*pivot,*pk;
9759: unsigned int **mat;
9760: ND_pairs pair;
9761:
9762: mat = (unsigned int **)mat0;
9763: for ( rank = 0, j = 0; j < col; j++ ) {
9764: for ( i = rank; i < row; i++ )
9765: mat[i][j] %= md;
9766: for ( i = rank; i < row; i++ )
9767: if ( mat[i][j] )
9768: break;
9769: if ( i == row ) {
9770: colstat[j] = 0;
9771: continue;
9772: } else
9773: colstat[j] = 1;
9774: if ( i != rank ) {
9775: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
9776: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
9777: if ( spactive ) {
9778: pair = spactive[i]; spactive[i] = spactive[rank];
9779: spactive[rank] = pair;
9780: }
9781: }
9782: pivot = mat[rank];
9783: s = sugar[rank];
9784: inv = invm(pivot[j],md);
9785: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
9786: if ( *pk ) {
9787: if ( *pk >= (unsigned int)md )
9788: *pk %= md;
9789: DMAR(*pk,inv,0,md,*pk)
9790: }
9791: for ( i = rank+1; i < row; i++ ) {
9792: t = mat[i];
9793: if ( (a = t[j]) != 0 ) {
9794: sugar[i] = MAX(sugar[i],s);
9795: red_by_vect(md,t+j,pivot+j,md-a,col-j);
9796: }
9797: }
9798: rank++;
9799: }
9800: for ( j = col-1, l = rank-1; j >= 0; j-- )
9801: if ( colstat[j] ) {
9802: pivot = mat[l];
9803: s = sugar[l];
9804: for ( i = 0; i < l; i++ ) {
9805: t = mat[i];
9806: t[j] %= md;
9807: if ( (a = t[j]) != 0 ) {
9808: sugar[i] = MAX(sugar[i],s);
9809: red_by_vect(md,t+j,pivot+j,md-a,col-j);
9810: }
9811: }
9812: l--;
9813: }
9814: for ( j = 0, l = 0; l < rank; j++ )
9815: if ( colstat[j] ) {
9816: t = mat[l];
9817: for ( k = j; k < col; k++ )
9818: if ( t[k] >= (unsigned int)md )
9819: t[k] %= md;
9820: l++;
9821: }
9822: return rank;
9823: }
9824:
1.40 noro 9825: int nd_gauss_elim_mod_s(UINT **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat,SIG *sig)
9826: {
9827: int i,j,k,l,rank,s,imin;
9828: UINT inv;
9829: UINT a;
9830: UINT *t,*pivot,*pk;
9831: UINT *ck;
9832: UINT *ct;
9833: ND_pairs pair;
9834: SIG sg;
9835: int *used;
9836:
9837: used = (int *)MALLOC(row*sizeof(int));
9838: for ( j = 0; j < col; j++ ) {
9839: for ( i = 0; i < row; i++ )
9840: a = mat[i][j] %= md;
9841: for ( i = 0; i < row; i++ )
9842: if ( !used[i] && mat[i][j] ) break;
9843: if ( i == row ) {
9844: colstat[j] = 0;
9845: continue;
9846: } else {
9847: colstat[j] = 1;
9848: used[i] = 1;
9849: }
9850: /* column j is normalized */
9851: s = sugar[i];
9852: inv = invm(mat[i][j],md);
9853: /* normalize pivot row */
9854: for ( k = j, pk = mat[i]+j; k < col; k++, pk++, ck++ ) {
9855: DMAR(*pk,inv,0,md,*pk);
9856: }
9857: for ( k = i+1; k < row; k++ ) {
9858: if ( (a = mat[k][j]) != 0 ) {
9859: sugar[k] = MAX(sugar[k],s);
9860: red_by_vect(md,mat[k]+j,mat[i]+j,(int)(md-a),col-j);
9861: Nf4_red++;
9862: }
9863: }
9864: }
9865: rank = 0;
9866: for ( i = 0; i < row; i++ ) {
9867: for ( j = 0; j < col; j++ )
9868: if ( mat[i][j] ) break;
9869: if ( j == col ) sugar[i] = -1;
9870: else rank++;
9871: }
9872: return rank;
9873: }
9874:
1.1 noro 9875:
1.7 noro 9876: int nd_gauss_elim_sf(UINT **mat0,int *sugar,int row,int col,int md,int *colstat)
1.1 noro 9877: {
1.7 noro 9878: int i,j,k,l,inv,a,rank,s;
9879: unsigned int *t,*pivot,*pk;
9880: unsigned int **mat;
9881:
9882: mat = (unsigned int **)mat0;
9883: for ( rank = 0, j = 0; j < col; j++ ) {
9884: for ( i = rank; i < row; i++ )
9885: if ( mat[i][j] )
9886: break;
9887: if ( i == row ) {
9888: colstat[j] = 0;
9889: continue;
9890: } else
9891: colstat[j] = 1;
9892: if ( i != rank ) {
9893: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
9894: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
9895: }
9896: pivot = mat[rank];
9897: s = sugar[rank];
9898: inv = _invsf(pivot[j]);
9899: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
9900: if ( *pk )
9901: *pk = _mulsf(*pk,inv);
9902: for ( i = rank+1; i < row; i++ ) {
9903: t = mat[i];
9904: if ( (a = t[j]) != 0 ) {
9905: sugar[i] = MAX(sugar[i],s);
9906: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
9907: }
9908: }
9909: rank++;
9910: }
9911: for ( j = col-1, l = rank-1; j >= 0; j-- )
9912: if ( colstat[j] ) {
9913: pivot = mat[l];
9914: s = sugar[l];
9915: for ( i = 0; i < l; i++ ) {
9916: t = mat[i];
9917: if ( (a = t[j]) != 0 ) {
9918: sugar[i] = MAX(sugar[i],s);
9919: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
9920: }
9921: }
9922: l--;
9923: }
9924: return rank;
9925: }
1.1 noro 9926:
1.7 noro 9927: int ndv_ishomo(NDV p)
9928: {
9929: NMV m;
9930: int len,h;
1.1 noro 9931:
9932: if ( !p ) return 1;
9933: len = LEN(p);
9934: m = BDY(p);
9935: h = TD(DL(m));
9936: NMV_ADV(m);
9937: for ( len--; len; len--, NMV_ADV(m) )
1.20 noro 9938: if ( TD(DL(m)) != h ) {
9939: return 0;
9940: }
1.1 noro 9941: return 1;
9942: }
9943:
9944: void ndv_save(NDV p,int index)
9945: {
9946: FILE *s;
9947: char name[BUFSIZ];
9948: short id;
9949: int nv,sugar,len,n,i,td,e,j;
9950: NMV m;
9951: unsigned int *dl;
9952: int mpos;
9953:
9954: sprintf(name,"%s/%d",Demand,index);
9955: s = fopen(name,"w");
9956: savevl(s,0);
9957: if ( !p ) {
9958: saveobj(s,0);
9959: return;
9960: }
9961: id = O_DP;
9962: nv = NV(p);
9963: sugar = SG(p);
9964: len = LEN(p);
9965: write_short(s,(unsigned short *)&id); write_int(s,(unsigned int *)&nv); write_int(s,(unsigned int *)&sugar);
9966: write_int(s,(unsigned int *)&len);
9967:
9968: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 9969: saveobj(s,(Obj)CZ(m));
1.1 noro 9970: dl = DL(m);
9971: td = TD(dl);
9972: write_int(s,(unsigned int *)&td);
9973: for ( j = 0; j < nv; j++ ) {
9974: e = GET_EXP(dl,j);
9975: write_int(s,(unsigned int *)&e);
9976: }
9977: if ( nd_module ) {
9978: mpos = MPOS(dl); write_int(s,(unsigned int *)&mpos);
9979: }
9980: }
9981: fclose(s);
9982: }
9983:
9984: void nd_save_mod(ND p,int index)
9985: {
9986: FILE *s;
9987: char name[BUFSIZ];
9988: int nv,sugar,len,c;
9989: NM m;
9990:
9991: sprintf(name,"%s/%d",Demand,index);
9992: s = fopen(name,"w");
9993: if ( !p ) {
9994: len = 0;
9995: write_int(s,(unsigned int *)&len);
9996: fclose(s);
9997: return;
9998: }
9999: nv = NV(p);
10000: sugar = SG(p);
10001: len = LEN(p);
10002: write_int(s,(unsigned int *)&nv); write_int(s,(unsigned int *)&sugar); write_int(s,(unsigned int *)&len);
10003: for ( m = BDY(p); m; m = NEXT(m) ) {
10004: c = CM(m); write_int(s,(unsigned int *)&c);
10005: write_intarray(s,(unsigned int *)DL(m),nd_wpd);
10006: }
10007: fclose(s);
10008: }
10009:
10010: NDV ndv_load(int index)
10011: {
10012: FILE *s;
10013: char name[BUFSIZ];
10014: short id;
10015: int nv,sugar,len,n,i,td,e,j;
10016: NDV d;
10017: NMV m0,m;
10018: unsigned int *dl;
10019: Obj obj;
10020: int mpos;
10021:
10022: sprintf(name,"%s/%d",Demand,index);
10023: s = fopen(name,"r");
10024: if ( !s ) return 0;
10025:
10026: skipvl(s);
10027: read_short(s,(unsigned short *)&id);
10028: if ( !id ) return 0;
10029: read_int(s,(unsigned int *)&nv);
10030: read_int(s,(unsigned int *)&sugar);
10031: read_int(s,(unsigned int *)&len);
10032:
10033: m0 = m = MALLOC(len*nmv_adv);
10034: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 10035: loadobj(s,&obj); CZ(m) = (Z)obj;
1.1 noro 10036: dl = DL(m);
10037: ndl_zero(dl);
10038: read_int(s,(unsigned int *)&td); TD(dl) = td;
10039: for ( j = 0; j < nv; j++ ) {
10040: read_int(s,(unsigned int *)&e);
10041: PUT_EXP(dl,j,e);
10042: }
10043: if ( nd_module ) {
10044: read_int(s,(unsigned int *)&mpos); MPOS(dl) = mpos;
10045: }
10046: if ( nd_blockmask ) ndl_weight_mask(dl);
10047: }
10048: fclose(s);
10049: MKNDV(nv,m0,len,d);
10050: SG(d) = sugar;
10051: return d;
10052: }
10053:
10054: ND nd_load_mod(int index)
10055: {
10056: FILE *s;
10057: char name[BUFSIZ];
10058: int nv,sugar,len,i,c;
10059: ND d;
10060: NM m0,m;
10061:
10062: sprintf(name,"%s/%d",Demand,index);
10063: s = fopen(name,"r");
10064: /* if the file does not exist, it means p[index]=0 */
10065: if ( !s ) return 0;
10066:
10067: read_int(s,(unsigned int *)&nv);
10068: if ( !nv ) { fclose(s); return 0; }
10069:
10070: read_int(s,(unsigned int *)&sugar);
10071: read_int(s,(unsigned int *)&len);
10072: for ( m0 = 0, i = 0; i < len; i++ ) {
10073: NEXTNM(m0,m);
10074: read_int(s,(unsigned int *)&c); CM(m) = c;
10075: read_intarray(s,(unsigned int *)DL(m),nd_wpd);
10076: }
10077: NEXT(m) = 0;
10078: MKND(nv,m0,len,d);
10079: SG(d) = sugar;
10080: fclose(s);
10081: return d;
10082: }
10083:
10084: void nd_det(int mod,MAT f,P *rp)
10085: {
10086: VL fv,tv;
10087: int n,i,j,max,e,nvar,sgn,k0,l0,len0,len,k,l,a;
10088: pointer **m;
10089: P **w;
10090: P mp,r;
10091: NDV **dm;
10092: NDV *t,*mi,*mj;
10093: NDV d,s,mij,mjj;
10094: ND u;
10095: NMV nmv;
10096: UINT *bound;
10097: PGeoBucket bucket;
10098: struct order_spec *ord;
10099: Z dq,dt,ds;
10100: Z mone;
10101: Z gn,qn,dn0,nm,dn;
10102:
10103: create_order_spec(0,0,&ord);
10104: nd_init_ord(ord);
10105: get_vars((Obj)f,&fv);
10106: if ( f->row != f->col )
10107: error("nd_det : non-square matrix");
10108: n = f->row;
10109: m = f->body;
10110: for ( nvar = 0, tv = fv; tv; tv = NEXT(tv), nvar++ );
10111:
10112: if ( !nvar ) {
10113: if ( !mod )
10114: detp(CO,(P **)m,n,rp);
10115: else {
10116: w = (P **)almat_pointer(n,n);
10117: for ( i = 0; i < n; i++ )
10118: for ( j = 0; j < n; j++ )
10119: ptomp(mod,(P)m[i][j],&w[i][j]);
10120: detmp(CO,mod,w,n,&mp);
10121: mptop(mp,rp);
10122: }
10123: return;
10124: }
10125:
10126: if ( !mod ) {
10127: w = (P **)almat_pointer(n,n);
10128: dq = ONE;
10129: for ( i = 0; i < n; i++ ) {
10130: dn0 = ONE;
10131: for ( j = 0; j < n; j++ ) {
10132: if ( !m[i][j] ) continue;
10133: lgp(m[i][j],&nm,&dn);
1.6 noro 10134: gcdz(dn0,dn,&gn); divsz(dn0,gn,&qn); mulz(qn,dn,&dn0);
1.1 noro 10135: }
10136: if ( !UNIZ(dn0) ) {
10137: ds = dn0;
10138: for ( j = 0; j < n; j++ )
10139: mulp(CO,(P)m[i][j],(P)ds,&w[i][j]);
10140: mulz(dq,ds,&dt); dq = dt;
10141: } else
10142: for ( j = 0; j < n; j++ )
10143: w[i][j] = (P)m[i][j];
10144: }
10145: m = (pointer **)w;
10146: }
10147:
10148: for ( i = 0, max = 1; i < n; i++ )
10149: for ( j = 0; j < n; j++ )
10150: for ( tv = fv; tv; tv = NEXT(tv) ) {
10151: e = getdeg(tv->v,(P)m[i][j]);
10152: max = MAX(e,max);
10153: }
10154: nd_setup_parameters(nvar,max);
10155: dm = (NDV **)almat_pointer(n,n);
10156: for ( i = 0, max = 1; i < n; i++ )
10157: for ( j = 0; j < n; j++ ) {
10158: dm[i][j] = ptondv(CO,fv,m[i][j]);
10159: if ( mod ) ndv_mod(mod,dm[i][j]);
10160: if ( dm[i][j] && !LEN(dm[i][j]) ) dm[i][j] = 0;
10161: }
10162: d = ptondv(CO,fv,(P)ONE);
10163: if ( mod ) ndv_mod(mod,d);
10164: chsgnz(ONE,&mone);
10165: for ( j = 0, sgn = 1; j < n; j++ ) {
10166: if ( DP_Print ) {
10167: fprintf(asir_out,".");
10168: }
10169: for ( i = j; i < n && !dm[i][j]; i++ );
10170: if ( i == n ) {
10171: *rp = 0;
10172: return;
10173: }
10174: k0 = i; l0 = j; len0 = LEN(dm[k0][l0]);
10175: for ( k = j; k < n; k++ )
10176: for ( l = j; l < n; l++ )
10177: if ( dm[k][l] && LEN(dm[k][l]) < len0 ) {
10178: k0 = k; l0 = l; len0 = LEN(dm[k][l]);
10179: }
10180: if ( k0 != j ) {
10181: t = dm[j]; dm[j] = dm[k0]; dm[k0] = t;
10182: sgn = -sgn;
10183: }
10184: if ( l0 != j ) {
10185: for ( k = j; k < n; k++ ) {
10186: s = dm[k][j]; dm[k][j] = dm[k][l0]; dm[k][l0] = s;
10187: }
10188: sgn = -sgn;
10189: }
10190: bound = nd_det_compute_bound(dm,n,j);
10191: for ( k = 0; k < nd_nvar; k++ )
10192: if ( bound[k]*2 > nd_mask0 ) break;
10193: if ( k < nd_nvar )
10194: nd_det_reconstruct(dm,n,j,d);
10195:
10196: for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) {
10197: /* if ( DP_Print ) fprintf(asir_out," i=%d\n ",i); */
10198: mi = dm[i]; mij = mi[j];
10199: if ( mod )
10200: ndv_mul_c(mod,mij,mod-1);
10201: else
10202: ndv_mul_c_q(mij,mone);
10203: for ( k = j+1; k < n; k++ ) {
10204: /* if ( DP_Print ) fprintf(asir_out,"k=%d ",k); */
10205: bucket = create_pbucket();
10206: if ( mi[k] ) {
10207: nmv = BDY(mjj); len = LEN(mjj);
10208: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
10209: u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d)));
10210: add_pbucket(mod,bucket,u);
10211: }
10212: }
10213: if ( mj[k] && mij ) {
10214: nmv = BDY(mij); len = LEN(mij);
10215: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
10216: u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d)));
10217: add_pbucket(mod,bucket,u);
10218: }
10219: }
10220: u = nd_quo(mod,bucket,d);
10221: mi[k] = ndtondv(mod,u);
10222: }
10223: /* if ( DP_Print ) fprintf(asir_out,"\n",k); */
10224: }
10225: d = mjj;
10226: }
10227: if ( DP_Print ) {
10228: fprintf(asir_out,"\n");
10229: }
10230: if ( sgn < 0 ) {
10231: if ( mod )
10232: ndv_mul_c(mod,d,mod-1);
10233: else
10234: ndv_mul_c_q(d,mone);
10235: }
10236: r = ndvtop(mod,CO,fv,d);
10237: if ( !mod && !UNIQ(dq) )
10238: divsp(CO,r,(P)dq,rp);
10239: else
10240: *rp = r;
10241: }
10242:
10243: ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d)
10244: {
10245: NM mr,mr0;
10246: NM tnm;
10247: NMV m;
10248: UINT *d0,*dt,*dm;
10249: int c,n,td,i,c1,c2,len;
10250: Z q;
10251: ND r;
10252:
10253: if ( !p ) return 0;
10254: else {
10255: n = NV(p); m = BDY(p); len = LEN(p);
10256: d0 = DL(m0);
10257: td = TD(d);
10258: mr0 = 0;
10259: NEWNM(tnm);
10260: if ( mod ) {
10261: c = CM(m0);
10262: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
10263: ndl_add(DL(m),d0,DL(tnm));
10264: if ( ndl_reducible(DL(tnm),d) ) {
10265: NEXTNM(mr0,mr);
10266: c1 = CM(m); DMAR(c1,c,0,mod,c2); CM(mr) = c2;
10267: ndl_copy(DL(tnm),DL(mr));
10268: }
10269: }
10270: } else {
1.6 noro 10271: q = CZ(m0);
1.1 noro 10272: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
10273: ndl_add(DL(m),d0,DL(tnm));
10274: if ( ndl_reducible(DL(tnm),d) ) {
10275: NEXTNM(mr0,mr);
1.6 noro 10276: mulz(CZ(m),q,&CZ(mr));
1.1 noro 10277: ndl_copy(DL(tnm),DL(mr));
10278: }
10279: }
10280: }
10281: if ( !mr0 )
10282: return 0;
10283: else {
10284: NEXT(mr) = 0;
10285: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
10286: MKND(NV(p),mr0,len,r);
10287: SG(r) = SG(p) + TD(d0);
10288: return r;
10289: }
10290: }
10291: }
10292:
10293: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d)
10294: {
10295: int i,obpe,oadv,h,k,l;
10296: static NM prev_nm_free_list;
10297: EPOS oepos;
10298:
10299: obpe = nd_bpe;
10300: oadv = nmv_adv;
10301: oepos = nd_epos;
10302: if ( obpe < 2 ) nd_bpe = 2;
10303: else if ( obpe < 3 ) nd_bpe = 3;
10304: else if ( obpe < 4 ) nd_bpe = 4;
10305: else if ( obpe < 5 ) nd_bpe = 5;
10306: else if ( obpe < 6 ) nd_bpe = 6;
10307: else if ( obpe < 8 ) nd_bpe = 8;
10308: else if ( obpe < 10 ) nd_bpe = 10;
10309: else if ( obpe < 16 ) nd_bpe = 16;
10310: else if ( obpe < 32 ) nd_bpe = 32;
10311: else error("nd_det_reconstruct : exponent too large");
10312:
10313: nd_setup_parameters(nd_nvar,0);
10314: prev_nm_free_list = _nm_free_list;
10315: _nm_free_list = 0;
10316: for ( k = j; k < n; k++ )
10317: for (l = j; l < n; l++ )
10318: ndv_realloc(dm[k][l],obpe,oadv,oepos);
10319: ndv_realloc(d,obpe,oadv,oepos);
10320: prev_nm_free_list = 0;
10321: #if 0
10322: GC_gcollect();
10323: #endif
10324: }
10325:
10326: /* returns a UINT array containing degree bounds */
10327:
10328: UINT *nd_det_compute_bound(NDV **dm,int n,int j)
10329: {
10330: UINT *d0,*d1,*d,*t,*r;
10331: int k,l,i;
10332:
10333: d0 = (UINT *)MALLOC(nd_nvar*sizeof(UINT));
10334: for ( k = 0; k < nd_nvar; k++ ) d0[k] = 0;
10335: for ( k = j; k < n; k++ )
10336: for ( l = j; l < n; l++ )
10337: if ( dm[k][l] ) {
10338: d = ndv_compute_bound(dm[k][l]);
10339: for ( i = 0; i < nd_nvar; i++ )
10340: d0[i] = MAX(d0[i],d[i]);
10341: }
10342: return d0;
10343: }
10344:
10345: DL nd_separate_d(UINT *d,UINT *trans)
10346: {
10347: int n,td,i,e,j;
10348: DL a;
10349:
10350: ndl_zero(trans);
10351: td = 0;
10352: for ( i = 0; i < nd_ntrans; i++ ) {
10353: e = GET_EXP(d,i);
10354: PUT_EXP(trans,i,e);
10355: td += MUL_WEIGHT(e,i);
10356: }
10357: if ( nd_ntrans+nd_nalg < nd_nvar ) {
10358: /* homogenized */
10359: i = nd_nvar-1;
10360: e = GET_EXP(d,i);
10361: PUT_EXP(trans,i,e);
10362: td += MUL_WEIGHT(e,i);
10363: }
10364: TD(trans) = td;
10365: if ( nd_blockmask) ndl_weight_mask(trans);
10366: NEWDL(a,nd_nalg);
10367: td = 0;
10368: for ( i = 0; i < nd_nalg; i++ ) {
10369: j = nd_ntrans+i;
10370: e = GET_EXP(d,j);
10371: a->d[i] = e;
10372: td += e;
10373: }
10374: a->td = td;
10375: return a;
10376: }
10377:
10378: int nd_monic(int mod,ND *p)
10379: {
10380: UINT *trans,*t;
10381: DL alg;
10382: MP mp0,mp;
10383: NM m,m0,m1,ma0,ma,mb,mr0,mr;
10384: ND r;
10385: DL dl;
10386: DP nm;
10387: NDV ndv;
10388: DAlg inv,cd;
10389: ND s,c;
10390: Z l,mul;
10391: Z ln;
10392: int n,ntrans,i,e,td,is_lc,len;
10393: NumberField nf;
10394: struct oEGT eg0,eg1;
10395:
10396: if ( !(nf = get_numberfield()) )
10397: error("nd_monic : current_numberfield is not set");
10398:
10399: /* Q coef -> DAlg coef */
10400: NEWNM(ma0); ma = ma0;
10401: m = BDY(*p);
10402: is_lc = 1;
10403: while ( 1 ) {
10404: NEWMP(mp0); mp = mp0;
1.6 noro 10405: mp->c = (Obj)CZ(m);
1.1 noro 10406: mp->dl = nd_separate_d(DL(m),DL(ma));
10407: NEWNM(mb);
10408: for ( m = NEXT(m); m; m = NEXT(m) ) {
10409: alg = nd_separate_d(DL(m),DL(mb));
10410: if ( !ndl_equal(DL(ma),DL(mb)) )
10411: break;
1.6 noro 10412: NEXTMP(mp0,mp); mp->c = (Obj)CZ(m); mp->dl = alg;
1.1 noro 10413: }
10414: NEXT(mp) = 0;
10415: MKDP(nd_nalg,mp0,nm);
10416: MKDAlg(nm,ONE,cd);
10417: if ( is_lc == 1 ) {
10418: /* if the lc is a rational number, we have nothing to do */
10419: if ( !mp0->dl->td )
10420: return 1;
10421:
10422: get_eg(&eg0);
10423: invdalg(cd,&inv);
10424: get_eg(&eg1); add_eg(&eg_invdalg,&eg0,&eg1);
10425: /* check the validity of inv */
10426: if ( mod && !remqi((Q)inv->dn,mod) )
10427: return 0;
10428: CA(ma) = nf->one;
10429: is_lc = 0;
10430: ln = ONE;
10431: } else {
10432: muldalg(cd,inv,&CA(ma));
10433: lcmz(ln,CA(ma)->dn,&ln);
10434: }
10435: if ( m ) {
10436: NEXT(ma) = mb; ma = mb;
10437: } else {
10438: NEXT(ma) = 0;
10439: break;
10440: }
10441: }
10442: /* l = lcm(denoms) */
10443: l = ln;
10444: for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) {
1.6 noro 10445: divsz(l,CA(m)->dn,&mul);
1.1 noro 10446: for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) {
10447: NEXTNM(mr0,mr);
1.6 noro 10448: mulz((Z)mp->c,mul,&CZ(mr));
1.1 noro 10449: dl = mp->dl;
10450: td = TD(DL(m));
10451: ndl_copy(DL(m),DL(mr));
10452: for ( i = 0; i < nd_nalg; i++ ) {
10453: e = dl->d[i];
10454: PUT_EXP(DL(mr),i+nd_ntrans,e);
10455: td += MUL_WEIGHT(e,i+nd_ntrans);
10456: }
10457: if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m));
10458: TD(DL(mr)) = td;
10459: if ( nd_blockmask) ndl_weight_mask(DL(mr));
10460: }
10461: }
10462: NEXT(mr) = 0;
10463: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
10464: MKND(NV(*p),mr0,len,r);
10465: /* XXX */
10466: SG(r) = SG(*p);
10467: nd_free(*p);
10468: *p = r;
10469: return 1;
10470: }
10471:
10472: NODE reverse_node(NODE n)
10473: {
10474: NODE t,t1;
10475:
10476: for ( t = 0; n; n = NEXT(n) ) {
10477: MKNODE(t1,BDY(n),t); t = t1;
10478: }
10479: return t;
10480: }
10481:
10482: P ndc_div(int mod,union oNDC a,union oNDC b)
10483: {
10484: union oNDC c;
10485: int inv,t;
10486:
10487: if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m));
1.10 noro 10488: else if ( mod == -2 ) divlf(a.z,b.z,&c.z);
1.1 noro 10489: else if ( mod ) {
10490: inv = invm(b.m,mod);
10491: DMAR(a.m,inv,0,mod,t); c.m = t;
10492: } else if ( nd_vc )
10493: divsp(nd_vc,a.p,b.p,&c.p);
10494: else
10495: divsz(a.z,b.z,&c.z);
10496: return ndctop(mod,c);
10497: }
10498:
10499: P ndctop(int mod,union oNDC c)
10500: {
10501: Z q;
10502: int e;
10503: GFS gfs;
10504:
10505: if ( mod == -1 ) {
10506: e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs;
10507: } else if ( mod == -2 ) {
1.10 noro 10508: q = c.z; return (P)q;
1.1 noro 10509: } else if ( mod > 0 ) {
1.6 noro 10510: STOZ(c.m,q); return (P)q;
1.1 noro 10511: } else
10512: return (P)c.p;
10513: }
10514:
10515: /* [0,0,0,cont] = p -> p/cont */
10516:
10517: void finalize_tracelist(int i,P cont)
10518: {
10519: LIST l;
10520: NODE node;
10521: Z iq;
10522:
10523: if ( !UNIQ(cont) ) {
10524: node = mknode(4,NULLP,NULLP,NULLP,cont);
10525: MKLIST(l,node); MKNODE(node,l,nd_tracelist);
10526: nd_tracelist = node;
10527: }
1.6 noro 10528: STOZ(i,iq);
1.1 noro 10529: nd_tracelist = reverse_node(nd_tracelist);
10530: MKLIST(l,nd_tracelist);
10531: node = mknode(2,iq,l); MKLIST(l,node);
10532: MKNODE(node,l,nd_alltracelist); MKLIST(l,node);
10533: nd_alltracelist = node; nd_tracelist = 0;
10534: }
10535:
10536: void conv_ilist(int demand,int trace,NODE g,int **indp)
10537: {
10538: int n,i,j;
10539: int *ind;
10540: NODE t;
10541:
10542: n = length(g);
10543: ind = (int *)MALLOC(n*sizeof(int));
10544: for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) {
10545: j = (long)BDY(t); ind[i] = j;
10546: BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j]));
10547: }
10548: if ( indp ) *indp = ind;
10549: }
10550:
1.30 noro 10551: NODE conv_ilist_s(int demand,int trace,int **indp)
10552: {
10553: int n,i,j;
10554: int *ind;
10555: NODE g0,g;
10556:
10557: n = nd_psn;
10558: ind = (int *)MALLOC(n*sizeof(int));
10559: g0 = 0;
10560: for ( i = 0; i < n; i++ ) {
10561: ind[i] = i;
10562: NEXTNODE(g0,g);
10563: BDY(g) = (pointer)(demand?ndv_load(i):(trace?nd_ps_trace[i]:nd_ps[i]));
10564: }
10565: if ( g0 ) NEXT(g) = 0;
10566: if ( indp ) *indp = ind;
10567: return g0;
10568: }
10569:
1.46 noro 10570: void parse_nd_option(VL vl,NODE opt)
1.1 noro 10571: {
1.38 noro 10572: NODE t,p,u;
1.1 noro 10573: int i,s,n;
1.38 noro 10574: char *key;
10575: Obj value;
1.46 noro 10576: VL oldvl;
1.1 noro 10577:
1.41 noro 10578: nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_norb = 0; nd_gbblock = 0;
1.1 noro 10579: nd_newelim = 0; nd_intersect = 0; nd_nzlist = 0;
10580: nd_splist = 0; nd_check_splist = 0;
1.38 noro 10581: nd_sugarweight = 0; nd_f4red =0; nd_rank0 = 0;
10582: nd_f4_td = 0; nd_sba_f4step = 2; nd_sba_pot = 0; nd_sba_largelcm = 0;
1.41 noro 10583: nd_sba_dontsort = 0; nd_top = 0; nd_sba_redundant_check = 0;
1.46 noro 10584: nd_sba_syz = 0; nd_sba_modord = 0; nd_sba_inputisgb = 0;
1.49 ! noro 10585: nd_hpdata = 0;
1.39 noro 10586:
1.38 noro 10587: for ( t = opt; t; t = NEXT(t) ) {
10588: p = BDY((LIST)BDY(t));
10589: key = BDY((STRING)BDY(p));
10590: value = (Obj)BDY(NEXT(p));
10591: if ( !strcmp(key,"gentrace") )
10592: nd_gentrace = value?1:0;
10593: else if ( !strcmp(key,"gensyz") )
10594: nd_gensyz = value?1:0;
10595: else if ( !strcmp(key,"nora") )
10596: nd_nora = value?1:0;
1.41 noro 10597: else if ( !strcmp(key,"norb") )
10598: nd_norb = value?1:0;
1.38 noro 10599: else if ( !strcmp(key,"gbblock") ) {
10600: if ( value && OID(value) == O_LIST ) {
1.1 noro 10601: u = BDY((LIST)value);
1.38 noro 10602: nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int));
1.1 noro 10603: for ( i = 0; u; u = NEXT(u) ) {
10604: p = BDY((LIST)BDY(u));
1.6 noro 10605: s = nd_gbblock[i++] = ZTOS((Q)BDY(p));
10606: nd_gbblock[i++] = s+ZTOS((Q)BDY(NEXT(p)))-1;
1.1 noro 10607: }
10608: nd_gbblock[i] = -1;
1.38 noro 10609: } else
10610: nd_gbblock = 0;
1.1 noro 10611: } else if ( !strcmp(key,"newelim") )
10612: nd_newelim = value?1:0;
10613: else if ( !strcmp(key,"intersect") )
10614: nd_intersect = value?1:0;
1.17 noro 10615: else if ( !strcmp(key,"syzgen") )
10616: nd_intersect = ZTOS((Q)value);
1.1 noro 10617: else if ( !strcmp(key,"lf") )
10618: nd_lf = value?1:0;
10619: else if ( !strcmp(key,"trace") ) {
1.38 noro 10620: if ( value ) {
10621: u = BDY((LIST)value);
10622: nd_nzlist = BDY((LIST)ARG2(u));
10623: nd_bpe = ZTOS((Q)ARG3(u));
10624: }
1.1 noro 10625: } else if ( !strcmp(key,"f4red") ) {
1.38 noro 10626: nd_f4red = ZTOS((Q)value);
1.1 noro 10627: } else if ( !strcmp(key,"rank0") ) {
1.38 noro 10628: nd_rank0 = value?1:0;
1.1 noro 10629: } else if ( !strcmp(key,"splist") ) {
1.38 noro 10630: nd_splist = value?1:0;
1.1 noro 10631: } else if ( !strcmp(key,"check_splist") ) {
10632: nd_check_splist = BDY((LIST)value);
1.49 ! noro 10633: } else if ( !strcmp(key,"hpdata") ) {
! 10634: nd_hpdata = BDY((LIST)value);
1.1 noro 10635: } else if ( !strcmp(key,"sugarweight") ) {
10636: u = BDY((LIST)value);
1.38 noro 10637: n = length(u);
10638: nd_sugarweight = MALLOC(n*sizeof(int));
1.1 noro 10639: for ( i = 0; i < n; i++, u = NEXT(u) )
1.38 noro 10640: nd_sugarweight[i] = ZTOS((Q)BDY(u));
10641: } else if ( !strcmp(key,"f4_td") ) {
10642: nd_f4_td = value?1:0;
10643: } else if ( !strcmp(key,"sba_f4step") ) {
10644: nd_sba_f4step = value?ZTOS((Q)value):0;
10645: } else if ( !strcmp(key,"sba_pot") ) {
1.44 noro 10646: nd_sba_pot = ZTOS((Q)value);
1.38 noro 10647: } else if ( !strcmp(key,"sba_largelcm") ) {
10648: nd_sba_largelcm = value?1:0;
1.39 noro 10649: } else if ( !strcmp(key,"sba_dontsort") ) {
10650: nd_sba_dontsort = value?1:0;
1.44 noro 10651: } else if ( !strcmp(key,"sba_syz") ) {
10652: nd_sba_syz = value?1:0;
1.46 noro 10653: } else if ( !strcmp(key,"sba_modord") ) {
10654: // value=[vlist,ordspec,weight]
10655: u = BDY((LIST)value);
10656: pltovl((LIST)ARG0(u),&oldvl);
10657: nd_sba_modord = create_comp_sig_spec(vl,oldvl,(Obj)ARG1(u),argc(u)==3?ARG2(u):0);
10658: } else if ( !strcmp(key,"sba_gbinput") ) {
10659: nd_sba_inputisgb = value?1:0;
10660: if ( nd_sba_inputisgb != 0 ) {
10661: // value=[vlist,ordspec,weight]
10662: u = BDY((LIST)value);
10663: pltovl((LIST)ARG0(u),&oldvl);
10664: nd_sba_modord = create_comp_sig_spec(vl,oldvl,(Obj)ARG1(u),argc(u)==3?ARG2(u):0);
10665: }
1.41 noro 10666: } else if ( !strcmp(key,"sba_redundant_check") ) {
10667: nd_sba_redundant_check = value?1:0;
1.39 noro 10668: } else if ( !strcmp(key,"top") ) {
10669: nd_top = value?1:0;
1.1 noro 10670: }
1.38 noro 10671: }
1.44 noro 10672: if ( nd_sba_syz ) nd_sba_dontsort = 1;
1.1 noro 10673: }
10674:
10675: ND mdptond(DP d);
10676: ND nd_mul_nm(int mod,NM m0,ND p);
10677: ND nd_mul_nm_lf(NM m0,ND p);
10678: ND *btog(NODE ti,ND **p,int nb,int mod);
10679: ND btog_one(NODE ti,ND *p,int nb,int mod);
10680: MAT nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,MAT *rp);
10681: VECT nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos,MAT *rp);
10682:
10683: /* d:monomial */
10684: ND mdptond(DP d)
10685: {
10686: NM m;
10687: ND r;
10688:
10689: if ( OID(d) == 1 )
10690: r = ptond(CO,CO,(P)d);
10691: else {
10692: NEWNM(m);
10693: dltondl(NV(d),BDY(d)->dl,DL(m));
1.6 noro 10694: CZ(m) = (Z)BDY(d)->c;
1.1 noro 10695: NEXT(m) = 0;
10696: MKND(NV(d),m,1,r);
10697: }
10698: return r;
10699: }
10700:
10701: ND nd_mul_nm(int mod,NM m0,ND p)
10702: {
10703: UINT *d0;
10704: int c0,c1,c;
10705: NM tm,mr,mr0;
10706: ND r;
10707:
10708: if ( !p ) return 0;
10709: d0 = DL(m0);
10710: c0 = CM(m0);
10711: mr0 = 0;
10712: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
10713: NEXTNM(mr0,mr);
10714: c = CM(tm); DMAR(c0,c,0,mod,c1); CM(mr) = c1;
10715: ndl_add(d0,DL(tm),DL(mr));
10716: }
10717: NEXT(mr) = 0;
10718: MKND(NV(p),mr0,LEN(p),r);
10719: return r;
10720: }
10721:
10722: ND nd_mul_nm_lf(NM m0,ND p)
10723: {
10724: UINT *d0;
10725: Z c0,c1,c;
10726: NM tm,mr,mr0;
10727: ND r;
10728:
10729: if ( !p ) return 0;
10730: d0 = DL(m0);
10731: c0 = CZ(m0);
10732: mr0 = 0;
10733: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
10734: NEXTNM(mr0,mr);
10735: c = CZ(tm); mullf(c0,CZ(tm),&c1); CZ(mr) = c1;
10736: ndl_add(d0,DL(tm),DL(mr));
10737: }
10738: NEXT(mr) = 0;
10739: MKND(NV(p),mr0,LEN(p),r);
10740: return r;
10741: }
10742:
10743: ND *btog(NODE ti,ND **p,int nb,int mod)
10744: {
10745: PGeoBucket *r;
10746: int i,ci;
10747: NODE t,s;
10748: ND m,tp;
10749: ND *pi,*rd;
10750: P c;
10751:
10752: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
10753: for ( i = 0; i < nb; i++ )
10754: r[i] = create_pbucket();
10755: for ( t = ti; t; t = NEXT(t) ) {
10756: s = BDY((LIST)BDY(t));
10757: if ( ARG0(s) ) {
10758: m = mdptond((DP)ARG2(s));
1.6 noro 10759: ptomp(mod,(P)HCZ(m),&c);
1.1 noro 10760: if ( (ci = ((MQ)c)->cont) != 0 ) {
10761: HCM(m) = ci;
1.6 noro 10762: pi = p[ZTOS((Q)ARG1(s))];
1.1 noro 10763: for ( i = 0; i < nb; i++ ) {
10764: tp = nd_mul_nm(mod,BDY(m),pi[i]);
10765: add_pbucket(mod,r[i],tp);
10766: }
10767: }
10768: ci = 1;
10769: } else {
10770: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
10771: ci = invm(ci,mod);
10772: }
10773: }
10774: rd = (ND *)MALLOC(nb*sizeof(ND));
10775: for ( i = 0; i < nb; i++ )
10776: rd[i] = normalize_pbucket(mod,r[i]);
10777: if ( ci != 1 )
10778: for ( i = 0; i < nb; i++ ) nd_mul_c(mod,rd[i],ci);
10779: return rd;
10780: }
10781:
10782: /* YYY */
10783: ND *btog_lf(NODE ti,ND **p,int nb)
10784: {
10785: PGeoBucket *r;
10786: int i;
10787: NODE t,s;
10788: ND m,tp;
10789: ND *pi,*rd;
10790: LM lm;
10791: Z lf,c;
10792:
10793: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
10794: for ( i = 0; i < nb; i++ )
10795: r[i] = create_pbucket();
10796: for ( t = ti; t; t = NEXT(t) ) {
10797: s = BDY((LIST)BDY(t));
10798: if ( ARG0(s) ) {
10799: m = mdptond((DP)ARG2(s));
1.6 noro 10800: simp_ff((Obj)HCZ(m),(Obj *)&lm);
1.1 noro 10801: if ( lm ) {
10802: lmtolf(lm,&lf); HCZ(m) = lf;
1.6 noro 10803: pi = p[ZTOS((Q)ARG1(s))];
1.1 noro 10804: for ( i = 0; i < nb; i++ ) {
10805: tp = nd_mul_nm_lf(BDY(m),pi[i]);
10806: add_pbucket(-2,r[i],tp);
10807: }
10808: }
10809: c = ONE;
10810: } else {
10811: simp_ff((Obj)ARG3(s),(Obj *)&lm); lmtolf(lm,&lf); invz(lf,current_mod_lf,&c);
10812: }
10813: }
10814: rd = (ND *)MALLOC(nb*sizeof(ND));
10815: for ( i = 0; i < nb; i++ )
10816: rd[i] = normalize_pbucket(-2,r[i]);
10817: for ( i = 0; i < nb; i++ ) nd_mul_c_lf(rd[i],c);
10818: return rd;
10819: }
10820:
10821: ND btog_one(NODE ti,ND *p,int nb,int mod)
10822: {
10823: PGeoBucket r;
10824: int i,ci,j;
10825: NODE t,s;
10826: ND m,tp;
10827: ND pi,rd;
10828: P c;
10829:
10830: r = create_pbucket();
10831: for ( t = ti; t; t = NEXT(t) ) {
10832: s = BDY((LIST)BDY(t));
10833: if ( ARG0(s) ) {
10834: m = mdptond((DP)ARG2(s));
1.6 noro 10835: ptomp(mod,(P)HCZ(m),&c);
1.1 noro 10836: if ( (ci = ((MQ)c)->cont) != 0 ) {
10837: HCM(m) = ci;
1.6 noro 10838: pi = p[j=ZTOS((Q)ARG1(s))];
1.1 noro 10839: if ( !pi ) {
10840: pi = nd_load_mod(j);
10841: tp = nd_mul_nm(mod,BDY(m),pi);
10842: nd_free(pi);
10843: add_pbucket(mod,r,tp);
10844: } else {
10845: tp = nd_mul_nm(mod,BDY(m),pi);
10846: add_pbucket(mod,r,tp);
10847: }
10848: }
10849: ci = 1;
10850: } else {
10851: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
10852: ci = invm(ci,mod);
10853: }
10854: }
10855: rd = normalize_pbucket(mod,r);
10856: free_pbucket(r);
10857: if ( ci != 1 ) nd_mul_c(mod,rd,ci);
10858: return rd;
10859: }
10860:
10861: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp);
10862:
10863: MAT nd_btog(LIST f,LIST v,int mod,struct order_spec *ord,LIST tlist,MAT *rp)
10864: {
10865: int i,j,n,m,nb,pi0,pi1,nvar;
10866: VL fv,tv,vv;
10867: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
10868: ND **p;
10869: ND *c;
10870: ND u;
10871: P inv;
10872: MAT mat;
10873:
10874: if ( mod == -2 )
10875: return nd_btog_lf(f,v,ord,tlist,rp);
10876:
10877: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 10878: parse_nd_option(vv,current_option);
1.1 noro 10879: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
10880: switch ( ord->id ) {
10881: case 1:
10882: if ( ord->nv != nvar )
10883: error("nd_check : invalid order specification");
10884: break;
10885: default:
10886: break;
10887: }
10888: nd_init_ord(ord);
10889: #if 0
1.6 noro 10890: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 10891: #else
10892: nd_bpe = 32;
10893: #endif
10894: nd_setup_parameters(nvar,0);
10895: permtrace = BDY((LIST)ARG2(BDY(tlist)));
10896: intred = BDY((LIST)ARG3(BDY(tlist)));
10897: ind = BDY((LIST)ARG4(BDY(tlist)));
10898: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
10899: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 10900: j = ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 10901: if ( j > i ) i = j;
10902: }
10903: n = i+1;
10904: nb = length(BDY(f));
10905: p = (ND **)MALLOC(n*sizeof(ND *));
10906: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
10907: pi = BDY((LIST)BDY(t));
1.6 noro 10908: pi0 = ZTOS((Q)ARG0(pi)); pi1 = ZTOS((Q)ARG1(pi));
1.1 noro 10909: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
10910: ptomp(mod,(P)ARG2(pi),&inv);
10911: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
10912: u = ptond(CO,vv,(P)ONE);
10913: HCM(u) = ((MQ)inv)->cont;
10914: c[pi1] = u;
10915: }
10916: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
10917: printf("%d ",i); fflush(stdout);
10918: ti = BDY((LIST)BDY(t));
1.6 noro 10919: p[j=ZTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 10920: }
10921: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
10922: printf("%d ",i); fflush(stdout);
10923: ti = BDY((LIST)BDY(t));
1.6 noro 10924: p[j=ZTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 10925: }
10926: m = length(ind);
10927: MKMAT(mat,nb,m);
10928: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
1.6 noro 10929: for ( i = 0, c = p[ZTOS((Q)BDY(t))]; i < nb; i++ )
1.1 noro 10930: BDY(mat)[i][j] = ndtodp(mod,c[i]);
10931: return mat;
10932: }
10933:
10934: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp)
10935: {
10936: int i,j,n,m,nb,pi0,pi1,nvar;
10937: VL fv,tv,vv;
10938: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
10939: ND **p;
10940: ND *c;
10941: ND u;
10942: MAT mat;
10943: LM lm;
10944: Z lf,inv;
10945:
10946: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 10947: parse_nd_option(vv,current_option);
1.1 noro 10948: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
10949: switch ( ord->id ) {
10950: case 1:
10951: if ( ord->nv != nvar )
10952: error("nd_check : invalid order specification");
10953: break;
10954: default:
10955: break;
10956: }
10957: nd_init_ord(ord);
10958: #if 0
1.6 noro 10959: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 10960: #else
10961: nd_bpe = 32;
10962: #endif
10963: nd_setup_parameters(nvar,0);
10964: permtrace = BDY((LIST)ARG2(BDY(tlist)));
10965: intred = BDY((LIST)ARG3(BDY(tlist)));
10966: ind = BDY((LIST)ARG4(BDY(tlist)));
10967: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
10968: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 10969: j = ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 10970: if ( j > i ) i = j;
10971: }
10972: n = i+1;
10973: nb = length(BDY(f));
10974: p = (ND **)MALLOC(n*sizeof(ND *));
10975: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
10976: pi = BDY((LIST)BDY(t));
1.6 noro 10977: pi0 = ZTOS((Q)ARG0(pi)); pi1 = ZTOS((Q)ARG1(pi));
1.1 noro 10978: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
10979: simp_ff((Obj)ARG2(pi),(Obj *)&lm); lmtolf(lm,&lf); invz(lf,current_mod_lf,&inv);
10980: u = ptond(CO,vv,(P)ONE);
10981: HCZ(u) = inv;
10982: c[pi1] = u;
10983: }
10984: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
10985: printf("%d ",i); fflush(stdout);
10986: ti = BDY((LIST)BDY(t));
1.6 noro 10987: p[j=ZTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
1.1 noro 10988: }
10989: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
10990: printf("%d ",i); fflush(stdout);
10991: ti = BDY((LIST)BDY(t));
1.6 noro 10992: p[j=ZTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
1.1 noro 10993: }
10994: m = length(ind);
10995: MKMAT(mat,nb,m);
10996: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
1.6 noro 10997: for ( i = 0, c = p[ZTOS((Q)BDY(t))]; i < nb; i++ )
1.1 noro 10998: BDY(mat)[i][j] = ndtodp(-2,c[i]);
10999: return mat;
11000: }
11001:
11002: VECT nd_btog_one(LIST f,LIST v,int mod,struct order_spec *ord,
11003: LIST tlist,int pos,MAT *rp)
11004: {
11005: int i,j,n,m,nb,pi0,pi1,nvar;
11006: VL fv,tv,vv;
11007: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
11008: ND *p;
11009: ND *c;
11010: ND u;
11011: P inv;
11012: VECT vect;
11013:
11014: if ( mod == -2 )
11015: error("nd_btog_one : not implemented yet for a large finite field");
11016:
11017: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11018: parse_nd_option(vv,current_option);
1.1 noro 11019: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11020: switch ( ord->id ) {
11021: case 1:
11022: if ( ord->nv != nvar )
11023: error("nd_check : invalid order specification");
11024: break;
11025: default:
11026: break;
11027: }
11028: nd_init_ord(ord);
11029: #if 0
1.6 noro 11030: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 11031: #else
11032: nd_bpe = 32;
11033: #endif
11034: nd_setup_parameters(nvar,0);
11035: permtrace = BDY((LIST)ARG2(BDY(tlist)));
11036: intred = BDY((LIST)ARG3(BDY(tlist)));
11037: ind = BDY((LIST)ARG4(BDY(tlist)));
11038: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
11039: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.6 noro 11040: j = ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 11041: if ( j > i ) i = j;
11042: }
11043: n = i+1;
11044: nb = length(BDY(f));
11045: p = (ND *)MALLOC(n*sizeof(ND *));
11046: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
11047: pi = BDY((LIST)BDY(t));
1.6 noro 11048: pi0 = ZTOS((Q)ARG0(pi)); pi1 = ZTOS((Q)ARG1(pi));
1.1 noro 11049: if ( pi1 == pos ) {
11050: ptomp(mod,(P)ARG2(pi),&inv);
11051: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
11052: u = ptond(CO,vv,(P)ONE);
11053: HCM(u) = ((MQ)inv)->cont;
11054: p[pi0] = u;
11055: }
11056: }
11057: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
11058: printf("%d ",i); fflush(stdout);
11059: ti = BDY((LIST)BDY(t));
1.6 noro 11060: p[j=ZTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11061: if ( Demand ) {
11062: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
11063: }
11064: }
11065: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
11066: printf("%d ",i); fflush(stdout);
11067: ti = BDY((LIST)BDY(t));
1.6 noro 11068: p[j=ZTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11069: if ( Demand ) {
11070: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
11071: }
11072: }
11073: m = length(ind);
11074: MKVECT(vect,m);
11075: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) {
1.6 noro 11076: u = p[ZTOS((Q)BDY(t))];
1.1 noro 11077: if ( !u ) {
1.6 noro 11078: u = nd_load_mod(ZTOS((Q)BDY(t)));
1.1 noro 11079: BDY(vect)[j] = ndtodp(mod,u);
11080: nd_free(u);
11081: } else
11082: BDY(vect)[j] = ndtodp(mod,u);
11083: }
11084: return vect;
11085: }
11086:
11087: void ndv_print_lf(NDV p)
11088: {
11089: NMV m;
11090: int i,len;
11091:
11092: if ( !p ) printf("0\n");
11093: else {
11094: len = LEN(p);
11095: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
11096: printf("+");
11097: mpz_out_str(asir_out,10,BDY(CZ(m)));
11098: printf("*");
11099: ndl_print(DL(m));
11100: }
11101: printf("\n");
11102: }
11103: }
11104:
11105: void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp)
11106: {
11107: VL tv,fv,vv,vc,av;
11108: NODE fd,fd0,in0,in,r,r0,t,s,cand,alist;
11109: int m,nocheck,nvar,mindex,e,max;
11110: NDV c;
11111: NMV a;
11112: P p,zp;
11113: Q dmy;
11114: EPOS oepos;
11115: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
11116: Alg alpha,dp;
11117: P poly;
11118: LIST f1,f2,zpl;
11119: Obj obj;
11120: NumberField nf;
11121: struct order_spec *ord1;
11122: struct oEGT eg_check,eg0,eg1;
11123: NODE tr,tl1,tl2,tl3,tl4;
11124: LIST l1,l2,l3,l4,l5;
11125: int *perm;
11126: int j,ret;
11127: NODE retn;
11128: Q jq,bpe;
11129:
11130: nd_module = 0;
11131: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11132: parse_nd_option(vv,current_option);
1.1 noro 11133: if ( nd_vc )
11134: error("nd_f4_lf_trace : computation over a rational function field is not implemented");
11135: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11136: switch ( ord->id ) {
11137: case 1:
11138: if ( ord->nv != nvar )
11139: error("nd_f4_lf_trace : invalid order specification");
11140: break;
11141: default:
11142: break;
11143: }
11144:
11145: nd_ntrans = nvar;
11146: nd_nalg = 0;
11147:
11148: nocheck = 0;
11149: mindex = 0;
11150:
11151: /* do not use on-demand load/save */
11152: nd_demand = 0;
11153: m = trace > 1 ? trace : get_lprime(mindex);
11154: nd_init_ord(ord);
11155: mrank = 0;
11156: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
11157: for ( tv = vv; tv; tv = NEXT(tv) ) {
11158: if ( nd_module ) {
11159: s = BDY((LIST)BDY(t));
11160: trank = length(s);
11161: mrank = MAX(mrank,trank);
11162: for ( ; s; s = NEXT(s) ) {
11163: e = getdeg(tv->v,(P)BDY(s));
11164: max = MAX(e,max);
11165: }
11166: } else {
11167: e = getdeg(tv->v,(P)BDY(t));
11168: max = MAX(e,max);
11169: }
11170: }
11171: nd_setup_parameters(nvar,max);
11172: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
11173: ishomo = 1;
11174: /* XXX */
11175: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
11176: if ( nd_module ) {
11177: c = (pointer)pltondv(CO,vv,(LIST)BDY(t));
11178: } else {
11179: c = (pointer)ptondv(CO,vv,(P)BDY(t));
11180: }
11181: if ( ishomo )
11182: ishomo = ishomo && ndv_ishomo(c);
11183: if ( c ) {
11184: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
11185: ndv_mod(-2,c);
11186: NEXTNODE(in0,in); BDY(in) = (pointer)c;
11187: }
11188: }
11189: if ( in0 ) NEXT(in) = 0;
11190: if ( fd0 ) NEXT(fd) = 0;
11191: if ( !ishomo && homo ) {
11192: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
11193: c = (NDV)BDY(t); len = LEN(c);
11194: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
11195: wmax = MAX(TD(DL(a)),wmax);
11196: }
11197: homogenize_order(ord,nvar,&ord1);
11198: nd_init_ord(ord1);
11199: nd_setup_parameters(nvar+1,wmax);
11200: for ( t = fd0; t; t = NEXT(t) )
11201: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
11202: }
11203: if ( MaxDeg > 0 ) nocheck = 1;
1.24 noro 11204: ret = ndv_setup(-2,m,fd0,nd_gbblock?1:0,0,0);
1.1 noro 11205: if ( ret )
11206: cand = nd_f4_lf_trace_main(m,&perm);
11207: if ( !ret || !cand ) {
11208: *rp = 0; return;
11209: }
11210: if ( !ishomo && homo ) {
11211: /* dehomogenization */
11212: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
11213: nd_init_ord(ord);
11214: nd_setup_parameters(nvar,0);
11215: }
11216: cand = ndv_reducebase(cand,perm);
11217: cand = ndv_reduceall(-2,cand);
11218: cbpe = nd_bpe;
11219: get_eg(&eg0);
11220: if ( (ret = ndv_check_membership(-2,in0,obpe,oadv,oepos,cand)) != 0 ) {
11221: /* gbcheck : cand is a GB of Id(cand) ? */
11222: retn = nd_f4(-2,0,0);
11223: }
11224: if ( !retn ) {
11225: /* failure */
11226: *rp = 0; return;
11227: }
11228: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
11229: if ( DP_Print )
1.5 noro 11230: fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime);
1.1 noro 11231: /* dp->p */
11232: nd_bpe = cbpe;
11233: nd_setup_parameters(nd_nvar,0);
11234: for ( r = cand; r; r = NEXT(r) ) {
11235: if ( nd_module ) BDY(r) = ndvtopl(-2,CO,vv,BDY(r),mrank);
11236: else BDY(r) = (pointer)ndvtop(-2,CO,vv,BDY(r));
11237: }
11238: MKLIST(*rp,cand);
11239: }
11240:
11241: NODE nd_f4_lf_trace_main(int m,int **indp)
11242: {
11243: int i,nh,stat,index;
11244: NODE r,rm,g;
11245: ND_pairs d,l,l0,t;
11246: ND spol,red;
11247: NDV nf,redv,nfqv,nfv;
11248: NM s0,s;
11249: NODE rp0,srp0,nflist,nflist_lf;
11250: int nsp,nred,col,rank,len,k,j,a;
11251: UINT c;
11252: UINT **spmat;
11253: UINT *s0vect,*svect,*p,*v;
11254: int *colstat;
11255: IndArray *imat;
11256: int *rhead;
11257: int spcol,sprow;
11258: int sugar;
11259: PGeoBucket bucket;
11260: struct oEGT eg0,eg1,eg_f4;
11261:
11262: g = 0; d = 0;
11263: for ( i = 0; i < nd_psn; i++ ) {
11264: d = update_pairs(d,g,i,0);
11265: g = update_base(g,i);
11266: }
11267: while ( d ) {
11268: get_eg(&eg0);
11269: l = nd_minsugarp(d,&d);
11270: sugar = SG(l);
11271: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
11272: bucket = create_pbucket();
11273: stat = nd_sp_f4(m,0,l,bucket);
11274: if ( !stat ) {
11275: for ( t = l; NEXT(t); t = NEXT(t) );
11276: NEXT(t) = d; d = l;
11277: d = nd_reconstruct(1,d);
11278: continue;
11279: }
11280: if ( bucket->m < 0 ) continue;
11281: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
11282: if ( !col ) {
11283: for ( t = l; NEXT(t); t = NEXT(t) );
11284: NEXT(t) = d; d = l;
11285: d = nd_reconstruct(1,d);
11286: continue;
11287: }
11288: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
11289: if ( DP_Print )
1.5 noro 11290: fprintf(asir_out,"\nsugar=%d,symb=%.3fsec,",sugar,eg_f4.exectime);
1.1 noro 11291: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
11292: if ( !l0 ) continue;
11293: l = l0;
11294:
11295: /* over LF */
11296: bucket = create_pbucket();
11297: stat = nd_sp_f4(-2,1,l,bucket);
11298: if ( !stat ) {
11299: for ( t = l; NEXT(t); t = NEXT(t) );
11300: NEXT(t) = d; d = l;
11301: d = nd_reconstruct(1,d);
11302: continue;
11303: }
11304: if ( bucket->m < 0 ) continue;
11305: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
11306: if ( !col ) {
11307: for ( t = l; NEXT(t); t = NEXT(t) );
11308: NEXT(t) = d; d = l;
11309: d = nd_reconstruct(1,d);
11310: continue;
11311: }
11312: nflist_lf = nd_f4_red(-2,l,1,s0vect,col,rp0,0);
11313: /* adding new bases */
11314: for ( rm = nflist, r = nflist_lf; r && rm; rm = NEXT(rm), r = NEXT(r) ) {
11315: nfv = (NDV)BDY(rm);
11316: nfqv = (NDV)BDY(r);
11317: if ( DL_COMPARE(HDL(nfv),HDL(nfqv)) ) return 0;
11318: ndv_removecont(m,nfv);
11319: ndv_removecont(-2,nfqv);
1.24 noro 11320: nh = ndv_newps(-2,nfv,nfqv);
1.1 noro 11321: d = update_pairs(d,g,nh,0);
11322: g = update_base(g,nh);
11323: }
11324: if ( r || rm ) return 0;
11325: }
11326: conv_ilist(nd_demand,1,g,indp);
11327: return g;
11328: }
11329:
1.7 noro 11330: #if SIZEOF_LONG==8
11331:
11332: NDV vect64_to_ndv(mp_limb_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
11333: {
11334: int j,k,len;
11335: UINT *p;
11336: UINT c;
11337: NDV r;
11338: NMV mr0,mr;
11339:
11340: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
11341: if ( !len ) return 0;
11342: else {
11343: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
11344: #if 0
11345: ndv_alloc += nmv_adv*len;
11346: #endif
11347: mr = mr0;
11348: p = s0vect;
11349: for ( j = k = 0; j < col; j++, p += nd_wpd )
11350: if ( !rhead[j] ) {
11351: if ( (c = (UINT)vect[k++]) != 0 ) {
11352: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
11353: }
11354: }
11355: MKNDV(nd_nvar,mr0,len,r);
11356: return r;
11357: }
11358: }
11359:
1.28 noro 11360: NDV vect64_to_ndv_s(mp_limb_t *vect,int col,UINT *s0vect)
11361: {
11362: int j,k,len;
11363: UINT *p;
11364: UINT c;
11365: NDV r;
11366: NMV mr0,mr;
11367:
11368: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
11369: if ( !len ) return 0;
11370: else {
11371: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
11372: mr = mr0;
11373: p = s0vect;
11374: for ( j = k = 0; j < col; j++, p += nd_wpd )
11375: if ( (c = (UINT)vect[k++]) != 0 ) {
11376: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
11377: }
11378: MKNDV(nd_nvar,mr0,len,r);
11379: return r;
11380: }
11381: }
11382:
1.7 noro 11383: int nd_to_vect64(int mod,UINT *s0,int n,ND d,mp_limb_t *r)
11384: {
11385: NM m;
1.11 noro 11386: UINT *t,*s,*u;
11387: int i,st,ed,md,prev,c;
1.7 noro 11388:
11389: for ( i = 0; i < n; i++ ) r[i] = 0;
1.11 noro 11390: prev = 0;
11391: for ( i = 0, m = BDY(d); m; m = NEXT(m) ) {
11392: t = DL(m);
11393: st = prev;
11394: ed = n;
11395: while ( ed > st ) {
11396: md = (st+ed)/2;
11397: u = s0+md*nd_wpd;
11398: c = DL_COMPARE(u,t);
11399: if ( c == 0 ) break;
11400: else if ( c > 0 ) st = md;
11401: else ed = md;
11402: }
11403: r[md] = (mp_limb_t)CM(m);
11404: prev = md;
1.7 noro 11405: }
11406: for ( i = 0; !r[i]; i++ );
11407: return i;
11408: }
11409:
11410: #define MOD128(a,c,m) ((a)=(((c)!=0||((a)>=(m)))?(((((U128)(c))<<64)+(a))%(m)):(a)))
11411:
1.28 noro 11412: 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 11413: {
11414: int i,j,k,len,pos,prev;
11415: mp_limb_t a,c,c1,c2;
11416: IndArray ivect;
11417: unsigned char *ivc;
11418: unsigned short *ivs;
11419: unsigned int *ivi;
11420: NDV redv;
11421: NMV mr;
11422: NODE rp;
11423: int maxrs;
11424:
11425: for ( i = 0; i < col; i++ ) cvect[i] = 0;
11426: maxrs = 0;
11427: for ( i = 0; i < nred; i++ ) {
11428: ivect = imat[i];
11429: k = ivect->head;
11430: a = svect[k]; c = cvect[k];
11431: MOD128(a,c,m);
11432: svect[k] = a; cvect[k] = 0;
1.28 noro 11433: if ( (c = svect[k]) != 0 && (sig == 0 || comp_sig(sig,rp0[i]->sig) > 0 ) ) {
1.11 noro 11434: Nf4_red++;
1.7 noro 11435: maxrs = MAX(maxrs,rp0[i]->sugar);
11436: c = m-c; redv = nd_ps[rp0[i]->index];
11437: len = LEN(redv); mr = BDY(redv);
11438: svect[k] = 0; prev = k;
11439: switch ( ivect->width ) {
11440: case 1:
11441: ivc = ivect->index.c;
11442: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11443: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.12 noro 11444: c2 = svect[pos]+c1*c;
11445: if ( c2 < svect[pos] ) cvect[pos]++;
11446: svect[pos] = c2;
1.7 noro 11447: }
11448: break;
11449: case 2:
11450: ivs = ivect->index.s;
11451: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11452: pos = prev+ivs[j]; c1 = CM(mr); prev = pos;
1.12 noro 11453: c2 = svect[pos]+c1*c;
11454: if ( c2 < svect[pos] ) cvect[pos]++;
11455: svect[pos] = c2;
1.7 noro 11456: }
11457: break;
11458: case 4:
11459: ivi = ivect->index.i;
11460: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11461: pos = prev+ivi[j]; c1 = CM(mr); prev = pos;
1.12 noro 11462: c2 = svect[pos]+c1*c;
11463: if ( c2 < svect[pos] ) cvect[pos]++;
11464: svect[pos] = c2;
1.7 noro 11465: }
11466: break;
11467: }
11468: }
11469: }
11470: for ( i = 0; i < col; i++ ) {
11471: a = svect[i]; c = cvect[i]; MOD128(a,c,m); svect[i] = a;
11472: }
11473: return maxrs;
11474: }
11475:
11476: /* for Fp, 2^15=<p<2^29 */
11477:
11478: NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
11479: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
11480: {
11481: int spcol,sprow,a;
11482: int i,j,k,l,rank;
11483: NODE r0,r;
11484: ND_pairs sp;
11485: ND spol;
11486: mp_limb_t **spmat;
11487: mp_limb_t *svect,*cvect;
11488: mp_limb_t *v;
11489: int *colstat;
11490: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
11491: int maxrs;
11492: int *spsugar;
11493: ND_pairs *spactive;
11494:
11495: spcol = col-nred;
11496: get_eg(&eg0);
11497: /* elimination (1st step) */
11498: spmat = (mp_limb_t **)MALLOC(nsp*sizeof(mp_limb_t *));
11499: svect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11500: cvect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11501: spsugar = (int *)MALLOC(nsp*sizeof(int));
11502: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
11503: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
11504: nd_sp(m,0,sp,&spol);
11505: if ( !spol ) continue;
11506: nd_to_vect64(m,s0vect,col,spol,svect);
1.28 noro 11507: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred,0);
1.7 noro 11508: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
11509: if ( i < col ) {
11510: spmat[sprow] = v = (mp_limb_t *)MALLOC_ATOMIC(spcol*sizeof(mp_limb_t));
11511: for ( j = k = 0; j < col; j++ )
11512: if ( !rhead[j] ) v[k++] = (UINT)svect[j];
11513: spsugar[sprow] = MAX(maxrs,SG(spol));
11514: if ( nz )
11515: spactive[sprow] = sp;
11516: sprow++;
11517: }
11518: nd_free(spol);
11519: }
1.12 noro 11520: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
1.7 noro 11521: if ( DP_Print ) {
11522: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
11523: fflush(asir_out);
11524: }
11525: /* free index arrays */
11526: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
11527:
11528: /* elimination (2nd step) */
11529: colstat = (int *)MALLOC(spcol*sizeof(int));
11530: rank = nd_gauss_elim_mod64(spmat,spsugar,spactive,sprow,spcol,m,colstat);
11531: r0 = 0;
11532: for ( i = 0; i < rank; i++ ) {
11533: NEXTNODE(r0,r); BDY(r) =
11534: (pointer)vect64_to_ndv(spmat[i],spcol,col,rhead,s0vect);
11535: SG((NDV)BDY(r)) = spsugar[i];
11536: GCFREE(spmat[i]);
11537: }
11538: if ( r0 ) NEXT(r) = 0;
11539:
11540: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
1.12 noro 11541: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
1.7 noro 11542: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
11543: if ( DP_Print ) {
11544: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
11545: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
11546: nsp,nred,sprow,spcol,rank);
11547: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
11548: }
11549: if ( nz ) {
11550: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
11551: if ( rank > 0 ) {
11552: NEXT(spactive[rank-1]) = 0;
11553: *nz = spactive[0];
11554: } else
11555: *nz = 0;
11556: }
11557: return r0;
11558: }
11559:
11560: int nd_gauss_elim_mod64(mp_limb_t **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
11561: {
11562: int i,j,k,l,rank,s;
11563: mp_limb_t inv;
11564: mp_limb_t a;
11565: UINT c;
11566: mp_limb_t *t,*pivot,*pk;
11567: UINT *ck;
11568: UINT **cmat;
11569: UINT *ct;
11570: ND_pairs pair;
11571:
11572: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
11573: for ( i = 0; i < row; i++ ) {
11574: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
11575: bzero(cmat[i],col*sizeof(UINT));
11576: }
11577:
11578: for ( rank = 0, j = 0; j < col; j++ ) {
11579: for ( i = rank; i < row; i++ ) {
11580: a = mat[i][j]; c = cmat[i][j];
11581: MOD128(a,c,md);
11582: mat[i][j] = a; cmat[i][j] = 0;
11583: }
11584: for ( i = rank; i < row; i++ )
11585: if ( mat[i][j] )
11586: break;
11587: if ( i == row ) {
11588: colstat[j] = 0;
11589: continue;
11590: } else
11591: colstat[j] = 1;
11592: if ( i != rank ) {
11593: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
11594: ct = cmat[i]; cmat[i] = cmat[rank]; cmat[rank] = ct;
11595: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
11596: if ( spactive ) {
11597: pair = spactive[i]; spactive[i] = spactive[rank];
11598: spactive[rank] = pair;
11599: }
11600: }
11601: /* column j is normalized */
11602: s = sugar[rank];
11603: inv = invm((UINT)mat[rank][j],md);
11604: /* normalize pivot row */
11605: for ( k = j, pk = mat[rank]+j, ck = cmat[rank]+j; k < col; k++, pk++, ck++ ) {
11606: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
11607: }
11608: for ( i = rank+1; i < row; i++ ) {
11609: if ( (a = mat[i][j]) != 0 ) {
11610: sugar[i] = MAX(sugar[i],s);
11611: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[rank]+j,(int)(md-a),col-j);
1.11 noro 11612: Nf4_red++;
1.7 noro 11613: }
11614: }
11615: rank++;
11616: }
11617: for ( j = col-1, l = rank-1; j >= 0; j-- )
11618: if ( colstat[j] ) {
11619: for ( k = j, pk = mat[l]+j, ck = cmat[l]+j; k < col; k++, pk++, ck++ ) {
11620: a = *pk; c = *ck; MOD128(a,c,md); *pk = a; *ck = 0;
11621: }
11622: s = sugar[l];
11623: for ( i = 0; i < l; i++ ) {
11624: a = mat[i][j]; c = cmat[i][j]; MOD128(a,c,md); mat[i][j] = a; cmat[i][j] = 0;
11625: if ( a ) {
11626: sugar[i] = MAX(sugar[i],s);
11627: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[l]+j,(int)(md-a),col-j);
1.11 noro 11628: Nf4_red++;
1.7 noro 11629: }
11630: }
11631: l--;
11632: }
11633: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
11634: GCFREE(cmat);
11635: return rank;
11636: }
11637:
1.28 noro 11638: 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)
11639: {
11640: int i,j,k,l,rank,s,imin;
11641: mp_limb_t inv;
11642: mp_limb_t a;
11643: UINT c;
11644: mp_limb_t *t,*pivot,*pk;
11645: UINT *ck;
11646: UINT **cmat;
11647: UINT *ct;
11648: ND_pairs pair;
11649: SIG sg;
1.31 noro 11650: int *used;
1.28 noro 11651:
1.31 noro 11652: used = (int *)MALLOC(row*sizeof(int));
1.28 noro 11653: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
11654: for ( i = 0; i < row; i++ ) {
11655: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
11656: bzero(cmat[i],col*sizeof(UINT));
11657: }
11658:
1.31 noro 11659: for ( j = 0; j < col; j++ ) {
11660: for ( i = 0; i < row; i++ ) {
1.28 noro 11661: a = mat[i][j]; c = cmat[i][j];
11662: MOD128(a,c,md);
11663: mat[i][j] = a; cmat[i][j] = 0;
11664: }
1.31 noro 11665: for ( i = 0; i < row; i++ )
11666: if ( !used[i] && mat[i][j] ) break;
11667: if ( i == row ) {
1.28 noro 11668: colstat[j] = 0;
11669: continue;
1.31 noro 11670: } else {
1.28 noro 11671: colstat[j] = 1;
1.31 noro 11672: used[i] = 1;
1.28 noro 11673: }
11674: /* column j is normalized */
1.31 noro 11675: s = sugar[i];
11676: inv = invm((UINT)mat[i][j],md);
1.28 noro 11677: /* normalize pivot row */
1.31 noro 11678: for ( k = j, pk = mat[i]+j, ck = cmat[i]+j; k < col; k++, pk++, ck++ ) {
1.28 noro 11679: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
11680: }
1.31 noro 11681: for ( k = i+1; k < row; k++ ) {
11682: if ( (a = mat[k][j]) != 0 ) {
11683: sugar[k] = MAX(sugar[k],s);
11684: red_by_vect64(md,mat[k]+j,cmat[k]+j,mat[i]+j,(int)(md-a),col-j);
1.28 noro 11685: Nf4_red++;
11686: }
11687: }
11688: }
1.31 noro 11689: rank = 0;
11690: for ( i = 0; i < row; i++ ) {
11691: for ( j = 0; j < col; j++ )
11692: if ( mat[i][j] ) break;
11693: if ( j == col ) sugar[i] = -1;
11694: else rank++;
11695: }
1.28 noro 11696: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
11697: GCFREE(cmat);
11698: return rank;
11699: }
11700:
11701: NODE nd_f4_red_mod64_main_s(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
11702: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,NODE *syzlistp)
11703: {
11704: int spcol,sprow,a;
11705: int i,j,k,l,rank;
11706: NODE r0,r;
11707: ND_pairs sp;
11708: ND spol;
11709: mp_limb_t **spmat;
11710: mp_limb_t *svect,*cvect;
11711: mp_limb_t *v;
11712: int *colstat;
11713: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
11714: int maxrs;
11715: int *spsugar;
11716: ND_pairs *spactive;
11717: SIG *spsig;
11718:
11719: get_eg(&eg0);
11720: /* elimination (1st step) */
11721: spmat = (mp_limb_t **)MALLOC(nsp*sizeof(mp_limb_t *));
11722: cvect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11723: spsugar = (int *)MALLOC(nsp*sizeof(int));
11724: spsig = (SIG *)MALLOC(nsp*sizeof(SIG));
11725: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
11726: nd_sp(m,0,sp,&spol);
11727: if ( !spol ) {
1.29 noro 11728: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
1.28 noro 11729: continue;
11730: }
11731: svect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11732: nd_to_vect64(m,s0vect,col,spol,svect);
11733: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred,spol->sig);
11734: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
11735: if ( i < col ) {
11736: spmat[sprow] = svect;
11737: spsugar[sprow] = MAX(maxrs,SG(spol));
11738: spsig[sprow] = sp->sig;
11739: sprow++;
11740: } else {
1.29 noro 11741: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
1.28 noro 11742: }
11743: nd_free(spol);
11744: }
11745: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
11746: if ( DP_Print ) {
11747: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
11748: fflush(asir_out);
11749: }
11750: /* free index arrays */
11751: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
11752:
11753: /* elimination (2nd step) */
11754: colstat = (int *)MALLOC(col*sizeof(int));
11755: rank = nd_gauss_elim_mod64_s(spmat,spsugar,0,sprow,col,m,colstat,spsig);
11756: r0 = 0;
1.31 noro 11757: for ( i = 0; i < sprow; i++ ) {
11758: if ( spsugar[i] >= 0 ) {
11759: NEXTNODE(r0,r);
11760: BDY(r) = vect64_to_ndv_s(spmat[i],col,s0vect);
11761: SG((NDV)BDY(r)) = spsugar[i];
11762: ((NDV)BDY(r))->sig = spsig[i];
11763: } else
11764: syzlistp[spsig[i]->pos] = insert_sig(syzlistp[spsig[i]->pos],spsig[i]);
1.28 noro 11765: GCFREE(spmat[i]);
11766: }
11767: if ( r0 ) NEXT(r) = 0;
11768: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
11769: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
11770: if ( DP_Print ) {
11771: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
11772: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
11773: nsp,nred,sprow,col,rank);
11774: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
11775: }
11776: return r0;
11777: }
1.40 noro 11778: #endif
1.28 noro 11779:
11780: NODE nd_f4_red_s(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,NODE *syzlistp)
11781: {
11782: IndArray *imat;
11783: int nsp,nred,i,start;
11784: int *rhead;
11785: NODE r0,rp;
11786: ND_pairs sp;
11787: NM_ind_pair *rvect;
11788: UINT *s;
11789: int *s0hash;
11790: struct oEGT eg0,eg1,eg_conv;
11791:
11792: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
11793: nred = length(rp0);
11794: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
11795: rhead = (int *)MALLOC(col*sizeof(int));
11796: for ( i = 0; i < col; i++ ) rhead[i] = 0;
11797:
11798: /* construction of index arrays */
11799: get_eg(&eg0);
11800: if ( DP_Print ) {
11801: fprintf(asir_out,"%dx%d,",nsp+nred,col);
11802: fflush(asir_out);
11803: }
11804: rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
11805: for ( start = 0, rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
11806: rvect[i] = (NM_ind_pair)BDY(rp);
11807: imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,rvect[i],start);
11808: rhead[imat[i]->head] = 1;
11809: start = imat[i]->head;
11810: }
11811: get_eg(&eg1); init_eg(&eg_conv); add_eg(&eg_conv,&eg0,&eg1); add_eg(&f4_conv,&eg0,&eg1);
11812: if ( DP_Print ) {
11813: fprintf(asir_out,"conv=%.3fsec,",eg_conv.exectime);
11814: fflush(asir_out);
11815: }
11816: if ( m > 0 )
1.40 noro 11817: #if SIZEOF_LONG==8
1.28 noro 11818: r0 = nd_f4_red_mod64_main_s(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,syzlistp);
1.40 noro 11819: #else
11820: r0 = nd_f4_red_main_s(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,syzlistp);
11821: #endif
1.28 noro 11822: else
11823: // r0 = nd_f4_red_q_main_s(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
11824: error("nd_f4_red_q_main_s : not implemented yet");
11825: return r0;
11826: }
11827:
11828: INLINE int ndl_find_reducer_minsig(UINT *dg)
11829: {
11830: RHist r;
11831: int i,singular,ret,d,k,imin;
11832: SIG t;
11833: static int wpd,nvar;
11834: static SIG quo,quomin;
11835: static UINT *tmp;
11836:
11837: if ( !quo || nvar != nd_nvar ) { NEWSIG(quo); NEWSIG(quomin); }
11838: if ( wpd != nd_wpd ) {
11839: wpd = nd_wpd;
11840: tmp = (UINT *)MALLOC(wpd*sizeof(UINT));
11841: }
11842: #if 0
11843: d = ndl_hash_value(dg);
11844: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
11845: if ( ndl_equal(dg,DL(r)) ) {
11846: return r->index;
11847: }
11848: }
11849: #endif
11850: imin = -1;
11851: for ( i = 0; i < nd_psn; i++ ) {
11852: r = nd_psh[i];
11853: if ( ndl_reducible(dg,DL(r)) ) {
11854: ndl_sub(dg,DL(r),tmp);
11855: _ndltodl(tmp,DL(quo));
11856: _addtodl(nd_nvar,DL(nd_psh[i]->sig),DL(quo));
11857: quo->pos = nd_psh[i]->sig->pos;
11858: if ( imin < 0 || comp_sig(quomin,quo) > 0 ) {
11859: t = quo; quo = quomin; quomin = t;
11860: imin = i;
11861: }
11862: }
11863: }
11864: if ( imin == -1 ) return nd_psn;
11865: else {
11866: #if 0
11867: nd_append_red(dg,i);
11868: #endif
11869: return imin;
11870: }
11871: }
11872:
11873: int nd_symbolic_preproc_s(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
11874: {
11875: NODE rp0,rp;
11876: NM mul,head,s0,s;
11877: int index,col,i,sugar;
11878: RHist h;
11879: UINT *s0v,*p;
11880: NM_ind_pair pair;
11881: ND red;
11882: NDV *ps;
11883: SIG sig;
11884:
11885: s0 = 0; rp0 = 0; col = 0;
11886: if ( nd_demand )
11887: ps = trace?nd_ps_trace_sym:nd_ps_sym;
11888: else
11889: ps = trace?nd_ps_trace:nd_ps;
11890: while ( 1 ) {
11891: head = remove_head_pbucket_symbolic(bucket);
11892: if ( !head ) break;
11893: if ( !s0 ) s0 = head;
11894: else NEXT(s) = head;
11895: s = head;
11896: index = ndl_find_reducer_minsig(DL(head));
11897: if ( index >= 0 && index < nd_psn ) {
11898: h = nd_psh[index];
11899: NEWNM(mul);
11900: ndl_sub(DL(head),DL(h),DL(mul));
11901: if ( ndl_check_bound2(index,DL(mul)) )
11902: return 0;
11903: sugar = TD(DL(mul))+SG(ps[index]);
11904: NEWSIG(sig);
11905: _ndltodl(DL(mul),DL(sig));
11906: _addtodl(nd_nvar,DL(nd_psh[index]->sig),DL(sig));
11907: sig->pos = nd_psh[index]->sig->pos;
11908: MKNM_ind_pair(pair,mul,index,sugar,sig);
11909: red = ndv_mul_nm_symbolic(mul,ps[index]);
11910: add_pbucket_symbolic(bucket,nd_remove_head(red));
11911: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
11912: }
11913: col++;
11914: }
11915: if ( rp0 ) NEXT(rp) = 0;
11916: NEXT(s) = 0;
11917: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
11918: for ( i = 0, p = s0v, s = s0; i < col;
11919: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
11920: *s0vect = s0v;
11921: *r = rp0;
11922:
11923: return col;
11924: }
11925:
11926: NODE nd_sba_f4(int m,int **indp)
11927: {
1.34 noro 11928: int i,nh,stat,index,f4red,f4step;
1.33 noro 11929: int col,rank,len,k,j,a,sugar,nbase,psugar,ms;
11930: NODE r,g,rp0,nflist;
1.41 noro 11931: ND_pairs d,l,t,l1;
1.33 noro 11932: ND h,nf;
11933: NDV nfv;
11934: union oNDC hc;
11935: UINT *s0vect;
1.28 noro 11936: UINT c;
11937: PGeoBucket bucket;
1.33 noro 11938: NODE *syzlist;
11939: SIG sig;
1.28 noro 11940: struct oEGT eg0,eg1,eg_f4;
1.33 noro 11941: struct oEGT eg2,eg_update,eg_remove,eg_large,eg_nf,eg_nfzero;
1.28 noro 11942:
11943: Nf4_red=0;
1.30 noro 11944: d = 0;
1.29 noro 11945: syzlist = (NODE *)MALLOC(nd_psn*sizeof(NODE));
1.28 noro 11946: for ( i = 0; i < nd_psn; i++ ) {
1.30 noro 11947: d = update_pairs_s(d,i,syzlist);
1.28 noro 11948: }
1.30 noro 11949: nd_nbase = nd_psn;
1.28 noro 11950: f4red = 1;
1.33 noro 11951: psugar = 0;
1.34 noro 11952: f4step = 0;
1.28 noro 11953: while ( d ) {
1.33 noro 11954: for ( t = d, ms = SG(d); t; t = NEXT(t) )
11955: if ( SG(t) < ms ) ms = SG(t);
1.38 noro 11956: if ( ms == psugar && f4step >= nd_sba_f4step ) {
1.33 noro 11957: again:
11958: l = d; d = d->next;
1.41 noro 11959: #if 0
1.33 noro 11960: if ( small_lcm(l) ) {
11961: if ( DP_Print ) fprintf(asir_out,"M");
11962: continue;
11963: }
11964: sig = l->sig;
11965: stat = nd_sp(m,0,l,&h);
1.41 noro 11966: #else
11967: l1 = find_smallest_lcm(l);
11968: if ( l1 == 0 ) {
11969: if ( DP_Print ) fprintf(asir_out,"M");
11970: continue;
11971: }
11972: sig = l1->sig;
11973: stat = nd_sp(m,0,l1,&h);
11974: #endif
1.33 noro 11975: if ( !stat ) {
11976: NEXT(l) = d; d = l;
11977: d = nd_reconstruct(0,d);
11978: goto again;
11979: }
11980: get_eg(&eg1);
11981: #if USE_GEOBUCKET
1.39 noro 11982: 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 11983: #else
1.39 noro 11984: stat = nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.33 noro 11985: #endif
11986: get_eg(&eg2);
11987: if ( !stat ) {
11988: NEXT(l) = d; d = l;
11989: d = nd_reconstruct(0,d);
11990: goto again;
11991: } else if ( stat == -1 ) {
11992: if ( DP_Print ) { printf("S"); fflush(stdout); }
11993: FREENDP(l);
11994: } else if ( nf ) {
11995: if ( DP_Print ) { printf("+"); fflush(stdout); }
11996: add_eg(&eg_nf,&eg1,&eg2);
11997: hc = HCU(nf);
11998: nd_removecont(m,nf);
11999: nfv = ndtondv(m,nf); nd_free(nf);
12000: nh = ndv_newps(m,nfv,0);
12001:
1.30 noro 12002: d = update_pairs_s(d,nh,syzlist);
12003: nd_sba_pos[sig->pos] = append_one(nd_sba_pos[sig->pos],nh);
1.33 noro 12004: FREENDP(l);
1.28 noro 12005: } else {
1.33 noro 12006: add_eg(&eg_nfzero,&eg1,&eg2);
12007: // syzygy
12008: get_eg(&eg1);
12009: d = remove_spair_s(d,sig);
12010: get_eg(&eg2); add_eg(&eg_remove,&eg1,&eg2);
1.29 noro 12011: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
1.33 noro 12012: if ( DP_Print ) { printf("."); fflush(stdout); }
12013: FREENDP(l);
12014: }
12015: } else {
1.34 noro 12016: if ( ms != psugar ) f4step = 1;
12017: else f4step++;
1.33 noro 12018: again2:
12019: psugar = ms;
12020: l = nd_minsugarp_s(d,&d);
12021: sugar = nd_sugarweight?d->sugar2:SG(d);
12022: bucket = create_pbucket();
12023: stat = nd_sp_f4(m,0,l,bucket);
12024: if ( !stat ) {
12025: for ( t = l; NEXT(t); t = NEXT(t) );
12026: NEXT(t) = d; d = l;
12027: d = nd_reconstruct(0,d);
12028: goto again2;
12029: }
12030: if ( bucket->m < 0 ) continue;
12031: col = nd_symbolic_preproc_s(bucket,0,&s0vect,&rp0);
12032: if ( !col ) {
1.37 noro 12033: for ( t = l; NEXT(t); t = NEXT(t) )
12034: ;
12035: NEXT(t) = d; d = l;
1.33 noro 12036: d = nd_reconstruct(0,d);
12037: goto again2;
12038: }
1.34 noro 12039: if ( DP_Print ) fprintf(asir_out,"\nsugar=%d,",psugar);
1.33 noro 12040: nflist = nd_f4_red_s(m,l,0,s0vect,col,rp0,syzlist);
12041: /* adding new bases */
12042: for ( r = nflist; r; r = NEXT(r) ) {
12043: nfv = (NDV)BDY(r);
1.38 noro 12044: if ( nd_f4_td ) SG(nfv) = nd_tdeg(nfv);
1.33 noro 12045: ndv_removecont(m,nfv);
12046: nh = ndv_newps(m,nfv,0);
12047: d = update_pairs_s(d,nh,syzlist);
12048: nd_sba_pos[nfv->sig->pos] = append_one(nd_sba_pos[nfv->sig->pos],nh);
12049: }
12050: for ( i = 0; i < nd_nbase; i++ )
12051: for ( r = syzlist[i]; r; r = NEXT(r) )
12052: d = remove_spair_s(d,(SIG)BDY(r));
12053: d = remove_large_lcm(d);
12054: if ( DP_Print ) {
1.34 noro 12055: fprintf(asir_out,"f4red=%d,gblen=%d",f4red,nd_psn); fflush(asir_out);
1.33 noro 12056: }
12057: f4red++;
1.28 noro 12058: }
12059: }
12060: if ( DP_Print ) {
1.34 noro 12061: fprintf(asir_out,"\nnumber of red=%d,",Nf4_red);
1.28 noro 12062: }
1.30 noro 12063: g = conv_ilist_s(nd_demand,0,indp);
1.28 noro 12064: return g;
12065: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>