Annotation of OpenXM_contrib2/asir2018/engine/nd.c, Revision 1.66
1.66 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2018/engine/nd.c,v 1.65 2022/04/03 00:39:12 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.63 noro 73: static int nd_top,nd_sba_syz,nd_sba_inputisgb,nd_sba_heu;
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: matrix mat;
182:
183: mat = (matrix)MALLOC(sizeof(struct matrix));
184: mat->row = row;
185: mat->col = col;
186: mat->a = a = (unsigned long **)MALLOC(row*sizeof(unsigned long *));
187: return mat;
188: }
189:
190:
191: void _ND_alloc()
192: {
193: ND p;
194: int i;
195:
196: for ( i = 0; i < 1024; i++ ) {
197: p = (ND)MALLOC(sizeof(struct oND));
198: p->body = (NM)_nd_free_list; _nd_free_list = p;
199: }
200: }
201:
202: void _NDP_alloc()
203: {
204: ND_pairs p;
205: int i;
206:
207: for ( i = 0; i < 1024; i++ ) {
208: p = (ND_pairs)MALLOC(sizeof(struct oND_pairs)
209: +(nd_wpd-1)*sizeof(UINT));
210: p->next = _ndp_free_list; _ndp_free_list = p;
211: }
212: }
213:
214: INLINE int nd_length(ND p)
215: {
216: NM m;
217: int i;
218:
219: if ( !p )
220: return 0;
221: else {
222: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
223: return i;
224: }
225: }
226:
227: extern int dp_negative_weight;
228:
229: INLINE int ndl_reducible(UINT *d1,UINT *d2)
230: {
231: UINT u1,u2;
232: int i,j;
233:
234: if ( nd_module && (MPOS(d1) != MPOS(d2)) ) return 0;
235:
236: if ( !dp_negative_weight && TD(d1) < TD(d2) ) return 0;
237: #if USE_UNROLL
238: switch ( nd_bpe ) {
239: case 3:
240: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
241: u1 = d1[i]; u2 = d2[i];
242: if ( (u1&0x38000000) < (u2&0x38000000) ) return 0;
243: if ( (u1& 0x7000000) < (u2& 0x7000000) ) return 0;
244: if ( (u1& 0xe00000) < (u2& 0xe00000) ) return 0;
245: if ( (u1& 0x1c0000) < (u2& 0x1c0000) ) return 0;
246: if ( (u1& 0x38000) < (u2& 0x38000) ) return 0;
247: if ( (u1& 0x7000) < (u2& 0x7000) ) return 0;
248: if ( (u1& 0xe00) < (u2& 0xe00) ) return 0;
249: if ( (u1& 0x1c0) < (u2& 0x1c0) ) return 0;
250: if ( (u1& 0x38) < (u2& 0x38) ) return 0;
251: if ( (u1& 0x7) < (u2& 0x7) ) return 0;
252: }
253: return 1;
254: break;
255: case 4:
256: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
257: u1 = d1[i]; u2 = d2[i];
258: if ( (u1&0xf0000000) < (u2&0xf0000000) ) return 0;
259: if ( (u1& 0xf000000) < (u2& 0xf000000) ) return 0;
260: if ( (u1& 0xf00000) < (u2& 0xf00000) ) return 0;
261: if ( (u1& 0xf0000) < (u2& 0xf0000) ) return 0;
262: if ( (u1& 0xf000) < (u2& 0xf000) ) return 0;
263: if ( (u1& 0xf00) < (u2& 0xf00) ) return 0;
264: if ( (u1& 0xf0) < (u2& 0xf0) ) return 0;
265: if ( (u1& 0xf) < (u2& 0xf) ) return 0;
266: }
267: return 1;
268: break;
269: case 6:
270: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
271: u1 = d1[i]; u2 = d2[i];
272: if ( (u1&0x3f000000) < (u2&0x3f000000) ) return 0;
273: if ( (u1& 0xfc0000) < (u2& 0xfc0000) ) return 0;
274: if ( (u1& 0x3f000) < (u2& 0x3f000) ) return 0;
275: if ( (u1& 0xfc0) < (u2& 0xfc0) ) return 0;
276: if ( (u1& 0x3f) < (u2& 0x3f) ) return 0;
277: }
278: return 1;
279: break;
280: case 8:
281: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
282: u1 = d1[i]; u2 = d2[i];
283: if ( (u1&0xff000000) < (u2&0xff000000) ) return 0;
284: if ( (u1& 0xff0000) < (u2& 0xff0000) ) return 0;
285: if ( (u1& 0xff00) < (u2& 0xff00) ) return 0;
286: if ( (u1& 0xff) < (u2& 0xff) ) return 0;
287: }
288: return 1;
289: break;
290: case 16:
291: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
292: u1 = d1[i]; u2 = d2[i];
293: if ( (u1&0xffff0000) < (u2&0xffff0000) ) return 0;
294: if ( (u1& 0xffff) < (u2& 0xffff) ) return 0;
295: }
296: return 1;
297: break;
298: case 32:
299: for ( i = nd_exporigin; i < nd_wpd; i++ )
300: if ( d1[i] < d2[i] ) return 0;
301: return 1;
302: break;
303: default:
304: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
305: u1 = d1[i]; u2 = d2[i];
306: for ( j = 0; j < nd_epw; j++ )
307: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
308: }
309: return 1;
310: }
311: #else
312: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
313: u1 = d1[i]; u2 = d2[i];
314: for ( j = 0; j < nd_epw; j++ )
315: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
316: }
317: return 1;
318: #endif
319: }
320:
321: /*
322: * If the current order is a block order,
323: * then the last block is length 1 and contains
324: * the homo variable. Otherwise, the original
325: * order is either 0 or 2.
326: */
327:
328: void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepos,int ompos,int weight)
329: {
330: int w,i,e,n,omask0;
331:
332: omask0 = obpe==32?0xffffffff:((1<<obpe)-1);
333: n = nd_nvar-1;
334: ndl_zero(r);
335: for ( i = 0; i < n; i++ ) {
336: e = GET_EXP_OLD(d,i);
337: PUT_EXP(r,i,e);
338: }
339: w = TD(d);
340: PUT_EXP(r,nd_nvar-1,weight-w);
341: if ( nd_module ) MPOS(r) = d[ompos];
342: TD(r) = weight;
343: if ( nd_blockmask ) ndl_weight_mask(r);
344: }
345:
346: void ndl_dehomogenize(UINT *d)
347: {
348: UINT mask;
349: UINT h;
350: int i,bits;
351:
352: if ( nd_blockmask ) {
353: h = GET_EXP(d,nd_nvar-1);
354: XOR_EXP(d,nd_nvar-1,h);
355: TD(d) -= h;
356: ndl_weight_mask(d);
357: } else {
358: if ( nd_isrlex ) {
359: if ( nd_bpe == 32 ) {
360: h = d[nd_exporigin];
361: for ( i = nd_exporigin+1; i < nd_wpd; i++ )
362: d[i-1] = d[i];
363: d[i-1] = 0;
364: TD(d) -= h;
365: } else {
366: bits = nd_epw*nd_bpe;
367: mask = bits==32?0xffffffff:((1<<(nd_epw*nd_bpe))-1);
368: h = (d[nd_exporigin]>>((nd_epw-1)*nd_bpe))&nd_mask0;
369: for ( i = nd_exporigin; i < nd_wpd; i++ )
370: d[i] = ((d[i]<<nd_bpe)&mask)
371: |(i+1<nd_wpd?((d[i+1]>>((nd_epw-1)*nd_bpe))&nd_mask0):0);
372: TD(d) -= h;
373: }
374: } else {
375: h = GET_EXP(d,nd_nvar-1);
376: XOR_EXP(d,nd_nvar-1,h);
377: TD(d) -= h;
378: }
379: }
380: }
381:
382: void ndl_lcm(UINT *d1,unsigned *d2,UINT *d)
383: {
384: UINT t1,t2,u,u1,u2;
1.65 noro 385: int i,j;
1.1 noro 386:
387: if ( nd_module && (MPOS(d1) != MPOS(d2)) )
388: error("ndl_lcm : inconsistent monomials");
389: #if USE_UNROLL
390: switch ( nd_bpe ) {
391: case 3:
392: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
393: u1 = d1[i]; u2 = d2[i];
394: t1 = (u1&0x38000000); t2 = (u2&0x38000000); u = t1>t2?t1:t2;
395: t1 = (u1& 0x7000000); t2 = (u2& 0x7000000); u |= t1>t2?t1:t2;
396: t1 = (u1& 0xe00000); t2 = (u2& 0xe00000); u |= t1>t2?t1:t2;
397: t1 = (u1& 0x1c0000); t2 = (u2& 0x1c0000); u |= t1>t2?t1:t2;
398: t1 = (u1& 0x38000); t2 = (u2& 0x38000); u |= t1>t2?t1:t2;
399: t1 = (u1& 0x7000); t2 = (u2& 0x7000); u |= t1>t2?t1:t2;
400: t1 = (u1& 0xe00); t2 = (u2& 0xe00); u |= t1>t2?t1:t2;
401: t1 = (u1& 0x1c0); t2 = (u2& 0x1c0); u |= t1>t2?t1:t2;
402: t1 = (u1& 0x38); t2 = (u2& 0x38); u |= t1>t2?t1:t2;
403: t1 = (u1& 0x7); t2 = (u2& 0x7); u |= t1>t2?t1:t2;
404: d[i] = u;
405: }
406: break;
407: case 4:
408: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
409: u1 = d1[i]; u2 = d2[i];
410: t1 = (u1&0xf0000000); t2 = (u2&0xf0000000); u = t1>t2?t1:t2;
411: t1 = (u1& 0xf000000); t2 = (u2& 0xf000000); u |= t1>t2?t1:t2;
412: t1 = (u1& 0xf00000); t2 = (u2& 0xf00000); u |= t1>t2?t1:t2;
413: t1 = (u1& 0xf0000); t2 = (u2& 0xf0000); u |= t1>t2?t1:t2;
414: t1 = (u1& 0xf000); t2 = (u2& 0xf000); u |= t1>t2?t1:t2;
415: t1 = (u1& 0xf00); t2 = (u2& 0xf00); u |= t1>t2?t1:t2;
416: t1 = (u1& 0xf0); t2 = (u2& 0xf0); u |= t1>t2?t1:t2;
417: t1 = (u1& 0xf); t2 = (u2& 0xf); u |= t1>t2?t1:t2;
418: d[i] = u;
419: }
420: break;
421: case 6:
422: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
423: u1 = d1[i]; u2 = d2[i];
424: t1 = (u1&0x3f000000); t2 = (u2&0x3f000000); u = t1>t2?t1:t2;
425: t1 = (u1& 0xfc0000); t2 = (u2& 0xfc0000); u |= t1>t2?t1:t2;
426: t1 = (u1& 0x3f000); t2 = (u2& 0x3f000); u |= t1>t2?t1:t2;
427: t1 = (u1& 0xfc0); t2 = (u2& 0xfc0); u |= t1>t2?t1:t2;
428: t1 = (u1& 0x3f); t2 = (u2& 0x3f); u |= t1>t2?t1:t2;
429: d[i] = u;
430: }
431: break;
432: case 8:
433: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
434: u1 = d1[i]; u2 = d2[i];
435: t1 = (u1&0xff000000); t2 = (u2&0xff000000); u = t1>t2?t1:t2;
436: t1 = (u1& 0xff0000); t2 = (u2& 0xff0000); u |= t1>t2?t1:t2;
437: t1 = (u1& 0xff00); t2 = (u2& 0xff00); u |= t1>t2?t1:t2;
438: t1 = (u1& 0xff); t2 = (u2& 0xff); u |= t1>t2?t1:t2;
439: d[i] = u;
440: }
441: break;
442: case 16:
443: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
444: u1 = d1[i]; u2 = d2[i];
445: t1 = (u1&0xffff0000); t2 = (u2&0xffff0000); u = t1>t2?t1:t2;
446: t1 = (u1& 0xffff); t2 = (u2& 0xffff); u |= t1>t2?t1:t2;
447: d[i] = u;
448: }
449: break;
450: case 32:
451: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
452: u1 = d1[i]; u2 = d2[i];
453: d[i] = u1>u2?u1:u2;
454: }
455: break;
456: default:
457: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
458: u1 = d1[i]; u2 = d2[i];
459: for ( j = 0, u = 0; j < nd_epw; j++ ) {
460: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
461: }
462: d[i] = u;
463: }
464: break;
465: }
466: #else
467: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
468: u1 = d1[i]; u2 = d2[i];
469: for ( j = 0, u = 0; j < nd_epw; j++ ) {
470: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
471: }
472: d[i] = u;
473: }
474: #endif
475: if ( nd_module ) MPOS(d) = MPOS(d1);
476: TD(d) = ndl_weight(d);
477: if ( nd_blockmask ) ndl_weight_mask(d);
478: }
479:
480: void ndl_max(UINT *d1,unsigned *d2,UINT *d)
481: {
482: UINT t1,t2,u,u1,u2;
1.65 noro 483: int i,j;
1.1 noro 484:
485: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
486: u1 = d1[i]; u2 = d2[i];
487: for ( j = 0, u = 0; j < nd_epw; j++ ) {
488: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
489: }
490: d[i] = u;
491: }
492: }
493:
494: int ndl_weight(UINT *d)
495: {
496: UINT t,u;
497: int i,j;
498:
499: if ( current_dl_weight_vector )
500: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
501: u = GET_EXP(d,i);
502: t += MUL_WEIGHT(u,i);
503: }
504: else
505: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
506: u = d[i];
507: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
508: t += (u&nd_mask0);
509: }
1.20 noro 510: if ( nd_module && nd_module_rank && MPOS(d) )
511: t += nd_module_weight[MPOS(d)-1];
512: for ( i = nd_exporigin; i < nd_wpd; i++ )
513: if ( d[i] && !t )
514: printf("afo\n");
1.1 noro 515: return t;
516: }
517:
518: /* for sugarweight */
519:
520: int ndl_weight2(UINT *d)
521: {
522: int t,u;
1.65 noro 523: int i;
1.1 noro 524:
525: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
526: u = GET_EXP(d,i);
527: t += nd_sugarweight[i]*u;
528: }
1.20 noro 529: if ( nd_module && nd_module_rank && MPOS(d) )
530: t += nd_module_weight[MPOS(d)-1];
1.1 noro 531: return t;
532: }
533:
534: void ndl_weight_mask(UINT *d)
535: {
536: UINT t,u;
537: UINT *mask;
538: int i,j,k,l;
539:
540: l = nd_blockmask->n;
541: for ( k = 0; k < l; k++ ) {
542: mask = nd_blockmask->mask[k];
543: if ( current_dl_weight_vector )
544: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
545: u = GET_EXP_MASK(d,i,mask);
546: t += MUL_WEIGHT(u,i);
547: }
548: else
549: for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) {
550: u = d[i]&mask[i];
551: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
552: t += (u&nd_mask0);
553: }
554: d[k+1] = t;
555: }
556: }
557:
1.21 noro 558: int ndl_glex_compare(UINT *d1,UINT *d2)
559: {
560: if ( TD(d1) > TD(d2) ) return 1;
561: else if ( TD(d1) < TD(d2) ) return -1;
562: else return ndl_lex_compare(d1,d2);
563: }
564:
1.1 noro 565: int ndl_lex_compare(UINT *d1,UINT *d2)
566: {
567: int i;
568:
569: d1 += nd_exporigin;
570: d2 += nd_exporigin;
571: for ( i = nd_exporigin; i < nd_wpd; i++, d1++, d2++ )
572: if ( *d1 > *d2 )
573: return nd_isrlex ? -1 : 1;
574: else if ( *d1 < *d2 )
575: return nd_isrlex ? 1 : -1;
576: return 0;
577: }
578:
579: int ndl_block_compare(UINT *d1,UINT *d2)
580: {
1.65 noro 581: int i,l,j,ord_o;
1.1 noro 582: struct order_pair *op;
583: UINT t1,t2,m;
584: UINT *mask;
585:
586: l = nd_blockmask->n;
587: op = nd_blockmask->order_pair;
588: for ( j = 0; j < l; j++ ) {
589: mask = nd_blockmask->mask[j];
590: ord_o = op[j].order;
591: if ( ord_o < 2 ) {
592: if ( (t1=d1[j+1]) > (t2=d2[j+1]) ) return 1;
593: else if ( t1 < t2 ) return -1;
594: }
595: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
596: m = mask[i];
597: t1 = d1[i]&m;
598: t2 = d2[i]&m;
599: if ( t1 > t2 )
600: return !ord_o ? -1 : 1;
601: else if ( t1 < t2 )
602: return !ord_o ? 1 : -1;
603: }
604: }
605: return 0;
606: }
607:
608: int ndl_matrix_compare(UINT *d1,UINT *d2)
609: {
610: int i,j,s,row;
611: int *v;
612: Z **mat;
613: Z *w;
614: Z t1;
615: Z t,t2;
616:
1.6 noro 617: for ( j = 0; j < nd_nvar; j++ )
618: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
1.1 noro 619: if ( nd_top_weight ) {
620: if ( OID(nd_top_weight) == O_VECT ) {
1.6 noro 621: mat = (Z **)&BDY((VECT)nd_top_weight);
622: row = 1;
1.1 noro 623: } else {
624: mat = (Z **)BDY((MAT)nd_top_weight);
1.6 noro 625: row = ((MAT)nd_top_weight)->row;
1.1 noro 626: }
627: for ( i = 0; i < row; i++ ) {
1.6 noro 628: w = mat[i];
1.1 noro 629: for ( j = 0, t = 0; j < nd_nvar; j++ ) {
1.6 noro 630: STOZ(nd_work_vector[j],t1);
1.1 noro 631: mulz(w[j],t1,&t2);
632: addz(t,t2,&t1);
633: t = t1;
634: }
1.6 noro 635: if ( t ) {
636: s = sgnz(t);
1.1 noro 637: if ( s > 0 ) return 1;
638: else if ( s < 0 ) return -1;
1.6 noro 639: }
1.1 noro 640: }
1.6 noro 641: }
642: for ( i = 0; i < nd_matrix_len; i++ ) {
643: v = nd_matrix[i];
644: for ( j = 0, s = 0; j < nd_nvar; j++ )
645: s += v[j]*nd_work_vector[j];
646: if ( s > 0 ) return 1;
647: else if ( s < 0 ) return -1;
648: }
1.1 noro 649: if ( !ndl_equal(d1,d2) )
1.6 noro 650: error("ndl_matrix_compare : invalid matrix");
651: return 0;
1.1 noro 652: }
653:
654: int ndl_composite_compare(UINT *d1,UINT *d2)
655: {
656: int i,j,s,start,end,len,o;
657: int *v;
658: struct sparse_weight *sw;
659:
660: for ( j = 0; j < nd_nvar; j++ )
661: nd_work_vector[j] = GET_EXP(d1,j)-GET_EXP(d2,j);
662: for ( i = 0; i < nd_worb_len; i++ ) {
663: len = nd_worb[i].length;
664: switch ( nd_worb[i].type ) {
665: case IS_DENSE_WEIGHT:
666: v = nd_worb[i].body.dense_weight;
667: for ( j = 0, s = 0; j < len; j++ )
668: s += v[j]*nd_work_vector[j];
669: if ( s > 0 ) return 1;
670: else if ( s < 0 ) return -1;
671: break;
672: case IS_SPARSE_WEIGHT:
673: sw = nd_worb[i].body.sparse_weight;
674: for ( j = 0, s = 0; j < len; j++ )
675: s += sw[j].value*nd_work_vector[sw[j].pos];
676: if ( s > 0 ) return 1;
677: else if ( s < 0 ) return -1;
678: break;
679: case IS_BLOCK:
680: o = nd_worb[i].body.block.order;
681: start = nd_worb[i].body.block.start;
682: switch ( o ) {
683: case 0:
684: end = start+len;
685: for ( j = start, s = 0; j < end; j++ )
686: s += MUL_WEIGHT(nd_work_vector[j],j);
687: if ( s > 0 ) return 1;
688: else if ( s < 0 ) return -1;
689: for ( j = end-1; j >= start; j-- )
690: if ( nd_work_vector[j] < 0 ) return 1;
691: else if ( nd_work_vector[j] > 0 ) return -1;
692: break;
693: case 1:
694: end = start+len;
695: for ( j = start, s = 0; j < end; j++ )
696: s += MUL_WEIGHT(nd_work_vector[j],j);
697: if ( s > 0 ) return 1;
698: else if ( s < 0 ) return -1;
699: for ( j = start; j < end; j++ )
700: if ( nd_work_vector[j] > 0 ) return 1;
701: else if ( nd_work_vector[j] < 0 ) return -1;
702: break;
703: case 2:
704: end = start+len;
705: for ( j = start; j < end; j++ )
706: if ( nd_work_vector[j] > 0 ) return 1;
707: else if ( nd_work_vector[j] < 0 ) return -1;
708: break;
709: }
710: break;
711: }
712: }
713: return 0;
714: }
715:
716: /* TDH -> WW -> TD-> RL */
717:
718: int ndl_ww_lex_compare(UINT *d1,UINT *d2)
719: {
720: int i,m,e1,e2;
721:
722: if ( TD(d1) > TD(d2) ) return 1;
723: else if ( TD(d1) < TD(d2) ) return -1;
724: m = nd_nvar>>1;
725: for ( i = 0, e1 = e2 = 0; i < m; i++ ) {
726: e1 += current_weyl_weight_vector[i]*(GET_EXP(d1,m+i)-GET_EXP(d1,i));
727: e2 += current_weyl_weight_vector[i]*(GET_EXP(d2,m+i)-GET_EXP(d2,i));
728: }
729: if ( e1 > e2 ) return 1;
730: else if ( e1 < e2 ) return -1;
731: return ndl_lex_compare(d1,d2);
732: }
733:
1.21 noro 734: // common function for module glex and grlex comparison
735: int ndl_module_glex_compare(UINT *d1,UINT *d2)
1.1 noro 736: {
1.21 noro 737: int c;
1.1 noro 738:
1.21 noro 739: switch ( nd_module_ordtype ) {
740: case 0:
741: if ( TD(d1) > TD(d2) ) return 1;
742: else if ( TD(d1) < TD(d2) ) return -1;
743: else if ( (c = ndl_lex_compare(d1,d2)) != 0 ) return c;
744: else if ( MPOS(d1) < MPOS(d2) ) return 1;
745: else if ( MPOS(d1) > MPOS(d2) ) return -1;
746: else return 0;
747: break;
1.1 noro 748:
1.21 noro 749: case 1:
1.65 noro 750: if ( nd_pot_nelim && MPOS(d1)>=(UINT)(nd_pot_nelim+1) && MPOS(d2) >= (UINT)(nd_pot_nelim+1) ) {
1.19 noro 751: if ( TD(d1) > TD(d2) ) return 1;
752: else if ( TD(d1) < TD(d2) ) return -1;
753: if ( (c = ndl_lex_compare(d1,d2)) != 0 ) return c;
754: if ( MPOS(d1) < MPOS(d2) ) return 1;
755: else if ( MPOS(d1) > MPOS(d2) ) return -1;
756: }
757: if ( MPOS(d1) < MPOS(d2) ) return 1;
758: else if ( MPOS(d1) > MPOS(d2) ) return -1;
1.21 noro 759: else if ( TD(d1) > TD(d2) ) return 1;
760: else if ( TD(d1) < TD(d2) ) return -1;
761: else return ndl_lex_compare(d1,d2);
762: break;
1.1 noro 763:
1.21 noro 764: case 2: // weight -> POT
765: if ( TD(d1) > TD(d2) ) return 1;
766: else if ( TD(d1) < TD(d2) ) return -1;
767: else if ( MPOS(d1) < MPOS(d2) ) return 1;
768: else if ( MPOS(d1) > MPOS(d2) ) return -1;
769: else return ndl_lex_compare(d1,d2);
770: break;
1.1 noro 771:
1.21 noro 772: default:
773: error("ndl_module_glex_compare : invalid module_ordtype");
1.28 noro 774: return 0;
1.21 noro 775: }
1.1 noro 776: }
777:
1.21 noro 778: // common for module comparison
779: int ndl_module_compare(UINT *d1,UINT *d2)
1.1 noro 780: {
1.21 noro 781: int c;
1.1 noro 782:
1.21 noro 783: switch ( nd_module_ordtype ) {
784: case 0:
1.23 noro 785: if ( (c = (*ndl_base_compare_function)(d1,d2)) != 0 ) return c;
1.21 noro 786: else if ( MPOS(d1) > MPOS(d2) ) return -1;
787: else if ( MPOS(d1) < MPOS(d2) ) return 1;
788: else return 0;
789: break;
1.1 noro 790:
1.21 noro 791: case 1:
792: if ( MPOS(d1) < MPOS(d2) ) return 1;
793: else if ( MPOS(d1) > MPOS(d2) ) return -1;
794: else return (*ndl_base_compare_function)(d1,d2);
795: break;
1.1 noro 796:
1.21 noro 797: case 2: // weight -> POT
798: if ( TD(d1) > TD(d2) ) return 1;
799: else if ( TD(d1) < TD(d2) ) return -1;
800: else if ( MPOS(d1) < MPOS(d2) ) return 1;
801: else if ( MPOS(d1) > MPOS(d2) ) return -1;
802: else return (*ndl_base_compare_function)(d1,d2);
803: break;
1.1 noro 804:
1.21 noro 805: default:
806: error("ndl_module_compare : invalid module_ordtype");
1.28 noro 807: return 0;
1.21 noro 808: }
1.1 noro 809: }
810:
1.21 noro 811: extern DMMstack dmm_stack;
812: void _addtodl(int n,DL d1,DL d2);
1.31 noro 813: void _adddl(int n,DL d1,DL d2,DL d3);
1.21 noro 814: int _eqdl(int n,DL d1,DL d2);
815:
816: int ndl_module_schreyer_compare(UINT *m1,UINT *m2)
817: {
1.44 noro 818: int pos1,pos2,t,j,retpot;
1.21 noro 819: DMM *in;
820: DMMstack s;
821: static DL d1=0;
822: static DL d2=0;
823: static int dlen=0;
1.44 noro 824: extern int ReversePOT;
1.21 noro 825:
1.44 noro 826: if ( ReversePOT ) retpot = -1;
827: else retpot = 1;
1.21 noro 828: pos1 = MPOS(m1); pos2 = MPOS(m2);
829: if ( pos1 == pos2 ) return (*ndl_base_compare_function)(m1,m2);
830: if ( nd_nvar > dlen ) {
831: NEWDL(d1,nd_nvar);
832: NEWDL(d2,nd_nvar);
833: dlen = nd_nvar;
834: }
835: d1->td = TD(m1);
836: for ( j = 0; j < nd_nvar; j++ ) d1->d[j] = GET_EXP(m1,j);
837: d2->td = TD(m2);
838: for ( j = 0; j < nd_nvar; j++ ) d2->d[j] = GET_EXP(m2,j);
839: for ( s = dmm_stack; s; s = NEXT(s) ) {
840: in = s->in;
841: _addtodl(nd_nvar,in[pos1]->dl,d1);
842: _addtodl(nd_nvar,in[pos2]->dl,d2);
843: if ( in[pos1]->pos == in[pos2]->pos && _eqdl(nd_nvar,d1,d2)) {
1.44 noro 844: if ( pos1 < pos2 ) return retpot;
845: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 846: else return 0;
847: }
848: pos1 = in[pos1]->pos;
849: pos2 = in[pos2]->pos;
850: if ( pos1 == pos2 ) return (*dl_base_compare_function)(nd_nvar,d1,d2);
851: }
852: // comparison by the bottom order
853: switch ( nd_base_ordtype ) {
854: case 0:
855: t = (*dl_base_compare_function)(nd_nvar,d1,d2);
856: if ( t ) return t;
1.44 noro 857: else if ( pos1 < pos2 ) return retpot;
858: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 859: else return 0;
860: break;
861: case 1:
1.44 noro 862: if ( pos1 < pos2 ) return retpot;
863: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 864: else return (*dl_base_compare_function)(nd_nvar,d1,d2);
865: break;
866: case 2:
867: if ( d1->td > d2->td ) return 1;
868: else if ( d1->td < d2->td ) return -1;
1.44 noro 869: else if ( pos1 < pos2 ) return retpot;
870: else if ( pos1 > pos2 ) return -retpot;
1.21 noro 871: else return (*dl_base_compare_function)(nd_nvar,d1,d2);
872: break;
873: default:
874: error("ndl_schreyer_compare : invalid base ordtype");
1.28 noro 875: return 0;
1.21 noro 876: }
1.1 noro 877: }
878:
879: INLINE int ndl_equal(UINT *d1,UINT *d2)
880: {
881: int i;
882:
883: switch ( nd_wpd ) {
884: case 2:
885: if ( TD(d2) != TD(d1) ) return 0;
886: if ( d2[1] != d1[1] ) return 0;
887: return 1;
888: break;
889: case 3:
890: if ( TD(d2) != TD(d1) ) return 0;
891: if ( d2[1] != d1[1] ) return 0;
892: if ( d2[2] != d1[2] ) return 0;
893: return 1;
894: break;
895: default:
896: for ( i = 0; i < nd_wpd; i++ )
897: if ( *d1++ != *d2++ ) return 0;
898: return 1;
899: break;
900: }
901: }
902:
903: INLINE void ndl_copy(UINT *d1,UINT *d2)
904: {
905: int i;
906:
907: switch ( nd_wpd ) {
908: case 2:
909: TD(d2) = TD(d1);
910: d2[1] = d1[1];
911: break;
912: case 3:
913: TD(d2) = TD(d1);
914: d2[1] = d1[1];
915: d2[2] = d1[2];
916: break;
917: default:
918: for ( i = 0; i < nd_wpd; i++ )
919: d2[i] = d1[i];
920: break;
921: }
922: }
923:
924: INLINE void ndl_zero(UINT *d)
925: {
926: int i;
927: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
928: }
929:
930: INLINE void ndl_add(UINT *d1,UINT *d2,UINT *d)
931: {
932: int i;
933:
934: if ( nd_module ) {
935: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
936: error("ndl_add : invalid operation");
937: }
938: #if 1
939: switch ( nd_wpd ) {
940: case 2:
941: TD(d) = TD(d1)+TD(d2);
942: d[1] = d1[1]+d2[1];
943: break;
944: case 3:
945: TD(d) = TD(d1)+TD(d2);
946: d[1] = d1[1]+d2[1];
947: d[2] = d1[2]+d2[2];
948: break;
949: default:
950: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
951: break;
952: }
953: #else
954: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i];
955: #endif
956: }
957:
958: /* d1 += d2 */
959: INLINE void ndl_addto(UINT *d1,UINT *d2)
960: {
961: int i;
962:
963: if ( nd_module ) {
964: if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) )
965: error("ndl_addto : invalid operation");
966: }
967: #if 1
968: switch ( nd_wpd ) {
969: case 2:
970: TD(d1) += TD(d2);
971: d1[1] += d2[1];
972: break;
973: case 3:
974: TD(d1) += TD(d2);
975: d1[1] += d2[1];
976: d1[2] += d2[2];
977: break;
978: default:
979: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
980: break;
981: }
982: #else
983: for ( i = 0; i < nd_wpd; i++ ) d1[i] += d2[i];
984: #endif
985: }
986:
987: INLINE void ndl_sub(UINT *d1,UINT *d2,UINT *d)
988: {
989: int i;
990:
991: for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]-d2[i];
992: }
993:
994: int ndl_disjoint(UINT *d1,UINT *d2)
995: {
1.65 noro 996: UINT t1,t2,u1,u2;
1.1 noro 997: int i,j;
998:
999: if ( nd_module && (MPOS(d1) == MPOS(d2)) ) return 0;
1000: #if USE_UNROLL
1001: switch ( nd_bpe ) {
1002: case 3:
1003: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1004: u1 = d1[i]; u2 = d2[i];
1005: t1 = u1&0x38000000; t2 = u2&0x38000000; if ( t1&&t2 ) return 0;
1006: t1 = u1& 0x7000000; t2 = u2& 0x7000000; if ( t1&&t2 ) return 0;
1007: t1 = u1& 0xe00000; t2 = u2& 0xe00000; if ( t1&&t2 ) return 0;
1008: t1 = u1& 0x1c0000; t2 = u2& 0x1c0000; if ( t1&&t2 ) return 0;
1009: t1 = u1& 0x38000; t2 = u2& 0x38000; if ( t1&&t2 ) return 0;
1010: t1 = u1& 0x7000; t2 = u2& 0x7000; if ( t1&&t2 ) return 0;
1011: t1 = u1& 0xe00; t2 = u2& 0xe00; if ( t1&&t2 ) return 0;
1012: t1 = u1& 0x1c0; t2 = u2& 0x1c0; if ( t1&&t2 ) return 0;
1013: t1 = u1& 0x38; t2 = u2& 0x38; if ( t1&&t2 ) return 0;
1014: t1 = u1& 0x7; t2 = u2& 0x7; if ( t1&&t2 ) return 0;
1015: }
1016: return 1;
1017: break;
1018: case 4:
1019: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1020: u1 = d1[i]; u2 = d2[i];
1021: t1 = u1&0xf0000000; t2 = u2&0xf0000000; if ( t1&&t2 ) return 0;
1022: t1 = u1& 0xf000000; t2 = u2& 0xf000000; if ( t1&&t2 ) return 0;
1023: t1 = u1& 0xf00000; t2 = u2& 0xf00000; if ( t1&&t2 ) return 0;
1024: t1 = u1& 0xf0000; t2 = u2& 0xf0000; if ( t1&&t2 ) return 0;
1025: t1 = u1& 0xf000; t2 = u2& 0xf000; if ( t1&&t2 ) return 0;
1026: t1 = u1& 0xf00; t2 = u2& 0xf00; if ( t1&&t2 ) return 0;
1027: t1 = u1& 0xf0; t2 = u2& 0xf0; if ( t1&&t2 ) return 0;
1028: t1 = u1& 0xf; t2 = u2& 0xf; if ( t1&&t2 ) return 0;
1029: }
1030: return 1;
1031: break;
1032: case 6:
1033: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1034: u1 = d1[i]; u2 = d2[i];
1035: t1 = u1&0x3f000000; t2 = u2&0x3f000000; if ( t1&&t2 ) return 0;
1036: t1 = u1& 0xfc0000; t2 = u2& 0xfc0000; if ( t1&&t2 ) return 0;
1037: t1 = u1& 0x3f000; t2 = u2& 0x3f000; if ( t1&&t2 ) return 0;
1038: t1 = u1& 0xfc0; t2 = u2& 0xfc0; if ( t1&&t2 ) return 0;
1039: t1 = u1& 0x3f; t2 = u2& 0x3f; if ( t1&&t2 ) return 0;
1040: }
1041: return 1;
1042: break;
1043: case 8:
1044: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1045: u1 = d1[i]; u2 = d2[i];
1046: t1 = u1&0xff000000; t2 = u2&0xff000000; if ( t1&&t2 ) return 0;
1047: t1 = u1& 0xff0000; t2 = u2& 0xff0000; if ( t1&&t2 ) return 0;
1048: t1 = u1& 0xff00; t2 = u2& 0xff00; if ( t1&&t2 ) return 0;
1049: t1 = u1& 0xff; t2 = u2& 0xff; if ( t1&&t2 ) return 0;
1050: }
1051: return 1;
1052: break;
1053: case 16:
1054: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1055: u1 = d1[i]; u2 = d2[i];
1056: t1 = u1&0xffff0000; t2 = u2&0xffff0000; if ( t1&&t2 ) return 0;
1057: t1 = u1& 0xffff; t2 = u2& 0xffff; if ( t1&&t2 ) return 0;
1058: }
1059: return 1;
1060: break;
1061: case 32:
1062: for ( i = nd_exporigin; i < nd_wpd; i++ )
1063: if ( d1[i] && d2[i] ) return 0;
1064: return 1;
1065: break;
1066: default:
1067: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1068: u1 = d1[i]; u2 = d2[i];
1069: for ( j = 0; j < nd_epw; j++ ) {
1070: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
1071: u1 >>= nd_bpe; u2 >>= nd_bpe;
1072: }
1073: }
1074: return 1;
1075: break;
1076: }
1077: #else
1078: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1079: u1 = d1[i]; u2 = d2[i];
1080: for ( j = 0; j < nd_epw; j++ ) {
1081: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
1082: u1 >>= nd_bpe; u2 >>= nd_bpe;
1083: }
1084: }
1085: return 1;
1086: #endif
1087: }
1088:
1089: int ndl_check_bound(UINT *d1,UINT *d2)
1090: {
1091: UINT u2;
1092: int i,j,ind,k;
1093:
1094: ind = 0;
1095: #if USE_UNROLL
1096: switch ( nd_bpe ) {
1097: case 3:
1098: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1099: u2 = d2[i];
1100: if ( d1[ind++]+((u2>>27)&0x7) >= 0x8 ) return 1;
1101: if ( d1[ind++]+((u2>>24)&0x7) >= 0x8 ) return 1;
1102: if ( d1[ind++]+((u2>>21)&0x7) >= 0x8 ) return 1;
1103: if ( d1[ind++]+((u2>>18)&0x7) >= 0x8 ) return 1;
1104: if ( d1[ind++]+((u2>>15)&0x7) >= 0x8 ) return 1;
1105: if ( d1[ind++]+((u2>>12)&0x7) >= 0x8 ) return 1;
1106: if ( d1[ind++]+((u2>>9)&0x7) >= 0x8 ) return 1;
1107: if ( d1[ind++]+((u2>>6)&0x7) >= 0x8 ) return 1;
1108: if ( d1[ind++]+((u2>>3)&0x7) >= 0x8 ) return 1;
1109: if ( d1[ind++]+(u2&0x7) >= 0x8 ) return 1;
1110: }
1111: return 0;
1112: break;
1113: case 4:
1114: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1115: u2 = d2[i];
1116: if ( d1[ind++]+((u2>>28)&0xf) >= 0x10 ) return 1;
1117: if ( d1[ind++]+((u2>>24)&0xf) >= 0x10 ) return 1;
1118: if ( d1[ind++]+((u2>>20)&0xf) >= 0x10 ) return 1;
1119: if ( d1[ind++]+((u2>>16)&0xf) >= 0x10 ) return 1;
1120: if ( d1[ind++]+((u2>>12)&0xf) >= 0x10 ) return 1;
1121: if ( d1[ind++]+((u2>>8)&0xf) >= 0x10 ) return 1;
1122: if ( d1[ind++]+((u2>>4)&0xf) >= 0x10 ) return 1;
1123: if ( d1[ind++]+(u2&0xf) >= 0x10 ) return 1;
1124: }
1125: return 0;
1126: break;
1127: case 6:
1128: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1129: u2 = d2[i];
1130: if ( d1[ind++]+((u2>>24)&0x3f) >= 0x40 ) return 1;
1131: if ( d1[ind++]+((u2>>18)&0x3f) >= 0x40 ) return 1;
1132: if ( d1[ind++]+((u2>>12)&0x3f) >= 0x40 ) return 1;
1133: if ( d1[ind++]+((u2>>6)&0x3f) >= 0x40 ) return 1;
1134: if ( d1[ind++]+(u2&0x3f) >= 0x40 ) return 1;
1135: }
1136: return 0;
1137: break;
1138: case 8:
1139: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1140: u2 = d2[i];
1141: if ( d1[ind++]+((u2>>24)&0xff) >= 0x100 ) return 1;
1142: if ( d1[ind++]+((u2>>16)&0xff) >= 0x100 ) return 1;
1143: if ( d1[ind++]+((u2>>8)&0xff) >= 0x100 ) return 1;
1144: if ( d1[ind++]+(u2&0xff) >= 0x100 ) return 1;
1145: }
1146: return 0;
1147: break;
1148: case 16:
1149: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1150: u2 = d2[i];
1151: if ( d1[ind++]+((u2>>16)&0xffff) > 0x10000 ) return 1;
1152: if ( d1[ind++]+(u2&0xffff) > 0x10000 ) return 1;
1153: }
1154: return 0;
1155: break;
1156: case 32:
1157: for ( i = nd_exporigin; i < nd_wpd; i++ )
1158: if ( d1[i]+d2[i]<d1[i] ) return 1;
1159: return 0;
1160: break;
1161: default:
1162: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1163: u2 = d2[i];
1164: k = (nd_epw-1)*nd_bpe;
1165: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
1166: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1167: }
1168: return 0;
1169: break;
1170: }
1171: #else
1172: for ( i = nd_exporigin; i < nd_wpd; i++ ) {
1173: u2 = d2[i];
1174: k = (nd_epw-1)*nd_bpe;
1175: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
1176: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
1177: }
1178: return 0;
1179: #endif
1180: }
1181:
1182: int ndl_check_bound2(int index,UINT *d2)
1183: {
1184: return ndl_check_bound(nd_bound[index],d2);
1185: }
1186:
1187: INLINE int ndl_hash_value(UINT *d)
1188: {
1189: int i;
1.11 noro 1190: UINT r;
1.1 noro 1191:
1192: r = 0;
1193: for ( i = 0; i < nd_wpd; i++ )
1.12 noro 1194: r = (r*1511+d[i]);
1.11 noro 1195: r %= REDTAB_LEN;
1.1 noro 1196: return r;
1197: }
1198:
1199: INLINE int ndl_find_reducer(UINT *dg)
1200: {
1201: RHist r;
1202: int d,k,i;
1203:
1204: d = ndl_hash_value(dg);
1205: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1206: if ( ndl_equal(dg,DL(r)) ) {
1207: if ( k > 0 ) nd_notfirst++;
1208: nd_found++;
1209: return r->index;
1210: }
1211: }
1212: if ( Reverse )
1213: for ( i = nd_psn-1; i >= 0; i-- ) {
1214: r = nd_psh[i];
1215: if ( ndl_reducible(dg,DL(r)) ) {
1216: nd_create++;
1217: nd_append_red(dg,i);
1218: return i;
1219: }
1220: }
1221: else
1222: for ( i = 0; i < nd_psn; i++ ) {
1223: r = nd_psh[i];
1224: if ( ndl_reducible(dg,DL(r)) ) {
1225: nd_create++;
1226: nd_append_red(dg,i);
1227: return i;
1228: }
1229: }
1230: return -1;
1231: }
1232:
1.41 noro 1233: INLINE int ndl_find_reducer_nonsig(UINT *dg)
1234: {
1235: RHist r;
1236: int i;
1237:
1238: for ( i = 0; i < nd_psn; i++ ) {
1239: r = nd_psh[i];
1240: if ( ndl_reducible(dg,DL(r)) ) return i;
1241: }
1242: return -1;
1243: }
1244:
1.24 noro 1245: // ret=0,...,nd_psn-1 => reducer found
1246: // ret=nd_psn => reducer not found
1247: // ret=-1 => singular top reducible
1248:
1249: int comp_sig(SIG s1,SIG s2);
1250: void _ndltodl(UINT *ndl,DL dl);
1251:
1252: void print_sig(SIG s)
1253: {
1254: int i;
1255:
1256: fprintf(asir_out,"<<");
1257: for ( i = 0; i < nd_nvar; i++ ) {
1258: fprintf(asir_out,"%d",s->dl->d[i]);
1259: if ( i != nd_nvar-1 ) fprintf(asir_out,",");
1260: }
1261: fprintf(asir_out,">>*e%d",s->pos);
1262: }
1263:
1.45 noro 1264: void print_siglist(NODE l)
1265: {
1266: for ( ; l; l = NEXT(l) )
1267: print_sig((SIG)l->body);
1268: }
1269:
1270:
1.35 noro 1271: // assuming increasing order wrt signature
1272:
1.24 noro 1273: INLINE int ndl_find_reducer_s(UINT *dg,SIG sig)
1274: {
1275: RHist r;
1.27 noro 1276: int i,singular,ret,d,k;
1.26 noro 1277: static int wpd,nvar;
1.24 noro 1278: static SIG quo;
1279: static UINT *tmp;
1280:
1.26 noro 1281: if ( !quo || nvar != nd_nvar ) NEWSIG(quo);
1282: if ( wpd != nd_wpd ) {
1.24 noro 1283: wpd = nd_wpd;
1284: tmp = (UINT *)MALLOC(wpd*sizeof(UINT));
1285: }
1.27 noro 1286: d = ndl_hash_value(dg);
1.35 noro 1287: #if 1
1.27 noro 1288: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1289: if ( ndl_equal(dg,DL(r)) ) {
1290: return r->index;
1291: }
1292: }
1.35 noro 1293: #endif
1.24 noro 1294: singular = 0;
1295: for ( i = 0; i < nd_psn; i++ ) {
1296: r = nd_psh[i];
1297: if ( ndl_reducible(dg,DL(r)) ) {
1.27 noro 1298: ndl_sub(dg,DL(r),tmp);
1.24 noro 1299: _ndltodl(tmp,DL(quo));
1300: _addtodl(nd_nvar,DL(nd_psh[i]->sig),DL(quo));
1301: quo->pos = nd_psh[i]->sig->pos;
1.55 noro 1302: _adddl(nd_nvar,DL(quo),nd_sba_hm[quo->pos],DL2(quo));
1.24 noro 1303: ret = comp_sig(sig,quo);
1.64 noro 1304: // if ( ret >= 0 ) { singular = 0; break; }
1.24 noro 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: {
1.65 noro 1317: int c;
1318: int can;
1.1 noro 1319: NM m1,m2,mr0,mr,s;
1320:
1321: if ( !p1 ) return p2;
1322: else if ( !p2 ) return p1;
1323: else {
1324: can = 0;
1.65 noro 1325: for ( m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1.1 noro 1326: c = DL_COMPARE(DL(m1),DL(m2));
1327: switch ( c ) {
1328: case 0:
1329: s = m1; m1 = NEXT(m1);
1330: can++; NEXTNM2(mr0,mr,s);
1331: s = m2; m2 = NEXT(m2); FREENM(s);
1332: break;
1333: case 1:
1334: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1335: break;
1336: case -1:
1337: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1338: break;
1339: }
1340: }
1341: if ( !mr0 )
1342: if ( m1 ) mr0 = m1;
1343: else if ( m2 ) mr0 = m2;
1344: else return 0;
1345: else if ( m1 ) NEXT(mr) = m1;
1346: else if ( m2 ) NEXT(mr) = m2;
1347: else NEXT(mr) = 0;
1348: BDY(p1) = mr0;
1349: SG(p1) = MAX(SG(p1),SG(p2));
1350: LEN(p1) = LEN(p1)+LEN(p2)-can;
1351: FREEND(p2);
1352: return p1;
1353: }
1354: }
1355:
1356: ND nd_add(int mod,ND p1,ND p2)
1357: {
1.65 noro 1358: int c;
1359: int t,can;
1.1 noro 1360: NM m1,m2,mr0,mr,s;
1361:
1.11 noro 1362: Nnd_add++;
1.1 noro 1363: if ( !p1 ) return p2;
1364: else if ( !p2 ) return p1;
1365: else if ( mod == -1 ) return nd_add_sf(p1,p2);
1366: else if ( mod == -2 ) return nd_add_lf(p1,p2);
1367: else if ( !mod ) return nd_add_q(p1,p2);
1368: else {
1369: can = 0;
1.65 noro 1370: for ( m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1.1 noro 1371: c = DL_COMPARE(DL(m1),DL(m2));
1372: switch ( c ) {
1373: case 0:
1374: t = ((CM(m1))+(CM(m2))) - mod;
1375: if ( t < 0 ) t += mod;
1376: s = m1; m1 = NEXT(m1);
1377: if ( t ) {
1378: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1379: } else {
1380: can += 2; FREENM(s);
1381: }
1382: s = m2; m2 = NEXT(m2); FREENM(s);
1383: break;
1384: case 1:
1385: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1386: break;
1387: case -1:
1388: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1389: break;
1390: }
1391: }
1392: if ( !mr0 )
1393: if ( m1 ) mr0 = m1;
1394: else if ( m2 ) mr0 = m2;
1395: else return 0;
1396: else if ( m1 ) NEXT(mr) = m1;
1397: else if ( m2 ) NEXT(mr) = m2;
1398: else NEXT(mr) = 0;
1399: BDY(p1) = mr0;
1400: SG(p1) = MAX(SG(p1),SG(p2));
1401: LEN(p1) = LEN(p1)+LEN(p2)-can;
1402: FREEND(p2);
1403: return p1;
1404: }
1405: }
1406:
1407: /* XXX on opteron, the inlined manipulation of destructive additon of
1408: * two NM seems to make gcc optimizer get confused, so the part is
1409: * done in a function.
1410: */
1411:
1412: int nm_destructive_add_q(NM *m1,NM *m2,NM *mr0,NM *mr)
1413: {
1414: NM s;
1415: P t;
1416: int can;
1417:
1418: addp(nd_vc,CP(*m1),CP(*m2),&t);
1419: s = *m1; *m1 = NEXT(*m1);
1420: if ( t ) {
1421: can = 1; NEXTNM2(*mr0,*mr,s); CP(*mr) = (t);
1422: } else {
1423: can = 2; FREENM(s);
1424: }
1425: s = *m2; *m2 = NEXT(*m2); FREENM(s);
1426: return can;
1427: }
1428:
1429: ND nd_add_q(ND p1,ND p2)
1430: {
1.65 noro 1431: int c,can;
1.1 noro 1432: NM m1,m2,mr0,mr,s;
1.66 ! noro 1433: P t;
1.1 noro 1434:
1435: if ( !p1 ) return p2;
1436: else if ( !p2 ) return p1;
1437: else {
1438: can = 0;
1.65 noro 1439: for ( m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1.1 noro 1440: c = DL_COMPARE(DL(m1),DL(m2));
1441: switch ( c ) {
1442: case 0:
1443: #if defined(__x86_64__)
1444: can += nm_destructive_add_q(&m1,&m2,&mr0,&mr);
1445: #else
1446: addp(nd_vc,CP(m1),CP(m2),&t);
1447: s = m1; m1 = NEXT(m1);
1448: if ( t ) {
1449: can++; NEXTNM2(mr0,mr,s); CP(mr) = (t);
1450: } else {
1451: can += 2; FREENM(s);
1452: }
1453: s = m2; m2 = NEXT(m2); FREENM(s);
1454: #endif
1455: break;
1456: case 1:
1457: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1458: break;
1459: case -1:
1460: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1461: break;
1462: }
1463: }
1464: if ( !mr0 )
1465: if ( m1 ) mr0 = m1;
1466: else if ( m2 ) mr0 = m2;
1467: else return 0;
1468: else if ( m1 ) NEXT(mr) = m1;
1469: else if ( m2 ) NEXT(mr) = m2;
1470: else NEXT(mr) = 0;
1471: BDY(p1) = mr0;
1472: SG(p1) = MAX(SG(p1),SG(p2));
1473: LEN(p1) = LEN(p1)+LEN(p2)-can;
1474: FREEND(p2);
1475: return p1;
1476: }
1477: }
1478:
1479: ND nd_add_sf(ND p1,ND p2)
1480: {
1.65 noro 1481: int c,can;
1.1 noro 1482: NM m1,m2,mr0,mr,s;
1483: int t;
1484:
1485: if ( !p1 ) return p2;
1486: else if ( !p2 ) return p1;
1487: else {
1488: can = 0;
1.65 noro 1489: for ( m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1.1 noro 1490: c = DL_COMPARE(DL(m1),DL(m2));
1491: switch ( c ) {
1492: case 0:
1493: t = _addsf(CM(m1),CM(m2));
1494: s = m1; m1 = NEXT(m1);
1495: if ( t ) {
1496: can++; NEXTNM2(mr0,mr,s); CM(mr) = (t);
1497: } else {
1498: can += 2; FREENM(s);
1499: }
1500: s = m2; m2 = NEXT(m2); FREENM(s);
1501: break;
1502: case 1:
1503: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
1504: break;
1505: case -1:
1506: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
1507: break;
1508: }
1509: }
1510: if ( !mr0 )
1511: if ( m1 ) mr0 = m1;
1512: else if ( m2 ) mr0 = m2;
1513: else return 0;
1514: else if ( m1 ) NEXT(mr) = m1;
1515: else if ( m2 ) NEXT(mr) = m2;
1516: else NEXT(mr) = 0;
1517: BDY(p1) = mr0;
1518: SG(p1) = MAX(SG(p1),SG(p2));
1519: LEN(p1) = LEN(p1)+LEN(p2)-can;
1520: FREEND(p2);
1521: return p1;
1522: }
1523: }
1524:
1525:
1526: ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp)
1527: {
1528: int c,c1,c2;
1529: Z cg,cred,gcd,tq;
1530: P cgp,credp,gcdp;
1531: Obj tr,tr1;
1532:
1533: if ( mod == -1 ) {
1534: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1535: *divp = (Obj)ONE;
1536: } else if ( mod == -2 ) {
1537: Z inv,t;
1538: divlf(ONE,HCZ(p),&inv);
1539: chsgnlf(HCZ(g),&t);
1540: mullf(inv,t,&CZ(mul));
1541: *divp = (Obj)ONE;
1542: } else if ( mod ) {
1543: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1544: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1545: *divp = (Obj)ONE;
1546: } else if ( nd_vc ) {
1547: ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp);
1548: divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp);
1549: chsgnp(cgp,&CP(mul));
1550: nd_mul_c_q(d,credp); nd_mul_c_q(g,credp);
1551: if ( dn ) {
1552: mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr);
1553: reductr(nd_vc,tr,&tr1); dn->r = (R)tr1;
1554: }
1555: *divp = (Obj)credp;
1556: } else {
1.6 noro 1557: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1558: chsgnz(cg,&CZ(mul));
1.1 noro 1559: nd_mul_c_q(d,(P)cred); nd_mul_c_q(g,(P)cred);
1560: if ( dn ) {
1561: mulz(dn->z,cred,&tq); dn->z = tq;
1562: }
1563: *divp = (Obj)cred;
1564: }
1565: return nd_add(mod,g,ndv_mul_nm(mod,mul,p));
1566: }
1567:
1568: /* ret=1 : success, ret=0 : overflow */
1.6 noro 1569: int nd_nf(int mod,ND d,ND g,NDV *ps,int full,ND *rp)
1.1 noro 1570: {
1.65 noro 1571: NM m,tail;
1.1 noro 1572: NM mul;
1.65 noro 1573: int n,sugar,index;
1.1 noro 1574: RHist h;
1.65 noro 1575: NDV p;
1.1 noro 1576: Z iq;
1577: DP dmul;
1578: NODE node;
1579: LIST hist;
1580: double hmag;
1.65 noro 1581: Obj div;
1.1 noro 1582: union oNDC hg;
1583: P cont;
1584:
1585: if ( !g ) {
1586: *rp = d;
1587: return 1;
1588: }
1589: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1590:
1.65 noro 1591: sugar = SG(g);
1.1 noro 1592: n = NV(g);
1593: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1594: if ( d )
1595: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1596: for ( ; g; ) {
1597: index = ndl_find_reducer(HDL(g));
1598: if ( index >= 0 ) {
1599: h = nd_psh[index];
1600: ndl_sub(HDL(g),DL(h),DL(mul));
1601: if ( ndl_check_bound2(index,DL(mul)) ) {
1602: nd_free(g); nd_free(d);
1603: return 0;
1604: }
1605: p = nd_demand ? ndv_load(index) : ps[index];
1606: /* d+g -> div*(d+g)+mul*p */
1.6 noro 1607: g = nd_reduce2(mod,d,g,p,mul,0,&div);
1.1 noro 1608: if ( nd_gentrace ) {
1609: /* Trace=[div,index,mul,ONE] */
1.6 noro 1610: STOZ(index,iq);
1.1 noro 1611: nmtodp(mod,mul,&dmul);
1612: node = mknode(4,div,iq,dmul,ONE);
1613: }
1.65 noro 1614: sugar = MAX(sugar,(int)(SG(p)+TD(DL(mul))));
1.1 noro 1615: if ( !mod && g && !nd_vc && ((double)(p_mag(HCP(g))) > hmag) ) {
1616: hg = HCU(g);
1617: nd_removecont2(d,g);
1.6 noro 1618: if ( nd_gentrace ) {
1.1 noro 1619: /* overwrite cont : Trace=[div,index,mul,cont] */
1.6 noro 1620: /* exact division */
1.1 noro 1621: cont = ndc_div(mod,hg,HCU(g));
1622: if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont;
1623: }
1624: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1625: }
1626: MKLIST(hist,node);
1627: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1628: } else if ( !full ) {
1629: *rp = g;
1630: return 1;
1631: } else {
1632: m = BDY(g);
1633: if ( NEXT(m) ) {
1634: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1635: } else {
1636: FREEND(g); g = 0;
1637: }
1638: if ( d ) {
1639: NEXT(tail)=m; tail=m; LEN(d)++;
1640: } else {
1641: MKND(n,m,1,d); tail = BDY(d);
1642: }
1643: }
1644: }
1645: if ( d ) SG(d) = sugar;
1646: *rp = d;
1647: return 1;
1648: }
1649:
1.24 noro 1650: // ret=1 => success
1651: // ret=0 => overflow
1652: // ret=-1 => singular top reducible
1653:
1654: int nd_nf_s(int mod,ND d,ND g,NDV *ps,int full,ND *rp)
1655: {
1.65 noro 1656: NM m,tail;
1.24 noro 1657: NM mul;
1.65 noro 1658: int n,sugar,index;
1.24 noro 1659: RHist h;
1.65 noro 1660: NDV p;
1.24 noro 1661: Z iq;
1662: DP dmul;
1663: NODE node;
1664: LIST hist;
1665: double hmag;
1.65 noro 1666: Obj div;
1667: // union oNDC hg;
1.24 noro 1668: SIG sig;
1669:
1670: if ( !g ) {
1671: *rp = d;
1672: return 1;
1673: }
1674: if ( !mod ) hmag = ((double)p_mag(HCP(g)))*nd_scale;
1675:
1.65 noro 1676: sugar = SG(g);
1.24 noro 1677: n = NV(g);
1678: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1679: if ( d )
1680: for ( tail = BDY(d); NEXT(tail); tail = NEXT(tail) );
1681: sig = g->sig;
1682: for ( ; g; ) {
1683: index = ndl_find_reducer_s(HDL(g),sig);
1684: if ( index >= 0 && index < nd_psn ) {
1685: // reducer found
1686: h = nd_psh[index];
1687: ndl_sub(HDL(g),DL(h),DL(mul));
1688: if ( ndl_check_bound2(index,DL(mul)) ) {
1689: nd_free(g); nd_free(d);
1690: return 0;
1691: }
1692: p = ps[index];
1693: /* d+g -> div*(d+g)+mul*p */
1694: g = nd_reduce2(mod,d,g,p,mul,0,&div);
1.65 noro 1695: sugar = MAX(sugar,(int)(SG(p)+TD(DL(mul))));
1.24 noro 1696: if ( !mod && g && ((double)(p_mag(HCP(g))) > hmag) ) {
1.65 noro 1697: // hg = HCU(g);
1.24 noro 1698: nd_removecont2(d,g);
1699: hmag = ((double)p_mag(HCP(g)))*nd_scale;
1700: }
1.55 noro 1701: if ( nd_gentrace ) {
1702: /* Trace=[div,index,mul,ONE] */
1703: STOZ(index,iq);
1704: nmtodp(mod,mul,&dmul);
1705: node = mknode(4,div,iq,dmul,ONE);
1706: }
1707: MKLIST(hist,node);
1708: MKNODE(node,hist,nd_tracelist); nd_tracelist = node;
1.24 noro 1709: } else if ( index == -1 ) {
1710: // singular top reducible
1711: return -1;
1712: } else if ( !full ) {
1713: *rp = g;
1714: g->sig = sig;
1715: return 1;
1716: } else {
1717: m = BDY(g);
1718: if ( NEXT(m) ) {
1719: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1720: } else {
1721: FREEND(g); g = 0;
1722: }
1723: if ( d ) {
1724: NEXT(tail)=m; tail=m; LEN(d)++;
1725: } else {
1726: MKND(n,m,1,d); tail = BDY(d);
1727: }
1728: }
1729: }
1730: if ( d ) {
1731: SG(d) = sugar;
1732: d->sig = sig;
1733: }
1734: *rp = d;
1735: return 1;
1736: }
1737:
1.1 noro 1738: int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp)
1739: {
1740: int hindex,index;
1741: NDV p;
1.65 noro 1742: ND d,red;
1743: NM mul,m,tail;
1744: int sugar,psugar,n;
1.1 noro 1745: PGeoBucket bucket;
1746: int c,c1,c2;
1.65 noro 1747: Z cg,cred,gcd;
1.1 noro 1748: RHist h;
1749: double hmag,gmag;
1750: int count = 0;
1751: int hcount = 0;
1752:
1753: if ( !g ) {
1754: *rp = 0;
1755: return 1;
1756: }
1757: sugar = SG(g);
1758: n = NV(g);
1.6 noro 1759: if ( !mod ) hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1.1 noro 1760: bucket = create_pbucket();
1761: add_pbucket(mod,bucket,g);
1762: d = 0;
1763: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1764: while ( 1 ) {
1765: if ( mod > 0 || mod == -1 )
1766: hindex = head_pbucket(mod,bucket);
1767: else if ( mod == -2 )
1768: hindex = head_pbucket_lf(bucket);
1769: else
1770: hindex = head_pbucket_q(bucket);
1771: if ( hindex < 0 ) {
1772: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1773: if ( d ) SG(d) = sugar;
1774: *rp = d;
1775: return 1;
1776: }
1777: g = bucket->body[hindex];
1778: index = ndl_find_reducer(HDL(g));
1779: if ( index >= 0 ) {
1780: count++;
1781: if ( !d ) hcount++;
1782: h = nd_psh[index];
1783: ndl_sub(HDL(g),DL(h),DL(mul));
1784: if ( ndl_check_bound2(index,DL(mul)) ) {
1785: nd_free(d);
1786: free_pbucket(bucket);
1787: *rp = 0;
1788: return 0;
1789: }
1790: p = ps[index];
1791: if ( mod == -1 )
1792: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1793: else if ( mod == -2 ) {
1794: Z inv,t;
1795: divlf(ONE,HCZ(p),&inv);
1796: chsgnlf(HCZ(g),&t);
1797: mullf(inv,t,&CZ(mul));
1798: } else if ( mod ) {
1799: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1800: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1801: } else {
1.6 noro 1802: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1803: chsgnz(cg,&CZ(mul));
1.1 noro 1804: nd_mul_c_q(d,(P)cred);
1805: mulq_pbucket(bucket,cred);
1806: g = bucket->body[hindex];
1.6 noro 1807: gmag = (double)p_mag((P)HCZ(g));
1.1 noro 1808: }
1809: red = ndv_mul_nm(mod,mul,p);
1810: bucket->body[hindex] = nd_remove_head(g);
1811: red = nd_remove_head(red);
1812: add_pbucket(mod,bucket,red);
1813: psugar = SG(p)+TD(DL(mul));
1814: sugar = MAX(sugar,psugar);
1815: if ( !mod && hmag && (gmag > hmag) ) {
1816: g = normalize_pbucket(mod,bucket);
1817: if ( !g ) {
1818: if ( d ) SG(d) = sugar;
1819: *rp = d;
1820: return 1;
1821: }
1822: nd_removecont2(d,g);
1.6 noro 1823: hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1.1 noro 1824: add_pbucket(mod,bucket,g);
1825: }
1826: } else if ( !full ) {
1827: g = normalize_pbucket(mod,bucket);
1828: if ( g ) SG(g) = sugar;
1829: *rp = g;
1830: return 1;
1831: } else {
1832: m = BDY(g);
1833: if ( NEXT(m) ) {
1834: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1835: } else {
1836: FREEND(g); g = 0;
1837: }
1838: bucket->body[hindex] = g;
1839: NEXT(m) = 0;
1840: if ( d ) {
1841: NEXT(tail)=m; tail=m; LEN(d)++;
1842: } else {
1843: MKND(n,m,1,d); tail = BDY(d);
1844: }
1845: }
1846: }
1847: }
1848:
1.25 noro 1849: int nd_nf_pbucket_s(int mod,ND g,NDV *ps,int full,ND *rp)
1850: {
1851: int hindex,index;
1852: NDV p;
1.65 noro 1853: ND d,red;
1854: NM mul,m,tail;
1855: int sugar,psugar,n;
1.25 noro 1856: PGeoBucket bucket;
1857: int c,c1,c2;
1.65 noro 1858: Z cg,cred,gcd;
1.25 noro 1859: RHist h;
1860: double hmag,gmag;
1861: int count = 0;
1862: int hcount = 0;
1863: SIG sig;
1864:
1865: if ( !g ) {
1866: *rp = 0;
1867: return 1;
1868: }
1869: sugar = SG(g);
1870: n = NV(g);
1871: if ( !mod ) hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1872: bucket = create_pbucket();
1873: add_pbucket(mod,bucket,g);
1874: d = 0;
1875: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
1876: sig = g->sig;
1877: while ( 1 ) {
1878: if ( mod > 0 || mod == -1 )
1879: hindex = head_pbucket(mod,bucket);
1880: else if ( mod == -2 )
1881: hindex = head_pbucket_lf(bucket);
1882: else
1883: hindex = head_pbucket_q(bucket);
1884: if ( hindex < 0 ) {
1885: if ( DP_Print > 3 ) printf("(%d %d)",count,hcount);
1886: if ( d ) {
1887: SG(d) = sugar;
1888: d->sig = sig;
1889: }
1890: *rp = d;
1891: return 1;
1892: }
1893: g = bucket->body[hindex];
1894: index = ndl_find_reducer_s(HDL(g),sig);
1895: if ( index >= 0 && index < nd_psn ) {
1896: count++;
1897: if ( !d ) hcount++;
1898: h = nd_psh[index];
1899: ndl_sub(HDL(g),DL(h),DL(mul));
1900: if ( ndl_check_bound2(index,DL(mul)) ) {
1901: nd_free(d);
1902: free_pbucket(bucket);
1903: *rp = 0;
1904: return 0;
1905: }
1906: p = ps[index];
1907: if ( mod == -1 )
1908: CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g)));
1909: else if ( mod == -2 ) {
1910: Z inv,t;
1911: divlf(ONE,HCZ(p),&inv);
1912: chsgnlf(HCZ(g),&t);
1913: mullf(inv,t,&CZ(mul));
1914: } else if ( mod ) {
1915: c1 = invm(HCM(p),mod); c2 = mod-HCM(g);
1916: DMAR(c1,c2,0,mod,c); CM(mul) = c;
1917: } else {
1918: igcd_cofactor(HCZ(g),HCZ(p),&gcd,&cg,&cred);
1919: chsgnz(cg,&CZ(mul));
1920: nd_mul_c_q(d,(P)cred);
1921: mulq_pbucket(bucket,cred);
1922: g = bucket->body[hindex];
1923: gmag = (double)p_mag((P)HCZ(g));
1924: }
1925: red = ndv_mul_nm(mod,mul,p);
1926: bucket->body[hindex] = nd_remove_head(g);
1927: red = nd_remove_head(red);
1928: add_pbucket(mod,bucket,red);
1929: psugar = SG(p)+TD(DL(mul));
1930: sugar = MAX(sugar,psugar);
1931: if ( !mod && hmag && (gmag > hmag) ) {
1932: g = normalize_pbucket(mod,bucket);
1933: if ( !g ) {
1934: if ( d ) {
1935: SG(d) = sugar;
1936: d->sig = sig;
1937: }
1938: *rp = d;
1939: return 1;
1940: }
1941: nd_removecont2(d,g);
1942: hmag = ((double)p_mag((P)HCZ(g)))*nd_scale;
1943: add_pbucket(mod,bucket,g);
1944: }
1945: } else if ( index == -1 ) {
1946: // singular top reducible
1947: return -1;
1948: } else if ( !full ) {
1949: g = normalize_pbucket(mod,bucket);
1950: if ( g ) {
1951: SG(g) = sugar;
1952: g->sig = sig;
1953: }
1954: *rp = g;
1955: return 1;
1956: } else {
1957: m = BDY(g);
1958: if ( NEXT(m) ) {
1959: BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--;
1960: } else {
1961: FREEND(g); g = 0;
1962: }
1963: bucket->body[hindex] = g;
1964: NEXT(m) = 0;
1965: if ( d ) {
1966: NEXT(tail)=m; tail=m; LEN(d)++;
1967: } else {
1968: MKND(n,m,1,d); tail = BDY(d);
1969: }
1970: }
1971: }
1972: }
1973:
1.1 noro 1974: /* input : list of NDV, cand : list of NDV */
1975:
1976: int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand)
1977: {
1.65 noro 1978: int i,stat;
1.1 noro 1979: ND nf,d;
1980: NDV r;
1981: NODE t,s;
1982: Z q;
1983: LIST list;
1984:
1.24 noro 1985: ndv_setup(m,0,cand,nd_gentrace?1:0,1,0);
1.65 noro 1986: // n = length(cand);
1.1 noro 1987:
1988: if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; }
1989: /* membercheck : list is a subset of Id(cand) ? */
1990: for ( t = input, i = 0; t; t = NEXT(t), i++ ) {
1991: again:
1992: nd_tracelist = 0;
1993: if ( nd_bpe > obpe )
1994: r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos);
1995: else
1996: r = (NDV)BDY(t);
1997: #if 0
1998: // moved to nd_f4_lf_trace()
1999: if ( m == -2 ) ndv_mod(m,r);
2000: #endif
2001: d = ndvtond(m,r);
1.6 noro 2002: stat = nd_nf(m,0,d,nd_ps,0,&nf);
1.1 noro 2003: if ( !stat ) {
2004: nd_reconstruct(0,0);
2005: goto again;
2006: } else if ( nf ) return 0;
2007: if ( nd_gentrace ) {
2008: nd_tracelist = reverse_node(nd_tracelist);
2009: MKLIST(list,nd_tracelist);
1.6 noro 2010: STOZ(i,q); s = mknode(2,q,list); MKLIST(list,s);
1.1 noro 2011: MKNODE(s,list,nd_alltracelist);
2012: nd_alltracelist = s; nd_tracelist = 0;
2013: }
2014: if ( DP_Print ) { printf("."); fflush(stdout); }
2015: }
2016: if ( DP_Print ) { printf("\n"); }
2017: return 1;
2018: }
2019:
2020: ND nd_remove_head(ND p)
2021: {
2022: NM m;
2023:
2024: m = BDY(p);
2025: if ( !NEXT(m) ) {
2026: FREEND(p); p = 0;
2027: } else {
2028: BDY(p) = NEXT(m); LEN(p)--;
2029: }
2030: FREENM(m);
2031: return p;
2032: }
2033:
2034: ND nd_separate_head(ND p,ND *head)
2035: {
2036: NM m,m0;
2037: ND r;
2038:
2039: m = BDY(p);
2040: if ( !NEXT(m) ) {
2041: *head = p; p = 0;
2042: } else {
2043: m0 = m;
2044: BDY(p) = NEXT(m); LEN(p)--;
2045: NEXT(m0) = 0;
2046: MKND(NV(p),m0,1,r);
2047: *head = r;
2048: }
2049: return p;
2050: }
2051:
2052: PGeoBucket create_pbucket()
2053: {
2054: PGeoBucket g;
2055:
2056: g = CALLOC(1,sizeof(struct oPGeoBucket));
2057: g->m = -1;
2058: return g;
2059: }
2060:
2061: void free_pbucket(PGeoBucket b) {
2062: int i;
2063:
2064: for ( i = 0; i <= b->m; i++ )
2065: if ( b->body[i] ) {
2066: nd_free(b->body[i]);
2067: b->body[i] = 0;
2068: }
2069: GCFREE(b);
2070: }
2071:
1.39 noro 2072: #if 0
1.1 noro 2073: void add_pbucket_symbolic(PGeoBucket g,ND d)
2074: {
2075: int l,i,k,m;
2076:
2077: if ( !d )
2078: return;
2079: l = LEN(d);
2080: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2081: /* 2^(k-1) < l <= 2^k (=m) */
2082: d = nd_merge(g->body[k],d);
2083: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
2084: g->body[k] = 0;
2085: d = nd_merge(g->body[k+1],d);
2086: }
2087: g->body[k] = d;
2088: g->m = MAX(g->m,k);
2089: }
1.39 noro 2090: #else
2091: void add_pbucket_symbolic(PGeoBucket g,ND d)
2092: {
1.65 noro 2093: int l,k,m,m0;
1.39 noro 2094:
2095: if ( !d )
2096: return;
2097: m0 = g->m;
2098: while ( 1 ) {
2099: l = LEN(d);
2100: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2101: /* 2^(k-1) < l <= 2^k (=m) */
2102: if ( g->body[k] == 0 ) {
2103: g->body[k] = d;
2104: m0 = MAX(k,m0);
2105: break;
2106: } else {
2107: d = nd_merge(g->body[k],d);
2108: g->body[k] = 0;
2109: }
2110: }
2111: g->m = m0;
2112: }
2113: #endif
1.1 noro 2114:
1.39 noro 2115: #if 0
1.1 noro 2116: void add_pbucket(int mod,PGeoBucket g,ND d)
2117: {
2118: int l,i,k,m;
2119:
2120: if ( !d )
2121: return;
2122: l = LEN(d);
2123: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2124: /* 2^(k-1) < l <= 2^k (=m) */
2125: d = nd_add(mod,g->body[k],d);
2126: for ( ; d && LEN(d) > m; k++, m <<= 1 ) {
2127: g->body[k] = 0;
2128: d = nd_add(mod,g->body[k+1],d);
2129: }
2130: g->body[k] = d;
2131: g->m = MAX(g->m,k);
2132: }
1.39 noro 2133: #else
2134: void add_pbucket(int mod,PGeoBucket g,ND d)
2135: {
1.65 noro 2136: int l,k,m,m0;
1.39 noro 2137:
2138: m0 = g->m;
2139: while ( d != 0 ) {
2140: l = LEN(d);
2141: for ( k = 0, m = 1; l > m; k++, m <<= 1 );
2142: /* 2^(k-1) < l <= 2^k (=m) */
2143: if ( g->body[k] == 0 ) {
2144: g->body[k] = d;
2145: m0 = MAX(k,m0);
2146: break;
2147: } else {
2148: d = nd_add(mod,g->body[k],d);
2149: g->body[k] = 0;
2150: }
2151: }
2152: g->m = m0;
2153: }
2154: #endif
1.1 noro 2155:
2156: void mulq_pbucket(PGeoBucket g,Z c)
2157: {
2158: int k;
2159:
2160: for ( k = 0; k <= g->m; k++ )
2161: nd_mul_c_q(g->body[k],(P)c);
2162: }
2163:
2164: NM remove_head_pbucket_symbolic(PGeoBucket g)
2165: {
2166: int j,i,k,c;
2167: NM head;
2168:
2169: k = g->m;
2170: j = -1;
2171: for ( i = 0; i <= k; i++ ) {
2172: if ( !g->body[i] ) continue;
2173: if ( j < 0 ) j = i;
2174: else {
2175: c = DL_COMPARE(HDL(g->body[i]),HDL(g->body[j]));
2176: if ( c > 0 )
2177: j = i;
2178: else if ( c == 0 )
2179: g->body[i] = nd_remove_head(g->body[i]);
2180: }
2181: }
2182: if ( j < 0 ) return 0;
2183: else {
2184: head = BDY(g->body[j]);
2185: if ( !NEXT(head) ) {
2186: FREEND(g->body[j]);
2187: g->body[j] = 0;
2188: } else {
2189: BDY(g->body[j]) = NEXT(head);
2190: LEN(g->body[j])--;
2191: }
2192: return head;
2193: }
2194: }
2195:
2196: int head_pbucket(int mod,PGeoBucket g)
2197: {
1.65 noro 2198: int j,i,c,k,sum;
2199: UINT *dj;
1.1 noro 2200: ND gi,gj;
2201:
2202: k = g->m;
2203: while ( 1 ) {
2204: j = -1;
2205: for ( i = 0; i <= k; i++ ) {
2206: if ( !(gi = g->body[i]) )
2207: continue;
2208: if ( j < 0 ) {
2209: j = i;
2210: gj = g->body[j];
2211: dj = HDL(gj);
2212: sum = HCM(gj);
2213: } else {
2214: c = DL_COMPARE(HDL(gi),dj);
2215: if ( c > 0 ) {
2216: if ( sum ) HCM(gj) = sum;
2217: else g->body[j] = nd_remove_head(gj);
2218: j = i;
2219: gj = g->body[j];
2220: dj = HDL(gj);
2221: sum = HCM(gj);
2222: } else if ( c == 0 ) {
2223: if ( mod == -1 )
2224: sum = _addsf(sum,HCM(gi));
2225: else {
2226: sum = sum+HCM(gi)-mod;
2227: if ( sum < 0 ) sum += mod;
2228: }
2229: g->body[i] = nd_remove_head(gi);
2230: }
2231: }
2232: }
2233: if ( j < 0 ) return -1;
2234: else if ( sum ) {
2235: HCM(gj) = sum;
2236: return j;
2237: } else
2238: g->body[j] = nd_remove_head(gj);
2239: }
2240: }
2241:
2242: int head_pbucket_q(PGeoBucket g)
2243: {
1.65 noro 2244: int j,i,c,k;
1.1 noro 2245: Z sum,t;
2246: ND gi,gj;
2247:
2248: k = g->m;
2249: while ( 1 ) {
2250: j = -1;
2251: for ( i = 0; i <= k; i++ ) {
2252: if ( !(gi = g->body[i]) ) continue;
2253: if ( j < 0 ) {
2254: j = i;
2255: gj = g->body[j];
1.6 noro 2256: sum = HCZ(gj);
1.1 noro 2257: } else {
1.65 noro 2258: // nv = NV(gi);
1.1 noro 2259: c = DL_COMPARE(HDL(gi),HDL(gj));
2260: if ( c > 0 ) {
1.6 noro 2261: if ( sum ) HCZ(gj) = sum;
1.1 noro 2262: else g->body[j] = nd_remove_head(gj);
2263: j = i;
2264: gj = g->body[j];
1.6 noro 2265: sum = HCZ(gj);
1.1 noro 2266: } else if ( c == 0 ) {
1.6 noro 2267: addz(sum,HCZ(gi),&t);
1.1 noro 2268: sum = t;
2269: g->body[i] = nd_remove_head(gi);
2270: }
2271: }
2272: }
2273: if ( j < 0 ) return -1;
2274: else if ( sum ) {
1.6 noro 2275: HCZ(gj) = sum;
1.1 noro 2276: return j;
2277: } else
2278: g->body[j] = nd_remove_head(gj);
2279: }
2280: }
2281:
2282: int head_pbucket_lf(PGeoBucket g)
2283: {
1.65 noro 2284: int j,i,c,k;
1.1 noro 2285: Z sum,t;
2286: ND gi,gj;
2287:
2288: k = g->m;
2289: while ( 1 ) {
2290: j = -1;
2291: for ( i = 0; i <= k; i++ ) {
2292: if ( !(gi = g->body[i]) ) continue;
2293: if ( j < 0 ) {
2294: j = i;
2295: gj = g->body[j];
2296: sum = HCZ(gj);
2297: } else {
1.65 noro 2298: // nv = NV(gi);
1.1 noro 2299: c = DL_COMPARE(HDL(gi),HDL(gj));
2300: if ( c > 0 ) {
2301: if ( sum ) HCZ(gj) = sum;
2302: else g->body[j] = nd_remove_head(gj);
2303: j = i;
2304: gj = g->body[j];
2305: sum = HCZ(gj);
2306: } else if ( c == 0 ) {
2307: addlf(sum,HCZ(gi),&t);
2308: sum = t;
2309: g->body[i] = nd_remove_head(gi);
2310: }
2311: }
2312: }
2313: if ( j < 0 ) return -1;
2314: else if ( sum ) {
2315: HCZ(gj) = sum;
2316: return j;
2317: } else
2318: g->body[j] = nd_remove_head(gj);
2319: }
2320: }
2321:
2322: ND normalize_pbucket(int mod,PGeoBucket g)
2323: {
2324: int i;
1.65 noro 2325: ND r;
1.1 noro 2326:
2327: r = 0;
2328: for ( i = 0; i <= g->m; i++ ) {
2329: r = nd_add(mod,r,g->body[i]);
2330: g->body[i] = 0;
2331: }
2332: g->m = -1;
2333: return r;
2334: }
2335:
2336: #if 0
2337: void register_hcf(NDV p)
2338: {
2339: DCP dc,t;
2340: P hc,h;
2341: int c;
2342: NODE l,l1,prev;
2343:
2344: hc = p->body->c.p;
2345: if ( !nd_vc || NUM(hc) ) return;
2346: fctrp(nd_vc,hc,&dc);
2347: for ( t = dc; t; t = NEXT(t) ) {
2348: h = t->c;
2349: if ( NUM(h) ) continue;
2350: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2351: c = compp(nd_vc,h,(P)BDY(l));
2352: if ( c >= 0 ) break;
2353: }
2354: if ( !l || c > 0 ) {
2355: MKNODE(l1,h,l);
2356: if ( !prev )
2357: nd_hcf = l1;
2358: else
2359: NEXT(prev) = l1;
2360: }
2361: }
2362: }
2363: #else
2364: void register_hcf(NDV p)
2365: {
2366: P hc,h,q;
2367: Q dmy;
2368: int c;
2369: NODE l,l1,prev;
2370:
2371: hc = p->body->c.p;
2372: if ( NUM(hc) ) return;
2373: ptozp(hc,1,&dmy,&h);
2374: #if 1
2375: for ( l = nd_hcf; l; l = NEXT(l) ) {
2376: while ( 1 ) {
2377: if ( divtpz(nd_vc,h,(P)BDY(l),&q) ) h = q;
2378: else break;
2379: }
2380: }
2381: if ( NUM(h) ) return;
2382: #endif
2383: for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) {
2384: c = compp(nd_vc,h,(P)BDY(l));
2385: if ( c >= 0 ) break;
2386: }
2387: if ( !l || c > 0 ) {
2388: MKNODE(l1,h,l);
2389: if ( !prev )
2390: nd_hcf = l1;
2391: else
2392: NEXT(prev) = l1;
2393: }
2394: }
2395: #endif
2396:
2397: int do_diagonalize(int sugar,int m)
2398: {
1.65 noro 2399: int i,stat;
2400: ND nf,s,head;
1.6 noro 2401: NDV nfv;
1.65 noro 2402: P cont;
1.6 noro 2403: union oNDC hc;
2404: NODE node;
2405: LIST l;
2406: Z iq;
1.1 noro 2407:
1.64 noro 2408: if ( diag_period == 0 ) return 1;
1.6 noro 2409: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
2410: if ( nd_gentrace ) {
2411: /* Trace = [1,index,1,1] */
2412: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
2413: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
2414: }
2415: if ( nd_demand )
2416: nfv = ndv_load(i);
2417: else
2418: nfv = nd_ps[i];
2419: s = ndvtond(m,nfv);
2420: s = nd_separate_head(s,&head);
2421: stat = nd_nf(m,head,s,nd_ps,1,&nf);
2422: if ( !stat ) return 0;
2423: ndv_free(nfv);
2424: hc = HCU(nf); nd_removecont(m,nf);
2425: /* exact division */
2426: cont = ndc_div(m,hc,HCU(nf));
1.1 noro 2427: if ( nd_gentrace ) finalize_tracelist(i,cont);
1.6 noro 2428: nfv = ndtondv(m,nf);
2429: nd_free(nf);
2430: nd_bound[i] = ndv_compute_bound(nfv);
2431: if ( !m ) register_hcf(nfv);
2432: if ( nd_demand ) {
2433: ndv_save(nfv,i);
2434: ndv_free(nfv);
2435: } else
2436: nd_ps[i] = nfv;
2437: }
2438: return 1;
1.1 noro 2439: }
2440:
2441: LIST compute_splist()
2442: {
2443: NODE g,tn0,tn,node;
2444: LIST l0;
2445: ND_pairs d,t;
2446: int i;
2447: Z i1,i2;
2448:
2449: g = 0; d = 0;
2450: for ( i = 0; i < nd_psn; i++ ) {
2451: d = update_pairs(d,g,i,0);
2452: g = update_base(g,i);
2453: }
2454: for ( t = d, tn0 = 0; t; t = NEXT(t) ) {
2455: NEXTNODE(tn0,tn);
1.6 noro 2456: STOZ(t->i1,i1); STOZ(t->i2,i2);
1.1 noro 2457: node = mknode(2,i1,i2); MKLIST(l0,node);
2458: BDY(tn) = l0;
2459: }
2460: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
2461: return l0;
2462: }
2463:
1.49 noro 2464: typedef struct oHPDATA {
1.56 noro 2465: int n;
2466: P hn; // HP(t)=hn(t)/((1-t^w0)*...*(1-t^w(n-1)))
1.49 noro 2467: VECT x; // BDY(x)[i] = <<0,...,1,...,0>>
1.56 noro 2468: int *w;
1.49 noro 2469: } *HPDATA;
2470:
2471: void make_reduced(VECT b,int nv);
2472: void mhp_rec(VECT b,VECT x,P t,P *r);
2473: P mhp_ctop(P *r,P *plist,int n);
2474: DL monomial_colon(DL a,DL b,int n);
1.56 noro 2475: LIST dp_monomial_hilbert_poincare(VECT b,VECT x);
2476: LIST dp_monomial_hilbert_poincare_weight(VECT b,VECT x,int *w);
1.49 noro 2477:
2478: void setup_hpdata(HPDATA final,HPDATA current)
2479: {
1.65 noro 2480: int n,i;
1.49 noro 2481: DL *p;
1.56 noro 2482: VECT b,x;
1.49 noro 2483: DL dl;
1.56 noro 2484: LIST ret;
2485: int *w;
2486:
2487: final->n = n = nd_nvar;
2488: final->hn = (P)BDY(nd_hpdata);
1.59 noro 2489: #if 0
1.56 noro 2490: if ( NEXT(nd_hpdata) != 0 && (weight=(LIST)BDY(NEXT(nd_hpdata))) != 0 ) {
2491: wlen = length(BDY(weight));
2492: if ( n != wlen )
2493: error("setup_hpdata : inconsistent weight length");
2494: w = (int *)MALLOC(n*sizeof(int));
2495: for ( i = 0, nd = BDY((LIST)weight); i < n; i++, nd = NEXT(nd) )
2496: w[i] = ZTOS((Z)BDY(nd));
2497: } else
2498: w = 0;
1.59 noro 2499: #else
2500: w = current_dl_weight_vector;
2501: #endif
1.49 noro 2502: MKVECT(x,n);
2503: for ( i = 0; i < n; i++ ) {
2504: NEWDL(dl,n); dl->d[i] = 1; dl->td = 1; BDY(x)[i] = dl;
2505: }
2506: final->x = x;
1.56 noro 2507: final->w = w;
1.49 noro 2508:
2509: MKVECT(b,nd_psn); p = (DL *)BDY(b);
2510: for ( i = 0; i < nd_psn; i++ ) {
2511: p[i] = ndltodl(n,nd_psh[i]->dl);
2512: }
1.56 noro 2513: if ( w ) {
2514: ret = dp_monomial_hilbert_poincare_weight(b,x,w);
2515: } else
2516: ret = dp_monomial_hilbert_poincare(b,x);
2517: current->n = n;
2518: current->hn = (P)BDY(BDY(ret));
1.49 noro 2519: current->x = x;
1.56 noro 2520: current->w = w;
2521: }
2522:
2523: int comp_hn(P a, P b)
2524: {
2525: P s;
2526: DCP dc;
2527:
2528: subp(CO,a,b,&s);
1.57 noro 2529: if ( !s ) return -1;
1.56 noro 2530: else if ( OID(s) == 1 ) return 0;
2531: else {
2532: for ( dc = DC(s); NEXT(dc); dc = NEXT(dc) );
2533: return (int)ZTOS((Z)dc->d);
2534: }
1.49 noro 2535: }
2536:
1.56 noro 2537: void update_hpdata(HPDATA current,int nh)
1.49 noro 2538: {
1.65 noro 2539: NODE data1;
2540: DL new;
2541: int i,n;
1.49 noro 2542: Z dz;
2543: DL *p;
1.65 noro 2544: VECT b;
2545: P tv,td,s,hn;
1.49 noro 2546: LIST list1;
2547:
2548: n = nd_nvar;
2549: new = ndltodl(n,nd_psh[nh]->dl);
2550: MKVECT(b,nh); p = (DL *)BDY(b);
2551: for ( i = 0; i < nh; i++ ) {
2552: p[i] = monomial_colon(ndltodl(n,nd_psh[i]->dl),new,n);
2553: }
2554: // compute HP(I:new)
1.56 noro 2555: if ( current->w )
2556: list1 = dp_monomial_hilbert_poincare_weight(b,current->x,current->w);
2557: else
2558: list1 = dp_monomial_hilbert_poincare(b,current->x);
1.49 noro 2559: data1 = BDY((LIST)list1);
2560: // HP(I+<new>) = H(I)-t^d*H(I:new), d=tdeg(new)
2561: makevar("t",&tv); UTOZ(new->td,dz);
2562: pwrp(CO,tv,dz,&td);
2563: mulp(CO,(P)ARG0(data1),td,&s);
2564: subp(CO,current->hn,s,&hn);
2565: current->hn = hn;
2566: }
2567:
2568: ND_pairs nd_remove_same_sugar( ND_pairs d, int sugar)
2569: {
2570: struct oND_pairs root;
2571: ND_pairs prev,cur;
1.61 noro 2572: int i;
1.49 noro 2573:
2574: root.next = d;
2575: prev = &root; cur = d;
1.61 noro 2576: i = 0;
1.49 noro 2577: while ( cur ) {
1.61 noro 2578: if ( SG(cur) == sugar ) {
1.49 noro 2579: prev->next = cur->next;
1.61 noro 2580: i++;
2581: } else
1.49 noro 2582: prev = cur;
2583: cur = cur->next;
2584: }
1.63 noro 2585: if ( DP_Print && i ) fprintf(asir_out,"[%d]",i);
1.49 noro 2586: return root.next;
2587: }
2588:
1.1 noro 2589: /* return value = 0 => input is not a GB */
2590:
2591: NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp)
2592: {
1.6 noro 2593: int i,nh,sugar,stat;
1.65 noro 2594: NODE g,t;
1.6 noro 2595: ND_pairs d;
2596: ND_pairs l;
1.65 noro 2597: ND h,nf;
1.6 noro 2598: NDV nfv;
2599: Z q;
1.65 noro 2600: union oNDC hc;
1.6 noro 2601: int diag_count = 0;
1.41 noro 2602: int Nnfnz = 0,Nnfz = 0;
1.6 noro 2603: P cont;
2604: LIST list;
1.49 noro 2605: struct oHPDATA current_hpdata,final_hpdata;
2606:
1.27 noro 2607: struct oEGT eg1,eg2,eg_update;
1.6 noro 2608:
1.27 noro 2609: init_eg(&eg_update);
1.11 noro 2610: Nnd_add = 0;
1.6 noro 2611: g = 0; d = 0;
2612: for ( i = 0; i < nd_psn; i++ ) {
2613: d = update_pairs(d,g,i,gensyz);
2614: g = update_base(g,i);
2615: }
2616: sugar = 0;
1.49 noro 2617: if ( nd_hpdata ) {
1.52 noro 2618: if ( DP_Print ) fprintf(asir_out,"Hilbert driven algorithm.\n");
1.49 noro 2619: setup_hpdata(&final_hpdata,¤t_hpdata);
2620: }
1.6 noro 2621: while ( d ) {
1.1 noro 2622: again:
1.6 noro 2623: l = nd_minp(d,&d);
2624: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
2625: if ( SG(l) != sugar ) {
2626: if ( ishomo ) {
2627: diag_count = 0;
2628: stat = do_diagonalize(sugar,m);
1.1 noro 2629: if ( !stat ) {
1.6 noro 2630: NEXT(l) = d; d = l;
2631: d = nd_reconstruct(0,d);
2632: goto again;
1.1 noro 2633: }
1.6 noro 2634: }
2635: sugar = SG(l);
2636: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
2637: }
2638: stat = nd_sp(m,0,l,&h);
2639: if ( !stat ) {
2640: NEXT(l) = d; d = l;
2641: d = nd_reconstruct(0,d);
2642: goto again;
2643: }
1.1 noro 2644: #if USE_GEOBUCKET
1.39 noro 2645: stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!nd_top&&!Top,&nf)
2646: :nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 2647: #else
1.39 noro 2648: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 2649: #endif
1.6 noro 2650: if ( !stat ) {
2651: NEXT(l) = d; d = l;
2652: d = nd_reconstruct(0,d);
2653: goto again;
2654: } else if ( nf ) {
1.41 noro 2655: Nnfnz++;
1.6 noro 2656: if ( checkonly || gensyz ) return 0;
1.1 noro 2657: if ( nd_newelim ) {
2658: if ( nd_module ) {
2659: if ( MPOS(HDL(nf)) > 1 ) return 0;
2660: } else if ( !(HDL(nf)[nd_exporigin] & nd_mask[0]) ) return 0;
2661: }
1.6 noro 2662: if ( DP_Print ) { printf("+"); fflush(stdout); }
2663: hc = HCU(nf);
2664: nd_removecont(m,nf);
2665: if ( !m && nd_nalg ) {
2666: nd_monic(0,&nf);
2667: nd_removecont(m,nf);
2668: }
2669: if ( nd_gentrace ) {
2670: /* exact division */
1.1 noro 2671: cont = ndc_div(m,hc,HCU(nf));
2672: if ( m || !UNIQ(cont) ) {
1.6 noro 2673: t = mknode(4,NULLP,NULLP,NULLP,cont);
2674: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
1.1 noro 2675: nd_tracelist = t;
2676: }
2677: }
1.6 noro 2678: nfv = ndtondv(m,nf); nd_free(nf);
1.24 noro 2679: nh = ndv_newps(m,nfv,0);
1.6 noro 2680: if ( !m && (ishomo && ++diag_count == diag_period) ) {
2681: diag_count = 0;
2682: stat = do_diagonalize(sugar,m);
2683: if ( !stat ) {
2684: NEXT(l) = d; d = l;
2685: d = nd_reconstruct(1,d);
2686: goto again;
1.1 noro 2687: }
1.6 noro 2688: }
1.27 noro 2689: get_eg(&eg1);
1.6 noro 2690: d = update_pairs(d,g,nh,0);
1.27 noro 2691: get_eg(&eg2); add_eg(&eg_update,&eg1,&eg2);
1.6 noro 2692: g = update_base(g,nh);
2693: FREENDP(l);
1.49 noro 2694: if ( nd_hpdata ) {
1.57 noro 2695: int dg,sugar0;
1.56 noro 2696:
2697: update_hpdata(¤t_hpdata,nh);
2698: dg = comp_hn(final_hpdata.hn,current_hpdata.hn);
1.57 noro 2699: if ( dg < 0 ) {
1.61 noro 2700: int d_len;
2701: for ( d_len = 0; d; d = d->next, d_len++);
2702: fprintf(asir_out,"[%d] We found a gb\n",d_len);
1.57 noro 2703: }
2704: sugar0 = sugar;
2705: while ( d && dg > sugar0 ) {
1.58 noro 2706: d = nd_remove_same_sugar(d,sugar0);
1.57 noro 2707: sugar0++;
1.49 noro 2708: }
2709: }
1.41 noro 2710: } else {
2711: Nnfz++;
2712: if ( nd_gentrace && gensyz ) {
2713: nd_tracelist = reverse_node(nd_tracelist);
2714: MKLIST(list,nd_tracelist);
2715: STOZ(-1,q); t = mknode(2,q,list); MKLIST(list,t);
2716: MKNODE(t,list,nd_alltracelist);
2717: nd_alltracelist = t; nd_tracelist = 0;
2718: }
1.57 noro 2719: if ( DP_Print ) { fprintf(asir_out,"."); fflush(asir_out); }
1.41 noro 2720: FREENDP(l);
2721: }
1.36 noro 2722: }
2723: conv_ilist(nd_demand,0,g,indp);
1.41 noro 2724: if ( !checkonly && DP_Print ) {
1.60 noro 2725: fprintf(asir_out,"\nnd_gb done. Nbase=%d,Nnd_add=%d,Npairs=%d, Nnfnz=%d,Nnfz=%d,",nd_psn,Nnd_add,Npairs,Nnfnz,Nnfz);
1.57 noro 2726: fprintf(asir_out,"Nremoved=%d\n",NcriB+NcriMF+Ncri2);
1.41 noro 2727: fflush(asir_out);
2728: }
2729: if ( DP_Print ) {
2730: print_eg("update",&eg_update); fprintf(asir_out,"\n");
2731: }
1.36 noro 2732: return g;
1.1 noro 2733: }
2734:
1.30 noro 2735: ND_pairs update_pairs_s(ND_pairs d,int t,NODE *syz);
1.47 noro 2736: int update_pairs_array_s(ND_pairs *d,int t,NODE *syz);
1.30 noro 2737: ND_pairs nd_newpairs_s(int t ,NODE *syz);
1.47 noro 2738: ND_pairs *nd_newpairs_array_s(int t ,NODE *syz);
1.24 noro 2739:
2740: int nd_nf_pbucket_s(int mod,ND g,NDV *ps,int full,ND *nf);
2741: int nd_nf_s(int mod,ND d,ND g,NDV *ps,int full,ND *nf);
2742:
2743: void _copydl(int n,DL d1,DL d2);
2744: void _subfromdl(int n,DL d1,DL d2);
2745: extern int (*cmpdl)(int n,DL d1,DL d2);
1.53 noro 2746: int _dl_redble_ext(DL,DL,DL,int);
2747:
2748: int primitive_irred(ND p,SIG sig)
2749: {
2750: static int wpd=0,dlen=0;
2751: static DL dquo,squo;
2752: static UINT *quo;
2753: int i;
2754:
2755: if ( dlen < nd_nvar ) {
2756: NEWDL(dquo,nd_nvar);
2757: NEWDL(squo,nd_nvar);
2758: dlen = nd_nvar;
2759: }
2760: if ( wpd != nd_wpd ) {
2761: wpd = nd_wpd;
2762: quo = (UINT *)MALLOC(wpd*sizeof(UINT));
2763: }
2764: for ( i = 0; i < nd_psn; i++ ) {
2765: if ( sig->pos == nd_psh[i]->sig->pos &&
2766: _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),squo,nd_nvar) )
2767: if ( ndl_reducible(HDL(p),DL(nd_psh[i])) ) {
2768: if ( DP_Print ) fprintf(asir_out,"D");
2769: ndl_sub(HDL(p),DL(nd_psh[i]),quo);
2770: _ndltodl(quo,dquo);
2771: if ( _eqdl(nd_nvar,squo,dquo) )
2772: return 0;
2773: }
2774: }
2775: return 1;
2776: }
1.24 noro 2777:
2778: NODE insert_sig(NODE l,SIG s)
2779: {
2780: int pos;
2781: DL sig;
2782: struct oNODE root;
2783: NODE p,prev,r;
2784: SIG t;
2785:
2786: pos = s->pos; sig = DL(s);
2787: root.next = l; prev = &root;
2788: for ( p = l; p; p = p->next ) {
2789: t = (SIG)p->body;
2790: if ( t->pos == pos ) {
2791: if ( _dl_redble(DL(t),sig,nd_nvar) )
2792: return root.next;
2793: else if ( _dl_redble(sig,DL(t),nd_nvar) )
2794: // remove p
2795: prev->next = p->next;
1.45 noro 2796: else
2797: prev = p;
1.24 noro 2798: } else
2799: prev = p;
2800: }
1.27 noro 2801: NEWNODE(r); r->body = (pointer)s; r->next = 0;
2802: for ( p = &root; p->next; p = p->next );
2803: p->next = r;
2804: // r->next = root.next;
2805: // return r;
2806: return root.next;
1.24 noro 2807: }
2808:
2809: ND_pairs remove_spair_s(ND_pairs d,SIG sig)
2810: {
2811: struct oND_pairs root;
2812: ND_pairs prev,p;
2813: SIG spsig;
2814:
2815: root.next = d;
2816: prev = &root; p = d;
2817: while ( p ) {
2818: spsig = p->sig;
1.26 noro 2819: if ( sig->pos == spsig->pos && _dl_redble(DL(sig),DL(spsig),nd_nvar) ) {
1.24 noro 2820: // remove p
2821: prev->next = p->next;
1.26 noro 2822: Nsyz++;
2823: } else
1.24 noro 2824: prev = p;
2825: p = p->next;
2826: }
2827: return (ND_pairs)root.next;
2828: }
2829:
1.28 noro 2830: int small_lcm(ND_pairs l)
2831: {
2832: SIG sig;
2833: int i;
1.29 noro 2834: NODE t;
1.28 noro 2835: static DL lcm,mul,quo;
1.44 noro 2836: static int nvar = 0;
1.28 noro 2837:
1.38 noro 2838: if ( nd_sba_largelcm ) return 0;
1.28 noro 2839: if ( nvar < nd_nvar ) {
2840: nvar = nd_nvar; NEWDL(lcm,nvar); NEWDL(quo,nvar); NEWDL(mul,nvar);
2841: }
2842: sig = l->sig;
2843: _ndltodl(l->lcm,lcm);
1.29 noro 2844: #if 0
1.28 noro 2845: for ( i = 0; i < nd_psn; i++ ) {
2846: if ( sig->pos == nd_psh[i]->sig->pos &&
1.29 noro 2847: _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
1.28 noro 2848: _ndltodl(DL(nd_psh[i]),mul);
2849: _addtodl(nd_nvar,quo,mul);
2850: if ( (*cmpdl)(nd_nvar,lcm,mul) > 0 )
2851: break;
2852: }
2853: }
2854: if ( i < nd_psn ) return 1;
2855: else return 0;
1.29 noro 2856: #else
2857: for ( t = nd_sba_pos[sig->pos]; t; t = t->next ) {
2858: i = (long)BDY(t);
2859: if ( _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
2860: _ndltodl(DL(nd_psh[i]),mul);
2861: _addtodl(nd_nvar,quo,mul);
2862: if ( (*cmpdl)(nd_nvar,lcm,mul) > 0 )
2863: break;
2864: }
2865: }
2866: if ( t ) return 1;
2867: else return 0;
2868: #endif
1.28 noro 2869: }
2870:
1.41 noro 2871: ND_pairs find_smallest_lcm(ND_pairs l)
2872: {
2873: SIG sig;
2874: int i,minindex;
2875: NODE t;
2876: ND_pairs r;
2877: struct oSIG sig1;
1.55 noro 2878: static DL mul,quo,quo2,minlm;
1.44 noro 2879: static int nvar = 0;
1.41 noro 2880:
2881: if ( nvar < nd_nvar ) {
2882: nvar = nd_nvar;
1.55 noro 2883: NEWDL(quo,nvar); NEWDL(quo2,nvar); NEWDL(mul,nvar);
1.41 noro 2884: NEWDL(minlm,nvar);
2885: }
2886: sig = l->sig;
2887: // find mg s.t. m*s(g)=sig and m*lm(g) is minimal
2888: _ndltodl(l->lcm,minlm); minindex = -1;
2889: for ( t = nd_sba_pos[sig->pos]; t; t = t->next ) {
2890: i = (long)BDY(t);
2891: if ( _dl_redble_ext(DL(nd_psh[i]->sig),DL(sig),quo,nd_nvar) ) {
2892: _ndltodl(DL(nd_psh[i]),mul);
2893: _addtodl(nd_nvar,quo,mul);
2894: if ( (*cmpdl)(nd_nvar,minlm,mul) > 0 ) {
2895: minindex = i;
1.47 noro 2896: break;
1.41 noro 2897: _copydl(nd_nvar,mul,minlm);
2898: }
2899: }
2900: }
2901: // l->lcm is minimal; return l itself
2902: if ( minindex < 0 ) return l;
1.47 noro 2903: else return 0;
1.41 noro 2904: for ( i = 0; i < nd_psn; i++ ) {
2905: if ( i == minindex ) continue;
2906: _ndltodl(DL(nd_psh[i]),mul);
2907: if ( _dl_redble_ext(mul,minlm,quo,nd_nvar) ) {
2908: _addtodl(nd_nvar,nd_ps[i]->sig->dl,quo);
2909: sig1.pos = nd_ps[i]->sig->pos;
2910: sig1.dl = quo;
1.55 noro 2911: sig1.dl2 = quo2;
2912: _adddl(nd_nvar,sig1.dl,nd_sba_hm[sig1.pos],sig1.dl2);
1.41 noro 2913: if ( comp_sig(sig,&sig1) > 0 ) {
2914: // printf("X");
2915: NEWND_pairs(r);
2916: r->sig = sig;
2917: r->i1 = minindex;
2918: r->i2 = i;
2919: dltondl(nd_nvar,minlm,r->lcm);
2920: r->next = 0;
2921: return r;
2922: }
2923: }
2924: }
2925: // there is no suitable spair
2926: return 0;
2927: }
2928:
1.28 noro 2929: ND_pairs remove_large_lcm(ND_pairs d)
2930: {
2931: struct oND_pairs root;
2932: ND_pairs prev,p;
2933:
2934: root.next = d;
2935: prev = &root; p = d;
2936: while ( p ) {
1.41 noro 2937: #if 0
1.28 noro 2938: if ( small_lcm(p) ) {
2939: // remove p
2940: prev->next = p->next;
2941: } else
1.41 noro 2942: #else
2943: if ( find_smallest_lcm(p) == 0 ) {
2944: // remove p
2945: prev->next = p->next;
2946: } else
2947: #endif
1.28 noro 2948: prev = p;
2949: p = p->next;
2950: }
2951: return (ND_pairs)root.next;
2952: }
2953:
1.26 noro 2954: struct oEGT eg_create,eg_newpairs,eg_merge;
2955:
1.30 noro 2956: NODE conv_ilist_s(int demand,int trace,int **indp);
2957:
1.44 noro 2958: // S(fj*ei-fi*ej)
2959:
1.45 noro 2960: void _subdl(int,DL,DL,DL);
2961:
1.44 noro 2962: SIG trivial_sig(int i,int j)
2963: {
1.45 noro 2964: static DL lcm;
1.44 noro 2965: static struct oSIG sigi,sigj;
2966: static int nvar = 0;
2967: SIG sig;
2968:
2969: if ( nvar != nd_nvar ) {
1.45 noro 2970: nvar = nd_nvar; NEWDL(lcm,nvar); NEWDL(sigi.dl,nvar); NEWDL(sigj.dl,nvar);
1.55 noro 2971: NEWDL(sigi.dl2,nvar); NEWDL(sigj.dl2,nvar);
1.45 noro 2972: }
1.46 noro 2973: if ( nd_sba_inputisgb != 0 ) {
1.45 noro 2974: lcm_of_DL(nd_nvar,nd_sba_hm[i],nd_sba_hm[j],lcm);
2975: sigi.pos = i; _subdl(nd_nvar,lcm,nd_sba_hm[i],sigi.dl);
1.55 noro 2976: _copydl(nd_nvar,lcm,sigi.dl2);
1.45 noro 2977: sigj.pos = j; _subdl(nd_nvar,lcm,nd_sba_hm[j],sigj.dl);
1.55 noro 2978: _copydl(nd_nvar,lcm,sigj.dl2);
1.45 noro 2979: if ( comp_sig(&sigi,&sigj) > 0 ) sig = dup_sig(&sigi);
2980: else sig = dup_sig(&sigj);
2981: } else {
2982: sigi.pos = i; _copydl(nd_nvar,nd_sba_hm[j],sigi.dl);
1.55 noro 2983: _adddl(nd_nvar,sigi.dl,nd_sba_hm[i],sigi.dl2);
1.45 noro 2984: sigj.pos = j; _copydl(nd_nvar,nd_sba_hm[i],sigj.dl);
1.55 noro 2985: _adddl(nd_nvar,sigj.dl,nd_sba_hm[j],sigj.dl2);
1.45 noro 2986: if ( comp_sig(&sigi,&sigj) > 0 ) sig = dup_sig(&sigi);
2987: else sig = dup_sig(&sigj);
1.44 noro 2988: }
2989: return sig;
2990: }
2991:
1.47 noro 2992: int nd_minsig(ND_pairs *d)
2993: {
2994: int min,i,ret;
2995:
2996: min = -1;
2997: for ( i = 0; i < nd_nbase; i++ ) {
2998: if ( d[i] != 0 ) {
2999: if ( min < 0 ) min = i;
3000: else {
3001: ret = comp_sig(d[i]->sig,d[min]->sig);
3002: if ( ret < 0 ) min = i;
3003: }
3004: }
3005: }
3006: return min;
3007: }
3008:
3009: int dlength(ND_pairs d)
3010: {
3011: int i;
3012: for ( i = 0; d; d = d->next, i++ );
3013: return i;
3014: }
3015:
1.44 noro 3016: NODE nd_sba_buch(int m,int ishomo,int **indp,NODE *syzp)
1.24 noro 3017: {
1.39 noro 3018: int i,j,nh,sugar,stat,pos;
1.65 noro 3019: NODE g;
1.47 noro 3020: ND_pairs *d;
1.41 noro 3021: ND_pairs l,l1;
1.65 noro 3022: ND h,nf;
1.24 noro 3023: NDV nfv;
1.65 noro 3024: // union oNDC hc;
1.24 noro 3025: SIG sig;
1.29 noro 3026: NODE *syzlist;
1.47 noro 3027: int ngen,ind;
1.41 noro 3028: int Nnominimal,Nredundant;
1.28 noro 3029: DL lcm,quo,mul;
1.49 noro 3030: struct oHPDATA final_hpdata,current_hpdata;
1.65 noro 3031: struct oEGT eg1,eg2,eg3,eg4,eg_remove,eg_large,eg_nf,eg_nfzero;
1.50 noro 3032: struct oEGT eg_minsig,eg_smallest,eg_removecont,eg_hpdata,eg_updatepairs,eg_sbabuch,eg_sp;
1.47 noro 3033: int Nnfs=0,Nnfz=0,Nnfnz=0,dlen,nsyz;
1.24 noro 3034:
1.27 noro 3035: init_eg(&eg_remove);
1.29 noro 3036: syzlist = (NODE *)MALLOC(nd_psn*sizeof(NODE));
1.47 noro 3037: d = (ND_pairs *)MALLOC(nd_psn*sizeof(ND_pairs));
3038: nd_nbase = nd_psn;
1.26 noro 3039: Nsyz = 0;
1.24 noro 3040: Nnd_add = 0;
1.41 noro 3041: Nnominimal = 0;
1.26 noro 3042: Nredundant = 0;
1.44 noro 3043: ngen = nd_psn;
1.56 noro 3044: if ( !do_weyl || nd_sba_inputisgb ) {
1.48 noro 3045: for ( i = 0; i < nd_psn; i++ )
3046: for ( j = i+1; j < nd_psn; j++ ) {
3047: sig = trivial_sig(i,j);
3048: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
3049: }
1.29 noro 3050: }
1.47 noro 3051: dlen = 0;
1.41 noro 3052: for ( i = 0; i < nd_psn; i++ ) {
1.47 noro 3053: dlen += update_pairs_array_s(d,i,syzlist);
1.41 noro 3054: }
1.24 noro 3055: sugar = 0;
1.39 noro 3056: pos = 0;
1.49 noro 3057: if ( nd_hpdata ) {
3058: setup_hpdata(&final_hpdata,¤t_hpdata);
3059: }
1.26 noro 3060: NEWDL(lcm,nd_nvar); NEWDL(quo,nd_nvar); NEWDL(mul,nd_nvar);
1.50 noro 3061: init_eg(&eg_sp);
1.26 noro 3062: init_eg(&eg_create);
3063: init_eg(&eg_merge);
1.47 noro 3064: init_eg(&eg_minsig);
3065: init_eg(&eg_smallest);
1.29 noro 3066: init_eg(&eg_large);
1.31 noro 3067: init_eg(&eg_nf);
3068: init_eg(&eg_nfzero);
1.50 noro 3069: init_eg(&eg_removecont);
3070: init_eg(&eg_updatepairs);
3071: init_eg(&eg_hpdata);
3072: init_eg(&eg_sbabuch);
3073: get_eg(&eg3);
1.47 noro 3074: while ( 1 ) {
1.53 noro 3075: if ( DP_Print && !nd_hpdata && dlen%1000 == 0 ) fprintf(asir_out,"(%d)",dlen);
1.47 noro 3076: again :
3077: get_eg(&eg1);
3078: ind = nd_minsig(d);
3079: get_eg(&eg2); add_eg(&eg_minsig,&eg1,&eg2);
3080: if ( ind < 0 ) break;
3081: l = d[ind];
3082: // printf("(%d,%d)",l->i1,l->i2); print_sig(l->sig); printf("\n");
3083: get_eg(&eg1);
1.41 noro 3084: l1 = find_smallest_lcm(l);
1.47 noro 3085: get_eg(&eg2); add_eg(&eg_smallest,&eg1,&eg2);
1.41 noro 3086: if ( l1 == 0 ) {
1.47 noro 3087: d[ind] = d[ind]->next; dlen--;
1.53 noro 3088: // if ( DP_Print && !nd_hpdata ) fprintf(asir_out,"M");
1.41 noro 3089: Nnominimal++;
3090: continue;
3091: }
3092: if ( SG(l1) != sugar ) {
3093: sugar = SG(l1);
3094: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
3095: }
3096: sig = l1->sig;
3097: if ( DP_Print && nd_sba_pot ) {
3098: if ( sig->pos != pos ) {
3099: fprintf(asir_out,"[%d]",sig->pos);
3100: pos = sig->pos;
3101: }
3102: }
1.50 noro 3103: get_eg(&eg1);
1.41 noro 3104: stat = nd_sp(m,0,l1,&h);
1.50 noro 3105: get_eg(&eg2); add_eg(&eg_sp,&eg1,&eg2);
1.24 noro 3106: if ( !stat ) {
1.47 noro 3107: nd_reconstruct_s(0,d);
1.24 noro 3108: goto again;
3109: }
1.31 noro 3110: get_eg(&eg1);
1.25 noro 3111: #if USE_GEOBUCKET
1.55 noro 3112: stat = (m&&!nd_gentrace)?nd_nf_pbucket_s(m,h,nd_ps,!nd_top&&!Top,&nf):nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.24 noro 3113: #else
1.39 noro 3114: stat = nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.24 noro 3115: #endif
1.31 noro 3116: get_eg(&eg2);
1.24 noro 3117: if ( !stat ) {
1.47 noro 3118: nd_reconstruct_s(0,d);
1.24 noro 3119: goto again;
3120: } else if ( stat == -1 ) {
1.47 noro 3121: d[ind] = d[ind]->next; dlen--;
1.41 noro 3122: Nnfs++;
1.24 noro 3123: if ( DP_Print ) { printf("S"); fflush(stdout); }
3124: } else if ( nf ) {
1.47 noro 3125: d[ind] = d[ind]->next; dlen--;
1.41 noro 3126: Nnfnz++;
3127: if ( DP_Print ) {
3128: if ( nd_sba_redundant_check ) {
3129: if ( ndl_find_reducer_nonsig(HDL(nf)) >= 0 ) {
3130: Nredundant++;
3131: printf("R");
3132: } else
3133: printf("+");
3134: } else
3135: printf("+");
3136: fflush(stdout);
3137: }
1.31 noro 3138: add_eg(&eg_nf,&eg1,&eg2);
1.65 noro 3139: // hc = HCU(nf);
3140: get_eg(&eg1);
3141: nd_removecont(m,nf);
3142: get_eg(&eg2); add_eg(&eg_removecont,&eg1,&eg2);
3143: nfv = ndtondv(m,nf); nd_free(nf);
3144: nh = ndv_newps(m,nfv,0);
1.55 noro 3145:
1.65 noro 3146: get_eg(&eg1);
3147: dlen += update_pairs_array_s(d,nh,syzlist);
3148: get_eg(&eg2); add_eg(&eg_updatepairs,&eg1,&eg2);
3149: nd_sba_pos[sig->pos] = append_one(nd_sba_pos[sig->pos],nh);
3150: if ( nd_hpdata ) {
3151: int dg,sugar0;
3152:
3153: get_eg(&eg1);
3154: update_hpdata(¤t_hpdata,nh);
3155: get_eg(&eg2); add_eg(&eg_hpdata,&eg1,&eg2);
3156: dg = comp_hn(final_hpdata.hn,current_hpdata.hn);
3157: // if ( !compp(CO,final_hpdata.hn,current_hpdata.hn) )
3158: if ( dg < 0 ) {
3159: if ( DP_Print ) { printf("\nWe found a gb.\n"); }
3160: break;
3161: } else if ( nd_sba_heu == 1 ) {
3162: for ( i = 0; i < ngen; i++ ) {
3163: sugar0 = sugar;
3164: while ( d[i] && dg > sugar0 ) {
3165: d[i] = nd_remove_same_sugar(d[i],sugar0);
3166: sugar0++;
3167: }
1.63 noro 3168: }
3169: }
1.49 noro 3170: }
1.65 noro 3171: } else {
1.47 noro 3172: d[ind] = d[ind]->next; dlen--;
1.41 noro 3173: Nnfz++;
1.31 noro 3174: add_eg(&eg_nfzero,&eg1,&eg2);
1.65 noro 3175: // syzygy
1.27 noro 3176: get_eg(&eg1);
1.65 noro 3177: nsyz = Nsyz;
3178: d[sig->pos] = remove_spair_s(d[sig->pos],sig);
3179: dlen -= Nsyz-nsyz;
1.27 noro 3180: get_eg(&eg2); add_eg(&eg_remove,&eg1,&eg2);
1.65 noro 3181: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
3182: if ( DP_Print ) { printf("."); fflush(stdout); }
3183: }
3184: }
3185: get_eg(&eg4); add_eg(&eg_sbabuch,&eg3,&eg4);
3186: g = conv_ilist_s(nd_demand,0,indp);
3187: if ( DP_Print ) {
3188: printf("\ndlen=%d,nd_sba done. nd_add=%d,Nsyz=%d,Nsamesig=%d,Nnominimal=%d\n",dlen,Nnd_add,Nsyz,Nsamesig,Nnominimal);
3189: printf("Nbase=%d,Nnfnz=%d,Nnfz=%d,Nnfsingular=%d\n",nd_psn,Nnfnz,Nnfz,Nnfs);
3190: fflush(stdout);
3191: if ( nd_sba_redundant_check )
3192: printf("Nredundant=%d\n",Nredundant);
3193: fflush(stdout);
3194: print_eg("sp",&eg_sp);
3195: print_eg("create",&eg_create);
3196: print_eg("merge",&eg_merge);
3197: print_eg("minsig",&eg_minsig);
3198: print_eg("smallest",&eg_smallest);
3199: print_eg("remove",&eg_remove);
3200: printf("\n");
3201: print_eg("nf",&eg_nf);
3202: print_eg("nfzero",&eg_nfzero);
3203: print_eg("removecont",&eg_removecont);
3204: print_eg("updatepairs",&eg_updatepairs);
3205: print_eg("hpdata",&eg_hpdata);
3206: print_eg("total",&eg_sbabuch);
3207: printf("\n");
3208: }
3209: if ( nd_sba_syz ) {
3210: print_eg("remove",&eg_remove);
3211: print_eg("nf",&eg_nf);
3212: print_eg("nfzero",&eg_nfzero);
3213: printf("\n");
3214: }
3215: if ( nd_sba_syz ) {
3216: NODE hsyz,tsyz,prev;
3217:
3218: hsyz = 0;
3219: for ( i = 0; i < ngen; i++ ) {
3220: tsyz = syzlist[i];
3221: for ( prev = 0; tsyz != 0; prev = tsyz, tsyz = NEXT(tsyz))
3222: BDY(tsyz) = (pointer)sigtodpm((SIG)BDY(tsyz));
3223: if ( prev != 0 ) {
3224: prev->next = hsyz; hsyz = syzlist[i];
3225: }
3226: }
3227: *syzp = hsyz;
3228: } else *syzp = 0;
3229: return g;
1.24 noro 3230: }
3231:
1.1 noro 3232: /* splist = [[i1,i2],...] */
3233:
3234: int check_splist(int m,NODE splist)
3235: {
3236: NODE t,p;
3237: ND_pairs d,r,l;
3238: int stat;
3239: ND h,nf;
3240:
3241: for ( d = 0, t = splist; t; t = NEXT(t) ) {
3242: p = BDY((LIST)BDY(t));
1.6 noro 3243: NEXTND_pairs(d,r);
1.65 noro 3244: r->i1 = (int)ZTOS((Q)ARG0(p)); r->i2 = (int)ZTOS((Q)ARG1(p));
1.6 noro 3245: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.1 noro 3246: SG(r) = TD(LCM(r)); /* XXX */
3247: }
3248: if ( d ) NEXT(r) = 0;
3249:
1.6 noro 3250: while ( d ) {
1.1 noro 3251: again:
1.6 noro 3252: l = nd_minp(d,&d);
3253: stat = nd_sp(m,0,l,&h);
3254: if ( !stat ) {
3255: NEXT(l) = d; d = l;
3256: d = nd_reconstruct(0,d);
3257: goto again;
3258: }
1.39 noro 3259: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.6 noro 3260: if ( !stat ) {
3261: NEXT(l) = d; d = l;
3262: d = nd_reconstruct(0,d);
3263: goto again;
3264: } else if ( nf ) return 0;
1.1 noro 3265: if ( DP_Print) { printf("."); fflush(stdout); }
1.6 noro 3266: }
1.1 noro 3267: if ( DP_Print) { printf("done.\n"); fflush(stdout); }
3268: return 1;
3269: }
3270:
3271: int check_splist_f4(int m,NODE splist)
3272: {
3273: UINT *s0vect;
1.6 noro 3274: PGeoBucket bucket;
1.1 noro 3275: NODE p,rp0,t;
3276: ND_pairs d,r,l,ll;
3277: int col,stat;
3278:
3279: for ( d = 0, t = splist; t; t = NEXT(t) ) {
3280: p = BDY((LIST)BDY(t));
1.6 noro 3281: NEXTND_pairs(d,r);
1.65 noro 3282: r->i1 = (int)ZTOS((Q)ARG0(p)); r->i2 = (int)ZTOS((Q)ARG1(p));
1.6 noro 3283: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
1.1 noro 3284: SG(r) = TD(LCM(r)); /* XXX */
3285: }
3286: if ( d ) NEXT(r) = 0;
3287:
1.6 noro 3288: while ( d ) {
3289: l = nd_minsugarp(d,&d);
3290: bucket = create_pbucket();
3291: stat = nd_sp_f4(m,0,l,bucket);
3292: if ( !stat ) {
3293: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
3294: NEXT(ll) = d; d = l;
3295: d = nd_reconstruct(0,d);
3296: continue;
3297: }
3298: if ( bucket->m < 0 ) continue;
3299: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
3300: if ( !col ) {
3301: for ( ll = l; NEXT(ll); ll = NEXT(ll) );
3302: NEXT(ll) = d; d = l;
3303: d = nd_reconstruct(0,d);
3304: continue;
1.1 noro 3305: }
1.6 noro 3306: if ( nd_f4_red(m,l,0,s0vect,col,rp0,0) ) return 0;
3307: }
3308: return 1;
1.1 noro 3309: }
3310:
3311: int do_diagonalize_trace(int sugar,int m)
3312: {
1.65 noro 3313: int i,stat;
3314: ND nf,s,head;
3315: NDV nfv;
1.6 noro 3316: union oNDC hc;
3317: NODE node;
3318: LIST l;
3319: Z iq;
1.65 noro 3320: P cont;
1.1 noro 3321:
1.64 noro 3322: if ( diag_period == 0 ) return 1;
1.6 noro 3323: for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) {
3324: if ( nd_gentrace ) {
3325: /* Trace = [1,index,1,1] */
3326: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
3327: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
3328: }
3329: /* for nd_ps */
3330: s = ndvtond(m,nd_ps[i]);
3331: s = nd_separate_head(s,&head);
3332: stat = nd_nf_pbucket(m,s,nd_ps,1,&nf);
3333: if ( !stat ) return 0;
3334: nf = nd_add(m,head,nf);
3335: ndv_free(nd_ps[i]);
3336: nd_ps[i] = ndtondv(m,nf);
3337: nd_free(nf);
3338:
3339: /* for nd_ps_trace */
3340: if ( nd_demand )
3341: nfv = ndv_load(i);
3342: else
3343: nfv = nd_ps_trace[i];
3344: s = ndvtond(0,nfv);
3345: s = nd_separate_head(s,&head);
3346: stat = nd_nf(0,head,s,nd_ps_trace,1,&nf);
3347: if ( !stat ) return 0;
3348: ndv_free(nfv);
3349: hc = HCU(nf); nd_removecont(0,nf);
3350: /* exact division */
1.1 noro 3351: cont = ndc_div(0,hc,HCU(nf));
1.6 noro 3352: if ( nd_gentrace ) finalize_tracelist(i,cont);
3353: nfv = ndtondv(0,nf);
3354: nd_free(nf);
3355: nd_bound[i] = ndv_compute_bound(nfv);
3356: register_hcf(nfv);
3357: if ( nd_demand ) {
3358: ndv_save(nfv,i);
3359: ndv_free(nfv);
3360: } else
3361: nd_ps_trace[i] = nfv;
3362: }
3363: return 1;
1.1 noro 3364: }
3365:
3366: static struct oEGT eg_invdalg;
3367: struct oEGT eg_le;
3368:
3369: void nd_subst_vector(VL vl,P p,NODE subst,P *r)
3370: {
3371: NODE tn;
3372: P p1;
3373:
3374: for ( tn = subst; tn; tn = NEXT(NEXT(tn)) ) {
3375: substp(vl,p,BDY(tn),BDY(NEXT(tn)),&p1); p = p1;
3376: }
3377: *r = p;
3378: }
3379:
3380: NODE nd_gb_trace(int m,int ishomo,int **indp)
3381: {
1.6 noro 3382: int i,nh,sugar,stat;
1.65 noro 3383: NODE g,t;
1.6 noro 3384: ND_pairs d;
3385: ND_pairs l;
1.65 noro 3386: ND h,nf,nfq;
1.6 noro 3387: NDV nfv,nfqv;
1.65 noro 3388: Z q;
1.6 noro 3389: P hc;
1.65 noro 3390: union oNDC hnfq;
1.6 noro 3391: struct oEGT eg_monic,egm0,egm1;
3392: int diag_count = 0;
3393: P cont;
3394: LIST list;
1.49 noro 3395: struct oHPDATA current_hpdata,final_hpdata;
1.6 noro 3396:
3397: init_eg(&eg_monic);
3398: init_eg(&eg_invdalg);
3399: init_eg(&eg_le);
3400: g = 0; d = 0;
3401: for ( i = 0; i < nd_psn; i++ ) {
3402: d = update_pairs(d,g,i,0);
3403: g = update_base(g,i);
3404: }
3405: sugar = 0;
1.49 noro 3406: if ( nd_hpdata ) {
1.52 noro 3407: if ( DP_Print ) fprintf(asir_out,"Hilbert driven algorithm.\n");
1.49 noro 3408: setup_hpdata(&final_hpdata,¤t_hpdata);
3409: }
3410:
1.6 noro 3411: while ( d ) {
1.1 noro 3412: again:
1.6 noro 3413: l = nd_minp(d,&d);
3414: if ( MaxDeg > 0 && SG(l) > MaxDeg ) break;
3415: if ( SG(l) != sugar ) {
1.1 noro 3416: #if 1
1.6 noro 3417: if ( ishomo ) {
3418: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3419: stat = do_diagonalize_trace(sugar,m);
3420: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3421: diag_count = 0;
1.1 noro 3422: if ( !stat ) {
1.6 noro 3423: NEXT(l) = d; d = l;
3424: d = nd_reconstruct(1,d);
3425: goto again;
1.1 noro 3426: }
1.6 noro 3427: }
3428: #endif
3429: sugar = SG(l);
3430: if ( DP_Print ) fprintf(asir_out,"%d",sugar);
3431: }
3432: stat = nd_sp(m,0,l,&h);
3433: if ( !stat ) {
3434: NEXT(l) = d; d = l;
3435: d = nd_reconstruct(1,d);
3436: goto again;
3437: }
1.1 noro 3438: #if USE_GEOBUCKET
1.39 noro 3439: stat = nd_nf_pbucket(m,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 3440: #else
1.39 noro 3441: stat = nd_nf(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.1 noro 3442: #endif
1.6 noro 3443: if ( !stat ) {
3444: NEXT(l) = d; d = l;
3445: d = nd_reconstruct(1,d);
3446: goto again;
3447: } else if ( nf ) {
3448: if ( nd_demand ) {
3449: nfqv = ndv_load(nd_psn);
3450: nfq = ndvtond(0,nfqv);
3451: } else
3452: nfq = 0;
3453: if ( !nfq ) {
1.39 noro 3454: if ( !nd_sp(0,1,l,&h) || !nd_nf(0,0,h,nd_ps_trace,!nd_top&&!Top,&nfq) ) {
1.6 noro 3455: NEXT(l) = d; d = l;
3456: d = nd_reconstruct(1,d);
3457: goto again;
3458: }
3459: }
3460: if ( nfq ) {
3461: /* m|HC(nfq) => failure */
3462: if ( nd_vc ) {
3463: nd_subst_vector(nd_vc,HCP(nfq),nd_subst,&hc); q = (Z)hc;
3464: } else
3465: q = HCZ(nfq);
3466: if ( !remqi((Q)q,m) ) return 0;
3467:
3468: if ( DP_Print ) { printf("+"); fflush(stdout); }
3469: hnfq = HCU(nfq);
3470: if ( nd_nalg ) {
3471: /* m|DN(HC(nf)^(-1)) => failure */
3472: get_eg(&egm0);
3473: if ( !nd_monic(m,&nfq) ) return 0;
3474: get_eg(&egm1); add_eg(&eg_monic,&egm0,&egm1);
3475: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
3476: nfv = ndv_dup(0,nfqv); ndv_mod(m,nfv); nd_free(nf);
3477: } else {
3478: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq);
3479: nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf);
3480: }
3481: if ( nd_gentrace ) {
3482: /* exact division */
3483: cont = ndc_div(0,hnfq,HCU(nfqv));
3484: if ( !UNIQ(cont) ) {
3485: t = mknode(4,NULLP,NULLP,NULLP,cont);
3486: MKLIST(list,t); MKNODE(t,list,nd_tracelist);
3487: nd_tracelist = t;
3488: }
3489: }
1.24 noro 3490: nh = ndv_newps(0,nfv,nfqv);
1.6 noro 3491: if ( ishomo && ++diag_count == diag_period ) {
3492: diag_count = 0;
3493: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3494: stat = do_diagonalize_trace(sugar,m);
3495: if ( DP_Print > 2 ) fprintf(asir_out,"|");
3496: if ( !stat ) {
1.1 noro 3497: NEXT(l) = d; d = l;
3498: d = nd_reconstruct(1,d);
3499: goto again;
1.6 noro 3500: }
1.1 noro 3501: }
1.6 noro 3502: d = update_pairs(d,g,nh,0);
3503: g = update_base(g,nh);
1.49 noro 3504: if ( nd_hpdata ) {
1.57 noro 3505: int dg,sugar0;
1.56 noro 3506:
3507: update_hpdata(¤t_hpdata,nh);
3508: dg = comp_hn(final_hpdata.hn,current_hpdata.hn);
1.57 noro 3509: if ( dg < 0 ) {
1.61 noro 3510: int d_len;
3511: for ( d_len = 0; d; d = d->next, d_len++);
3512: fprintf(asir_out,"[%d] We found a gb\n",d_len);
1.57 noro 3513: }
3514: sugar0 = sugar;
3515: while ( d && dg > sugar0 ) {
1.58 noro 3516: d = nd_remove_same_sugar(d,sugar0);
1.57 noro 3517: sugar0++;
1.49 noro 3518: }
3519: }
1.6 noro 3520: } else {
1.57 noro 3521: if ( DP_Print ) { fprintf(asir_out,"*"); fflush(asir_out); }
1.6 noro 3522: }
3523: } else {
1.57 noro 3524: if ( DP_Print ) { fprintf(asir_out,"."); fflush(asir_out); }
1.1 noro 3525: }
1.6 noro 3526: FREENDP(l);
3527: }
3528: if ( nd_nalg ) {
3529: if ( DP_Print ) {
3530: print_eg("monic",&eg_monic);
3531: print_eg("invdalg",&eg_invdalg);
3532: print_eg("le",&eg_le);
1.1 noro 3533: }
1.6 noro 3534: }
1.1 noro 3535: conv_ilist(nd_demand,1,g,indp);
1.60 noro 3536: if ( DP_Print ) { fprintf(asir_out,"\nnd_gb_trace done. Nbase=%d\n",nd_psn); fflush(asir_out); }
1.6 noro 3537: return g;
1.1 noro 3538: }
3539:
3540: int ndv_compare(NDV *p1,NDV *p2)
3541: {
3542: return DL_COMPARE(HDL(*p1),HDL(*p2));
3543: }
3544:
3545: int ndv_compare_rev(NDV *p1,NDV *p2)
3546: {
3547: return -DL_COMPARE(HDL(*p1),HDL(*p2));
3548: }
3549:
3550: int ndvi_compare(NDVI p1,NDVI p2)
3551: {
3552: return DL_COMPARE(HDL(p1->p),HDL(p2->p));
3553: }
3554:
3555: int ndvi_compare_rev(NDVI p1,NDVI p2)
3556: {
3557: return -DL_COMPARE(HDL(p1->p),HDL(p2->p));
3558: }
3559:
3560: NODE ndv_reduceall(int m,NODE f)
3561: {
3562: int i,j,n,stat;
3563: ND nf,g,head;
3564: NODE t,a0,a;
3565: NODE node;
3566: LIST l;
3567: Z iq,jq;
3568: int *perm;
3569: union oNDC hc;
1.65 noro 3570: P cont;
1.1 noro 3571:
3572: if ( nd_nora ) return f;
3573: n = length(f);
1.24 noro 3574: ndv_setup(m,0,f,0,1,0);
1.1 noro 3575: perm = (int *)MALLOC(n*sizeof(int));
3576: if ( nd_gentrace ) {
3577: for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) )
1.65 noro 3578: perm[i] = (int)ZTOS((Q)ARG1(BDY((LIST)BDY(t))));
1.1 noro 3579: }
3580: for ( i = 0; i < n; ) {
3581: if ( nd_gentrace ) {
3582: /* Trace = [1,index,1,1] */
1.6 noro 3583: STOZ(i,iq); node = mknode(4,ONE,iq,ONE,ONE);
1.1 noro 3584: MKLIST(l,node); MKNODE(nd_tracelist,l,0);
3585: }
3586: g = ndvtond(m,nd_ps[i]);
3587: g = nd_separate_head(g,&head);
1.6 noro 3588: stat = nd_nf(m,head,g,nd_ps,1,&nf);
1.1 noro 3589: if ( !stat )
3590: nd_reconstruct(0,0);
3591: else {
3592: if ( DP_Print ) { printf("."); fflush(stdout); }
3593: ndv_free(nd_ps[i]);
3594: hc = HCU(nf); nd_removecont(m,nf);
3595: if ( nd_gentrace ) {
3596: for ( t = nd_tracelist; t; t = NEXT(t) ) {
1.65 noro 3597: jq = ARG1(BDY((LIST)BDY(t))); j = (int)ZTOS(jq);
1.6 noro 3598: STOZ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq;
1.1 noro 3599: }
1.6 noro 3600: /* exact division */
1.1 noro 3601: cont = ndc_div(m,hc,HCU(nf));
3602: finalize_tracelist(perm[i],cont);
3603: }
3604: nd_ps[i] = ndtondv(m,nf); nd_free(nf);
3605: nd_bound[i] = ndv_compute_bound(nd_ps[i]);
3606: i++;
3607: }
3608: }
3609: if ( DP_Print ) { printf("\n"); }
3610: for ( a0 = 0, i = 0; i < n; i++ ) {
3611: NEXTNODE(a0,a);
3612: if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i];
3613: else {
3614: for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break;
3615: BDY(a) = (pointer)nd_ps[j];
3616: }
3617: }
3618: NEXT(a) = 0;
3619: return a0;
3620: }
3621:
1.41 noro 3622: int ndplength(ND_pairs d)
3623: {
3624: int i;
3625: for ( i = 0; d; i++ ) d = NEXT(d);
3626: return i;
3627: }
3628:
1.1 noro 3629: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz)
3630: {
3631: ND_pairs d1,nd,cur,head,prev,remove;
1.41 noro 3632: int len0;
1.1 noro 3633:
3634: if ( !g ) return d;
3635: /* for testing */
3636: if ( gensyz && nd_gensyz == 2 ) {
3637: d1 = nd_newpairs(g,t);
3638: if ( !d )
3639: return d1;
3640: else {
3641: nd = d;
3642: while ( NEXT(nd) ) nd = NEXT(nd);
3643: NEXT(nd) = d1;
3644: return d;
3645: }
3646: }
3647: d = crit_B(d,t);
3648: d1 = nd_newpairs(g,t);
1.41 noro 3649: len0 = ndplength(d1);
1.1 noro 3650: d1 = crit_M(d1);
3651: d1 = crit_F(d1);
1.41 noro 3652: NcriMF += len0-ndplength(d1);
1.1 noro 3653: if ( gensyz || do_weyl )
3654: head = d1;
3655: else {
3656: prev = 0; cur = head = d1;
3657: while ( cur ) {
3658: if ( crit_2( cur->i1,cur->i2 ) ) {
3659: remove = cur;
3660: if ( !prev ) head = cur = NEXT(cur);
3661: else cur = NEXT(prev) = NEXT(cur);
1.41 noro 3662: FREENDP(remove); Ncri2++;
1.1 noro 3663: } else {
3664: prev = cur; cur = NEXT(cur);
3665: }
3666: }
3667: }
3668: if ( !d )
3669: return head;
3670: else {
3671: nd = d;
3672: while ( NEXT(nd) ) nd = NEXT(nd);
3673: NEXT(nd) = head;
3674: return d;
3675: }
3676: }
3677:
1.24 noro 3678: ND_pairs merge_pairs_s(ND_pairs d,ND_pairs d1);
3679:
1.30 noro 3680: ND_pairs update_pairs_s( ND_pairs d, int t,NODE *syz)
1.24 noro 3681: {
3682: ND_pairs d1;
1.26 noro 3683: struct oEGT eg1,eg2,eg3;
1.24 noro 3684:
1.30 noro 3685: if ( !t ) return d;
1.26 noro 3686: get_eg(&eg1);
1.30 noro 3687: d1 = nd_newpairs_s(t,syz);
1.26 noro 3688: get_eg(&eg2); add_eg(&eg_create,&eg1,&eg2);
1.24 noro 3689: d = merge_pairs_s(d,d1);
1.26 noro 3690: get_eg(&eg3); add_eg(&eg_merge,&eg2,&eg3);
1.24 noro 3691: return d;
3692: }
1.1 noro 3693:
1.47 noro 3694: int update_pairs_array_s( ND_pairs *d, int t,NODE *syz)
3695: {
3696: ND_pairs *d1;
3697: struct oEGT eg1,eg2,eg3;
3698: int i;
3699:
3700: if ( !t ) return 0;
3701: get_eg(&eg1);
3702: Nnewpair = 0;
3703: d1 = nd_newpairs_array_s(t,syz);
3704: get_eg(&eg2); add_eg(&eg_create,&eg1,&eg2);
3705: for ( i = 0; i < nd_nbase; i++ )
3706: d[i] = merge_pairs_s(d[i],d1[i]);
3707: get_eg(&eg3); add_eg(&eg_merge,&eg2,&eg3);
3708: return Nnewpair;
3709: }
3710:
1.1 noro 3711: ND_pairs nd_newpairs( NODE g, int t )
3712: {
3713: NODE h;
3714: UINT *dl;
3715: int ts,s,i,t0,min,max;
3716: ND_pairs r,r0;
3717:
3718: dl = DL(nd_psh[t]);
3719: ts = SG(nd_psh[t]) - TD(dl);
1.65 noro 3720: if ( nd_module && nd_intersect && (MPOS(dl) > (UINT)nd_intersect) ) return 0;
1.1 noro 3721: for ( r0 = 0, h = g; h; h = NEXT(h) ) {
3722: if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) )
3723: continue;
3724: if ( nd_gbblock ) {
3725: t0 = (long)BDY(h);
3726: for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) {
3727: min = nd_gbblock[i]; max = nd_gbblock[i+1];
3728: if ( t0 >= min && t0 <= max && t >= min && t <= max )
3729: break;
3730: }
3731: if ( nd_gbblock[i] >= 0 )
3732: continue;
3733: }
1.41 noro 3734: NEXTND_pairs(r0,r); Npairs++;
1.1 noro 3735: r->i1 = (long)BDY(h);
3736: r->i2 = t;
3737: ndl_lcm(DL(nd_psh[r->i1]),dl,r->lcm);
3738: s = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
3739: SG(r) = MAX(s,ts) + TD(LCM(r));
3740: /* experimental */
3741: if ( nd_sugarweight )
3742: r->sugar2 = ndl_weight2(r->lcm);
3743: }
3744: if ( r0 ) NEXT(r) = 0;
3745: return r0;
3746: }
3747:
1.46 noro 3748: int sig_cmpdl_op(int n,DL d1,DL d2)
3749: {
3750: int e1,e2,i,j,l;
3751: int *t1,*t2;
1.65 noro 3752: int len;
1.46 noro 3753: struct order_pair *pair;
3754:
3755: len = nd_sba_modord->block_length;
3756: pair = nd_sba_modord->order_pair;
3757:
3758: for ( i = 0, t1 = d1->d, t2 = d2->d; i < len; i++ ) {
3759: l = pair[i].length;
3760: switch ( pair[i].order ) {
3761: case 0:
3762: for ( j = 0, e1 = e2 = 0; j < l; j++ ) {
3763: e1 += t1[j];
3764: e2 += t2[j];
3765: }
3766: if ( e1 > e2 )
3767: return 1;
3768: else if ( e1 < e2 )
3769: return -1;
3770: else {
3771: for ( j = l - 1; j >= 0 && t1[j] == t2[j]; j-- );
3772: if ( j >= 0 )
3773: return t1[j] < t2[j] ? 1 : -1;
3774: }
3775: break;
3776: case 1:
3777: for ( j = 0, e1 = e2 = 0; j < l; j++ ) {
3778: e1 += t1[j];
3779: e2 += t2[j];
3780: }
3781: if ( e1 > e2 )
3782: return 1;
3783: else if ( e1 < e2 )
3784: return -1;
3785: else {
3786: for ( j = 0; j < l && t1[j] == t2[j]; j++ );
3787: if ( j < l )
3788: return t1[j] > t2[j] ? 1 : -1;
3789: }
3790: break;
3791: case 2:
3792: for ( j = 0; j < l && t1[j] == t2[j]; j++ );
3793: if ( j < l )
3794: return t1[j] > t2[j] ? 1 : -1;
3795: break;
3796: default:
3797: error("sig_cmpdl_op : invalid order"); break;
3798: }
1.65 noro 3799: t1 += l; t2 += l; // head += l;
1.46 noro 3800: }
3801: return 0;
3802: }
3803:
3804: int sig_cmpdl_mat(int n,DL d1,DL d2)
3805: {
3806: int *v,*t1,*t2;
3807: int s,i,j,len;
3808: int **matrix;
3809: static int *w;
3810: static int nvar = 0;
3811:
3812: if ( nvar != n ) {
3813: nvar = n; w = (int *)MALLOC(n*sizeof(int));
3814: }
3815: for ( i = 0, t1 = d1->d, t2 = d2->d; i < n; i++ )
3816: w[i] = t1[i]-t2[i];
3817: len = nd_sba_modord->row;
3818: matrix = nd_sba_modord->matrix;
3819: for ( j = 0; j < len; j++ ) {
3820: v = matrix[j];
3821: for ( i = 0, s = 0; i < n; i++ )
3822: s += v[i]*w[i];
3823: if ( s > 0 )
3824: return 1;
3825: else if ( s < 0 )
3826: return -1;
3827: }
3828: return 0;
3829: }
3830:
3831: struct comp_sig_spec *create_comp_sig_spec(VL current_vl,VL old_vl,Obj ord,Obj weight)
3832: {
3833: struct comp_sig_spec *spec;
3834: VL ovl,vl;
3835: V ov;
3836: int i,j,n,nvar,s;
3837: NODE node,t,tn;
3838: struct order_pair *l;
3839: MAT m;
3840: Obj **b;
3841: int **w;
3842: int *a;
3843:
3844: spec = (struct comp_sig_spec *)MALLOC(sizeof(struct comp_sig_spec));
3845: for ( i = 0, vl = current_vl; vl; vl = NEXT(vl), i++ );
3846: spec->n = nvar = i;
3847: if ( old_vl != 0 ) {
3848: spec->oldv = (int *)MALLOC(nvar*sizeof(int));
3849: for ( i = 0, ovl = old_vl; i < nvar; ovl = NEXT(ovl), i++ ) {
3850: ov = ovl->v;
3851: for ( j = 0, vl = current_vl; vl; vl = NEXT(vl), j++ )
3852: if ( ov == vl->v ) break;
3853: spec->oldv[i] = j;
3854: }
3855: } else
3856: spec->oldv = 0;
3857: if ( !ord || NUM(ord) ) {
3858: switch ( ZTOS((Z)ord) ) {
3859: case 0:
3860: spec->cmpdl = cmpdl_revgradlex; break;
3861: case 1:
3862: spec->cmpdl = cmpdl_gradlex; break;
3863: case 2:
3864: spec->cmpdl = cmpdl_lex; break;
3865: default:
3866: error("create_comp_sig_spec : invalid spec"); break;
3867: }
3868: } else if ( OID(ord) == O_LIST ) {
3869: node = BDY((LIST)ord);
3870: for ( n = 0, t = node; t; t = NEXT(t), n++ );
3871: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
3872: for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {
1.65 noro 3873: tn = BDY((LIST)BDY(t)); l[i].order = (int)ZTOS((Q)BDY(tn));
3874: tn = NEXT(tn); l[i].length = (int)ZTOS((Q)BDY(tn));
1.46 noro 3875: s += l[i].length;
3876: }
3877: if ( s != nvar )
3878: error("create_comp_sig_spec : invalid spec");
3879: spec->order_pair = l;
3880: spec->block_length = n;
3881: spec->cmpdl = sig_cmpdl_op;
3882: } else if ( OID(ord) == O_MAT ) {
3883: m = (MAT)ord; b = (Obj **)BDY(m);
3884: if ( m->col != nvar )
3885: error("create_comp_sig_spec : invalid spec");
3886: w = almat(m->row,m->col);
3887: for ( i = 0; i < m->row; i++ )
3888: for ( j = 0; j < m->col; j++ )
1.65 noro 3889: w[i][j] = (int)ZTOS((Q)b[i][j]);
1.46 noro 3890: spec->row = m->row;
3891: spec->matrix = w;
3892: spec->cmpdl = sig_cmpdl_mat;
3893: } else
3894: error("create_comp_sig_spec : invalid spec");
3895: if ( weight != 0 ) {
3896: node = BDY((LIST)weight);
3897: a = (int *)MALLOC(nvar*sizeof(int));
3898: for ( i = 0; i < nvar; i++, node = NEXT(node) )
1.65 noro 3899: a[i] = (int)ZTOS((Z)BDY(node));
1.46 noro 3900: spec->weight = a;
3901: }
3902: return spec;
3903: }
3904:
3905: #define SIG_MUL_WEIGHT(a,i) (weight?(a)*weight[i]:(a))
3906:
3907: int comp_sig_monomial(int n,DL d1,DL d2)
3908: {
3909: static DL m1,m2;
3910: static int nvar = 0;
3911: int *oldv,*weight;
3912: int i,w1,w2;
3913:
3914: if ( nvar != n ) {
3915: nvar = n; NEWDL(m1,nvar); NEWDL(m2,nvar);
3916: }
3917: if ( !nd_sba_modord )
3918: return (*cmpdl)(n,d1,d2);
1.55 noro 3919: else if ( !nd_sba_modord->weight && !nd_sba_modord->oldv ) {
3920: return (*nd_sba_modord->cmpdl)(n,d1,d2);
3921: } else {
1.46 noro 3922: weight = nd_sba_modord->weight;
3923: oldv = nd_sba_modord->oldv;
3924: if ( oldv ) {
3925: for ( i = 0; i < n; i++ ) {
3926: m1->d[i] = d1->d[oldv[i]]; m2->d[i] = d2->d[oldv[i]];
3927: }
3928: } else {
3929: for ( i = 0; i < n; i++ ) {
3930: m1->d[i] = d1->d[i]; m2->d[i] = d2->d[i];
3931: }
3932: }
3933: for ( i = 0, w1 = w2 = 0; i < n; i++ ) {
3934: w1 += SIG_MUL_WEIGHT(m1->d[i],i);
3935: w2 += SIG_MUL_WEIGHT(m2->d[i],i);
3936: }
3937: m1->td = w1; m2->td = w2;
3938: return (*nd_sba_modord->cmpdl)(n,m1,m2);
3939: }
3940: }
3941:
1.24 noro 3942: int comp_sig(SIG s1,SIG s2)
3943: {
1.38 noro 3944: if ( nd_sba_pot ) {
3945: if ( s1->pos > s2->pos ) return 1;
3946: else if ( s1->pos < s2->pos ) return -1;
1.55 noro 3947: else return comp_sig_monomial(nd_nvar,DL(s1),DL(s2));
1.38 noro 3948: } else {
3949: static DL m1,m2;
1.44 noro 3950: static int nvar = 0;
1.38 noro 3951: int ret;
3952:
3953: if ( nvar != nd_nvar ) {
3954: nvar = nd_nvar; NEWDL(m1,nvar); NEWDL(m2,nvar);
3955: }
1.47 noro 3956: if ( !nd_sba_modord )
1.55 noro 3957: ret = (*cmpdl)(nd_nvar,DL2(s1),DL2(s2));
1.47 noro 3958: else
1.55 noro 3959: ret = comp_sig_monomial(nd_nvar,DL2(s1),DL2(s2));
1.38 noro 3960: if ( ret != 0 ) return ret;
3961: else if ( s1->pos > s2->pos ) return 1;
3962: else if ( s1->pos < s2->pos ) return -1;
3963: else return 0;
1.24 noro 3964: }
3965: }
3966:
3967: int _create_spair_s(int i1,int i2,ND_pairs sp,SIG sig1,SIG sig2)
3968: {
3969: int ret,s1,s2;
3970: RHist p1,p2;
3971: static int wpd;
3972: static UINT *lcm;
3973:
3974: sp->i1 = i1;
3975: sp->i2 = i2;
3976: p1 = nd_psh[i1];
3977: p2 = nd_psh[i2];
3978: ndl_lcm(DL(p1),DL(p2),sp->lcm);
1.49 noro 3979: #if 0
1.24 noro 3980: s1 = SG(p1)-TD(DL(p1));
3981: s2 = SG(p2)-TD(DL(p2));
3982: SG(sp) = MAX(s1,s2) + TD(sp->lcm);
1.49 noro 3983: #endif
1.24 noro 3984:
1.26 noro 3985: if ( wpd != nd_wpd ) {
1.24 noro 3986: wpd = nd_wpd;
3987: lcm = (UINT *)MALLOC(wpd*sizeof(UINT));
3988: }
3989: // DL(sig1) <- sp->lcm
3990: // DL(sig1) -= DL(p1)
3991: // DL(sig1) += DL(p1->sig)
1.27 noro 3992: ndl_sub(sp->lcm,DL(p1),lcm);
1.24 noro 3993: _ndltodl(lcm,DL(sig1));
3994: _addtodl(nd_nvar,DL(p1->sig),DL(sig1));
3995: sig1->pos = p1->sig->pos;
1.55 noro 3996: _adddl(nd_nvar,DL(sig1),nd_sba_hm[sig1->pos],DL2(sig1));
1.24 noro 3997:
3998: // DL(sig2) <- sp->lcm
3999: // DL(sig2) -= DL(p2)
4000: // DL(sig2) += DL(p2->sig)
1.27 noro 4001: ndl_sub(sp->lcm,DL(p2),lcm);
1.24 noro 4002: _ndltodl(lcm,DL(sig2));
4003: _addtodl(nd_nvar,DL(p2->sig),DL(sig2));
4004: sig2->pos = p2->sig->pos;
1.55 noro 4005: _adddl(nd_nvar,DL(sig2),nd_sba_hm[sig2->pos],DL2(sig2));
1.24 noro 4006:
4007: ret = comp_sig(sig1,sig2);
4008: if ( ret == 0 ) return 0;
4009: else if ( ret > 0 ) sp->sig = sig1;
4010: else sp->sig = sig2;
1.49 noro 4011:
4012: s1 = DL(sig1)->td+nd_sba_hm[p1->sig->pos]->td;
4013: s2 = DL(sig2)->td+nd_sba_hm[p2->sig->pos]->td;
4014: SG(sp) = MAX(s1,s2);
4015:
1.24 noro 4016: return 1;
4017: }
4018:
4019: SIG dup_sig(SIG sig)
4020: {
4021: SIG r;
4022:
4023: if ( !sig ) return 0;
4024: else {
4025: NEWSIG(r);
4026: _copydl(nd_nvar,DL(sig),DL(r));
1.55 noro 4027: _copydl(nd_nvar,DL2(sig),DL2(r));
1.24 noro 4028: r->pos = sig->pos;
4029: return r;
4030: }
4031: }
4032:
4033: void dup_ND_pairs(ND_pairs to,ND_pairs from)
4034: {
4035: to->i1 = from->i1;
4036: to->i2 = from->i2;
4037: to->sugar = from->sugar;
4038: to->sugar2 = from->sugar2;
4039: ndl_copy(from->lcm,to->lcm);
4040: to->sig = dup_sig(from->sig);
4041: }
4042:
4043: ND_pairs merge_pairs_s(ND_pairs p1,ND_pairs p2)
4044: {
4045: struct oND_pairs root;
1.65 noro 4046: ND_pairs q1,q2,r;
1.24 noro 4047: int ret;
4048:
4049: r = &root;
4050: for ( q1 = p1, q2 = p2; q1 != 0 && q2 != 0; ) {
4051: ret = comp_sig(q1->sig,q2->sig);
4052: if ( ret < 0 ) {
4053: r->next = q1; r = q1; q1 = q1->next;
4054: } else if ( ret > 0 ) {
4055: r->next = q2; r = q2; q2 = q2->next;
4056: } else {
1.47 noro 4057: Nnewpair--;
1.24 noro 4058: ret = DL_COMPARE(q1->lcm,q2->lcm);
1.35 noro 4059: Nsamesig++;
1.24 noro 4060: if ( ret < 0 ) {
4061: r->next = q1; r = q1; q1 = q1->next;
4062: q2 = q2->next;
4063: } else {
4064: r->next = q2; r = q2; q2 = q2->next;
4065: q1 = q1->next;
4066: }
4067: }
4068: }
4069: if ( q1 ) {
4070: r->next = q1;
4071: } else {
4072: r->next = q2;
4073: }
4074: return root.next;
4075: }
4076:
4077: ND_pairs insert_pair_s(ND_pairs l,ND_pairs s)
4078: {
4079: ND_pairs p,prev;
1.47 noro 4080: int ret=1;
1.24 noro 4081:
4082: for ( p = l, prev = 0; p != 0; prev = p, p = p->next ) {
4083: if ( (ret = comp_sig(s->sig,p->sig)) <= 0 )
4084: break;
4085: }
4086: if ( ret == 0 ) {
4087: ret = DL_COMPARE(s->lcm,p->lcm);
4088: if ( ret < 0 ) {
4089: // replace p with s
4090: s->next = p->next;
4091: if ( prev == 0 ) {
4092: return s;
4093: } else {
4094: prev->next = s;
4095: return l;
4096: }
4097: } else
4098: return l;
4099: } else {
4100: // insert s between prev and p
1.47 noro 4101: Nnewpair++;
1.24 noro 4102: s->next = p;
4103: if ( prev == 0 ) {
4104: return s;
4105: } else {
4106: prev->next = s;
4107: return l;
4108: }
4109: }
4110: }
4111:
1.29 noro 4112: INLINE int __dl_redble(DL d1,DL d2,int nvar)
4113: {
4114: int i;
4115:
4116: if ( d1->td > d2->td )
4117: return 0;
4118: for ( i = nvar-1; i >= 0; i-- )
4119: if ( d1->d[i] > d2->d[i] )
4120: break;
4121: if ( i >= 0 )
4122: return 0;
4123: else
4124: return 1;
4125: }
4126:
1.30 noro 4127: ND_pairs nd_newpairs_s(int t, NODE *syz)
1.24 noro 4128: {
1.65 noro 4129: NODE s;
4130: int ret,i;
4131: ND_pairs r0,_sp,sp;
1.29 noro 4132: SIG spsig,tsig;
1.44 noro 4133: static int nvar = 0;
1.29 noro 4134: static SIG _sig1,_sig2;
1.24 noro 4135:
4136: NEWND_pairs(_sp);
1.29 noro 4137: if ( !_sig1 || nvar != nd_nvar ) {
4138: nvar = nd_nvar; NEWSIG(_sig1); NEWSIG(_sig2);
4139: }
1.24 noro 4140: r0 = 0;
1.27 noro 4141: for ( i = 0; i < t; i++ ) {
4142: ret = _create_spair_s(i,t,_sp,_sig1,_sig2);
1.24 noro 4143: if ( ret ) {
4144: spsig = _sp->sig;
1.29 noro 4145: for ( s = syz[spsig->pos]; s; s = s->next ) {
1.24 noro 4146: tsig = (SIG)s->body;
1.29 noro 4147: if ( _dl_redble(DL(tsig),DL(spsig),nd_nvar) )
1.24 noro 4148: break;
4149: }
4150: if ( s == 0 ) {
4151: NEWND_pairs(sp);
4152: dup_ND_pairs(sp,_sp);
4153: r0 = insert_pair_s(r0,sp);
1.26 noro 4154: } else
4155: Nsyz++;
1.24 noro 4156: }
4157: }
4158: return r0;
4159: }
4160:
1.47 noro 4161: ND_pairs *nd_newpairs_array_s(int t, NODE *syz)
4162: {
1.65 noro 4163: NODE s;
4164: int ret,i;
4165: ND_pairs _sp,sp;
1.47 noro 4166: ND_pairs *d;
4167: SIG spsig,tsig;
4168: static int nvar = 0;
4169: static SIG _sig1,_sig2;
4170:
4171: NEWND_pairs(_sp);
4172: if ( !_sig1 || nvar != nd_nvar ) {
4173: nvar = nd_nvar; NEWSIG(_sig1); NEWSIG(_sig2);
4174: }
4175: d = (ND_pairs *)MALLOC(nd_nbase*sizeof(ND_pairs));
4176: Nnewpair = 0;
4177: for ( i = 0; i < t; i++ ) {
4178: ret = _create_spair_s(i,t,_sp,_sig1,_sig2);
4179: if ( ret ) {
4180: spsig = _sp->sig;
4181: for ( s = syz[spsig->pos]; s; s = s->next ) {
4182: tsig = (SIG)s->body;
4183: if ( _dl_redble(DL(tsig),DL(spsig),nd_nvar) )
4184: break;
4185: }
4186: if ( s == 0 ) {
4187: NEWND_pairs(sp);
4188: dup_ND_pairs(sp,_sp);
4189: d[spsig->pos] = insert_pair_s(d[spsig->pos],sp);
4190: } else
4191: Nsyz++;
4192: }
4193: }
4194: return d;
4195: }
4196:
1.1 noro 4197: /* ipair = [i1,i2],[i1,i2],... */
4198: ND_pairs nd_ipairtospair(NODE ipair)
4199: {
4200: int s1,s2;
4201: NODE tn,t;
4202: ND_pairs r,r0;
4203:
4204: for ( r0 = 0, t = ipair; t; t = NEXT(t) ) {
4205: NEXTND_pairs(r0,r);
4206: tn = BDY((LIST)BDY(t));
1.65 noro 4207: r->i1 = (int)ZTOS((Q)ARG0(tn));
4208: r->i2 = (int)ZTOS((Q)ARG1(tn));
1.1 noro 4209: ndl_lcm(DL(nd_psh[r->i1]),DL(nd_psh[r->i2]),r->lcm);
4210: s1 = SG(nd_psh[r->i1])-TD(DL(nd_psh[r->i1]));
4211: s2 = SG(nd_psh[r->i2])-TD(DL(nd_psh[r->i2]));
4212: SG(r) = MAX(s1,s2) + TD(LCM(r));
4213: /* experimental */
4214: if ( nd_sugarweight )
4215: r->sugar2 = ndl_weight2(r->lcm);
4216: }
4217: if ( r0 ) NEXT(r) = 0;
4218: return r0;
4219: }
4220:
4221: /* kokokara */
4222:
4223: ND_pairs crit_B( ND_pairs d, int s )
4224: {
4225: ND_pairs cur,head,prev,remove;
4226: UINT *t,*tl,*lcm;
4227:
4228: if ( !d ) return 0;
4229: t = DL(nd_psh[s]);
4230: prev = 0;
4231: head = cur = d;
4232: lcm = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
4233: while ( cur ) {
4234: tl = cur->lcm;
4235: if ( ndl_reducible(tl,t) ) {
4236: ndl_lcm(DL(nd_psh[cur->i1]),t,lcm);
4237: if ( !ndl_equal(lcm,tl) ) {
4238: ndl_lcm(DL(nd_psh[cur->i2]),t,lcm);
4239: if (!ndl_equal(lcm,tl)) {
4240: remove = cur;
4241: if ( !prev ) {
4242: head = cur = NEXT(cur);
4243: } else {
4244: cur = NEXT(prev) = NEXT(cur);
4245: }
1.41 noro 4246: FREENDP(remove); NcriB++;
1.1 noro 4247: } else {
4248: prev = cur; cur = NEXT(cur);
4249: }
4250: } else {
4251: prev = cur; cur = NEXT(cur);
4252: }
4253: } else {
4254: prev = cur; cur = NEXT(cur);
4255: }
4256: }
4257: return head;
4258: }
4259:
4260: ND_pairs crit_M( ND_pairs d1 )
4261: {
4262: ND_pairs e,d2,d3,dd,p;
4263: UINT *id,*jd;
4264:
4265: if ( !d1 ) return d1;
4266: for ( dd = 0, e = d1; e; e = d3 ) {
4267: if ( !(d2 = NEXT(e)) ) {
4268: NEXT(e) = dd;
4269: return e;
4270: }
4271: id = LCM(e);
4272: for ( d3 = 0; d2; d2 = p ) {
4273: p = NEXT(d2);
4274: jd = LCM(d2);
4275: if ( ndl_equal(jd,id) )
4276: ;
4277: else if ( TD(jd) > TD(id) )
4278: if ( ndl_reducible(jd,id) ) continue;
4279: else ;
4280: else if ( ndl_reducible(id,jd) ) goto delit;
4281: NEXT(d2) = d3;
4282: d3 = d2;
4283: }
4284: NEXT(e) = dd;
4285: dd = e;
4286: continue;
4287: /**/
4288: delit: NEXT(d2) = d3;
4289: d3 = d2;
4290: for ( ; p; p = d2 ) {
4291: d2 = NEXT(p);
4292: NEXT(p) = d3;
4293: d3 = p;
4294: }
4295: FREENDP(e);
4296: }
4297: return dd;
4298: }
4299:
4300: ND_pairs crit_F( ND_pairs d1 )
4301: {
4302: ND_pairs rest, head,remove;
4303: ND_pairs last, p, r, w;
4304: int s;
4305:
4306: if ( !d1 ) return d1;
4307: for ( head = last = 0, p = d1; NEXT(p); ) {
4308: r = w = equivalent_pairs(p,&rest);
4309: s = SG(r);
4310: w = NEXT(w);
4311: while ( w ) {
4312: if ( crit_2(w->i1,w->i2) ) {
4313: r = w;
4314: w = NEXT(w);
4315: while ( w ) {
4316: remove = w;
4317: w = NEXT(w);
4318: FREENDP(remove);
4319: }
4320: break;
4321: } else if ( SG(w) < s ) {
4322: FREENDP(r);
4323: r = w;
4324: s = SG(r);
4325: w = NEXT(w);
4326: } else {
4327: remove = w;
4328: w = NEXT(w);
4329: FREENDP(remove);
4330: }
4331: }
4332: if ( last ) NEXT(last) = r;
4333: else head = r;
4334: NEXT(last = r) = 0;
4335: p = rest;
4336: if ( !p ) return head;
4337: }
4338: if ( !last ) return p;
4339: NEXT(last) = p;
4340: return head;
4341: }
4342:
4343: int crit_2( int dp1, int dp2 )
4344: {
4345: return ndl_disjoint(DL(nd_psh[dp1]),DL(nd_psh[dp2]));
4346: }
4347:
4348: ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest )
4349: {
4350: ND_pairs w,p,r,s;
4351: UINT *d;
4352:
4353: w = d1;
4354: d = LCM(w);
4355: s = NEXT(w);
4356: NEXT(w) = 0;
4357: for ( r = 0; s; s = p ) {
4358: p = NEXT(s);
4359: if ( ndl_equal(d,LCM(s)) ) {
4360: NEXT(s) = w; w = s;
4361: } else {
4362: NEXT(s) = r; r = s;
4363: }
4364: }
4365: *prest = r;
4366: return w;
4367: }
4368:
4369: NODE update_base(NODE nd,int ndp)
4370: {
4371: UINT *dl, *dln;
4372: NODE last, p, head;
4373:
4374: dl = DL(nd_psh[ndp]);
4375: for ( head = last = 0, p = nd; p; ) {
4376: dln = DL(nd_psh[(long)BDY(p)]);
4377: if ( ndl_reducible( dln, dl ) ) {
4378: p = NEXT(p);
4379: if ( last ) NEXT(last) = p;
4380: } else {
4381: if ( !last ) head = p;
4382: p = NEXT(last = p);
4383: }
4384: }
4385: head = append_one(head,ndp);
4386: return head;
4387: }
4388:
4389: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest )
4390: {
4391: ND_pairs m,ml,p,l;
1.65 noro 4392: int s;
1.1 noro 4393:
4394: if ( !(p = NEXT(m = d)) ) {
4395: *prest = p;
4396: NEXT(m) = 0;
4397: return m;
4398: }
4399: if ( !NoSugar ) {
4400: if ( nd_sugarweight ) {
4401: s = m->sugar2;
4402: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4403: if ( (p->sugar2 < s)
4404: || ((p->sugar2 == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
4405: ml = l; m = p; s = m->sugar2;
4406: }
4407: } else {
4408: s = SG(m);
4409: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4410: if ( (SG(p) < s)
4411: || ((SG(p) == s) && (DL_COMPARE(LCM(p),LCM(m)) < 0)) ) {
4412: ml = l; m = p; s = SG(m);
4413: }
4414: }
4415: } else {
4416: for ( ml = 0, l = m; p; p = NEXT(l = p) )
4417: if ( DL_COMPARE(LCM(p),LCM(m)) < 0 ) {
4418: ml = l; m = p; s = SG(m);
4419: }
4420: }
4421: if ( !ml ) *prest = NEXT(m);
4422: else {
4423: NEXT(ml) = NEXT(m);
4424: *prest = d;
4425: }
4426: NEXT(m) = 0;
4427: return m;
4428: }
4429:
4430: ND_pairs nd_minsugarp( ND_pairs d, ND_pairs *prest )
4431: {
4432: int msugar,i;
4433: ND_pairs t,dm0,dm,dr0,dr;
4434:
4435: if ( nd_sugarweight ) {
4436: for ( msugar = d->sugar2, t = NEXT(d); t; t = NEXT(t) )
4437: if ( t->sugar2 < msugar ) msugar = t->sugar2;
4438: dm0 = 0; dr0 = 0;
4439: for ( i = 0, t = d; t; t = NEXT(t) )
4440: if ( i < nd_f4_nsp && t->sugar2 == msugar ) {
4441: if ( dm0 ) NEXT(dm) = t;
4442: else dm0 = t;
4443: dm = t;
4444: i++;
4445: } else {
4446: if ( dr0 ) NEXT(dr) = t;
4447: else dr0 = t;
4448: dr = t;
4449: }
4450: } else {
4451: for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) )
4452: if ( SG(t) < msugar ) msugar = SG(t);
4453: dm0 = 0; dr0 = 0;
4454: for ( i = 0, t = d; t; t = NEXT(t) )
4455: if ( i < nd_f4_nsp && SG(t) == msugar ) {
4456: if ( dm0 ) NEXT(dm) = t;
4457: else dm0 = t;
4458: dm = t;
4459: i++;
4460: } else {
4461: if ( dr0 ) NEXT(dr) = t;
4462: else dr0 = t;
4463: dr = t;
4464: }
4465: }
4466: NEXT(dm) = 0;
4467: if ( dr0 ) NEXT(dr) = 0;
4468: *prest = dr0;
4469: return dm0;
4470: }
4471:
1.28 noro 4472: ND_pairs nd_minsugarp_s( ND_pairs d, ND_pairs *prest )
4473: {
4474: int msugar;
4475: ND_pairs t,last;
4476:
4477: for ( msugar = SG(d), t = d; t; t = NEXT(t) )
4478: if ( SG(t) == msugar ) last = t;
4479: *prest = last->next;
4480: last->next = 0;
4481: return d;
4482: }
4483:
1.1 noro 4484: int nd_tdeg(NDV c)
4485: {
4486: int wmax = 0;
4487: int i,len;
4488: NMV a;
4489:
4490: len = LEN(c);
4491: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
1.65 noro 4492: wmax = MAX((int)TD(DL(a)),wmax);
1.1 noro 4493: return wmax;
4494: }
4495:
1.24 noro 4496: int ndv_newps(int m,NDV a,NDV aq)
1.1 noro 4497: {
4498: RHist r;
4499: NODE tn;
4500: LIST l;
4501: Z iq;
4502:
4503: if ( nd_psn == nd_pslen ) {
4504: nd_pslen *= 2;
4505: nd_ps = (NDV *)REALLOC((char *)nd_ps,nd_pslen*sizeof(NDV));
4506: nd_ps_trace = (NDV *)REALLOC((char *)nd_ps_trace,nd_pslen*sizeof(NDV));
4507: nd_psh = (RHist *)REALLOC((char *)nd_psh,nd_pslen*sizeof(RHist));
4508: nd_bound = (UINT **)
4509: REALLOC((char *)nd_bound,nd_pslen*sizeof(UINT *));
4510: nd_ps_sym = (NDV *)REALLOC((char *)nd_ps_sym,nd_pslen*sizeof(NDV));
4511: nd_ps_trace_sym = (NDV *)REALLOC((char *)nd_ps_trace_sym,nd_pslen*sizeof(NDV));
4512: }
4513: NEWRHist(r); nd_psh[nd_psn] = r;
4514: nd_ps[nd_psn] = a;
4515: if ( aq ) {
4516: nd_ps_trace[nd_psn] = aq;
4517: if ( !m ) {
4518: register_hcf(aq);
4519: } else if ( m == -2 ) {
4520: /* do nothing */
4521: } else
4522: error("ndv_newps : invalud modulus");
4523: nd_bound[nd_psn] = ndv_compute_bound(aq);
4524: #if 1
4525: SG(r) = SG(aq);
4526: #else
4527: SG(r) = nd_tdeg(aq);
4528: #endif
4529: ndl_copy(HDL(aq),DL(r));
1.24 noro 4530: r->sig = dup_sig(aq->sig);
1.1 noro 4531: } else {
4532: if ( !m ) register_hcf(a);
4533: nd_bound[nd_psn] = ndv_compute_bound(a);
4534: #if 1
4535: SG(r) = SG(a);
4536: #else
4537: SG(r) = nd_tdeg(a);
4538: #endif
4539: ndl_copy(HDL(a),DL(r));
1.24 noro 4540: r->sig = dup_sig(a->sig);
1.1 noro 4541: }
4542: if ( nd_demand ) {
4543: if ( aq ) {
4544: ndv_save(nd_ps_trace[nd_psn],nd_psn);
4545: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
4546: nd_ps_trace_sym[nd_psn] = ndv_symbolic(m,nd_ps_trace[nd_psn]);
4547: nd_ps_trace[nd_psn] = 0;
4548: } else {
4549: ndv_save(nd_ps[nd_psn],nd_psn);
4550: nd_ps_sym[nd_psn] = ndv_symbolic(m,nd_ps[nd_psn]);
4551: nd_ps[nd_psn] = 0;
4552: }
4553: }
4554: if ( nd_gentrace ) {
4555: /* reverse the tracelist and append it to alltracelist */
4556: nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist);
1.6 noro 4557: STOZ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn);
1.1 noro 4558: MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0;
4559: }
4560: return nd_psn++;
4561: }
4562:
1.46 noro 4563: // find LM wrt the specified modord
4564: void ndv_lm_modord(NDV p,DL d)
1.45 noro 4565: {
4566: NMV m;
4567: DL tmp;
4568: int len,i,ret;
4569:
4570: NEWDL(tmp,nd_nvar);
4571: m = BDY(p); len = LEN(p);
1.46 noro 4572: _ndltodl(DL(m),d); // printdl(d); printf("->");
1.45 noro 4573: for ( i = 1, NMV_ADV(m); i < len; i++, NMV_ADV(m) ) {
4574: _ndltodl(DL(m),tmp);
1.46 noro 4575: ret = comp_sig_monomial(nd_nvar,tmp,d);
1.45 noro 4576: if ( ret > 0 ) _copydl(nd_nvar,tmp,d);
4577: }
1.46 noro 4578: // printdl(d); printf("\n");
1.45 noro 4579: }
4580:
1.1 noro 4581: /* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */
4582: /* return 1 if success, 0 if failure (HC(a mod p)) */
4583:
1.24 noro 4584: int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont,int sba)
1.1 noro 4585: {
1.65 noro 4586: int i,j;
4587: NODE s,tn;
1.6 noro 4588: RHist r;
4589: NDVI w;
4590: NDV a,am;
4591: union oNDC hc;
4592: NODE node;
4593: Z iq,jq;
4594: LIST l;
4595:
4596: nd_found = 0; nd_notfirst = 0; nd_create = 0;
4597: /* initialize the tracelist */
4598: nd_tracelist = 0;
4599:
4600: for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++;
4601: w = (NDVI)MALLOC(nd_psn*sizeof(struct oNDVI));
4602: for ( i = j = 0, s = f; s; s = NEXT(s), j++ )
4603: if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; }
4604: if ( !dont_sort ) {
4605: /* XXX heuristic */
1.26 noro 4606: if ( !sba && !nd_ord->id && (nd_ord->ord.simple<2) )
1.6 noro 4607: qsort(w,nd_psn,sizeof(struct oNDVI),
4608: (int (*)(const void *,const void *))ndvi_compare_rev);
4609: else
4610: qsort(w,nd_psn,sizeof(struct oNDVI),
4611: (int (*)(const void *,const void *))ndvi_compare);
4612: }
4613: nd_pslen = 2*nd_psn;
4614: nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4615: nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4616: nd_ps_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4617: nd_ps_trace_sym = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
4618: nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist));
4619: nd_bound = (UINT **)MALLOC(nd_pslen*sizeof(UINT *));
4620: nd_hcf = 0;
1.1 noro 4621:
1.6 noro 4622: if ( trace && nd_vc )
4623: makesubst(nd_vc,&nd_subst);
4624: else
4625: nd_subst = 0;
1.1 noro 4626:
1.6 noro 4627: if ( !nd_red )
4628: nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
4629: for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0;
4630: for ( i = 0; i < nd_psn; i++ ) {
4631: hc = HCU(w[i].p);
4632: if ( trace ) {
4633: if ( mod == -2 ) {
4634: /* over a large finite field */
4635: /* trace = small modulus */
4636: a = nd_ps_trace[i] = ndv_dup(-2,w[i].p);
4637: ndv_mod(-2,a);
4638: if ( !dont_removecont) ndv_removecont(-2,a);
4639: am = nd_ps[i] = ndv_dup(trace,w[i].p);
4640: ndv_mod(trace,am);
1.65 noro 4641: if ( DL_COMPARE(HDL(am),HDL(a)) ) return 0;
1.6 noro 4642: ndv_removecont(trace,am);
4643: } else {
4644: a = nd_ps_trace[i] = ndv_dup(0,w[i].p);
4645: if ( !dont_removecont) ndv_removecont(0,a);
4646: register_hcf(a);
4647: am = nd_ps[i] = ndv_dup(mod,a);
4648: ndv_mod(mod,am);
1.65 noro 4649: if ( DL_COMPARE(HDL(am),HDL(a)) ) return 0;
1.6 noro 4650: ndv_removecont(mod,am);
4651: }
4652: } else {
4653: a = nd_ps[i] = ndv_dup(mod,w[i].p);
4654: if ( mod || !dont_removecont ) ndv_removecont(mod,a);
4655: if ( !mod ) register_hcf(a);
1.1 noro 4656: }
1.6 noro 4657: if ( nd_gentrace ) {
4658: STOZ(i,iq); STOZ(w[i].i,jq); node = mknode(3,iq,jq,ONE);
4659: /* exact division */
1.1 noro 4660: if ( !dont_removecont )
1.6 noro 4661: ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a));
4662: MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l;
4663: }
4664: NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r));
4665: nd_bound[i] = ndv_compute_bound(a);
4666: nd_psh[i] = r;
4667: if ( nd_demand ) {
4668: if ( trace ) {
4669: ndv_save(nd_ps_trace[i],i);
4670: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
4671: nd_ps_trace_sym[i] = ndv_symbolic(mod,nd_ps_trace[i]);
4672: nd_ps_trace[i] = 0;
4673: } else {
4674: ndv_save(nd_ps[i],i);
4675: nd_ps_sym[i] = ndv_symbolic(mod,nd_ps[i]);
4676: nd_ps[i] = 0;
4677: }
1.1 noro 4678: }
1.6 noro 4679: }
1.24 noro 4680: if ( sba ) {
1.27 noro 4681: nd_sba_hm = (DL *)MALLOC(nd_psn*sizeof(DL));
1.24 noro 4682: // setup signatures
1.27 noro 4683: for ( i = 0; i < nd_psn; i++ ) {
4684: SIG sig;
1.24 noro 4685:
1.27 noro 4686: NEWSIG(sig); sig->pos = i;
4687: nd_ps[i]->sig = sig;
4688: if ( nd_demand ) nd_ps_sym[i]->sig = sig;
4689: nd_psh[i]->sig = sig;
4690: if ( trace ) {
4691: nd_ps_trace[i]->sig = sig;
4692: if ( nd_demand ) nd_ps_trace_sym[i]->sig = sig;
4693: }
4694: NEWDL(nd_sba_hm[i],nd_nvar);
1.46 noro 4695: if ( nd_sba_modord )
4696: ndv_lm_modord(nd_ps[i],nd_sba_hm[i]);
1.45 noro 4697: else
4698: _ndltodl(DL(nd_psh[i]),nd_sba_hm[i]);
1.55 noro 4699: _adddl(nd_nvar,DL(sig),nd_sba_hm[i],DL2(sig));
1.27 noro 4700: }
1.29 noro 4701: nd_sba_pos = (NODE *)MALLOC(nd_psn*sizeof(NODE));
4702: for ( i = 0; i < nd_psn; i++ ) {
4703: j = nd_psh[i]->sig->pos;
4704: nd_sba_pos[j] = append_one(nd_sba_pos[j],i);
4705: }
1.24 noro 4706: }
1.6 noro 4707: if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0;
4708: return 1;
1.1 noro 4709: }
4710:
4711: struct order_spec *append_block(struct order_spec *spec,
4712: int nv,int nalg,int ord);
4713:
4714: extern VECT current_dl_weight_vector_obj;
4715: static VECT prev_weight_vector_obj;
4716:
4717: void preprocess_algcoef(VL vv,VL av,struct order_spec *ord,LIST f,
4718: struct order_spec **ord1p,LIST *f1p,NODE *alistp)
4719: {
1.65 noro 4720: NODE alist,t,s,arg;
1.1 noro 4721: VL tv;
4722: P poly;
4723: DP d;
4724: Alg alpha,dp;
4725: DAlg inv,da,hc;
4726: MP m;
4727: int i,nvar,nalg,n;
4728: NumberField nf;
1.65 noro 4729: LIST f1;
1.1 noro 4730: VECT obj,obj0;
4731: VECT tmp;
4732:
4733: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++);
4734: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++);
4735:
4736: for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) {
4737: NEXTNODE(alist,t); MKV(tv->v,poly);
4738: MKAlg(poly,alpha); BDY(t) = (pointer)alpha;
4739: tv->v = tv->v->priv;
4740: }
4741: NEXT(t) = 0;
4742:
4743: /* simplification, making polynomials monic */
4744: setfield_dalg(alist);
4745: obj_algtodalg((Obj)f,(Obj *)&f1);
4746: for ( t = BDY(f); t; t = NEXT(t) ) {
4747: initd(ord); ptod(vv,vv,(P)BDY(t),&d);
4748: hc = (DAlg)BDY(d)->c;
4749: if ( NID(hc) == N_DA ) {
4750: invdalg(hc,&inv);
4751: for ( m = BDY(d); m; m = NEXT(m) ) {
4752: muldalg(inv,(DAlg)m->c,&da); m->c = (Obj)da;
4753: }
4754: }
4755: initd(ord); dtop(vv,vv,d,(Obj *)&poly); BDY(f) = (pointer)poly;
4756: }
4757: obj_dalgtoalg((Obj)f1,(Obj *)&f);
4758:
4759: /* append alg vars to the var list */
4760: for ( tv = vv; NEXT(tv); tv = NEXT(tv) );
4761: NEXT(tv) = av;
4762:
4763: /* append a block to ord */
4764: *ord1p = append_block(ord,nvar,nalg,2);
4765:
4766: /* create generator list */
4767: nf = get_numberfield();
4768: for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) {
4769: MKAlg(nf->defpoly[i],dp);
4770: MKNODE(s,dp,t); t = s;
4771: }
4772: MKLIST(f1,t);
4773: *alistp = alist;
4774: algobjtorat((Obj)f1,(Obj *)f1p);
4775:
4776: /* creating a new weight vector */
4777: prev_weight_vector_obj = obj0 = current_dl_weight_vector_obj;
4778: n = nvar+nalg+1;
4779: MKVECT(obj,n);
4780: if ( obj0 && obj0->len == nvar )
4781: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = BDY(obj0)[i];
4782: else
4783: for ( i = 0; i < nvar; i++ ) BDY(obj)[i] = (pointer)ONE;
4784: for ( i = 0; i < nalg; i++ ) BDY(obj)[i+nvar] = 0;
4785: BDY(obj)[n-1] = (pointer)ONE;
4786: arg = mknode(1,obj);
4787: Pdp_set_weight(arg,&tmp);
4788: }
4789:
4790: NODE postprocess_algcoef(VL av,NODE alist,NODE r)
4791: {
4792: NODE s,t,u0,u;
4793: P p;
4794: VL tv;
4795: Obj obj;
4796: VECT tmp;
4797: NODE arg;
4798:
4799: u0 = 0;
4800: for ( t = r; t; t = NEXT(t) ) {
4801: p = (P)BDY(t);
4802: for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) {
4803: substr(CO,0,(Obj)p,tv->v,(Obj)BDY(s),&obj); p = (P)obj;
4804: }
4805: if ( OID(p) == O_P || (OID(p) == O_N && NID((Num)p) != N_A) ) {
4806: NEXTNODE(u0,u);
4807: BDY(u) = (pointer)p;
4808: }
4809: }
4810: arg = mknode(1,prev_weight_vector_obj);
4811: Pdp_set_weight(arg,&tmp);
4812:
4813: return u0;
4814: }
4815:
4816: void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
4817: {
1.65 noro 4818: VL tv,fv,vv,av;
4819: NODE fd,fd0,r0,t,x,s,xx,alist,r;
4820: int e,max,nvar,i;
4821: NDV b;
4822: int ishomo,nalg,mrank,trank,wmax,len;
1.1 noro 4823: NMV a;
1.65 noro 4824: P zp;
4825: Q dmy;
4826: LIST f1,zpl;
4827: struct order_spec *ord1;
4828: NODE tr,tl1,tl2,tl3,tl4,nzlist;
4829: LIST l1,l2,l3,l4,l5;
1.1 noro 4830: int j;
4831: Z jq,bpe,last_nonzero;
1.65 noro 4832: int *perm;
4833: EPOS oepos;
4834: int obpe,oadv,ompos,cbpe;
4835: VECT hvect;
1.1 noro 4836:
1.65 noro 4837: NcriB = NcriMF = Ncri2 = 0;
4838: nd_module = 0;
4839: if ( !m && Demand ) nd_demand = 1;
4840: else nd_demand = 0;
1.1 noro 4841:
1.65 noro 4842: if ( DP_Multiple )
4843: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
1.1 noro 4844: #if 0
1.65 noro 4845: ndv_alloc = 0;
1.1 noro 4846: #endif
1.65 noro 4847: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
4848: parse_nd_option(vv,current_option);
4849: if ( m && nd_vc )
4850: error("nd_{gr,f4} : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
4851: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
4852: switch ( ord->id ) {
4853: case 1:
4854: if ( ord->nv != nvar )
4855: error("nd_{gr,f4} : invalid order specification");
4856: break;
4857: default:
4858: break;
4859: }
4860: nd_nalg = 0;
4861: av = 0;
4862: if ( !m ) {
4863: get_algtree((Obj)f,&av);
4864: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
4865: nd_ntrans = nvar;
4866: nd_nalg = nalg;
4867: /* #i -> t#i */
4868: if ( nalg ) {
4869: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
4870: ord = ord1;
4871: f = f1;
1.1 noro 4872: }
1.65 noro 4873: nvar += nalg;
4874: }
4875: nd_init_ord(ord);
4876: mrank = 0;
4877: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
4878: for ( tv = vv; tv; tv = NEXT(tv) ) {
1.1 noro 4879: if ( nd_module ) {
1.16 noro 4880: if ( OID(BDY(t)) == O_DPM ) {
1.65 noro 4881: e = dpm_getdeg((DPM)BDY(t),&trank);
4882: max = MAX(e,max);
4883: mrank = MAX(mrank,trank);
1.16 noro 4884: } else {
1.65 noro 4885: s = BDY((LIST)BDY(t));
4886: trank = length(s);
4887: mrank = MAX(mrank,trank);
4888: for ( ; s; s = NEXT(s) ) {
4889: e = getdeg(tv->v,(P)BDY(s));
4890: max = MAX(e,max);
4891: }
1.16 noro 4892: }
1.1 noro 4893: } else {
1.43 noro 4894: if ( OID(BDY(t)) == O_DP ) {
1.65 noro 4895: e = dp_getdeg((DP)BDY(t));
4896: max = MAX(e,max);
1.43 noro 4897: } else {
1.65 noro 4898: e = getdeg(tv->v,(P)BDY(t));
4899: max = MAX(e,max);
1.43 noro 4900: }
1.1 noro 4901: }
4902: }
1.65 noro 4903: nd_setup_parameters(nvar,nd_nzlist?0:max);
4904: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
4905: ishomo = 1;
4906: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
4907: if ( nd_module ) {
4908: if ( OID(BDY(t)) == O_DPM ) {
4909: Z cont;
4910: DPM zdpm;
4911:
4912: if ( !m && !nd_gentrace ) dpm_ptozp((DPM)BDY(t),&cont,&zdpm);
4913: else zdpm = (DPM)BDY(t);
4914: b = (pointer)dpmtondv(m,zdpm);
4915: } else {
4916: if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
4917: else zpl = (LIST)BDY(t);
4918: b = (pointer)pltondv(CO,vv,zpl);
4919: }
4920: } else {
4921: if ( OID(BDY(t)) == O_DP ) {
4922: DP zdp;
4923:
4924: if ( !m && !nd_gentrace ) dp_ptozp((DP)BDY(t),&zdp);
4925: else zdp = (DP)BDY(t);
4926: b = (pointer)dptondv(m,zdp);
4927: } else {
4928: if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
4929: else zp = (P)BDY(t);
4930: b = (pointer)ptondv(CO,vv,zp);
4931: }
4932: }
4933: if ( ishomo )
4934: ishomo = ishomo && ndv_ishomo(b);
4935: if ( m ) ndv_mod(m,b);
4936: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
4937: }
4938: if ( fd0 ) NEXT(fd) = 0;
1.1 noro 4939:
4940: if ( !ishomo && homo ) {
4941: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
4942: b = (NDV)BDY(t); len = LEN(b);
4943: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
1.65 noro 4944: wmax = MAX((int)TD(DL(a)),wmax);
1.1 noro 4945: }
4946: homogenize_order(ord,nvar,&ord1);
4947: nd_init_ord(ord1);
4948: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
4949: for ( t = fd0; t; t = NEXT(t) )
4950: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
1.65 noro 4951: }
1.1 noro 4952:
1.65 noro 4953: ndv_setup(m,0,fd0,(nd_gbblock||nd_splist||nd_check_splist)?1:0,0,0);
4954: if ( nd_gentrace ) {
4955: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
4956: }
1.1 noro 4957: if ( nd_splist ) {
4958: *rp = compute_splist();
4959: return;
4960: }
4961: if ( nd_check_splist ) {
1.65 noro 4962: if ( f4 ) {
4963: if ( check_splist_f4(m,nd_check_splist) ) *rp = (LIST)ONE;
4964: else *rp = 0;
4965: } else {
4966: if ( check_splist(m,nd_check_splist) ) *rp = (LIST)ONE;
4967: else *rp = 0;
4968: }
1.1 noro 4969: return;
4970: }
1.65 noro 4971: x = f4?nd_f4(m,0,&perm):nd_gb(m,ishomo || homo,0,0,&perm);
1.1 noro 4972: if ( !x ) {
4973: *rp = 0; return;
4974: }
1.15 noro 4975: if ( nd_gentrace ) {
4976: MKVECT(hvect,nd_psn);
4977: for ( i = 0; i < nd_psn; i++ )
1.65 noro 4978: ndltodp(nd_psh[i]->dl,(DP *)&BDY(hvect)[i]);
1.15 noro 4979: }
1.1 noro 4980: if ( !ishomo && homo ) {
4981: /* dehomogenization */
4982: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
4983: nd_init_ord(ord);
4984: nd_setup_parameters(nvar,0);
4985: }
1.65 noro 4986: nd_demand = 0;
1.1 noro 4987: if ( nd_module && nd_intersect ) {
4988: for ( j = nd_psn-1, x = 0; j >= 0; j-- )
1.65 noro 4989: if ( MPOS(DL(nd_psh[j])) > (UINT)nd_intersect ) {
1.1 noro 4990: MKNODE(xx,(pointer)((unsigned long)j),x); x = xx;
4991: }
4992: conv_ilist(nd_demand,0,x,0);
4993: goto FINAL;
4994: }
1.65 noro 4995: if ( nd_gentrace && f4 ) { nzlist = nd_alltracelist; }
4996: x = ndv_reducebase(x,perm);
4997: if ( nd_gentrace && !f4 ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
4998: x = ndv_reduceall(m,x);
4999: cbpe = nd_bpe;
5000: if ( nd_gentrace && !f4 ) {
5001: tl2 = nd_alltracelist; nd_alltracelist = 0;
5002: ndv_check_membership(m,fd0,obpe,oadv,oepos,x);
5003: tl3 = nd_alltracelist; nd_alltracelist = 0;
5004: if ( nd_gensyz ) {
5005: nd_gb(m,0,1,1,0);
5006: tl4 = nd_alltracelist; nd_alltracelist = 0;
5007: } else tl4 = 0;
5008: }
5009: nd_bpe = cbpe;
5010: nd_setup_parameters(nd_nvar,0);
1.1 noro 5011: FINAL:
1.65 noro 5012: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5013: NEXTNODE(r0,r);
5014: if ( nd_module ) {
5015: if ( retdp ) BDY(r) = ndvtodpm(m,BDY(t));
5016: else BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank);
5017: } else if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
5018: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
5019: }
5020: if ( r0 ) NEXT(r) = 0;
5021: if ( !m && nd_nalg )
1.1 noro 5022: r0 = postprocess_algcoef(av,alist,r0);
1.65 noro 5023: MKLIST(*rp,r0);
5024: if ( nd_gentrace ) {
1.1 noro 5025: if ( f4 ) {
1.6 noro 5026: STOZ(16,bpe);
5027: STOZ(nd_last_nonzero,last_nonzero);
1.15 noro 5028: tr = mknode(6,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe,last_nonzero,hvect); MKLIST(*rp,tr);
1.1 noro 5029: } else {
5030: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
5031: tl3 = reverse_node(tl3);
5032: /* tl2 = [[i,[[*,j,*,*],...]],...] */
5033: for ( t = tl2; t; t = NEXT(t) ) {
5034: /* s = [i,[*,j,*,*],...] */
5035: s = BDY((LIST)BDY(t));
1.6 noro 5036: j = perm[ZTOS((Q)ARG0(s))]; STOZ(j,jq); ARG0(s) = (pointer)jq;
1.1 noro 5037: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.6 noro 5038: j = perm[ZTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOZ(j,jq);
1.1 noro 5039: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
5040: }
5041: }
5042: for ( j = length(x)-1, t = 0; j >= 0; j-- ) {
1.6 noro 5043: STOZ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.1 noro 5044: }
5045: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
5046: MKLIST(l5,tl4);
1.6 noro 5047: STOZ(nd_bpe,bpe);
1.15 noro 5048: tr = mknode(9,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe,hvect); MKLIST(*rp,tr);
1.1 noro 5049: }
5050: }
5051: #if 0
5052: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
5053: #endif
5054: }
5055:
1.28 noro 5056: NODE nd_sba_f4(int m,int **indp);
5057:
5058: void nd_sba(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp)
1.24 noro 5059: {
1.65 noro 5060: VL tv,fv,vv;
5061: NODE fd,fd0,r,r0,t,x,nd,nd1,syz;
1.24 noro 5062: int e,max,nvar,i;
5063: NDV b;
1.65 noro 5064: int ishomo,wmax,len;
1.24 noro 5065: NMV a;
1.65 noro 5066: P zp;
1.24 noro 5067: Q dmy;
5068: struct order_spec *ord1;
5069: int *perm;
5070: EPOS oepos;
1.65 noro 5071: int obpe,oadv,ompos;
1.51 noro 5072: struct oEGT eg0,eg1,egconv,egintred;
1.55 noro 5073: LIST l1,redind;
5074: Z z;
1.24 noro 5075:
5076: nd_module = 0;
5077: nd_demand = 0;
1.35 noro 5078: Nsamesig = 0;
1.24 noro 5079: if ( DP_Multiple )
5080: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
5081: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5082: parse_nd_option(vv,current_option);
1.24 noro 5083: if ( m && nd_vc )
5084: error("nd_sba : computation over Fp(X) is unsupported. Use dp_gr_mod_main().");
5085: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5086: switch ( ord->id ) {
5087: case 1:
5088: if ( ord->nv != nvar )
5089: error("nd_sba : invalid order specification");
1.65 noro 5090: break;
5091: default:
5092: break;
1.24 noro 5093: }
5094: nd_nalg = 0;
5095: nd_init_ord(ord);
5096: // for SIG comparison
5097: initd(ord);
5098: for ( t = BDY(f), max = 1; t; t = NEXT(t) ) {
5099: for ( tv = vv; tv; tv = NEXT(tv) ) {
1.43 noro 5100: if ( OID(BDY(t)) == O_DP ) {
5101: e = dp_getdeg((DP)BDY(t));
5102: max = MAX(e,max);
5103: } else {
5104: e = getdeg(tv->v,(P)BDY(t));
5105: max = MAX(e,max);
5106: }
1.24 noro 5107: }
5108: }
1.25 noro 5109: nd_setup_parameters(nvar,max);
1.24 noro 5110: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
5111: ishomo = 1;
5112: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1.43 noro 5113: if ( OID(BDY(t)) == O_DP ) {
5114: DP zdp;
5115:
5116: if ( !m ) dp_ptozp((DP)BDY(t),&zdp);
5117: else zdp = (DP)BDY(t);
5118: b = (pointer)dptondv(m,zdp);
5119: } else {
5120: if ( !m ) ptozp((P)BDY(t),1,&dmy,&zp);
5121: else zp = (P)BDY(t);
5122: b = (pointer)ptondv(CO,vv,zp);
5123: }
1.24 noro 5124: if ( ishomo )
5125: ishomo = ishomo && ndv_ishomo(b);
5126: if ( m ) ndv_mod(m,b);
5127: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
5128: }
5129: if ( fd0 ) NEXT(fd) = 0;
5130:
5131: if ( !ishomo && homo ) {
5132: for ( t = fd0, wmax = max; t; t = NEXT(t) ) {
5133: b = (NDV)BDY(t); len = LEN(b);
5134: for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) )
1.65 noro 5135: wmax = MAX((int)TD(DL(a)),wmax);
1.24 noro 5136: }
5137: homogenize_order(ord,nvar,&ord1);
5138: nd_init_ord(ord1);
1.42 noro 5139: // for SIG comparison
5140: initd(ord1);
1.24 noro 5141: nd_setup_parameters(nvar+1,nd_nzlist?0:wmax);
5142: for ( t = fd0; t; t = NEXT(t) )
5143: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
5144: }
5145:
1.39 noro 5146: ndv_setup(m,0,fd0,nd_sba_dontsort,0,1);
1.55 noro 5147: if ( nd_gentrace ) {
5148: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
5149: }
1.44 noro 5150: x = f4 ? nd_sba_f4(m,&perm) : nd_sba_buch(m,ishomo || homo,&perm,&syz);
1.24 noro 5151: if ( !x ) {
5152: *rp = 0; return;
5153: }
5154: if ( !ishomo && homo ) {
5155: /* dehomogenization */
5156: for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5157: nd_init_ord(ord);
1.42 noro 5158: // for SIG comparison
5159: initd(ord);
1.24 noro 5160: nd_setup_parameters(nvar,0);
5161: }
5162: nd_demand = 0;
1.51 noro 5163: get_eg(&eg0);
1.24 noro 5164: x = ndv_reducebase(x,perm);
1.55 noro 5165: for ( nd = 0, i = length(x)-1; i >= 0; i-- ) {
5166: STOZ(perm[i],z); MKNODE(nd1,z,nd); nd = nd1;
5167: }
5168: MKLIST(redind,nd);
1.24 noro 5169: x = ndv_reduceall(m,x);
1.51 noro 5170: get_eg(&eg1); init_eg(&egintred); add_eg(&egintred,&eg0,&eg1);
1.24 noro 5171: nd_setup_parameters(nd_nvar,0);
1.29 noro 5172: get_eg(&eg0);
1.24 noro 5173: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5174: NEXTNODE(r0,r);
5175: if ( retdp ) BDY(r) = ndvtodp(m,BDY(t));
1.34 noro 5176: else BDY(r) = ndvtop(m,CO,vv,BDY(t));
1.24 noro 5177: }
5178: if ( r0 ) NEXT(r) = 0;
1.44 noro 5179: if ( nd_sba_syz ) {
5180: LIST gb,hsyz;
5181:
5182: MKLIST(gb,r0);
5183: MKLIST(hsyz,syz);
5184: nd = mknode(2,gb,hsyz);
5185: MKLIST(*rp,nd);
1.55 noro 5186: } else if ( nd_gentrace ) {
5187: LIST gb,trace;
5188:
5189: MKLIST(trace,nd_alltracelist);
5190: MKLIST(gb,r0);
5191: nd = mknode(3,gb,redind,trace);
5192: MKLIST(*rp,nd);
1.44 noro 5193: } else
5194: MKLIST(*rp,r0);
1.29 noro 5195: get_eg(&eg1); init_eg(&egconv); add_eg(&egconv,&eg0,&eg1);
1.51 noro 5196: print_eg("intred",&egintred); fprintf(asir_out,"\n");
1.29 noro 5197: print_eg("conv",&egconv); fprintf(asir_out,"\n");
1.24 noro 5198: }
5199:
1.1 noro 5200: void nd_gr_postproc(LIST f,LIST v,int m,struct order_spec *ord,int do_check,LIST *rp)
5201: {
1.65 noro 5202: VL tv,fv,vv,av;
5203: NODE fd,fd0,r,r0,t,x,alist;
5204: int e,max,nvar,i,nalg;
1.1 noro 5205: NDV b;
1.65 noro 5206: int ishomo;
5207: P zp;
1.1 noro 5208: Q dmy;
1.65 noro 5209: LIST f1;
1.1 noro 5210: struct order_spec *ord1;
5211: int *perm;
5212:
5213: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 5214: parse_nd_option(vv,current_option);
1.1 noro 5215: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5216: switch ( ord->id ) {
5217: case 1:
5218: if ( ord->nv != nvar )
5219: error("nd_check : invalid order specification");
5220: break;
5221: default:
5222: break;
5223: }
5224: nd_nalg = 0;
5225: av = 0;
5226: if ( !m ) {
5227: get_algtree((Obj)f,&av);
5228: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
5229: nd_ntrans = nvar;
5230: nd_nalg = nalg;
5231: /* #i -> t#i */
5232: if ( nalg ) {
5233: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
5234: ord = ord1;
5235: f = f1;
5236: }
5237: nvar += nalg;
5238: }
5239: nd_init_ord(ord);
5240: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
5241: for ( tv = vv; tv; tv = NEXT(tv) ) {
5242: e = getdeg(tv->v,(P)BDY(t));
5243: max = MAX(e,max);
5244: }
5245: nd_setup_parameters(nvar,max);
5246: ishomo = 1;
5247: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
5248: ptozp((P)BDY(t),1,&dmy,&zp);
5249: b = (pointer)ptondv(CO,vv,zp);
5250: if ( ishomo )
5251: ishomo = ishomo && ndv_ishomo(b);
5252: if ( m ) ndv_mod(m,b);
5253: if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; }
5254: }
5255: if ( fd0 ) NEXT(fd) = 0;
1.24 noro 5256: ndv_setup(m,0,fd0,0,1,0);
1.1 noro 5257: for ( x = 0, i = 0; i < nd_psn; i++ )
5258: x = update_base(x,i);
5259: if ( do_check ) {
5260: x = nd_gb(m,ishomo,1,0,&perm);
5261: if ( !x ) {
5262: *rp = 0;
5263: return;
5264: }
5265: } else {
5266: #if 0
5267: /* bug ? */
5268: for ( t = x; t; t = NEXT(t) )
5269: BDY(t) = (pointer)nd_ps[(long)BDY(t)];
5270: #else
5271: conv_ilist(0,0,x,&perm);
5272: #endif
5273: }
5274: x = ndv_reducebase(x,perm);
5275: x = ndv_reduceall(m,x);
5276: for ( r0 = 0, t = x; t; t = NEXT(t) ) {
5277: NEXTNODE(r0,r);
5278: BDY(r) = ndvtop(m,CO,vv,BDY(t));
5279: }
5280: if ( r0 ) NEXT(r) = 0;
5281: if ( !m && nd_nalg )
5282: r0 = postprocess_algcoef(av,alist,r0);
5283: MKLIST(*rp,r0);
5284: }
5285:
5286: NDV recompute_trace(NODE trace,NDV *p,int m);
5287: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp);
5288:
5289: NDV recompute_trace(NODE ti,NDV *p,int mod)
5290: {
5291: int c,c1,c2,i;
5292: NM mul,m,tail;
5293: ND d,r,rm;
5294: NODE sj;
5295: NDV red;
5296: Obj mj;
5297:
5298: mul = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT));
5299: CM(mul) = 1;
5300: tail = 0;
5301: for ( i = 0, d = r = 0; ti; ti = NEXT(ti), i++ ) {
5302: sj = BDY((LIST)BDY(ti));
5303: if ( ARG0(sj) ) {
1.6 noro 5304: red = p[ZTOS((Q)ARG1(sj))];
1.1 noro 5305: mj = (Obj)ARG2(sj);
5306: if ( OID(mj) != O_DP ) ndl_zero(DL(mul));
5307: else dltondl(nd_nvar,BDY((DP)mj)->dl,DL(mul));
5308: rm = ndv_mul_nm(mod,mul,red);
5309: if ( !r ) r = rm;
5310: else {
5311: for ( m = BDY(r); m && !ndl_equal(m->dl,BDY(rm)->dl); m = NEXT(m), LEN(r)-- ) {
5312: if ( d ) {
5313: NEXT(tail) = m; tail = m; LEN(d)++;
5314: } else {
5315: MKND(nd_nvar,m,1,d); tail = BDY(d);
5316: }
5317: }
5318: if ( !m ) return 0; /* failure */
5319: else {
5320: BDY(r) = m;
5321: if ( mod > 0 || mod == -1 ) {
5322: c1 = invm(HCM(rm),mod); c2 = mod-HCM(r);
5323: DMAR(c1,c2,0,mod,c);
5324: nd_mul_c(mod,rm,c);
5325: } else {
5326: Z t,u;
5327:
5328: chsgnlf(HCZ(r),&t);
5329: divlf(t,HCZ(rm),&u);
5330: nd_mul_c_lf(rm,u);
5331: }
5332: r = nd_add(mod,r,rm);
5333: }
5334: }
5335: }
5336: }
5337: if ( tail ) NEXT(tail) = 0;
5338: d = nd_add(mod,d,r);
5339: nd_mul_c(mod,d,invm(HCM(d),mod));
5340: return ndtondv(mod,d);
5341: }
5342:
5343: void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp)
5344: {
1.65 noro 5345: VL tv,fv,vv;
5346: NODE r,r0,t;
5347: int nvar,i;
5348: NDV b;
5349: P zp;
5350: Q dmy;
1.1 noro 5351: NODE permtrace,intred,ind,perm,trace,ti;
5352: int len,n,j;
5353: NDV *db,*pb;
5354:
1.65 noro 5355: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
5356: parse_nd_option(vv,current_option);
5357: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5358: switch ( ord->id ) {
5359: case 1:
5360: if ( ord->nv != nvar )
5361: error("nd_check : invalid order specification");
5362: break;
5363: default:
5364: break;
5365: }
5366: nd_init_ord(ord);
5367: nd_bpe = (int)ZTOS((Q)ARG7(BDY(tlist)));
5368: nd_setup_parameters(nvar,0);
1.1 noro 5369:
5370: len = length(BDY(f));
5371: db = (NDV *)MALLOC(len*sizeof(NDV *));
5372: for ( i = 0, t = BDY(f); t; i++, t = NEXT(t) ) {
1.65 noro 5373: ptozp((P)BDY(t),1,&dmy,&zp);
5374: b = ptondv(CO,vv,zp);
5375: ndv_mod(m,b);
1.1 noro 5376: ndv_mul_c(m,b,invm(HCM(b),m));
5377: db[i] = b;
1.65 noro 5378: }
1.1 noro 5379:
5380: permtrace = BDY((LIST)ARG2(BDY(tlist)));
5381: intred = BDY((LIST)ARG3(BDY(tlist)));
5382: ind = BDY((LIST)ARG4(BDY(tlist)));
5383: perm = BDY((LIST)ARG0(permtrace));
5384: trace = NEXT(permtrace);
5385:
5386: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.65 noro 5387: j = (int)ZTOS((Q)ARG0(BDY((LIST)BDY(t))));
1.1 noro 5388: if ( j > i ) i = j;
5389: }
5390: n = i+1;
5391: pb = (NDV *)MALLOC(n*sizeof(NDV *));
5392: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
5393: ti = BDY((LIST)BDY(t));
1.6 noro 5394: pb[ZTOS((Q)ARG0(ti))] = db[ZTOS((Q)ARG1(ti))];
1.1 noro 5395: }
5396: for ( t = trace; t; t = NEXT(t) ) {
5397: ti = BDY((LIST)BDY(t));
1.6 noro 5398: pb[ZTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
5399: if ( !pb[ZTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
1.1 noro 5400: if ( DP_Print ) {
5401: fprintf(asir_out,"."); fflush(asir_out);
5402: }
5403: }
5404: for ( t = intred; t; t = NEXT(t) ) {
5405: ti = BDY((LIST)BDY(t));
1.6 noro 5406: pb[ZTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m);
5407: if ( !pb[ZTOS((Q)ARG0(ti))] ) { *rp = 0; return; }
1.1 noro 5408: if ( DP_Print ) {
1.65 noro 5409: fprintf(asir_out,"*"); fflush(asir_out);
5410: }
1.1 noro 5411: }
1.65 noro 5412: for ( r0 = 0, t = ind; t; t = NEXT(t) ) {
5413: NEXTNODE(r0,r);
1.6 noro 5414: b = pb[ZTOS((Q)BDY(t))];
1.65 noro 5415: ndv_mul_c(m,b,invm(HCM(b),m));
1.1 noro 5416: #if 0
1.65 noro 5417: BDY(r) = ndvtop(m,CO,vv,pb[ZTOS((Q)BDY(t))]);
1.1 noro 5418: #else
1.65 noro 5419: BDY(r) = ndvtodp(m,pb[ZTOS((Q)BDY(t))]);
1.1 noro 5420: #endif
1.65 noro 5421: }
5422: if ( r0 ) NEXT(r) = 0;
5423: MKLIST(*rp,r0);
5424: if ( DP_Print ) fprintf(asir_out,"\n");
1.1 noro 5425: }
5426:
1.16 noro 5427: 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 5428: {
1.65 noro 5429: VL tv,fv,vv,av;
5430: NODE fd,fd0,in0,in,r,t,s,cand,alist;
1.1 noro 5431: int m,nocheck,nvar,mindex,e,max;
5432: NDV c;
5433: NMV a;
1.65 noro 5434: P zp;
1.1 noro 5435: Q dmy;
5436: EPOS oepos;
5437: int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos;
1.65 noro 5438: LIST f1,zpl;
1.1 noro 5439: struct order_spec *ord1;
1.64 noro 5440: struct oEGT eg_check,eg_gb,eg_intred,eg0,eg1;
1.1 noro 5441: NODE tr,tl1,tl2,tl3,tl4;
5442: LIST l1,l2,l3,l4,l5;
5443: int *perm;
5444: int j,ret;
5445: Z jq,bpe;
1.15 noro 5446: VECT hvect;
1.1 noro 5447:
1.41 noro 5448: NcriB = NcriMF = Ncri2 = 0;
1.1 noro 5449: nd_module = 0;
5450: nd_lf = 0;
1.46 noro 5451: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
5452: parse_nd_option(vv,current_option);
1.1 noro 5453: if ( nd_lf ) {
5454: if ( f4 )
5455: nd_f4_lf_trace(f,v,trace,homo,ord,rp);
5456: else
5457: error("nd_gr_trace is not implemented yet over a large finite field");
5458: return;
5459: }
5460: if ( DP_Multiple )
5461: nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1);
5462:
5463: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
5464: switch ( ord->id ) {
5465: case 1:
5466: if ( ord->nv != nvar )
5467: error("nd_gr_trace : invalid order specification");
5468: break;
5469: default:
5470: break;
5471: }
5472:
5473: get_algtree((Obj)f,&av);
5474: for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ );
5475: nd_ntrans = nvar;
5476: nd_nalg = nalg;
5477: /* #i -> t#i */
5478: if ( nalg ) {
5479: preprocess_algcoef(vv,av,ord,f,&ord1,&f1,&alist);
5480: ord = ord1;
5481: f = f1;
5482: }
5483: nvar += nalg;
5484:
5485: nocheck = 0;
5486: mindex = 0;
5487:
5488: if ( Demand ) nd_demand = 1;
5489: else nd_demand = 0;
5490:
5491: /* setup modulus */
5492: if ( trace < 0 ) {
5493: trace = -trace;
5494: nocheck = 1;
5495: }
5496: m = trace > 1 ? trace : get_lprime(mindex);
5497: nd_init_ord(ord);
5498: mrank = 0;
5499: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
5500: for ( tv = vv; tv; tv = NEXT(tv) ) {
5501: if ( nd_module ) {
1.16 noro 5502: if ( OID(BDY(t)) == O_DPM ) {
5503: e = dpm_getdeg((DPM)BDY(t),&trank);
5504: max = MAX(e,max);
5505: mrank = MAX(mrank,trank);
5506: } else {
1.1 noro 5507: s = BDY((LIST)BDY(t));
5508: trank = length(s);
5509: mrank = MAX(mrank,trank);
5510: for ( ; s; s = NEXT(s) ) {
5511: e = getdeg(tv->v,(P)BDY(s));
5512: max = MAX(e,max);
5513: }
1.16 noro 5514: }
1.1 noro 5515: } else {
1.43 noro 5516: if ( OID(BDY(t)) == O_DP ) {
5517: e = dp_getdeg((DP)BDY(t));
5518: max = MAX(e,max);
5519: } else {
1.1 noro 5520: e = getdeg(tv->v,(P)BDY(t));
5521: max = MAX(e,max);
1.43 noro 5522: }
1.1 noro 5523: }
5524: }
5525: nd_setup_parameters(nvar,max);
5526: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
5527: ishomo = 1;
5528: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
5529: if ( nd_module ) {
1.16 noro 5530: if ( OID(BDY(t)) == O_DPM ) {
5531: Z cont;
5532: DPM zdpm;
5533:
1.17 noro 5534: if ( !nd_gentrace ) dpm_ptozp((DPM)BDY(t),&cont,&zdpm);
1.16 noro 5535: else zdpm = (DPM)BDY(t);
5536: c = (pointer)dpmtondv(m,zdpm);
5537: } else {
5538: if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl);
5539: else zpl = (LIST)BDY(t);
1.1 noro 5540: c = (pointer)pltondv(CO,vv,zpl);
1.16 noro 5541: }
1.1 noro 5542: } else {
1.43 noro 5543: if ( OID(BDY(t)) == O_DP ) {
5544: DP zdp;
5545:
5546: if ( !nd_gentrace ) dp_ptozp((DP)BDY(t),&zdp);
5547: else zdp = (DP)BDY(t);
5548: c = (pointer)dptondv(m,zdp);
5549: } else {
5550: if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp);
5551: else zp = (P)BDY(t);
5552: c = (pointer)ptondv(CO,vv,zp);
5553: }
1.1 noro 5554: }
5555: if ( ishomo )
5556: ishomo = ishomo && ndv_ishomo(c);
5557: if ( c ) {
5558: NEXTNODE(in0,in); BDY(in) = (pointer)c;
5559: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
5560: }
5561: }
5562: if ( in0 ) NEXT(in) = 0;
5563: if ( fd0 ) NEXT(fd) = 0;
5564: if ( !ishomo && homo ) {
5565: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
5566: c = (NDV)BDY(t); len = LEN(c);
5567: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
1.65 noro 5568: wmax = MAX((int)TD(DL(a)),wmax);
1.1 noro 5569: }
5570: homogenize_order(ord,nvar,&ord1);
5571: nd_init_ord(ord1);
5572: nd_setup_parameters(nvar+1,wmax);
5573: for ( t = fd0; t; t = NEXT(t) )
5574: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
5575: }
5576: if ( MaxDeg > 0 ) nocheck = 1;
5577: while ( 1 ) {
1.64 noro 5578: get_eg(&eg0);
5579: tl1 = tl2 = tl3 = tl4 = 0;
1.1 noro 5580: if ( Demand )
5581: nd_demand = 1;
1.24 noro 5582: ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0,0);
1.1 noro 5583: if ( nd_gentrace ) {
5584: MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0);
5585: }
5586: if ( ret )
5587: cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm);
5588: if ( !ret || !cand ) {
5589: /* failure */
5590: if ( trace > 1 ) { *rp = 0; return; }
5591: else m = get_lprime(++mindex);
5592: continue;
5593: }
1.15 noro 5594: if ( nd_gentrace ) {
5595: MKVECT(hvect,nd_psn);
5596: for ( i = 0; i < nd_psn; i++ )
5597: ndltodp(nd_psh[i]->dl,(DP *)&BDY(hvect)[i]);
5598: }
1.1 noro 5599: if ( !ishomo && homo ) {
5600: /* dehomogenization */
5601: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
5602: nd_init_ord(ord);
5603: nd_setup_parameters(nvar,0);
5604: }
1.64 noro 5605: get_eg(&eg1); init_eg(&eg_gb); add_eg(&eg_gb,&eg0,&eg1);
1.1 noro 5606: nd_demand = 0;
5607: cand = ndv_reducebase(cand,perm);
5608: if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; }
1.64 noro 5609: get_eg(&eg0);
1.1 noro 5610: cand = ndv_reduceall(0,cand);
1.64 noro 5611: get_eg(&eg1); init_eg(&eg_intred); add_eg(&eg_intred,&eg0,&eg1);
1.1 noro 5612: cbpe = nd_bpe;
5613: if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; }
5614: get_eg(&eg0);
5615: if ( nocheck )
5616: break;
5617: if ( (ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand)) != 0 ) {
5618: if ( nd_gentrace ) {
5619: tl3 = nd_alltracelist; nd_alltracelist = 0;
5620: } else tl3 = 0;
5621: /* gbcheck : cand is a GB of Id(cand) ? */
1.54 noro 5622: if ( nd_vc || nd_gentrace || nd_gensyz || do_weyl )
1.1 noro 5623: ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0;
5624: else
5625: ret = nd_f4(0,1,0)!=0;
5626: if ( nd_gentrace && nd_gensyz ) {
5627: tl4 = nd_alltracelist; nd_alltracelist = 0;
5628: } else tl4 = 0;
5629: }
5630: if ( ret ) break;
5631: else if ( trace > 1 ) {
5632: /* failure */
5633: *rp = 0; return;
5634: } else {
5635: /* try the next modulus */
5636: m = get_lprime(++mindex);
5637: /* reset the parameters */
5638: if ( !ishomo && homo ) {
5639: nd_init_ord(ord1);
5640: nd_setup_parameters(nvar+1,wmax);
5641: } else {
5642: nd_init_ord(ord);
5643: nd_setup_parameters(nvar,max);
5644: }
5645: }
5646: }
5647: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
5648: if ( DP_Print )
1.64 noro 5649: fprintf(asir_out,"gb=%.3fsec,check=%.3fsec,intred=%.3fsec\n",
5650: eg_gb.exectime,eg_check.exectime,eg_intred.exectime);
1.1 noro 5651: /* dp->p */
5652: nd_bpe = cbpe;
5653: nd_setup_parameters(nd_nvar,0);
5654: for ( r = cand; r; r = NEXT(r) ) {
1.16 noro 5655: if ( nd_module ) {
1.17 noro 5656: if ( retdp ) BDY(r) = ndvtodpm(0,BDY(r));
1.16 noro 5657: else BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank);
1.17 noro 5658: } else if ( retdp ) BDY(r) = ndvtodp(0,BDY(r));
5659: else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r));
1.1 noro 5660: }
5661: if ( nd_nalg )
5662: cand = postprocess_algcoef(av,alist,cand);
5663: MKLIST(*rp,cand);
5664: if ( nd_gentrace ) {
5665: tl1 = reverse_node(tl1); tl2 = reverse_node(tl2);
5666: tl3 = reverse_node(tl3);
5667: /* tl2 = [[i,[[*,j,*,*],...]],...] */
5668: for ( t = tl2; t; t = NEXT(t) ) {
5669: /* s = [i,[*,j,*,*],...] */
5670: s = BDY((LIST)BDY(t));
1.6 noro 5671: j = perm[ZTOS((Q)ARG0(s))]; STOZ(j,jq); ARG0(s) = (pointer)jq;
1.1 noro 5672: for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) {
1.6 noro 5673: j = perm[ZTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOZ(j,jq);
1.1 noro 5674: ARG1(BDY((LIST)BDY(s))) = (pointer)jq;
5675: }
5676: }
5677: for ( j = length(cand)-1, t = 0; j >= 0; j-- ) {
1.6 noro 5678: STOZ(perm[j],jq); MKNODE(s,jq,t); t = s;
1.1 noro 5679: }
5680: MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3);
5681: MKLIST(l5,tl4);
1.6 noro 5682: STOZ(nd_bpe,bpe);
1.15 noro 5683: tr = mknode(9,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe,hvect); MKLIST(*rp,tr);
1.1 noro 5684: }
5685: }
5686:
5687: /* XXX : module element is not considered */
5688:
5689: void dltondl(int n,DL dl,UINT *r)
5690: {
5691: UINT *d;
5692: int i,j,l,s,ord_l;
5693: struct order_pair *op;
5694:
5695: d = (unsigned int *)dl->d;
5696: for ( i = 0; i < nd_wpd; i++ ) r[i] = 0;
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++ ) PUT_EXP(r,s,d[s]);
5703: }
5704: TD(r) = ndl_weight(r);
5705: ndl_weight_mask(r);
5706: } else {
5707: for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]);
5708: TD(r) = ndl_weight(r);
5709: }
5710: }
5711:
5712: DL ndltodl(int n,UINT *ndl)
5713: {
5714: DL dl;
5715: int *d;
5716: int i,j,l,s,ord_l;
5717: struct order_pair *op;
5718:
1.33 noro 5719: NEWDL_NOINIT(dl,n);
1.1 noro 5720: dl->td = TD(ndl);
5721: d = dl->d;
5722: if ( nd_blockmask ) {
5723: l = nd_blockmask->n;
5724: op = nd_blockmask->order_pair;
5725: for ( j = 0, s = 0; j < l; j++ ) {
5726: ord_l = op[j].length;
5727: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
5728: }
5729: } else {
5730: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
5731: }
5732: return dl;
5733: }
5734:
1.24 noro 5735: void _ndltodl(UINT *ndl,DL dl)
5736: {
5737: int *d;
5738: int i,j,l,s,ord_l,n;
5739: struct order_pair *op;
5740:
5741: n = nd_nvar;
5742: dl->td = TD(ndl);
5743: d = dl->d;
5744: if ( nd_blockmask ) {
5745: l = nd_blockmask->n;
5746: op = nd_blockmask->order_pair;
5747: for ( j = 0, s = 0; j < l; j++ ) {
5748: ord_l = op[j].length;
5749: for ( i = 0; i < ord_l; i++, s++ ) d[s] = GET_EXP(ndl,s);
5750: }
5751: } else {
5752: for ( i = 0; i < n; i++ ) d[i] = GET_EXP(ndl,i);
5753: }
5754: }
5755:
1.1 noro 5756: void nmtodp(int mod,NM m,DP *r)
5757: {
5758: DP dp;
5759: MP mr;
5760:
5761: NEWMP(mr);
5762: mr->dl = ndltodl(nd_nvar,DL(m));
5763: mr->c = (Obj)ndctop(mod,m->c);
5764: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
5765: *r = dp;
5766: }
5767:
1.15 noro 5768: void ndltodp(UINT *d,DP *r)
5769: {
5770: DP dp;
5771: MP mr;
5772:
5773: NEWMP(mr);
5774: mr->dl = ndltodl(nd_nvar,d);
5775: mr->c = (Obj)ONE;
5776: NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td;
5777: *r = dp;
5778: }
5779:
1.1 noro 5780: void ndl_print(UINT *dl)
5781: {
5782: int n;
5783: int i,j,l,ord_l,s,s0;
5784: struct order_pair *op;
5785:
5786: n = nd_nvar;
5787: printf("<<");
5788: if ( nd_blockmask ) {
5789: l = nd_blockmask->n;
5790: op = nd_blockmask->order_pair;
5791: for ( j = 0, s = s0 = 0; j < l; j++ ) {
5792: ord_l = op[j].length;
5793: for ( i = 0; i < ord_l; i++, s++ )
5794: printf(s==n-1?"%d":"%d,",GET_EXP(dl,s));
5795: }
5796: } else {
5797: for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i));
5798: }
5799: printf(">>");
5800: if ( nd_module && MPOS(dl) )
5801: printf("*e%d",MPOS(dl));
5802: }
5803:
5804: void nd_print(ND p)
5805: {
5806: NM m;
5807:
5808: if ( !p )
5809: printf("0\n");
5810: else {
5811: for ( m = BDY(p); m; m = NEXT(m) ) {
5812: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
1.28 noro 5813: else printf("+%ld*",CM(m));
1.1 noro 5814: ndl_print(DL(m));
5815: }
5816: printf("\n");
5817: }
5818: }
5819:
5820: void nd_print_q(ND p)
5821: {
5822: NM m;
5823:
5824: if ( !p )
5825: printf("0\n");
5826: else {
5827: for ( m = BDY(p); m; m = NEXT(m) ) {
5828: printf("+");
1.6 noro 5829: printexpr(CO,(Obj)CZ(m));
1.1 noro 5830: printf("*");
5831: ndl_print(DL(m));
5832: }
5833: printf("\n");
5834: }
5835: }
5836:
5837: void ndp_print(ND_pairs d)
5838: {
5839: ND_pairs t;
5840:
5841: for ( t = d; t; t = NEXT(t) ) printf("%d,%d ",t->i1,t->i2);
5842: printf("\n");
5843: }
5844:
5845: void nd_removecont(int mod,ND p)
5846: {
5847: int i,n;
5848: Z *w;
5849: NM m;
5850: struct oVECT v;
5851:
5852: if ( mod == -1 ) nd_mul_c(mod,p,_invsf(HCM(p)));
5853: else if ( mod == -2 ) {
5854: Z inv;
5855: divlf(ONE,HCZ(p),&inv);
5856: nd_mul_c_lf(p,inv);
5857: } else if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod));
5858: else {
5859: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
5860: w = (Z *)MALLOC(n*sizeof(Q));
5861: v.len = n;
5862: v.body = (pointer *)w;
1.6 noro 5863: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5864: removecont_array((P *)w,n,1);
1.6 noro 5865: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5866: }
5867: }
5868:
5869: void nd_removecont2(ND p1,ND p2)
5870: {
5871: int i,n1,n2,n;
5872: Z *w;
5873: NM m;
5874: struct oVECT v;
5875:
5876: n1 = nd_length(p1);
5877: n2 = nd_length(p2);
5878: n = n1+n2;
5879: w = (Z *)MALLOC(n*sizeof(Q));
5880: v.len = n;
5881: v.body = (pointer *)w;
5882: i = 0;
5883: if ( p1 )
1.6 noro 5884: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5885: if ( p2 )
1.6 noro 5886: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CZ(m);
1.1 noro 5887: removecont_array((P *)w,n,1);
5888: i = 0;
5889: if ( p1 )
1.6 noro 5890: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5891: if ( p2 )
1.6 noro 5892: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CZ(m) = w[i];
1.1 noro 5893: }
5894:
5895: void ndv_removecont(int mod,NDV p)
5896: {
5897: int i,len,all_p;
5898: Z *c;
5899: P *w;
1.65 noro 5900: Z dvr;
1.1 noro 5901: P g,cont,tp;
5902: NMV m;
5903:
5904: if ( mod == -1 )
5905: ndv_mul_c(mod,p,_invsf(HCM(p)));
5906: else if ( mod == -2 ) {
5907: Z inv;
5908: divlf(ONE,HCZ(p),&inv);
5909: ndv_mul_c_lf(p,inv);
5910: } else if ( mod )
5911: ndv_mul_c(mod,p,invm(HCM(p),mod));
5912: else {
5913: len = p->len;
5914: w = (P *)MALLOC(len*sizeof(P));
5915: c = (Z *)MALLOC(len*sizeof(Q));
5916: for ( m = BDY(p), all_p = 1, i = 0; i < len; NMV_ADV(m), i++ ) {
5917: ptozp(CP(m),1,(Q *)&c[i],&w[i]);
5918: all_p = all_p && !NUM(w[i]);
5919: }
5920: if ( all_p ) {
5921: qltozl((Q *)c,len,&dvr); nd_heu_nezgcdnpz(nd_vc,w,len,1,&g);
5922: mulp(nd_vc,(P)dvr,g,&cont);
5923: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
5924: divsp(nd_vc,CP(m),cont,&tp); CP(m) = tp;
5925: }
5926: } else {
5927: sortbynm((Q *)c,len);
5928: qltozl((Q *)c,len,&dvr);
5929: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
5930: divsp(nd_vc,CP(m),(P)dvr,&tp); CP(m) = tp;
5931: }
5932: }
5933: }
5934: }
5935:
5936: /* koko */
5937:
5938: void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos,int ompos)
5939: {
5940: int len,i,max;
5941: NMV m,mr0,mr,t;
5942:
5943: len = p->len;
1.14 noro 5944: for ( m = BDY(p), i = 0, max = 0; i < len; NMV_OADV(m), i++ )
1.65 noro 5945: max = MAX(max,(int)TD(DL(m)));
1.1 noro 5946: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
5947: m = (NMV)((char *)mr0+(len-1)*oadv);
5948: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
5949: t = (NMV)MALLOC(nmv_adv);
5950: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
5951: ndl_homogenize(DL(m),DL(t),obpe,oepos,ompos,max);
1.6 noro 5952: CZ(mr) = CZ(m);
1.1 noro 5953: ndl_copy(DL(t),DL(mr));
5954: }
5955: NV(p)++;
5956: BDY(p) = mr0;
5957: }
5958:
5959: void ndv_dehomogenize(NDV p,struct order_spec *ord)
5960: {
5961: int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos;
5962: int pos;
5963: NMV m,r;
5964:
5965: len = p->len;
5966: newnvar = nd_nvar-1;
5967: newexporigin = nd_get_exporigin(ord);
5968: if ( nd_module ) newmpos = newexporigin-1;
5969: newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin;
5970: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ )
5971: ndl_dehomogenize(DL(m));
5972: if ( newwpd != nd_wpd ) {
5973: newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT));
5974: for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) {
1.6 noro 5975: CZ(r) = CZ(m);
1.1 noro 5976: if ( nd_module ) pos = MPOS(DL(m));
5977: for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j];
5978: adj = nd_exporigin-newexporigin;
5979: for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj];
5980: if ( nd_module ) {
5981: DL(r)[newmpos] = pos;
5982: }
5983: }
5984: }
5985: NV(p)--;
5986: }
5987:
5988: void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr)
5989: {
5990: int i;
5991: P *tpl,*tpl1;
5992: NODE l;
5993: P h,gcd,t;
5994:
5995: tpl = (P *)MALLOC(m*sizeof(P));
5996: tpl1 = (P *)MALLOC(m*sizeof(P));
5997: bcopy(pl,tpl,m*sizeof(P));
5998: gcd = (P)ONE;
5999: for ( l = nd_hcf; l; l = NEXT(l) ) {
6000: h = (P)BDY(l);
6001: while ( 1 ) {
6002: for ( i = 0; i < m; i++ )
6003: if ( !divtpz(vl,tpl[i],h,&tpl1[i]) )
6004: break;
6005: if ( i == m ) {
6006: bcopy(tpl1,tpl,m*sizeof(P));
6007: mulp(vl,gcd,h,&t); gcd = t;
6008: } else
6009: break;
6010: }
6011: }
6012: if ( DP_Print > 2 ){fprintf(asir_out,"[%d]",nmonop(gcd)); fflush(asir_out);}
6013: if ( full ) {
6014: heu_nezgcdnpz(vl,tpl,m,&t);
6015: mulp(vl,gcd,t,pr);
6016: } else
6017: *pr = gcd;
6018: }
6019:
6020: void removecont_array(P *p,int n,int full)
6021: {
1.65 noro 6022: int all_q,i;
1.1 noro 6023: Z *c;
6024: P *w;
6025: P t,s;
6026:
6027: for ( all_q = 1, i = 0; i < n; i++ )
6028: all_q = all_q && NUM(p[i]);
6029: if ( all_q ) {
6030: removecont_array_q((Z *)p,n);
6031: } else {
6032: c = (Z *)MALLOC(n*sizeof(Z));
6033: w = (P *)MALLOC(n*sizeof(P));
6034: for ( i = 0; i < n; i++ ) {
6035: ptozp(p[i],1,(Q *)&c[i],&w[i]);
6036: }
6037: removecont_array_q(c,n);
6038: nd_heu_nezgcdnpz(nd_vc,w,n,full,&t);
6039: for ( i = 0; i < n; i++ ) {
6040: divsp(nd_vc,w[i],t,&s); mulp(nd_vc,s,(P)c[i],&p[i]);
6041: }
6042: }
6043: }
6044:
6045: /* c is an int array */
6046:
6047: void removecont_array_q(Z *c,int n)
6048: {
6049: struct oVECT v;
6050: Z d0,d1,a,u,u1,gcd;
1.65 noro 6051: int i;
1.1 noro 6052: Z *q,*r;
6053:
6054: q = (Z *)MALLOC(n*sizeof(Z));
6055: r = (Z *)MALLOC(n*sizeof(Z));
6056: v.id = O_VECT; v.len = n; v.body = (pointer *)c;
6057: gcdvz_estimate(&v,&d0);
6058: for ( i = 0; i < n; i++ ) {
6059: divqrz(c[i],d0,&q[i],&r[i]);
6060: }
6061: for ( i = 0; i < n; i++ ) if ( r[i] ) break;
6062: if ( i < n ) {
6063: v.id = O_VECT; v.len = n; v.body = (pointer *)r;
6064: gcdvz(&v,&d1);
6065: gcdz(d0,d1,&gcd);
1.6 noro 6066: /* exact division */
6067: divsz(d0,gcd,&a);
1.1 noro 6068: for ( i = 0; i < n; i++ ) {
6069: mulz(a,q[i],&u);
6070: if ( r[i] ) {
1.6 noro 6071: /* exact division */
6072: divsz(r[i],gcd,&u1);
1.1 noro 6073: addz(u,u1,&q[i]);
6074: } else
6075: q[i] = u;
6076: }
6077: }
6078: for ( i = 0; i < n; i++ ) c[i] = q[i];
6079: }
6080:
1.4 noro 6081: void gcdv_mpz_estimate(mpz_t d0,mpz_t *c,int n);
6082:
6083: void mpz_removecont_array(mpz_t *c,int n)
6084: {
6085: mpz_t d0,a,u,u1,gcd;
6086: int i,j;
1.13 noro 6087: static mpz_t *q,*r;
6088: static int c_len = 0;
1.4 noro 6089:
6090: for ( i = 0; i < n; i++ )
6091: if ( mpz_sgn(c[i]) ) break;
6092: if ( i == n ) return;
6093: gcdv_mpz_estimate(d0,c,n);
1.13 noro 6094: if ( n > c_len ) {
6095: q = (mpz_t *)MALLOC(n*sizeof(mpz_t));
6096: r = (mpz_t *)MALLOC(n*sizeof(mpz_t));
6097: c_len = n;
6098: }
1.4 noro 6099: for ( i = 0; i < n; i++ ) {
6100: mpz_init(q[i]); mpz_init(r[i]);
6101: mpz_fdiv_qr(q[i],r[i],c[i],d0);
6102: }
6103: for ( i = 0; i < n; i++ )
6104: if ( mpz_sgn(r[i]) ) break;
6105: mpz_init(gcd); mpz_init(a); mpz_init(u); mpz_init(u1);
6106: if ( i < n ) {
6107: mpz_gcd(gcd,d0,r[i]);
6108: for ( j = i+1; j < n; j++ ) mpz_gcd(gcd,gcd,r[j]);
6109: mpz_div(a,d0,gcd);
6110: for ( i = 0; i < n; i++ ) {
6111: mpz_mul(u,a,q[i]);
6112: if ( mpz_sgn(r[i]) ) {
6113: mpz_div(u1,r[i],gcd);
6114: mpz_add(q[i],u,u1);
6115: } else
6116: mpz_set(q[i],u);
6117: }
6118: }
6119: for ( i = 0; i < n; i++ )
6120: mpz_set(c[i],q[i]);
6121: }
6122:
1.1 noro 6123: void nd_mul_c(int mod,ND p,int mul)
6124: {
6125: NM m;
6126: int c,c1;
6127:
6128: if ( !p ) return;
6129: if ( mul == 1 ) return;
6130: if ( mod == -1 )
6131: for ( m = BDY(p); m; m = NEXT(m) )
6132: CM(m) = _mulsf(CM(m),mul);
6133: else
6134: for ( m = BDY(p); m; m = NEXT(m) ) {
6135: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
6136: }
6137: }
6138:
6139: void nd_mul_c_lf(ND p,Z mul)
6140: {
6141: NM m;
6142: Z c;
6143:
6144: if ( !p ) return;
6145: if ( UNIZ(mul) ) return;
6146: for ( m = BDY(p); m; m = NEXT(m) ) {
6147: mullf(CZ(m),mul,&c); CZ(m) = c;
6148: }
6149: }
6150:
6151: void nd_mul_c_q(ND p,P mul)
6152: {
6153: NM m;
6154: P c;
6155:
6156: if ( !p ) return;
6157: if ( UNIQ(mul) ) return;
6158: for ( m = BDY(p); m; m = NEXT(m) ) {
6159: mulp(nd_vc,CP(m),mul,&c); CP(m) = c;
6160: }
6161: }
6162:
6163: void nd_mul_c_p(VL vl,ND p,P mul)
6164: {
6165: NM m;
6166: P c;
6167:
6168: if ( !p ) return;
6169: for ( m = BDY(p); m; m = NEXT(m) ) {
6170: mulp(vl,CP(m),mul,&c); CP(m) = c;
6171: }
6172: }
6173:
6174: void nd_free(ND p)
6175: {
6176: NM t,s;
6177:
6178: if ( !p ) return;
6179: t = BDY(p);
6180: while ( t ) {
6181: s = NEXT(t);
6182: FREENM(t);
6183: t = s;
6184: }
6185: FREEND(p);
6186: }
6187:
6188: void ndv_free(NDV p)
6189: {
6190: GCFREE(BDY(p));
6191: }
6192:
6193: void nd_append_red(UINT *d,int i)
6194: {
1.65 noro 6195: RHist m;
1.1 noro 6196: int h;
6197:
6198: NEWRHist(m);
6199: h = ndl_hash_value(d);
6200: m->index = i;
6201: ndl_copy(d,DL(m));
6202: NEXT(m) = nd_red[h];
6203: nd_red[h] = m;
6204: }
6205:
6206: UINT *ndv_compute_bound(NDV p)
6207: {
6208: UINT *d1,*d2,*t;
6209: UINT u;
6210: int i,j,k,l,len,ind;
6211: NMV m;
6212:
6213: if ( !p )
6214: return 0;
6215: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6216: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6217: len = LEN(p);
6218: m = BDY(p); ndl_copy(DL(m),d1); NMV_ADV(m);
6219: for ( i = 1; i < len; i++, NMV_ADV(m) ) {
6220: ndl_max(DL(m),d1,d2);
6221: t = d1; d1 = d2; d2 = t;
6222: }
6223: l = nd_nvar+31;
6224: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
6225: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
6226: u = d1[i];
6227: k = (nd_epw-1)*nd_bpe;
6228: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
6229: t[ind] = (u>>k)&nd_mask0;
6230: }
6231: for ( ; ind < l; ind++ ) t[ind] = 0;
6232: return t;
6233: }
6234:
6235: UINT *nd_compute_bound(ND p)
6236: {
6237: UINT *d1,*d2,*t;
6238: UINT u;
1.65 noro 6239: int i,j,k,l,ind;
1.1 noro 6240: NM m;
6241:
6242: if ( !p )
6243: return 0;
6244: d1 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6245: d2 = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
6246: m = BDY(p); ndl_copy(DL(m),d1); m = NEXT(m);
6247: for ( m = NEXT(m); m; m = NEXT(m) ) {
6248: ndl_lcm(DL(m),d1,d2);
6249: t = d1; d1 = d2; d2 = t;
6250: }
6251: l = nd_nvar+31;
6252: t = (UINT *)MALLOC_ATOMIC(l*sizeof(UINT));
6253: for ( i = nd_exporigin, ind = 0; i < nd_wpd; i++ ) {
6254: u = d1[i];
6255: k = (nd_epw-1)*nd_bpe;
6256: for ( j = 0; j < nd_epw; j++, k -= nd_bpe, ind++ )
6257: t[ind] = (u>>k)&nd_mask0;
6258: }
6259: for ( ; ind < l; ind++ ) t[ind] = 0;
6260: return t;
6261: }
6262:
6263: /* if nd_module == 1 then d[nd_exporigin-1] indicates the position */
6264: /* of a term. In this case we need additional 1 word. */
6265:
6266: int nd_get_exporigin(struct order_spec *ord)
6267: {
6268: switch ( ord->id ) {
1.21 noro 6269: case 0: case 2: case 256: case 258: case 300:
1.1 noro 6270: return 1+nd_module;
6271: case 1: case 257:
6272: /* block order */
6273: /* poly ring d[0]:weight d[1]:w0,...,d[nd_exporigin-1]:w(n-1) */
6274: /* module d[0]:weight d[1]:w0,...,d[nd_exporigin-2]:w(n-1) */
6275: return ord->ord.block.length+1+nd_module;
6276: case 3: case 259:
6277: #if 0
6278: error("nd_get_exporigin : composite order is not supported yet.");
6279: #else
6280: return 1+nd_module;
6281: #endif
6282: default:
6283: error("nd_get_exporigin : ivalid argument.");
6284: return 0;
6285: }
6286: }
6287:
6288: void nd_setup_parameters(int nvar,int max) {
1.65 noro 6289: int i,j,elen,wpd;
1.45 noro 6290: extern int CNVars;
1.1 noro 6291:
6292: nd_nvar = nvar;
1.45 noro 6293: CNVars = nvar;
1.1 noro 6294: if ( max ) {
6295: /* XXX */
6296: if ( do_weyl ) nd_bpe = 32;
6297: else if ( max < 2 ) nd_bpe = 1;
6298: else if ( max < 4 ) nd_bpe = 2;
6299: else if ( max < 8 ) nd_bpe = 3;
6300: else if ( max < 16 ) nd_bpe = 4;
6301: else if ( max < 32 ) nd_bpe = 5;
6302: else if ( max < 64 ) nd_bpe = 6;
6303: else if ( max < 256 ) nd_bpe = 8;
6304: else if ( max < 1024 ) nd_bpe = 10;
6305: else if ( max < 65536 ) nd_bpe = 16;
6306: else nd_bpe = 32;
6307: }
6308: if ( !do_weyl && weight_check && (current_dl_weight_vector || nd_matrix) ) {
6309: UINT t;
1.65 noro 6310: int st;
1.1 noro 6311: int *v;
6312: /* t = max(weights) */
6313: t = 0;
6314: if ( current_dl_weight_vector )
6315: for ( i = 0, t = 0; i < nd_nvar; i++ ) {
6316: if ( (st=current_dl_weight_vector[i]) < 0 ) st = -st;
1.65 noro 6317: if ( t < (UINT)st ) t = st;
1.1 noro 6318: }
6319: if ( nd_matrix )
6320: for ( i = 0; i < nd_matrix_len; i++ )
6321: for ( j = 0, v = nd_matrix[i]; j < nd_nvar; j++ ) {
6322: if ( (st=v[j]) < 0 ) st = -st;
1.65 noro 6323: if ( t < (UINT)st ) t = st;
1.1 noro 6324: }
6325: /* i = bitsize of t */
6326: for ( i = 0; t; t >>=1, i++ );
6327: /* i += bitsize of nd_nvar */
6328: for ( t = nd_nvar; t; t >>=1, i++);
6329: /* nd_bpe+i = bitsize of max(weights)*max(exp)*nd_nvar */
6330: if ( (nd_bpe+i) >= 31 )
6331: error("nd_setup_parameters : too large weight");
6332: }
6333: nd_epw = (sizeof(UINT)*8)/nd_bpe;
6334: elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0);
6335: nd_exporigin = nd_get_exporigin(nd_ord);
6336: wpd = nd_exporigin+elen;
6337: if ( nd_module )
6338: nd_mpos = nd_exporigin-1;
6339: else
6340: nd_mpos = -1;
6341: if ( wpd != nd_wpd ) {
6342: nd_free_private_storage();
6343: nd_wpd = wpd;
6344: }
6345: if ( nd_bpe < 32 ) {
6346: nd_mask0 = (1<<nd_bpe)-1;
6347: } else {
6348: nd_mask0 = 0xffffffff;
6349: }
6350: bzero(nd_mask,sizeof(nd_mask));
6351: nd_mask1 = 0;
6352: for ( i = 0; i < nd_epw; i++ ) {
6353: nd_mask[nd_epw-i-1] = (nd_mask0<<(i*nd_bpe));
6354: nd_mask1 |= (1<<(nd_bpe-1))<<(i*nd_bpe);
6355: }
6356: nmv_adv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(nd_wpd-1)*sizeof(UINT));
6357: nd_epos = nd_create_epos(nd_ord);
6358: nd_blockmask = nd_create_blockmask(nd_ord);
6359: nd_work_vector = (int *)REALLOC(nd_work_vector,nd_nvar*sizeof(int));
6360: }
6361:
6362: ND_pairs nd_reconstruct(int trace,ND_pairs d)
6363: {
6364: int i,obpe,oadv,h;
6365: static NM prev_nm_free_list;
6366: static ND_pairs prev_ndp_free_list;
1.65 noro 6367: RHist mr;
1.1 noro 6368: RHist r;
6369: RHist *old_red;
6370: ND_pairs s0,s,t;
6371: EPOS oepos;
6372:
6373: obpe = nd_bpe;
6374: oadv = nmv_adv;
6375: oepos = nd_epos;
6376: if ( obpe < 2 ) nd_bpe = 2;
6377: else if ( obpe < 3 ) nd_bpe = 3;
6378: else if ( obpe < 4 ) nd_bpe = 4;
6379: else if ( obpe < 5 ) nd_bpe = 5;
6380: else if ( obpe < 6 ) nd_bpe = 6;
6381: else if ( obpe < 8 ) nd_bpe = 8;
6382: else if ( obpe < 10 ) nd_bpe = 10;
6383: else if ( obpe < 16 ) nd_bpe = 16;
6384: else if ( obpe < 32 ) nd_bpe = 32;
6385: else error("nd_reconstruct : exponent too large");
6386:
6387: nd_setup_parameters(nd_nvar,0);
6388: prev_nm_free_list = _nm_free_list;
6389: prev_ndp_free_list = _ndp_free_list;
6390: _nm_free_list = 0;
6391: _ndp_free_list = 0;
6392: for ( i = nd_psn-1; i >= 0; i-- ) {
6393: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
6394: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
6395: }
6396: if ( trace )
6397: for ( i = nd_psn-1; i >= 0; i-- ) {
6398: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
6399: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
6400: }
6401: s0 = 0;
6402: for ( t = d; t; t = NEXT(t) ) {
6403: NEXTND_pairs(s0,s);
6404: s->i1 = t->i1;
6405: s->i2 = t->i2;
1.24 noro 6406: s->sig = t->sig;
1.1 noro 6407: SG(s) = SG(t);
6408: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
6409: }
6410:
6411: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
6412: for ( i = 0; i < REDTAB_LEN; i++ ) {
6413: old_red[i] = nd_red[i];
6414: nd_red[i] = 0;
6415: }
6416: for ( i = 0; i < REDTAB_LEN; i++ )
6417: for ( r = old_red[i]; r; r = NEXT(r) ) {
6418: NEWRHist(mr);
6419: mr->index = r->index;
6420: SG(mr) = SG(r);
6421: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
6422: h = ndl_hash_value(DL(mr));
6423: NEXT(mr) = nd_red[h];
6424: nd_red[h] = mr;
1.24 noro 6425: mr->sig = r->sig;
1.1 noro 6426: }
6427: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
6428: old_red = 0;
6429: for ( i = 0; i < nd_psn; i++ ) {
6430: NEWRHist(r); SG(r) = SG(nd_psh[i]);
6431: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
1.24 noro 6432: r->sig = nd_psh[i]->sig;
1.1 noro 6433: nd_psh[i] = r;
6434: }
6435: if ( s0 ) NEXT(s) = 0;
6436: prev_nm_free_list = 0;
6437: prev_ndp_free_list = 0;
6438: #if 0
6439: GC_gcollect();
6440: #endif
6441: return s0;
6442: }
6443:
1.30 noro 6444: void nd_reconstruct_s(int trace,ND_pairs *d)
6445: {
6446: int i,obpe,oadv,h;
6447: static NM prev_nm_free_list;
6448: static ND_pairs prev_ndp_free_list;
1.65 noro 6449: RHist mr;
1.30 noro 6450: RHist r;
6451: RHist *old_red;
6452: ND_pairs s0,s,t;
6453: EPOS oepos;
6454:
6455: obpe = nd_bpe;
6456: oadv = nmv_adv;
6457: oepos = nd_epos;
6458: if ( obpe < 2 ) nd_bpe = 2;
6459: else if ( obpe < 3 ) nd_bpe = 3;
6460: else if ( obpe < 4 ) nd_bpe = 4;
6461: else if ( obpe < 5 ) nd_bpe = 5;
6462: else if ( obpe < 6 ) nd_bpe = 6;
6463: else if ( obpe < 8 ) nd_bpe = 8;
6464: else if ( obpe < 10 ) nd_bpe = 10;
6465: else if ( obpe < 16 ) nd_bpe = 16;
6466: else if ( obpe < 32 ) nd_bpe = 32;
6467: else error("nd_reconstruct_s : exponent too large");
6468:
6469: nd_setup_parameters(nd_nvar,0);
6470: prev_nm_free_list = _nm_free_list;
6471: prev_ndp_free_list = _ndp_free_list;
6472: _nm_free_list = 0;
6473: _ndp_free_list = 0;
6474: for ( i = nd_psn-1; i >= 0; i-- ) {
6475: ndv_realloc(nd_ps[i],obpe,oadv,oepos);
6476: ndv_realloc(nd_ps_sym[i],obpe,oadv,oepos);
6477: }
6478: if ( trace )
6479: for ( i = nd_psn-1; i >= 0; i-- ) {
6480: ndv_realloc(nd_ps_trace[i],obpe,oadv,oepos);
6481: ndv_realloc(nd_ps_trace_sym[i],obpe,oadv,oepos);
6482: }
6483:
6484: for ( i = 0; i < nd_nbase; i++ ) {
6485: s0 = 0;
6486: for ( t = d[i]; t; t = NEXT(t) ) {
6487: NEXTND_pairs(s0,s);
6488: s->i1 = t->i1;
6489: s->i2 = t->i2;
6490: s->sig = t->sig;
6491: SG(s) = SG(t);
6492: ndl_reconstruct(LCM(t),LCM(s),obpe,oepos);
6493: }
1.47 noro 6494: if ( s0 ) NEXT(s) = 0;
1.30 noro 6495: d[i] = s0;
6496: }
6497:
6498: old_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
6499: for ( i = 0; i < REDTAB_LEN; i++ ) {
6500: old_red[i] = nd_red[i];
6501: nd_red[i] = 0;
6502: }
6503: for ( i = 0; i < REDTAB_LEN; i++ )
6504: for ( r = old_red[i]; r; r = NEXT(r) ) {
6505: NEWRHist(mr);
6506: mr->index = r->index;
6507: SG(mr) = SG(r);
6508: ndl_reconstruct(DL(r),DL(mr),obpe,oepos);
6509: h = ndl_hash_value(DL(mr));
6510: NEXT(mr) = nd_red[h];
6511: nd_red[h] = mr;
6512: mr->sig = r->sig;
6513: }
6514: for ( i = 0; i < REDTAB_LEN; i++ ) old_red[i] = 0;
6515: old_red = 0;
6516: for ( i = 0; i < nd_psn; i++ ) {
6517: NEWRHist(r); SG(r) = SG(nd_psh[i]);
6518: ndl_reconstruct(DL(nd_psh[i]),DL(r),obpe,oepos);
6519: r->sig = nd_psh[i]->sig;
6520: nd_psh[i] = r;
6521: }
6522: if ( s0 ) NEXT(s) = 0;
6523: prev_nm_free_list = 0;
6524: prev_ndp_free_list = 0;
6525: #if 0
6526: GC_gcollect();
6527: #endif
6528: }
6529:
1.1 noro 6530: void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos)
6531: {
1.65 noro 6532: int n,i,ei,omask0,j,s,ord_l,l;
1.1 noro 6533: struct order_pair *op;
6534:
6535: n = nd_nvar;
1.65 noro 6536: // oepw = (sizeof(UINT)*8)/obpe;
1.1 noro 6537: omask0 = (1<<obpe)-1;
6538: TD(r) = TD(d);
6539: for ( i = nd_exporigin; i < nd_wpd; i++ ) r[i] = 0;
6540: if ( nd_blockmask ) {
6541: l = nd_blockmask->n;
6542: op = nd_blockmask->order_pair;
6543: for ( i = 1; i < nd_exporigin; i++ )
6544: r[i] = d[i];
6545: for ( j = 0, s = 0; j < l; j++ ) {
6546: ord_l = op[j].length;
6547: for ( i = 0; i < ord_l; i++, s++ ) {
6548: ei = GET_EXP_OLD(d,s);
6549: PUT_EXP(r,s,ei);
6550: }
6551: }
6552: } else {
6553: for ( i = 0; i < n; i++ ) {
6554: ei = GET_EXP_OLD(d,i);
6555: PUT_EXP(r,i,ei);
6556: }
6557: }
6558: if ( nd_module ) MPOS(r) = MPOS(d);
6559: }
6560:
6561: ND nd_copy(ND p)
6562: {
6563: NM m,mr,mr0;
6564: ND r;
6565:
6566: if ( !p )
6567: return 0;
6568: else {
6569: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
6570: NEXTNM(mr0,mr);
6571: CM(mr) = CM(m);
6572: ndl_copy(DL(m),DL(mr));
6573: }
6574: NEXT(mr) = 0;
6575: MKND(NV(p),mr0,LEN(p),r);
6576: SG(r) = SG(p);
6577: return r;
6578: }
6579: }
6580:
6581: int nd_sp(int mod,int trace,ND_pairs p,ND *rp)
6582: {
6583: NM m1,m2;
6584: NDV p1,p2;
6585: ND t1,t2;
6586: UINT *lcm;
6587: P gp,tp;
6588: Z g,t;
6589: Z iq;
6590: LIST hist;
6591: NODE node;
6592: DP d;
6593:
6594: if ( !mod && nd_demand ) {
6595: p1 = ndv_load(p->i1); p2 = ndv_load(p->i2);
6596: } else {
6597: if ( trace ) {
6598: p1 = nd_ps_trace[p->i1]; p2 = nd_ps_trace[p->i2];
6599: } else {
6600: p1 = nd_ps[p->i1]; p2 = nd_ps[p->i2];
6601: }
6602: }
6603: lcm = LCM(p);
6604: NEWNM(m1); ndl_sub(lcm,HDL(p1),DL(m1));
6605: if ( ndl_check_bound2(p->i1,DL(m1)) ) {
6606: FREENM(m1); return 0;
6607: }
6608: NEWNM(m2); ndl_sub(lcm,HDL(p2),DL(m2));
6609: if ( ndl_check_bound2(p->i2,DL(m2)) ) {
6610: FREENM(m1); FREENM(m2); return 0;
6611: }
6612:
6613: if ( mod == -1 ) {
6614: CM(m1) = HCM(p2); CM(m2) = _chsgnsf(HCM(p1));
6615: } else if ( mod > 0 ) {
6616: CM(m1) = HCM(p2); CM(m2) = mod-HCM(p1);
6617: } else if ( mod == -2 ) {
6618: CZ(m1) = HCZ(p2); chsgnlf(HCZ(p1),&CZ(m2));
6619: } else if ( nd_vc ) {
6620: ezgcdpz(nd_vc,HCP(p1),HCP(p2),&gp);
6621: divsp(nd_vc,HCP(p2),gp,&CP(m1));
6622: divsp(nd_vc,HCP(p1),gp,&tp); chsgnp(tp,&CP(m2));
6623: } else {
1.6 noro 6624: igcd_cofactor(HCZ(p1),HCZ(p2),&g,&t,&CZ(m1)); chsgnz(t,&CZ(m2));
1.1 noro 6625: }
6626: t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2);
6627: *rp = nd_add(mod,t1,t2);
6628: if ( nd_gentrace ) {
6629: /* nd_tracelist is initialized */
1.6 noro 6630: STOZ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE);
1.1 noro 6631: MKLIST(hist,node); MKNODE(nd_tracelist,hist,0);
1.6 noro 6632: STOZ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE);
1.1 noro 6633: MKLIST(hist,node); MKNODE(node,hist,nd_tracelist);
6634: nd_tracelist = node;
6635: }
1.24 noro 6636: if ( *rp )
6637: (*rp)->sig = p->sig;
1.1 noro 6638: FREENM(m1); FREENM(m2);
6639: return 1;
6640: }
6641:
6642: void ndv_mul_c(int mod,NDV p,int mul)
6643: {
6644: NMV m;
6645: int c,c1,len,i;
6646:
6647: if ( !p ) return;
6648: len = LEN(p);
6649: if ( mod == -1 )
6650: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) )
6651: CM(m) = _mulsf(CM(m),mul);
6652: else
6653: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
6654: c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c;
6655: }
6656: }
6657:
6658: void ndv_mul_c_lf(NDV p,Z mul)
6659: {
6660: NMV m;
6661: Z c;
6662: int len,i;
6663:
6664: if ( !p ) return;
6665: len = LEN(p);
6666: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
6667: mullf(CZ(m),mul,&c); CZ(m) = c;
6668: }
6669: }
6670:
6671: /* for nd_det */
6672: void ndv_mul_c_q(NDV p,Z mul)
6673: {
6674: NMV m;
6675: Z c;
6676: int len,i;
6677:
6678: if ( !p ) return;
6679: len = LEN(p);
6680: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 6681: mulz(CZ(m),mul,&c); CZ(m) = c;
1.1 noro 6682: }
6683: }
6684:
6685: ND weyl_ndv_mul_nm(int mod,NM m0,NDV p) {
6686: int n2,i,j,l,n,tlen;
6687: UINT *d0;
6688: NM *tab,*psum;
6689: ND s,r;
6690: NM t;
6691: NMV m1;
6692:
6693: if ( !p ) return 0;
6694: n = NV(p); n2 = n>>1;
6695: d0 = DL(m0);
6696: l = LEN(p);
6697: for ( i = 0, tlen = 1; i < n2; i++ ) tlen *= (GET_EXP(d0,n2+i)+1);
6698: tab = (NM *)MALLOC(tlen*sizeof(NM));
6699: psum = (NM *)MALLOC(tlen*sizeof(NM));
6700: for ( i = 0; i < tlen; i++ ) psum[i] = 0;
6701: m1 = (NMV)(((char *)BDY(p))+nmv_adv*(l-1));
6702: for ( i = l-1; i >= 0; i--, NMV_PREV(m1) ) {
6703: /* m0(NM) * m1(NMV) => tab(NM) */
6704: weyl_mul_nm_nmv(n,mod,m0,m1,tab,tlen);
6705: for ( j = 0; j < tlen; j++ ) {
6706: if ( tab[j] ) {
6707: NEXT(tab[j]) = psum[j]; psum[j] = tab[j];
6708: }
6709: }
6710: }
6711: for ( i = tlen-1, r = 0; i >= 0; i-- )
6712: if ( psum[i] ) {
6713: for ( j = 0, t = psum[i]; t; t = NEXT(t), j++ );
6714: MKND(n,psum[i],j,s);
6715: r = nd_add(mod,r,s);
6716: }
6717: if ( r ) SG(r) = SG(p)+TD(d0);
6718: return r;
6719: }
6720:
6721: /* product of monomials */
6722: /* XXX block order is not handled correctly */
6723:
6724: void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *tab,int tlen)
6725: {
6726: int i,n2,j,s,curlen,homo,h,a,b,k,l,u,min;
6727: UINT *d0,*d1,*d,*dt,*ctab;
6728: Z *ctab_q;
6729: Z q,q1;
6730: UINT c0,c1,c;
6731: NM *p;
6732: NM m,t;
6733: int mpos;
6734:
6735: for ( i = 0; i < tlen; i++ ) tab[i] = 0;
6736: if ( !m0 || !m1 ) return;
6737: d0 = DL(m0); d1 = DL(m1); n2 = n>>1;
6738: if ( nd_module )
6739: if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation");
6740:
6741: NEWNM(m); d = DL(m);
6742: if ( mod ) {
6743: c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c;
6744: } else if ( nd_vc )
6745: mulp(nd_vc,CP(m0),CP(m1),&CP(m));
6746: else
1.6 noro 6747: mulz(CZ(m0),CZ(m1),&CZ(m));
1.1 noro 6748: for ( i = 0; i < nd_wpd; i++ ) d[i] = 0;
6749: homo = n&1 ? 1 : 0;
6750: if ( homo ) {
6751: /* offset of h-degree */
6752: h = GET_EXP(d0,n-1)+GET_EXP(d1,n-1);
6753: PUT_EXP(DL(m),n-1,h);
6754: TD(DL(m)) = h;
6755: if ( nd_blockmask ) ndl_weight_mask(DL(m));
6756: }
6757: tab[0] = m;
6758: NEWNM(m); d = DL(m);
6759: for ( i = 0, curlen = 1; i < n2; i++ ) {
6760: a = GET_EXP(d0,i); b = GET_EXP(d1,n2+i);
6761: k = GET_EXP(d0,n2+i); l = GET_EXP(d1,i);
6762: /* xi^a*(Di^k*xi^l)*Di^b */
6763: a += l; b += k;
6764: s = MUL_WEIGHT(a,i)+MUL_WEIGHT(b,n2+i);
6765: if ( !k || !l ) {
6766: for ( j = 0; j < curlen; j++ )
6767: if ( (t = tab[j]) != 0 ) {
6768: dt = DL(t);
6769: PUT_EXP(dt,i,a); PUT_EXP(dt,n2+i,b); TD(dt) += s;
6770: if ( nd_blockmask ) ndl_weight_mask(dt);
6771: }
6772: curlen *= k+1;
6773: continue;
6774: }
6775: min = MIN(k,l);
6776: if ( mod ) {
6777: ctab = (UINT *)MALLOC((min+1)*sizeof(UINT));
6778: mkwcm(k,l,mod,(int *)ctab);
6779: } else {
6780: ctab_q = (Z *)MALLOC((min+1)*sizeof(Z));
6781: mkwc(k,l,ctab_q);
6782: }
6783: for ( j = min; j >= 0; j-- ) {
6784: for ( u = 0; u < nd_wpd; u++ ) d[u] = 0;
6785: PUT_EXP(d,i,a-j); PUT_EXP(d,n2+i,b-j);
6786: h = MUL_WEIGHT(a-j,i)+MUL_WEIGHT(b-j,n2+i);
6787: if ( homo ) {
6788: TD(d) = s;
6789: PUT_EXP(d,n-1,s-h);
6790: } else TD(d) = h;
6791: if ( nd_blockmask ) ndl_weight_mask(d);
6792: if ( mod ) c = ctab[j];
6793: else q = ctab_q[j];
6794: p = tab+curlen*j;
6795: if ( j == 0 ) {
6796: for ( u = 0; u < curlen; u++, p++ ) {
6797: if ( tab[u] ) {
6798: ndl_addto(DL(tab[u]),d);
6799: if ( mod ) {
6800: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1;
6801: } else if ( nd_vc )
6802: mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u]));
6803: else {
1.6 noro 6804: mulz(CZ(tab[u]),q,&q1); CZ(tab[u]) = q1;
1.1 noro 6805: }
6806: }
6807: }
6808: } else {
6809: for ( u = 0; u < curlen; u++, p++ ) {
6810: if ( tab[u] ) {
6811: NEWNM(t);
6812: ndl_add(DL(tab[u]),d,DL(t));
6813: if ( mod ) {
6814: c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1;
6815: } else if ( nd_vc )
6816: mulp(nd_vc,CP(tab[u]),(P)q,&CP(t));
6817: else
1.6 noro 6818: mulz(CZ(tab[u]),q,&CZ(t));
1.1 noro 6819: *p = t;
6820: }
6821: }
6822: }
6823: }
6824: curlen *= k+1;
6825: }
6826: FREENM(m);
6827: if ( nd_module ) {
6828: mpos = MPOS(d1);
6829: for ( i = 0; i < tlen; i++ )
6830: if ( tab[i] ) {
6831: d = DL(tab[i]);
6832: MPOS(d) = mpos;
6833: TD(d) = ndl_weight(d);
6834: }
6835: }
6836: }
6837:
6838: ND ndv_mul_nm_symbolic(NM m0,NDV p)
6839: {
6840: NM mr,mr0;
6841: NMV m;
1.65 noro 6842: UINT *d;
6843: int i,len;
1.1 noro 6844: ND r;
6845:
6846: if ( !p ) return 0;
6847: else {
1.65 noro 6848: m = BDY(p);
1.1 noro 6849: d = DL(m0);
6850: len = LEN(p);
6851: mr0 = 0;
6852: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6853: NEXTNM(mr0,mr);
6854: CM(mr) = 1;
6855: ndl_add(DL(m),d,DL(mr));
6856: }
6857: NEXT(mr) = 0;
6858: MKND(NV(p),mr0,len,r);
6859: SG(r) = SG(p) + TD(d);
6860: return r;
6861: }
6862: }
6863:
6864: ND ndv_mul_nm(int mod,NM m0,NDV p)
6865: {
6866: NM mr,mr0;
6867: NMV m;
1.65 noro 6868: UINT *d;
6869: int c,i,c1,c2,len;
1.1 noro 6870: P q;
6871: ND r;
6872:
6873: if ( !p ) return 0;
6874: else if ( do_weyl ) {
6875: if ( mod < 0 ) {
6876: error("ndv_mul_nm : not implemented (weyl)");
6877: return 0;
6878: } else
6879: return weyl_ndv_mul_nm(mod,m0,p);
6880: } else {
1.65 noro 6881: m = BDY(p);
1.1 noro 6882: d = DL(m0);
6883: len = LEN(p);
6884: mr0 = 0;
6885: if ( mod == -1 ) {
6886: c = CM(m0);
6887: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6888: NEXTNM(mr0,mr);
6889: CM(mr) = _mulsf(CM(m),c);
6890: ndl_add(DL(m),d,DL(mr));
6891: }
6892: } else if ( mod == -2 ) {
6893: Z cl;
6894: cl = CZ(m0);
6895: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6896: NEXTNM(mr0,mr);
6897: mullf(CZ(m),cl,&CZ(mr));
6898: ndl_add(DL(m),d,DL(mr));
6899: }
6900: } else if ( mod ) {
6901: c = CM(m0);
6902: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6903: NEXTNM(mr0,mr);
6904: c1 = CM(m);
6905: DMAR(c1,c,0,mod,c2);
6906: CM(mr) = c2;
6907: ndl_add(DL(m),d,DL(mr));
6908: }
6909: } else {
6910: q = CP(m0);
6911: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
6912: NEXTNM(mr0,mr);
6913: mulp(nd_vc,CP(m),q,&CP(mr));
6914: ndl_add(DL(m),d,DL(mr));
6915: }
6916: }
6917: NEXT(mr) = 0;
6918: MKND(NV(p),mr0,len,r);
6919: SG(r) = SG(p) + TD(d);
6920: return r;
6921: }
6922: }
6923:
6924: ND nd_quo(int mod,PGeoBucket bucket,NDV d)
6925: {
6926: NM mq0,mq;
6927: NMV tm;
1.65 noro 6928: int i,nv,c,c1,c2,hindex;
1.1 noro 6929: ND p,t,r;
6930:
6931: if ( bucket->m < 0 ) return 0;
6932: else {
6933: nv = NV(d);
6934: mq0 = 0;
6935: tm = (NMV)MALLOC(nmv_adv);
6936: while ( 1 ) {
6937: if ( mod > 0 || mod == -1 )
6938: hindex = head_pbucket(mod,bucket);
6939: else if ( mod == -2 )
6940: hindex = head_pbucket_lf(bucket);
6941: else
6942: hindex = head_pbucket_q(bucket);
6943: if ( hindex < 0 ) break;
6944: p = bucket->body[hindex];
6945: NEXTNM(mq0,mq);
6946: ndl_sub(HDL(p),HDL(d),DL(mq));
6947: ndl_copy(DL(mq),DL(tm));
6948: if ( mod ) {
6949: c1 = invm(HCM(d),mod); c2 = HCM(p);
6950: DMAR(c1,c2,0,mod,c); CM(mq) = c;
6951: CM(tm) = mod-c;
6952: } else {
1.6 noro 6953: divsz(HCZ(p),HCZ(d),&CZ(mq));
6954: chsgnz(CZ(mq),&CZ(tm));
1.1 noro 6955: }
6956: t = ndv_mul_nmv_trunc(mod,tm,d,HDL(d));
6957: bucket->body[hindex] = nd_remove_head(p);
6958: t = nd_remove_head(t);
6959: add_pbucket(mod,bucket,t);
6960: }
6961: if ( !mq0 )
6962: r = 0;
6963: else {
6964: NEXT(mq) = 0;
6965: for ( i = 0, mq = mq0; mq; mq = NEXT(mq), i++ );
6966: MKND(nv,mq0,i,r);
6967: /* XXX */
6968: SG(r) = HTD(r);
6969: }
6970: return r;
6971: }
6972: }
6973:
6974: void ndv_realloc(NDV p,int obpe,int oadv,EPOS oepos)
6975: {
6976: NMV m,mr,mr0,t;
6977: int len,i,k;
6978:
6979: if ( !p ) return;
6980: m = BDY(p); len = LEN(p);
6981: mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p);
6982: m = (NMV)((char *)mr0+(len-1)*oadv);
6983: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
6984: t = (NMV)MALLOC(nmv_adv);
6985: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
1.6 noro 6986: CZ(t) = CZ(m);
1.1 noro 6987: for ( k = 0; k < nd_wpd; k++ ) DL(t)[k] = 0;
6988: ndl_reconstruct(DL(m),DL(t),obpe,oepos);
1.6 noro 6989: CZ(mr) = CZ(t);
1.1 noro 6990: ndl_copy(DL(t),DL(mr));
6991: }
6992: BDY(p) = mr0;
6993: }
6994:
6995: NDV ndv_dup_realloc(NDV p,int obpe,int oadv,EPOS oepos)
6996: {
6997: NMV m,mr,mr0;
6998: int len,i;
6999: NDV r;
7000:
7001: if ( !p ) return 0;
7002: m = BDY(p); len = LEN(p);
7003: mr0 = mr = (NMV)MALLOC(len*nmv_adv);
7004: for ( i = 0; i < len; i++, NMV_OADV(m), NMV_ADV(mr) ) {
7005: ndl_zero(DL(mr));
7006: ndl_reconstruct(DL(m),DL(mr),obpe,oepos);
1.6 noro 7007: CZ(mr) = CZ(m);
1.1 noro 7008: }
7009: MKNDV(NV(p),mr0,len,r);
7010: SG(r) = SG(p);
1.24 noro 7011: r->sig = p->sig;
1.1 noro 7012: return r;
7013: }
7014:
7015: /* duplicate p */
7016:
7017: NDV ndv_dup(int mod,NDV p)
7018: {
7019: NDV d;
7020: NMV t,m,m0;
7021: int i,len;
7022:
7023: if ( !p ) return 0;
7024: len = LEN(p);
7025: m0 = m = (NMV)((mod>0 || mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
7026: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
7027: ndl_copy(DL(t),DL(m));
1.6 noro 7028: CZ(m) = CZ(t);
1.1 noro 7029: }
7030: MKNDV(NV(p),m0,len,d);
7031: SG(d) = SG(p);
7032: return d;
7033: }
7034:
7035: NDV ndv_symbolic(int mod,NDV p)
7036: {
7037: NDV d;
7038: NMV t,m,m0;
7039: int i,len;
7040:
7041: if ( !p ) return 0;
7042: len = LEN(p);
7043: m0 = m = (NMV)((mod>0||mod==-1)?MALLOC_ATOMIC(len*nmv_adv):MALLOC(len*nmv_adv));
7044: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t), NMV_ADV(m) ) {
7045: ndl_copy(DL(t),DL(m));
1.6 noro 7046: CZ(m) = ONE;
1.1 noro 7047: }
7048: MKNDV(NV(p),m0,len,d);
7049: SG(d) = SG(p);
7050: return d;
7051: }
7052:
7053: ND nd_dup(ND p)
7054: {
7055: ND d;
7056: NM t,m,m0;
7057:
7058: if ( !p ) return 0;
7059: for ( m0 = 0, t = BDY(p); t; t = NEXT(t) ) {
7060: NEXTNM(m0,m);
7061: ndl_copy(DL(t),DL(m));
1.6 noro 7062: CZ(m) = CZ(t);
1.1 noro 7063: }
7064: if ( m0 ) NEXT(m) = 0;
7065: MKND(NV(p),m0,LEN(p),d);
7066: SG(d) = SG(p);
7067: return d;
7068: }
7069:
7070: /* XXX if p->len == 0 then it represents 0 */
7071:
7072: void ndv_mod(int mod,NDV p)
7073: {
7074: NMV t,d;
1.65 noro 7075: int r;
1.1 noro 7076: int i,len,dlen;
7077: P cp;
7078: Z c;
7079: Obj gfs;
7080:
7081: if ( !p ) return;
7082: len = LEN(p);
7083: dlen = 0;
7084: if ( mod == -1 )
7085: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7086: simp_ff((Obj)CP(t),&gfs);
7087: if ( gfs ) {
7088: r = FTOIF(CONT((GFS)gfs));
7089: CM(d) = r;
7090: ndl_copy(DL(t),DL(d));
7091: NMV_ADV(d);
7092: dlen++;
7093: }
7094: }
7095: else if ( mod == -2 )
7096: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7097: simp_ff((Obj)CP(t),&gfs);
7098: if ( gfs ) {
7099: lmtolf((LM)gfs,&CZ(d));
7100: ndl_copy(DL(t),DL(d));
7101: NMV_ADV(d);
7102: dlen++;
7103: }
7104: }
7105: else
7106: for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
7107: if ( nd_vc ) {
7108: nd_subst_vector(nd_vc,CP(t),nd_subst,&cp);
7109: c = (Z)cp;
7110: } else
1.6 noro 7111: c = CZ(t);
1.1 noro 7112: r = remqi((Q)c,mod);
7113: if ( r ) {
7114: CM(d) = r;
7115: ndl_copy(DL(t),DL(d));
7116: NMV_ADV(d);
7117: dlen++;
7118: }
7119: }
7120: LEN(p) = dlen;
7121: }
7122:
7123: NDV ptondv(VL vl,VL dvl,P p)
7124: {
7125: ND nd;
7126:
7127: nd = ptond(vl,dvl,p);
7128: return ndtondv(0,nd);
7129: }
7130:
7131: void pltozpl(LIST l,Q *cont,LIST *pp)
7132: {
1.16 noro 7133: NODE nd,nd1;
7134: int n;
7135: P *pl;
7136: Q *cl;
7137: int i;
7138: P dmy;
7139: Z dvr,inv;
7140: LIST r;
7141:
7142: nd = BDY(l); n = length(nd);
7143: pl = (P *)MALLOC(n*sizeof(P));
7144: cl = (Q *)MALLOC(n*sizeof(Q));
7145: for ( i = 0; i < n; i++, nd = NEXT(nd) ) {
7146: ptozp((P)BDY(nd),1,&cl[i],&dmy);
7147: }
7148: qltozl(cl,n,&dvr);
7149: divz(ONE,dvr,&inv);
7150: nd = BDY(l);
7151: for ( i = 0; i < n; i++, nd = NEXT(nd) )
7152: divsp(CO,(P)BDY(nd),(P)dvr,&pl[i]);
7153: nd = 0;
7154: for ( i = n-1; i >= 0; i-- ) {
7155: MKNODE(nd1,pl[i],nd); nd = nd1;
7156: }
7157: MKLIST(r,nd);
7158: *pp = r;
1.1 noro 7159: }
7160:
7161: /* (a1,a2,...,an) -> a1*e(1)+...+an*e(n) */
7162:
7163: NDV pltondv(VL vl,VL dvl,LIST p)
7164: {
7165: int i;
7166: NODE t;
7167: ND r,ri;
7168: NM m;
7169:
7170: if ( !nd_module ) error("pltond : module order must be set");
7171: r = 0;
7172: for ( i = 1, t = BDY(p); t; t = NEXT(t), i++ ) {
7173: ri = ptond(vl,dvl,(P)BDY(t));
7174: if ( ri )
7175: for ( m = BDY(ri); m; m = NEXT(m) ) {
7176: MPOS(DL(m)) = i;
7177: TD(DL(m)) = ndl_weight(DL(m));
7178: if ( nd_blockmask ) ndl_weight_mask(DL(m));
7179: }
7180: r = nd_add(0,r,ri);
7181: }
7182: return ndtondv(0,r);
7183: }
7184:
7185: ND ptond(VL vl,VL dvl,P p)
7186: {
1.65 noro 7187: int j,k,e,i;
1.1 noro 7188: VL tvl;
7189: V v;
7190: DCP dc;
7191: DCP *w;
1.65 noro 7192: ND r,t,s;
1.1 noro 7193: P x;
7194: UINT *d;
7195: NM m,m0;
7196:
7197: if ( !p )
7198: return 0;
7199: else if ( NUM(p) ) {
7200: NEWNM(m);
7201: ndl_zero(DL(m));
1.48 noro 7202: if ( RATN(p) && !INT((Q)p) )
1.1 noro 7203: error("ptond : input must be integer-coefficient");
1.6 noro 7204: CZ(m) = (Z)p;
1.1 noro 7205: NEXT(m) = 0;
7206: MKND(nd_nvar,m,1,r);
7207: SG(r) = 0;
7208: return r;
7209: } else {
7210: for ( dc = DC(p), k = 0; dc; dc = NEXT(dc), k++ );
7211: w = (DCP *)MALLOC(k*sizeof(DCP));
7212: for ( dc = DC(p), j = 0; j < k; dc = NEXT(dc), j++ ) w[j] = dc;
7213: for ( i = 0, tvl = dvl, v = VR(p);
7214: tvl && tvl->v != v; tvl = NEXT(tvl), i++ );
7215: if ( !tvl ) {
7216: for ( j = k-1, s = 0, MKV(v,x); j >= 0; j-- ) {
7217: t = ptond(vl,dvl,COEF(w[j]));
7218: pwrp(vl,x,DEG(w[j]),&p);
7219: nd_mul_c_p(CO,t,p); s = nd_add(0,s,t);
7220: }
7221: return s;
7222: } else {
7223: NEWNM(m0); d = DL(m0);
7224: for ( j = k-1, s = 0; j >= 0; j-- ) {
1.65 noro 7225: ndl_zero(d); e = (int)ZTOS(DEG(w[j])); PUT_EXP(d,i,e);
1.1 noro 7226: TD(d) = MUL_WEIGHT(e,i);
7227: if ( nd_blockmask) ndl_weight_mask(d);
7228: if ( nd_module ) MPOS(d) = 0;
7229: t = ptond(vl,dvl,COEF(w[j]));
7230: for ( m = BDY(t); m; m = NEXT(m) )
7231: ndl_addto(DL(m),d);
7232: SG(t) += TD(d);
7233: s = nd_add(0,s,t);
7234: }
7235: FREENM(m0);
7236: return s;
7237: }
7238: }
7239: }
7240:
7241: P ndvtop(int mod,VL vl,VL dvl,NDV p)
7242: {
7243: VL tvl;
7244: int len,n,j,i,e;
7245: NMV m;
7246: Z q;
7247: P c;
7248: UINT *d;
7249: P s,r,u,t,w;
7250: GFS gfs;
7251:
7252: if ( !p ) return 0;
7253: else {
7254: len = LEN(p);
7255: n = NV(p);
7256: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
7257: for ( j = len-1, s = 0; j >= 0; j--, NMV_PREV(m) ) {
7258: if ( mod == -1 ) {
7259: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
7260: } else if ( mod == -2 ) {
7261: c = (P)CZ(m);
7262: } else if ( mod > 0 ) {
1.6 noro 7263: STOZ(CM(m),q); c = (P)q;
1.1 noro 7264: } else
7265: c = CP(m);
7266: d = DL(m);
7267: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
1.6 noro 7268: MKV(tvl->v,r); e = GET_EXP(d,i); STOZ(e,q);
1.1 noro 7269: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
7270: }
7271: addp(vl,s,t,&u); s = u;
7272: }
7273: return s;
7274: }
7275: }
7276:
7277: LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank)
7278: {
7279: VL tvl;
7280: int len,n,j,i,e;
7281: NMV m;
7282: Z q;
7283: P c;
7284: UINT *d;
1.65 noro 7285: P r,u,t,w;
1.1 noro 7286: GFS gfs;
7287: P *a;
7288: LIST l;
7289: NODE nd,nd1;
7290:
7291: if ( !p ) return 0;
7292: else {
7293: a = (P *)MALLOC((rank+1)*sizeof(P));
7294: for ( i = 0; i <= rank; i++ ) a[i] = 0;
7295: len = LEN(p);
7296: n = NV(p);
7297: m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1));
7298: for ( j = len-1; j >= 0; j--, NMV_PREV(m) ) {
7299: if ( mod == -1 ) {
7300: e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs;
7301: } else if ( mod ) {
1.6 noro 7302: STOZ(CM(m),q); c = (P)q;
1.1 noro 7303: } else
7304: c = CP(m);
7305: d = DL(m);
7306: for ( i = 0, t = c, tvl = dvl; i < n; tvl = NEXT(tvl), i++ ) {
1.6 noro 7307: MKV(tvl->v,r); e = GET_EXP(d,i); STOZ(e,q);
1.1 noro 7308: pwrp(vl,r,q,&u); mulp(vl,t,u,&w); t = w;
7309: }
7310: addp(vl,a[MPOS(d)],t,&u); a[MPOS(d)] = u;
7311: }
7312: nd = 0;
7313: for ( i = rank; i > 0; i-- ) {
7314: MKNODE(nd1,a[i],nd); nd = nd1;
7315: }
7316: MKLIST(l,nd);
7317: return l;
7318: }
7319: }
7320:
7321: NDV ndtondv(int mod,ND p)
7322: {
7323: NDV d;
7324: NMV m,m0;
7325: NM t;
7326: int i,len;
7327:
7328: if ( !p ) return 0;
7329: len = LEN(p);
7330: if ( mod > 0 || mod == -1 )
7331: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7332: else
7333: m0 = m = MALLOC(len*nmv_adv);
7334: #if 0
7335: ndv_alloc += nmv_adv*len;
7336: #endif
7337: for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, NMV_ADV(m) ) {
7338: ndl_copy(DL(t),DL(m));
1.6 noro 7339: CZ(m) = CZ(t);
1.1 noro 7340: }
7341: MKNDV(NV(p),m0,len,d);
7342: SG(d) = SG(p);
1.24 noro 7343: d->sig = p->sig;
1.1 noro 7344: return d;
7345: }
7346:
1.16 noro 7347: static int dmm_comp_nv;
7348:
7349: int dmm_comp(DMM *a,DMM *b)
7350: {
7351: return -compdmm(dmm_comp_nv,*a,*b);
7352: }
7353:
7354: void dmm_sort_by_ord(DMM *a,int len,int nv)
7355: {
7356: dmm_comp_nv = nv;
7357: qsort(a,len,sizeof(DMM),(int (*)(const void *,const void *))dmm_comp);
7358: }
7359:
7360: void dpm_sort(DPM p,DPM *rp)
7361: {
7362: DMM t,t1;
7363: int len,i,n;
7364: DMM *a;
7365: DPM d;
7366:
7367: if ( !p ) *rp = 0;
7368: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7369: a = (DMM *)MALLOC(len*sizeof(DMM));
7370: for ( i = 0, t = BDY(p); i < len; i++, t = NEXT(t) ) a[i] = t;
7371: n = p->nv;
7372: dmm_sort_by_ord(a,len,n);
7373: t = 0;
7374: for ( i = len-1; i >= 0; i-- ) {
7375: NEWDMM(t1);
7376: t1->c = a[i]->c;
7377: t1->dl = a[i]->dl;
7378: t1->pos = a[i]->pos;
7379: t1->next = t;
7380: t = t1;
7381: }
7382: MKDPM(n,t,d);
7383: SG(d) = SG(p);
7384: *rp = d;
7385: }
7386:
1.18 noro 7387: int dpm_comp(DPM *a,DPM *b)
7388: {
1.22 noro 7389: return -compdpm(CO,*a,*b);
1.18 noro 7390: }
7391:
7392: NODE dpm_sort_list(NODE l)
7393: {
7394: int i,len;
7395: NODE t,t1;
7396: DPM *a;
7397:
7398: len = length(l);
7399: a = (DPM *)MALLOC(len*sizeof(DPM));
7400: for ( t = l, i = 0; i < len; i++, t = NEXT(t) ) a[i] = (DPM)BDY(t);
7401: qsort(a,len,sizeof(DPM),(int (*)(const void *,const void *))dpm_comp);
7402: t = 0;
7403: for ( i = len-1; i >= 0; i-- ) {
7404: MKNODE(t1,(pointer)a[i],t); t = t1;
7405: }
7406: return t;
7407: }
7408:
1.20 noro 7409: int nmv_comp(NMV a,NMV b)
7410: {
1.21 noro 7411: int t;
7412: t = DL_COMPARE(a->dl,b->dl);
7413: return -t;
1.20 noro 7414: }
7415:
1.43 noro 7416: NDV dptondv(int mod,DP p)
7417: {
7418: NDV d;
7419: NMV m,m0;
7420: MP t;
7421: int i,len,n;
7422:
7423: if ( !p ) return 0;
7424: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7425: n = p->nv;
7426: if ( mod > 0 || mod == -1 )
7427: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7428: else
7429: m0 = m = MALLOC(len*nmv_adv);
7430: for ( i = 0, t = BDY(p); i < len; i++, NMV_ADV(m), t = NEXT(t) ) {
7431: dltondl(n,t->dl,DL(m));
7432: TD(DL(m)) = ndl_weight(DL(m));
7433: CZ(m) = (Z)t->c;
7434: }
7435: qsort(m0,len,nmv_adv,(int (*)(const void *,const void *))nmv_comp);
7436: MKNDV(NV(p),m0,len,d);
7437: SG(d) = SG(p);
7438: return d;
7439: }
7440:
1.16 noro 7441: NDV dpmtondv(int mod,DPM p)
7442: {
7443: NDV d;
7444: NMV m,m0;
7445: DMM t;
7446: DMM *a;
7447: int i,len,n;
7448:
7449: if ( !p ) return 0;
7450: for ( t = BDY(p), len = 0; t; t = NEXT(t), len++ );
7451: a = (DMM *)MALLOC(len*sizeof(DMM));
7452: for ( i = 0, t = BDY(p); i < len; i++, t = NEXT(t) ) a[i] = t;
7453: n = p->nv;
7454: dmm_sort_by_ord(a,len,n);
7455: if ( mod > 0 || mod == -1 )
7456: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv);
7457: else
7458: m0 = m = MALLOC(len*nmv_adv);
7459: #if 0
7460: ndv_alloc += nmv_adv*len;
7461: #endif
7462: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
7463: dltondl(n,a[i]->dl,DL(m));
7464: MPOS(DL(m)) = a[i]->pos;
1.20 noro 7465: TD(DL(m)) = ndl_weight(DL(m));
1.16 noro 7466: CZ(m) = (Z)a[i]->c;
7467: }
1.20 noro 7468: qsort(m0,len,nmv_adv,(int (*)(const void *,const void *))nmv_comp);
1.16 noro 7469: MKNDV(NV(p),m0,len,d);
7470: SG(d) = SG(p);
7471: return d;
7472: }
7473:
1.1 noro 7474: ND ndvtond(int mod,NDV p)
7475: {
7476: ND d;
7477: NM m,m0;
7478: NMV t;
7479: int i,len;
7480:
7481: if ( !p ) return 0;
7482: m0 = 0;
7483: len = p->len;
7484: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7485: NEXTNM(m0,m);
7486: ndl_copy(DL(t),DL(m));
1.6 noro 7487: CZ(m) = CZ(t);
1.1 noro 7488: }
7489: NEXT(m) = 0;
7490: MKND(NV(p),m0,len,d);
7491: SG(d) = SG(p);
1.28 noro 7492: d->sig = p->sig;
1.1 noro 7493: return d;
7494: }
7495:
7496: DP ndvtodp(int mod,NDV p)
7497: {
7498: MP m,m0;
7499: DP d;
7500: NMV t;
7501: int i,len;
7502:
7503: if ( !p ) return 0;
7504: m0 = 0;
7505: len = p->len;
7506: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7507: NEXTMP(m0,m);
7508: m->dl = ndltodl(nd_nvar,DL(t));
7509: m->c = (Obj)ndctop(mod,t->c);
7510: }
7511: NEXT(m) = 0;
7512: MKDP(nd_nvar,m0,d);
7513: SG(d) = SG(p);
7514: return d;
7515: }
7516:
1.44 noro 7517: DPM sigtodpm(SIG s)
7518: {
7519: DMM m;
7520: DPM d;
7521:
7522: NEWDMM(m);
7523: m->c = (Obj)ONE;
7524: m->dl = s->dl;
7525: m->pos = s->pos+1;
7526: m->next = 0;
7527: MKDPM(nd_nvar,m,d);
7528: SG(d) = s->dl->td;
7529: return d;
7530: }
7531:
1.16 noro 7532: DPM ndvtodpm(int mod,NDV p)
7533: {
7534: DMM m,m0;
7535: DPM d;
7536: NMV t;
7537: int i,len;
7538:
7539: if ( !p ) return 0;
7540: m0 = 0;
7541: len = p->len;
7542: for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) {
7543: NEXTDMM(m0,m);
7544: m->dl = ndltodl(nd_nvar,DL(t));
7545: m->c = (Obj)ndctop(mod,t->c);
7546: m->pos = MPOS(DL(t));
7547: }
7548: NEXT(m) = 0;
7549: MKDPM(nd_nvar,m0,d);
7550: SG(d) = SG(p);
7551: return d;
7552: }
7553:
7554:
1.1 noro 7555: DP ndtodp(int mod,ND p)
7556: {
1.65 noro 7557: MP m,m0;
1.1 noro 7558: DP d;
1.65 noro 7559: NM t;
1.1 noro 7560:
1.65 noro 7561: if ( !p ) return 0;
7562: m0 = 0;
7563: for ( t = BDY(p); t; t = NEXT(t) ) {
7564: NEXTMP(m0,m);
7565: m->dl = ndltodl(nd_nvar,DL(t));
7566: m->c = (Obj)ndctop(mod,t->c);
7567: }
7568: NEXT(m) = 0;
1.1 noro 7569: MKDP(nd_nvar,m0,d);
1.65 noro 7570: SG(d) = SG(p);
7571: return d;
1.1 noro 7572: }
7573:
7574: void ndv_print(NDV p)
7575: {
7576: NMV m;
7577: int i,len;
7578:
7579: if ( !p ) printf("0\n");
7580: else {
7581: len = LEN(p);
7582: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7583: if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m)));
1.28 noro 7584: else printf("+%ld*",CM(m));
1.1 noro 7585: ndl_print(DL(m));
7586: }
7587: printf("\n");
7588: }
7589: }
7590:
7591: void ndv_print_q(NDV p)
7592: {
7593: NMV m;
7594: int i,len;
7595:
7596: if ( !p ) printf("0\n");
7597: else {
7598: len = LEN(p);
7599: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
7600: printf("+");
1.6 noro 7601: printexpr(CO,(Obj)CZ(m));
1.1 noro 7602: printf("*");
7603: ndl_print(DL(m));
7604: }
7605: printf("\n");
7606: }
7607: }
7608:
7609: NODE ndv_reducebase(NODE x,int *perm)
7610: {
7611: int len,i,j;
7612: NDVI w;
7613: NODE t,t0;
7614:
1.41 noro 7615: if ( nd_norb ) return x;
1.1 noro 7616: len = length(x);
7617: w = (NDVI)MALLOC(len*sizeof(struct oNDVI));
7618: for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) {
7619: w[i].p = BDY(t); w[i].i = perm[i];
7620: }
7621: for ( i = 0; i < len; i++ ) {
7622: for ( j = 0; j < i; j++ ) {
7623: if ( w[i].p && w[j].p ) {
7624: if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0;
7625: else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0;
7626: }
7627: }
7628: }
7629: for ( i = j = 0, t0 = 0; i < len; i++ ) {
7630: if ( w[i].p ) {
7631: NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p;
7632: perm[j++] = w[i].i;
7633: }
7634: }
7635: NEXT(t) = 0; x = t0;
7636: return x;
7637: }
7638:
7639: /* XXX incomplete */
7640:
1.21 noro 7641: extern DMMstack dmm_stack;
7642: int ndl_module_schreyer_compare(UINT *a,UINT *b);
1.16 noro 7643:
1.1 noro 7644: void nd_init_ord(struct order_spec *ord)
7645: {
7646: nd_module = (ord->id >= 256);
7647: if ( nd_module ) {
7648: nd_dcomp = -1;
1.21 noro 7649: nd_module_ordtype = ord->module_ordtype;
1.1 noro 7650: nd_pot_nelim = ord->pot_nelim;
7651: nd_poly_weight_len = ord->nv;
7652: nd_poly_weight = ord->top_weight;
7653: nd_module_rank = ord->module_rank;
7654: nd_module_weight = ord->module_top_weight;
7655: }
7656: nd_matrix = 0;
7657: nd_matrix_len = 0;
7658: switch ( ord->id ) {
7659: case 0:
7660: switch ( ord->ord.simple ) {
7661: case 0:
7662: nd_dcomp = 1;
7663: nd_isrlex = 1;
7664: break;
7665: case 1:
7666: nd_dcomp = 1;
7667: nd_isrlex = 0;
7668: break;
7669: case 2:
7670: nd_dcomp = 0;
7671: nd_isrlex = 0;
7672: ndl_compare_function = ndl_lex_compare;
7673: break;
7674: case 11:
7675: /* XXX */
7676: nd_dcomp = 0;
7677: nd_isrlex = 1;
7678: ndl_compare_function = ndl_ww_lex_compare;
7679: break;
7680: default:
7681: error("nd_gr : unsupported order");
7682: }
7683: break;
7684: case 1:
7685: /* block order */
7686: /* XXX */
7687: nd_dcomp = -1;
7688: nd_isrlex = 0;
7689: ndl_compare_function = ndl_block_compare;
7690: break;
7691: case 2:
7692: /* matrix order */
7693: /* XXX */
7694: nd_dcomp = -1;
7695: nd_isrlex = 0;
7696: nd_matrix_len = ord->ord.matrix.row;
7697: nd_matrix = ord->ord.matrix.matrix;
7698: ndl_compare_function = ndl_matrix_compare;
7699: break;
7700: case 3:
7701: /* composite order */
7702: nd_dcomp = -1;
7703: nd_isrlex = 0;
7704: nd_worb_len = ord->ord.composite.length;
7705: nd_worb = ord->ord.composite.w_or_b;
7706: ndl_compare_function = ndl_composite_compare;
7707: break;
7708:
7709: /* module order */
7710: case 256:
7711: switch ( ord->ord.simple ) {
7712: case 0:
1.21 noro 7713: nd_dcomp = 0;
1.1 noro 7714: nd_isrlex = 1;
1.21 noro 7715: ndl_compare_function = ndl_module_glex_compare;
1.1 noro 7716: break;
7717: case 1:
1.21 noro 7718: nd_dcomp = 0;
1.1 noro 7719: nd_isrlex = 0;
7720: ndl_compare_function = ndl_module_glex_compare;
7721: break;
7722: case 2:
1.21 noro 7723: nd_dcomp = 0;
1.1 noro 7724: nd_isrlex = 0;
1.21 noro 7725: ndl_compare_function = ndl_module_compare;
7726: ndl_base_compare_function = ndl_lex_compare;
1.1 noro 7727: break;
7728: default:
1.21 noro 7729: error("nd_init_ord : unsupported order");
1.1 noro 7730: }
7731: break;
7732: case 257:
7733: /* block order */
7734: nd_isrlex = 0;
1.21 noro 7735: ndl_compare_function = ndl_module_compare;
7736: ndl_base_compare_function = ndl_block_compare;
1.1 noro 7737: break;
7738: case 258:
7739: /* matrix order */
7740: nd_isrlex = 0;
7741: nd_matrix_len = ord->ord.matrix.row;
7742: nd_matrix = ord->ord.matrix.matrix;
1.21 noro 7743: ndl_compare_function = ndl_module_compare;
7744: ndl_base_compare_function = ndl_matrix_compare;
1.1 noro 7745: break;
7746: case 259:
7747: /* composite order */
7748: nd_isrlex = 0;
7749: nd_worb_len = ord->ord.composite.length;
7750: nd_worb = ord->ord.composite.w_or_b;
1.21 noro 7751: ndl_compare_function = ndl_module_compare;
7752: ndl_base_compare_function = ndl_composite_compare;
7753: break;
7754: case 300:
7755: /* schreyer order */
7756: if ( ord->base->id != 256 )
7757: error("nd_init_ord : unsupported base order");
7758: ndl_compare_function = ndl_module_schreyer_compare;
7759: dmm_stack = ord->dmmstack;
7760: switch ( ord->base->ord.simple ) {
7761: case 0:
7762: nd_isrlex = 1;
7763: ndl_base_compare_function = ndl_glex_compare;
7764: dl_base_compare_function = cmpdl_revgradlex;
7765: break;
7766: case 1:
7767: nd_isrlex = 0;
7768: ndl_base_compare_function = ndl_glex_compare;
7769: dl_base_compare_function = cmpdl_gradlex;
7770: break;
7771: case 2:
7772: nd_isrlex = 0;
7773: ndl_base_compare_function = ndl_lex_compare;
7774: dl_base_compare_function = cmpdl_lex;
7775: break;
7776: default:
7777: error("nd_init_ord : unsupported order");
7778: }
1.1 noro 7779: break;
7780: }
7781: nd_ord = ord;
7782: }
7783:
7784: BlockMask nd_create_blockmask(struct order_spec *ord)
7785: {
7786: int n,i,j,s,l;
7787: UINT *t;
7788: BlockMask bm;
7789:
7790: /* we only create mask table for block order */
7791: if ( ord->id != 1 && ord->id != 257 )
7792: return 0;
7793: n = ord->ord.block.length;
7794: bm = (BlockMask)MALLOC(sizeof(struct oBlockMask));
7795: bm->n = n;
7796: bm->order_pair = ord->ord.block.order_pair;
7797: bm->mask = (UINT **)MALLOC(n*sizeof(UINT *));
7798: for ( i = 0, s = 0; i < n; i++ ) {
7799: bm->mask[i] = t = (UINT *)MALLOC_ATOMIC(nd_wpd*sizeof(UINT));
7800: for ( j = 0; j < nd_wpd; j++ ) t[j] = 0;
7801: l = bm->order_pair[i].length;
7802: for ( j = 0; j < l; j++, s++ ) PUT_EXP(t,s,nd_mask0);
7803: }
7804: return bm;
7805: }
7806:
7807: EPOS nd_create_epos(struct order_spec *ord)
7808: {
7809: int i,j,l,s,ord_l,ord_o;
7810: EPOS epos;
7811: struct order_pair *op;
7812:
7813: epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS));
7814: switch ( ord->id ) {
1.21 noro 7815: case 0: case 256: case 300:
1.1 noro 7816: if ( nd_isrlex ) {
7817: for ( i = 0; i < nd_nvar; i++ ) {
7818: epos[i].i = nd_exporigin + (nd_nvar-1-i)/nd_epw;
7819: epos[i].s = (nd_epw-((nd_nvar-1-i)%nd_epw)-1)*nd_bpe;
7820: }
7821: } else {
7822: for ( i = 0; i < nd_nvar; i++ ) {
7823: epos[i].i = nd_exporigin + i/nd_epw;
7824: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
7825: }
7826: }
7827: break;
7828: case 1: case 257:
7829: /* block order */
7830: l = ord->ord.block.length;
7831: op = ord->ord.block.order_pair;
7832: for ( j = 0, s = 0; j < l; j++ ) {
7833: ord_o = op[j].order;
7834: ord_l = op[j].length;
7835: if ( !ord_o )
7836: for ( i = 0; i < ord_l; i++ ) {
7837: epos[s+i].i = nd_exporigin + (s+ord_l-i-1)/nd_epw;
7838: epos[s+i].s = (nd_epw-((s+ord_l-i-1)%nd_epw)-1)*nd_bpe;
7839: }
7840: else
7841: for ( i = 0; i < ord_l; i++ ) {
7842: epos[s+i].i = nd_exporigin + (s+i)/nd_epw;
7843: epos[s+i].s = (nd_epw-((s+i)%nd_epw)-1)*nd_bpe;
7844: }
7845: s += ord_l;
7846: }
7847: break;
7848: case 2:
7849: /* matrix order */
7850: case 3:
7851: /* composite order */
7852: default:
7853: for ( i = 0; i < nd_nvar; i++ ) {
7854: epos[i].i = nd_exporigin + i/nd_epw;
7855: epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe;
7856: }
7857: break;
7858: }
7859: return epos;
7860: }
7861:
7862: /* external interface */
7863:
7864: void nd_nf_p(Obj f,LIST g,LIST v,int m,struct order_spec *ord,Obj *rp)
7865: {
7866: NODE t,in0,in;
7867: ND ndf,nf;
7868: NDV ndvf;
7869: VL vv,tv;
7870: int stat,nvar,max,mrank;
7871: Q cont;
7872: P pp;
7873: LIST ppl;
7874:
7875: if ( !f ) {
7876: *rp = 0;
7877: return;
7878: }
7879: pltovl(v,&vv);
7880: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
7881:
7882: /* max=65536 implies nd_bpe=32 */
7883: max = 65536;
7884:
7885: nd_module = 0;
7886: /* nd_module will be set if ord is a module ordering */
7887: nd_init_ord(ord);
7888: nd_setup_parameters(nvar,max);
7889: if ( nd_module && OID(f) != O_LIST )
7890: error("nd_nf_p : the first argument must be a list");
7891: if ( nd_module ) mrank = length(BDY((LIST)f));
7892: /* conversion to ndv */
7893: for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) {
7894: NEXTNODE(in0,in);
7895: if ( nd_module ) {
7896: if ( !BDY(t) || OID(BDY(t)) != O_LIST
7897: || length(BDY((LIST)BDY(t))) != mrank )
7898: error("nd_nf_p : inconsistent basis element");
7899: if ( !m ) pltozpl((LIST)BDY(t),&cont,&ppl);
7900: else ppl = (LIST)BDY(t);
7901: BDY(in) = (pointer)pltondv(CO,vv,ppl);
7902: } else {
7903: if ( !m ) ptozp((P)BDY(t),1,&cont,&pp);
7904: else pp = (P)BDY(t);
7905: BDY(in) = (pointer)ptondv(CO,vv,pp);
7906: }
7907: if ( m ) ndv_mod(m,(NDV)BDY(in));
7908: }
7909: if ( in0 ) NEXT(in) = 0;
7910:
7911: if ( nd_module ) ndvf = pltondv(CO,vv,(LIST)f);
7912: else ndvf = ptondv(CO,vv,(P)f);
7913: if ( m ) ndv_mod(m,ndvf);
7914: ndf = (pointer)ndvtond(m,ndvf);
7915:
7916: /* dont sort, dont removecont */
1.24 noro 7917: ndv_setup(m,0,in0,1,1,0);
1.1 noro 7918: nd_scale=2;
1.6 noro 7919: stat = nd_nf(m,0,ndf,nd_ps,1,&nf);
1.1 noro 7920: if ( !stat )
7921: error("nd_nf_p : exponent too large");
7922: if ( nd_module ) *rp = (Obj)ndvtopl(m,CO,vv,ndtondv(m,nf),mrank);
7923: else *rp = (Obj)ndvtop(m,CO,vv,ndtondv(m,nf));
7924: }
7925:
7926: int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r)
7927: {
7928: NM m;
7929: UINT *t,*s;
7930: int i;
7931:
7932: for ( i = 0; i < n; i++ ) r[i] = 0;
7933: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7934: t = DL(m);
7935: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
7936: r[i] = CM(m);
7937: }
7938: for ( i = 0; !r[i]; i++ );
7939: return i;
7940: }
7941:
7942: int nd_to_vect_q(UINT *s0,int n,ND d,Z *r)
7943: {
7944: NM m;
7945: UINT *t,*s;
7946: int i;
7947:
7948: for ( i = 0; i < n; i++ ) r[i] = 0;
7949: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7950: t = DL(m);
7951: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.6 noro 7952: r[i] = CZ(m);
1.1 noro 7953: }
7954: for ( i = 0; !r[i]; i++ );
7955: return i;
7956: }
7957:
7958: int nd_to_vect_lf(UINT *s0,int n,ND d,mpz_t *r)
7959: {
7960: NM m;
7961: UINT *t,*s;
7962: int i;
7963:
7964: for ( i = 0; i < n; i++ ) { mpz_init(r[i]); mpz_set_ui(r[i],0); }
7965: for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) {
7966: t = DL(m);
7967: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
7968: mpz_set(r[i],BDY(CZ(m)));
7969: }
7970: for ( i = 0; !mpz_sgn(r[i]); i++ );
7971: return i;
7972: }
7973:
7974: unsigned long *nd_to_vect_2(UINT *s0,int n,int *s0hash,ND p)
7975: {
7976: NM m;
7977: unsigned long *v;
7978: int i,j,h,size;
7979: UINT *s,*t;
7980:
7981: size = sizeof(unsigned long)*(n+BLEN-1)/BLEN;
7982: v = (unsigned long *)MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
7983: bzero(v,size);
7984: for ( i = j = 0, s = s0, m = BDY(p); m; j++, m = NEXT(m) ) {
7985: t = DL(m);
7986: h = ndl_hash_value(t);
7987: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
7988: v[i/BLEN] |= 1L <<(i%BLEN);
7989: }
7990: return v;
7991: }
7992:
7993: int nd_nm_to_vect_2(UINT *s0,int n,int *s0hash,NDV p,NM m,unsigned long *v)
7994: {
7995: NMV mr;
7996: UINT *d,*t,*s;
7997: int i,j,len,h,head;
7998:
7999: d = DL(m);
8000: len = LEN(p);
8001: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8002: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
8003: ndl_add(d,DL(mr),t);
8004: h = ndl_hash_value(t);
8005: for ( ; h != s0hash[i] || !ndl_equal(t,s); s += nd_wpd, i++ );
8006: if ( j == 0 ) head = i;
8007: v[i/BLEN] |= 1L <<(i%BLEN);
8008: }
8009: return head;
8010: }
8011:
8012: Z *nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_pair pair)
8013: {
8014: NM m;
8015: NMV mr;
8016: UINT *d,*t,*s;
8017: NDV p;
8018: int i,j,len;
8019: Z *r;
8020:
8021: m = pair->mul;
8022: d = DL(m);
8023: p = nd_ps[pair->index];
8024: len = LEN(p);
8025: r = (Z *)CALLOC(n,sizeof(Q));
8026: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8027: for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) {
8028: ndl_add(d,DL(mr),t);
8029: for ( ; !ndl_equal(t,s); s += nd_wpd, i++ );
1.6 noro 8030: r[i] = CZ(mr);
1.1 noro 8031: }
8032: return r;
8033: }
8034:
1.11 noro 8035: IndArray nm_ind_pair_to_vect_compress(int trace,UINT *s0,int n,NM_ind_pair pair,int start)
1.1 noro 8036: {
8037: NM m;
8038: NMV mr;
1.65 noro 8039: UINT *d,*t,*u;
1.1 noro 8040: NDV p;
8041: unsigned char *ivc;
8042: unsigned short *ivs;
1.65 noro 8043: UINT *v,*ivi;
8044: int i,j,len,prev,diff,cdiff,st,ed,md,c;
1.1 noro 8045: IndArray r;
8046:
8047: m = pair->mul;
8048: d = DL(m);
8049: if ( trace )
8050: p = nd_demand?nd_ps_trace_sym[pair->index]:nd_ps_trace[pair->index];
8051: else
8052: p = nd_demand?nd_ps_sym[pair->index]:nd_ps[pair->index];
8053:
8054: len = LEN(p);
8055: t = (UINT *)MALLOC(nd_wpd*sizeof(UINT));
8056: v = (unsigned int *)MALLOC(len*sizeof(unsigned int));
1.11 noro 8057: for ( prev = start, mr = BDY(p), j = 0; j < len; j++, NMV_ADV(mr) ) {
8058: ndl_add(d,DL(mr),t);
8059: st = prev;
8060: ed = n;
8061: while ( ed > st ) {
8062: md = (st+ed)/2;
8063: u = s0+md*nd_wpd;
8064: c = DL_COMPARE(u,t);
8065: if ( c == 0 ) break;
8066: else if ( c > 0 ) st = md;
8067: else ed = md;
8068: }
8069: prev = v[j] = md;
1.1 noro 8070: }
8071: r = (IndArray)MALLOC(sizeof(struct oIndArray));
8072: r->head = v[0];
8073: diff = 0;
8074: for ( i = 1; i < len; i++ ) {
8075: cdiff = v[i]-v[i-1]; diff = MAX(cdiff,diff);
8076: }
8077: if ( diff < 256 ) {
8078: r->width = 1;
8079: ivc = (unsigned char *)MALLOC_ATOMIC(len*sizeof(unsigned char));
8080: r->index.c = ivc;
8081: for ( i = 1, ivc[0] = 0; i < len; i++ ) ivc[i] = v[i]-v[i-1];
8082: } else if ( diff < 65536 ) {
8083: r->width = 2;
8084: ivs = (unsigned short *)MALLOC_ATOMIC(len*sizeof(unsigned short));
8085: r->index.s = ivs;
8086: for ( i = 1, ivs[0] = 0; i < len; i++ ) ivs[i] = v[i]-v[i-1];
8087: } else {
8088: r->width = 4;
8089: ivi = (unsigned int *)MALLOC_ATOMIC(len*sizeof(unsigned int));
8090: r->index.i = ivi;
8091: for ( i = 1, ivi[0] = 0; i < len; i++ ) ivi[i] = v[i]-v[i-1];
8092: }
8093: return r;
8094: }
8095:
8096: int compress_array(Z *svect,Z *cvect,int n)
8097: {
8098: int i,j;
8099:
8100: for ( i = j = 0; i < n; i++ )
8101: if ( svect[i] ) cvect[j++] = svect[i];
8102: return j;
8103: }
8104:
8105: void expand_array(Z *svect,Z *cvect,int n)
8106: {
8107: int i,j;
8108:
8109: for ( i = j = 0; j < n; i++ )
8110: if ( svect[i] ) svect[i] = cvect[j++];
8111: }
8112:
1.8 noro 8113: #if 0
1.1 noro 8114: int ndv_reduce_vect_q(Z *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8115: {
8116: int i,j,k,len,pos,prev,nz;
8117: Z cs,mcs,c1,c2,cr,gcd,t;
8118: IndArray ivect;
8119: unsigned char *ivc;
8120: unsigned short *ivs;
8121: unsigned int *ivi;
8122: NDV redv;
8123: NMV mr;
8124: NODE rp;
8125: int maxrs;
8126: double hmag;
8127: Z *cvect;
1.3 noro 8128: int l;
1.1 noro 8129:
8130: maxrs = 0;
8131: for ( i = 0; i < col && !svect[i]; i++ );
8132: if ( i == col ) return maxrs;
8133: hmag = p_mag((P)svect[i])*nd_scale;
8134: cvect = (Z *)MALLOC(col*sizeof(Q));
8135: for ( i = 0; i < nred; i++ ) {
8136: ivect = imat[i];
8137: k = ivect->head;
8138: if ( svect[k] ) {
8139: maxrs = MAX(maxrs,rp0[i]->sugar);
8140: redv = nd_demand?ndv_load(rp0[i]->index)
8141: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
8142: len = LEN(redv); mr = BDY(redv);
1.6 noro 8143: igcd_cofactor(svect[k],CZ(mr),&gcd,&cs,&cr);
1.1 noro 8144: chsgnz(cs,&mcs);
8145: if ( !UNIQ(cr) ) {
8146: for ( j = 0; j < col; j++ ) {
8147: mulz(svect[j],cr,&c1); svect[j] = c1;
8148: }
8149: }
8150: svect[k] = 0; prev = k;
8151: switch ( ivect->width ) {
8152: case 1:
8153: ivc = ivect->index.c;
8154: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8155: pos = prev+ivc[j]; prev = pos;
1.6 noro 8156: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8157: }
8158: break;
8159: case 2:
8160: ivs = ivect->index.s;
8161: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8162: pos = prev+ivs[j]; prev = pos;
1.6 noro 8163: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8164: }
8165: break;
8166: case 4:
8167: ivi = ivect->index.i;
8168: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8169: pos = prev+ivi[j]; prev = pos;
1.6 noro 8170: muladdtoz(CZ(mr),mcs,&svect[pos]);
1.1 noro 8171: }
8172: break;
8173: }
8174: for ( j = k+1; j < col && !svect[j]; j++ );
8175: if ( j == col ) break;
8176: if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) {
8177: nz = compress_array(svect,cvect,col);
8178: removecont_array((P *)cvect,nz,1);
8179: expand_array(svect,cvect,nz);
8180: hmag = ((double)p_mag((P)svect[j]))*nd_scale;
8181: }
8182: }
8183: }
8184: nz = compress_array(svect,cvect,col);
8185: removecont_array((P *)cvect,nz,1);
8186: expand_array(svect,cvect,nz);
8187: if ( DP_Print ) {
8188: fprintf(asir_out,"-"); fflush(asir_out);
8189: }
8190: return maxrs;
8191: }
1.4 noro 8192: #else
1.9 noro 8193:
1.4 noro 8194: /* direct mpz version */
8195: int ndv_reduce_vect_q(Z *svect0,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8196: {
8197: int i,j,k,len,pos,prev;
8198: mpz_t cs,cr,gcd;
8199: IndArray ivect;
8200: unsigned char *ivc;
8201: unsigned short *ivs;
8202: unsigned int *ivi;
8203: NDV redv;
8204: NMV mr;
8205: int maxrs;
8206: double hmag;
1.13 noro 8207: static mpz_t *svect;
8208: static int svect_len=0;
1.4 noro 8209:
8210: maxrs = 0;
8211: for ( i = 0; i < col && !svect0[i]; i++ );
8212: if ( i == col ) return maxrs;
8213: hmag = p_mag((P)svect0[i])*nd_scale;
1.13 noro 8214: if ( col > svect_len ) {
8215: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
8216: svect_len = col;
8217: }
1.4 noro 8218: for ( i = 0; i < col; i++ ) {
8219: mpz_init(svect[i]);
8220: if ( svect0[i] )
8221: mpz_set(svect[i],BDY(svect0[i]));
8222: else
8223: mpz_set_ui(svect[i],0);
8224: }
8225: mpz_init(gcd); mpz_init(cs); mpz_init(cr);
8226: for ( i = 0; i < nred; i++ ) {
8227: ivect = imat[i];
8228: k = ivect->head;
8229: if ( mpz_sgn(svect[k]) ) {
8230: maxrs = MAX(maxrs,rp0[i]->sugar);
8231: redv = nd_demand?ndv_load(rp0[i]->index)
8232: :(trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]);
8233: len = LEN(redv); mr = BDY(redv);
1.6 noro 8234: mpz_gcd(gcd,svect[k],BDY(CZ(mr)));
1.4 noro 8235: mpz_div(cs,svect[k],gcd);
1.6 noro 8236: mpz_div(cr,BDY(CZ(mr)),gcd);
1.4 noro 8237: mpz_neg(cs,cs);
1.9 noro 8238: if ( MUNIMPZ(cr) )
8239: for ( j = 0; j < col; j++ ) mpz_neg(svect[j],svect[j]);
8240: else if ( !UNIMPZ(cr) )
8241: for ( j = 0; j < col; j++ ) {
8242: if ( mpz_sgn(svect[j]) ) mpz_mul(svect[j],svect[j],cr);
8243: }
1.4 noro 8244: mpz_set_ui(svect[k],0);
8245: prev = k;
8246: switch ( ivect->width ) {
8247: case 1:
8248: ivc = ivect->index.c;
8249: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8250: pos = prev+ivc[j]; prev = pos;
1.6 noro 8251: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8252: }
8253: break;
8254: case 2:
8255: ivs = ivect->index.s;
8256: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8257: pos = prev+ivs[j]; prev = pos;
1.6 noro 8258: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8259: }
8260: break;
8261: case 4:
8262: ivi = ivect->index.i;
8263: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8264: pos = prev+ivi[j]; prev = pos;
1.6 noro 8265: mpz_addmul(svect[pos],BDY(CZ(mr)),cs);
1.4 noro 8266: }
8267: break;
8268: }
8269: for ( j = k+1; j < col && !svect[j]; j++ );
8270: if ( j == col ) break;
8271: if ( hmag && ((double)mpz_sizeinbase(svect[j],2) > hmag) ) {
8272: mpz_removecont_array(svect,col);
8273: hmag = ((double)mpz_sizeinbase(svect[j],2))*nd_scale;
8274: }
8275: }
8276: }
8277: mpz_removecont_array(svect,col);
8278: if ( DP_Print ) {
8279: fprintf(asir_out,"-"); fflush(asir_out);
8280: }
8281: for ( i = 0; i < col; i++ )
8282: if ( mpz_sgn(svect[i]) ) MPZTOZ(svect[i],svect0[i]);
8283: else svect0[i] = 0;
8284: return maxrs;
8285: }
8286: #endif
1.1 noro 8287:
1.40 noro 8288: int ndv_reduce_vect(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred,SIG sig)
1.1 noro 8289: {
8290: int i,j,k,len,pos,prev;
8291: UINT c,c1,c2,c3,up,lo,dmy;
8292: IndArray ivect;
8293: unsigned char *ivc;
8294: unsigned short *ivs;
8295: unsigned int *ivi;
8296: NDV redv;
8297: NMV mr;
8298: int maxrs;
8299:
8300: maxrs = 0;
8301: for ( i = 0; i < nred; i++ ) {
8302: ivect = imat[i];
8303: k = ivect->head; svect[k] %= m;
1.40 noro 8304: if ( (c = svect[k]) != 0 && (sig == 0 || comp_sig(sig,rp0[i]->sig) > 0 ) ) {
1.1 noro 8305: maxrs = MAX(maxrs,rp0[i]->sugar);
8306: c = m-c; redv = nd_ps[rp0[i]->index];
8307: len = LEN(redv); mr = BDY(redv);
8308: svect[k] = 0; prev = k;
8309: switch ( ivect->width ) {
8310: case 1:
8311: ivc = ivect->index.c;
8312: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8313: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.40 noro 8314: if ( c1 ) {
8315: c2 = svect[pos];
1.1 noro 8316: DMA(c1,c,c2,up,lo);
8317: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8318: } else svect[pos] = lo;
1.40 noro 8319: }
1.1 noro 8320: }
8321: break;
8322: case 2:
8323: ivs = ivect->index.s;
8324: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8325: pos = prev+ivs[j]; c1 = CM(mr);
8326: prev = pos;
1.40 noro 8327: if ( c1 ) {
8328: c2 = svect[pos];
1.1 noro 8329: DMA(c1,c,c2,up,lo);
8330: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8331: } else svect[pos] = lo;
1.40 noro 8332: }
1.1 noro 8333: }
8334: break;
8335: case 4:
8336: ivi = ivect->index.i;
8337: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8338: pos = prev+ivi[j]; c1 = CM(mr);
8339: prev = pos;
1.40 noro 8340: if ( c1 ) {
8341: c2 = svect[pos];
1.1 noro 8342: DMA(c1,c,c2,up,lo);
8343: if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3;
8344: } else svect[pos] = lo;
1.40 noro 8345: }
1.1 noro 8346: }
8347: break;
8348: }
8349: }
8350: }
8351: for ( i = 0; i < col; i++ )
8352: if ( svect[i] >= (UINT)m ) svect[i] %= m;
8353: return maxrs;
8354: }
8355:
8356: int ndv_reduce_vect_sf(int m,UINT *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8357: {
8358: int i,j,k,len,pos,prev;
1.65 noro 8359: UINT c;
1.1 noro 8360: IndArray ivect;
8361: unsigned char *ivc;
8362: unsigned short *ivs;
8363: unsigned int *ivi;
8364: NDV redv;
8365: NMV mr;
8366: int maxrs;
8367:
8368: maxrs = 0;
8369: for ( i = 0; i < nred; i++ ) {
8370: ivect = imat[i];
8371: k = ivect->head;
8372: if ( (c = svect[k]) != 0 ) {
8373: maxrs = MAX(maxrs,rp0[i]->sugar);
8374: c = _chsgnsf(c); redv = nd_ps[rp0[i]->index];
8375: len = LEN(redv); mr = BDY(redv);
8376: svect[k] = 0; prev = k;
8377: switch ( ivect->width ) {
8378: case 1:
8379: ivc = ivect->index.c;
8380: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8381: pos = prev+ivc[j]; prev = pos;
8382: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8383: }
8384: break;
8385: case 2:
8386: ivs = ivect->index.s;
8387: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8388: pos = prev+ivs[j]; prev = pos;
8389: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8390: }
8391: break;
8392: case 4:
8393: ivi = ivect->index.i;
8394: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8395: pos = prev+ivi[j]; prev = pos;
8396: svect[pos] = _addsf(_mulsf(CM(mr),c),svect[pos]);
8397: }
8398: break;
8399: }
8400: }
8401: }
8402: return maxrs;
8403: }
8404:
8405: ND nd_add_lf(ND p1,ND p2)
8406: {
1.65 noro 8407: int c,can;
1.1 noro 8408: NM m1,m2,mr0,mr,s;
8409: Z t;
8410:
8411: if ( !p1 ) return p2;
8412: else if ( !p2 ) return p1;
8413: else {
8414: can = 0;
1.65 noro 8415: for ( m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1.1 noro 8416: c = DL_COMPARE(DL(m1),DL(m2));
8417: switch ( c ) {
8418: case 0:
8419: addlf(CZ(m1),CZ(m2),&t);
8420: s = m1; m1 = NEXT(m1);
8421: if ( t ) {
8422: can++; NEXTNM2(mr0,mr,s); CZ(mr) = (t);
8423: } else {
8424: can += 2; FREENM(s);
8425: }
8426: s = m2; m2 = NEXT(m2); FREENM(s);
8427: break;
8428: case 1:
8429: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
8430: break;
8431: case -1:
8432: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
8433: break;
8434: }
8435: }
8436: if ( !mr0 )
8437: if ( m1 ) mr0 = m1;
8438: else if ( m2 ) mr0 = m2;
8439: else return 0;
8440: else if ( m1 ) NEXT(mr) = m1;
8441: else if ( m2 ) NEXT(mr) = m2;
8442: else NEXT(mr) = 0;
8443: BDY(p1) = mr0;
8444: SG(p1) = MAX(SG(p1),SG(p2));
8445: LEN(p1) = LEN(p1)+LEN(p2)-can;
8446: FREEND(p2);
8447: return p1;
8448: }
8449: }
8450:
8451: int ndv_reduce_vect_lf(mpz_t *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred)
8452: {
8453: int i,j,k,len,pos,prev;
8454: IndArray ivect;
8455: unsigned char *ivc;
8456: unsigned short *ivs;
8457: unsigned int *ivi;
8458: NDV redv;
8459: NMV mr;
8460: int maxrs;
8461:
8462: maxrs = 0;
8463: lf_lazy = 1;
8464: for ( i = 0; i < nred; i++ ) {
8465: ivect = imat[i];
8466: k = ivect->head;
8467: mpz_mod(svect[k],svect[k],BDY(current_mod_lf));
8468: if ( mpz_sgn(svect[k]) ) {
8469: maxrs = MAX(maxrs,rp0[i]->sugar);
8470: mpz_neg(svect[k],svect[k]);
8471: redv = trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index];
8472: len = LEN(redv); mr = BDY(redv);
8473: prev = k;
8474: switch ( ivect->width ) {
8475: case 1:
8476: ivc = ivect->index.c;
8477: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8478: pos = prev+ivc[j]; prev = pos;
8479: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8480: }
8481: break;
8482: case 2:
8483: ivs = ivect->index.s;
8484: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8485: pos = prev+ivs[j]; prev = pos;
8486: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8487: }
8488: break;
8489: case 4:
8490: ivi = ivect->index.i;
8491: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
8492: pos = prev+ivi[j]; prev = pos;
8493: mpz_addmul(svect[pos],svect[k],BDY(CZ(mr)));
8494: }
8495: break;
8496: }
8497: mpz_set_ui(svect[k],0);
8498: }
8499: }
8500: lf_lazy=0;
8501: for ( i = 0; i < col; i++ ) {
8502: mpz_mod(svect[i],svect[i],BDY(current_mod_lf));
8503: }
8504: return maxrs;
8505: }
8506:
8507: int nd_gauss_elim_lf(mpz_t **mat0,int *sugar,int row,int col,int *colstat)
8508: {
8509: int i,j,k,l,rank,s;
1.65 noro 8510: mpz_t a,inv;
1.1 noro 8511: mpz_t *t,*pivot,*pk;
8512: mpz_t **mat;
8513:
8514: mpz_init(inv);
8515: mpz_init(a);
8516: mat = (mpz_t **)mat0;
8517: for ( rank = 0, j = 0; j < col; j++ ) {
8518: for ( i = rank; i < row; i++ ) {
8519: mpz_mod(mat[i][j],mat[i][j],BDY(current_mod_lf));
8520: }
8521: for ( i = rank; i < row; i++ )
8522: if ( mpz_sgn(mat[i][j]) )
8523: break;
8524: if ( i == row ) {
8525: colstat[j] = 0;
8526: continue;
8527: } else
8528: colstat[j] = 1;
8529: if ( i != rank ) {
8530: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
8531: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
8532: }
8533: pivot = mat[rank];
8534: s = sugar[rank];
8535: mpz_invert(inv,pivot[j],BDY(current_mod_lf));
8536: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
8537: if ( mpz_sgn(*pk) ) {
8538: mpz_mul(a,*pk,inv); mpz_mod(*pk,a,BDY(current_mod_lf));
8539: }
8540: for ( i = rank+1; i < row; i++ ) {
8541: t = mat[i];
8542: if ( mpz_sgn(t[j]) ) {
8543: sugar[i] = MAX(sugar[i],s);
8544: mpz_neg(a,t[j]);
8545: red_by_vect_lf(t+j,pivot+j,a,col-j);
8546: }
8547: }
8548: rank++;
8549: }
8550: for ( j = col-1, l = rank-1; j >= 0; j-- )
8551: if ( colstat[j] ) {
8552: pivot = mat[l];
8553: s = sugar[l];
8554: for ( k = j; k < col; k++ )
8555: mpz_mod(pivot[k],pivot[k],BDY(current_mod_lf));
8556: for ( i = 0; i < l; i++ ) {
8557: t = mat[i];
8558: if ( mpz_sgn(t[j]) ) {
8559: sugar[i] = MAX(sugar[i],s);
8560: mpz_neg(a,t[j]);
8561: red_by_vect_lf(t+j,pivot+j,a,col-j);
8562: }
8563: }
8564: l--;
8565: }
8566: for ( j = 0, l = 0; l < rank; j++ )
8567: if ( colstat[j] ) {
8568: t = mat[l];
8569: for ( k = j; k < col; k++ ) {
8570: mpz_mod(t[k],t[k],BDY(current_mod_lf));
8571: }
8572: l++;
8573: }
8574: return rank;
8575: }
8576:
8577:
8578: NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhead,UINT *s0vect)
8579: {
8580: int j,k,len;
8581: UINT *p;
8582: UINT c;
8583: NDV r;
8584: NMV mr0,mr;
8585:
8586: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
8587: if ( !len ) return 0;
8588: else {
8589: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8590: #if 0
8591: ndv_alloc += nmv_adv*len;
8592: #endif
8593: mr = mr0;
8594: p = s0vect;
8595: for ( j = k = 0; j < col; j++, p += nd_wpd )
8596: if ( !rhead[j] ) {
8597: if ( (c = vect[k++]) != 0 ) {
8598: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
8599: }
8600: }
8601: MKNDV(nd_nvar,mr0,len,r);
8602: return r;
8603: }
8604: }
8605:
1.40 noro 8606: NDV vect_to_ndv_s(UINT *vect,int col,UINT *s0vect)
8607: {
8608: int j,k,len;
8609: UINT *p;
8610: UINT c;
8611: NDV r;
8612: NMV mr0,mr;
8613:
8614: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
8615: if ( !len ) return 0;
8616: else {
8617: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8618: mr = mr0;
8619: p = s0vect;
8620: for ( j = k = 0; j < col; j++, p += nd_wpd )
8621: if ( (c = vect[k++]) != 0 ) {
8622: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
8623: }
8624: MKNDV(nd_nvar,mr0,len,r);
8625: return r;
8626: }
8627: }
8628:
1.1 noro 8629: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect)
8630: {
1.65 noro 8631: int j,len;
1.1 noro 8632: UINT *p;
8633: NDV r;
8634: NMV mr0,mr;
8635:
8636: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) len++;
8637: if ( !len ) return 0;
8638: else {
8639: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
8640: mr = mr0;
8641: p = s0vect;
8642: for ( j = 0; j < col; j++, p += nd_wpd )
8643: if ( vect[j/BLEN] & (1L<<(j%BLEN)) ) {
8644: ndl_copy(p,DL(mr)); CM(mr) = 1; NMV_ADV(mr);
8645: }
8646: MKNDV(nd_nvar,mr0,len,r);
8647: return r;
8648: }
8649: }
8650:
8651: /* for preprocessed vector */
8652:
8653: NDV vect_to_ndv_q(Z *vect,int spcol,int col,int *rhead,UINT *s0vect)
8654: {
1.6 noro 8655: int j,k,len;
8656: UINT *p;
8657: Z c;
8658: NDV r;
8659: NMV mr0,mr;
1.1 noro 8660:
1.6 noro 8661: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
8662: if ( !len ) return 0;
8663: else {
8664: mr0 = (NMV)MALLOC(nmv_adv*len);
1.1 noro 8665: #if 0
1.6 noro 8666: ndv_alloc += nmv_adv*len;
1.1 noro 8667: #endif
1.6 noro 8668: mr = mr0;
8669: p = s0vect;
8670: for ( j = k = 0; j < col; j++, p += nd_wpd ) {
8671: if ( !rhead[j] ) {
8672: if ( (c = vect[k++]) != 0 ) {
8673: if ( !INT(c) )
8674: error("vect_to_ndv_q : components must be integers");
1.65 noro 8675: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
1.6 noro 8676: }
8677: }
1.1 noro 8678: }
1.6 noro 8679: MKNDV(nd_nvar,mr0,len,r);
8680: return r;
8681: }
1.1 noro 8682: }
8683:
8684: NDV vect_to_ndv_lf(mpz_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
8685: {
8686: int j,k,len;
8687: UINT *p;
8688: mpz_t c;
8689: NDV r;
8690: NMV mr0,mr;
8691:
8692: for ( j = 0, len = 0; j < spcol; j++ ) if ( mpz_sgn(vect[j]) ) len++;
8693: if ( !len ) return 0;
8694: else {
8695: mr0 = (NMV)MALLOC(nmv_adv*len);
8696: #if 0
8697: ndv_alloc += nmv_adv*len;
8698: #endif
8699: mr = mr0;
8700: p = s0vect;
8701: for ( j = k = 0; j < col; j++, p += nd_wpd )
8702: if ( !rhead[j] ) {
8703: c[0] = vect[k++][0];
8704: if ( mpz_sgn(c) ) {
8705: ndl_copy(p,DL(mr)); MPZTOZ(c,CZ(mr)); NMV_ADV(mr);
8706: }
8707: }
8708: MKNDV(nd_nvar,mr0,len,r);
8709: return r;
8710: }
8711: }
8712:
8713: /* for plain vector */
8714:
8715: NDV plain_vect_to_ndv_q(Z *vect,int col,UINT *s0vect)
8716: {
8717: int j,k,len;
8718: UINT *p;
8719: Z c;
8720: NDV r;
8721: NMV mr0,mr;
8722:
8723: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
8724: if ( !len ) return 0;
8725: else {
8726: mr0 = (NMV)MALLOC(nmv_adv*len);
8727: #if 0
8728: ndv_alloc += nmv_adv*len;
8729: #endif
8730: mr = mr0;
8731: p = s0vect;
8732: for ( j = k = 0; j < col; j++, p += nd_wpd, k++ )
8733: if ( (c = vect[k]) != 0 ) {
8734: if ( !INT(c) )
1.6 noro 8735: error("plain_vect_to_ndv_q : components must be integers");
8736: ndl_copy(p,DL(mr)); CZ(mr) = c; NMV_ADV(mr);
1.1 noro 8737: }
8738: MKNDV(nd_nvar,mr0,len,r);
8739: return r;
8740: }
8741: }
8742:
8743: int nd_sp_f4(int m,int trace,ND_pairs l,PGeoBucket bucket)
8744: {
8745: ND_pairs t;
8746: int stat;
8747: ND spol;
8748:
8749: for ( t = l; t; t = NEXT(t) ) {
8750: stat = nd_sp(m,trace,t,&spol);
8751: if ( !stat ) return 0;
8752: if ( spol ) {
8753: add_pbucket_symbolic(bucket,spol);
8754: }
8755: }
8756: return 1;
8757: }
8758:
8759: int nd_symbolic_preproc(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
8760: {
8761: NODE rp0,rp;
8762: NM mul,head,s0,s;
8763: int index,col,i,sugar;
8764: RHist h;
8765: UINT *s0v,*p;
8766: NM_ind_pair pair;
8767: ND red;
8768: NDV *ps;
8769:
8770: s0 = 0; rp0 = 0; col = 0;
8771: if ( nd_demand )
8772: ps = trace?nd_ps_trace_sym:nd_ps_sym;
8773: else
8774: ps = trace?nd_ps_trace:nd_ps;
8775: while ( 1 ) {
8776: head = remove_head_pbucket_symbolic(bucket);
8777: if ( !head ) break;
8778: if ( !s0 ) s0 = head;
8779: else NEXT(s) = head;
8780: s = head;
8781: index = ndl_find_reducer(DL(head));
8782: if ( index >= 0 ) {
8783: h = nd_psh[index];
8784: NEWNM(mul);
8785: ndl_sub(DL(head),DL(h),DL(mul));
8786: if ( ndl_check_bound2(index,DL(mul)) )
8787: return 0;
8788: sugar = TD(DL(mul))+SG(ps[index]);
1.28 noro 8789: MKNM_ind_pair(pair,mul,index,sugar,0);
1.1 noro 8790: red = ndv_mul_nm_symbolic(mul,ps[index]);
8791: add_pbucket_symbolic(bucket,nd_remove_head(red));
8792: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
8793: }
8794: col++;
8795: }
8796: if ( rp0 ) NEXT(rp) = 0;
8797: NEXT(s) = 0;
8798: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
8799: for ( i = 0, p = s0v, s = s0; i < col;
8800: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
8801: *s0vect = s0v;
8802: *r = rp0;
8803: return col;
8804: }
8805:
8806: void print_ndp(ND_pairs l)
8807: {
8808: ND_pairs t;
8809:
8810: for ( t = l; t; t = NEXT(t) )
8811: printf("[%d,%d] ",t->i1,t->i2);
8812: printf("\n");
8813: }
8814:
8815: NODE nd_f4(int m,int checkonly,int **indp)
8816: {
1.65 noro 8817: int i,nh,stat,f4red;
8818: NODE r,g,tn0,tn,node;
8819: ND_pairs d,l,t,ll,lh;
1.1 noro 8820: LIST l0,l1;
1.65 noro 8821: NDV nf;
8822: NODE rp0,nflist,nzlist,nzlist_t;
8823: int col;
8824: UINT *s0vect;
8825: int sugar;
8826: PGeoBucket bucket;
8827: struct oEGT eg0,eg1,eg_f4;
8828: Z i1,i2,sugarq;
1.12 noro 8829:
1.65 noro 8830: init_eg(&f4_symb); init_eg(&f4_conv); init_eg(&f4_conv); init_eg(&f4_elim1); init_eg(&f4_elim2);
1.1 noro 8831: #if 0
1.65 noro 8832: ndv_alloc = 0;
1.1 noro 8833: #endif
1.65 noro 8834: Nf4_red=0;
8835: g = 0; d = 0;
8836: for ( i = 0; i < nd_psn; i++ ) {
8837: d = update_pairs(d,g,i,0);
8838: g = update_base(g,i);
8839: }
8840: nzlist = 0;
8841: nzlist_t = nd_nzlist;
8842: f4red = 1;
8843: nd_last_nonzero = 0;
8844: while ( d ) {
8845: get_eg(&eg0);
8846: l = nd_minsugarp(d,&d);
8847: sugar = nd_sugarweight?l->sugar2:SG(l);
8848: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
8849: if ( nzlist_t ) {
8850: node = BDY((LIST)BDY(nzlist_t));
8851: // sugarh = (int)ZTOS((Q)ARG0(node));
8852: tn = BDY((LIST)ARG1(node));
8853: if ( !tn ) {
8854: nzlist_t = NEXT(nzlist_t);
8855: continue;
8856: }
8857: /* tn = [[i1,i2],...] */
8858: lh = nd_ipairtospair(tn);
8859: }
8860: bucket = create_pbucket();
8861: stat = nd_sp_f4(m,0,l,bucket);
8862: if ( !stat ) {
8863: for ( t = l; NEXT(t); t = NEXT(t) );
8864: NEXT(t) = d; d = l;
8865: d = nd_reconstruct(0,d);
8866: continue;
8867: }
8868: if ( bucket->m < 0 ) continue;
8869: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
8870: if ( !col ) {
8871: for ( t = l; NEXT(t); t = NEXT(t) );
8872: NEXT(t) = d; d = l;
8873: d = nd_reconstruct(0,d);
8874: continue;
1.1 noro 8875: }
1.65 noro 8876: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); add_eg(&f4_symb,&eg0,&eg1);
8877: if ( DP_Print )
8878: fprintf(asir_out,"sugar=%d,symb=%.3fsec,",sugar,eg_f4.exectime);
8879: nflist = nd_f4_red(m,nd_nzlist?lh:l,0,s0vect,col,rp0,nd_gentrace?&ll:0);
8880: if ( checkonly && nflist ) return 0;
8881: /* adding new bases */
8882: if ( nflist ) nd_last_nonzero = f4red;
8883: for ( r = nflist; r; r = NEXT(r) ) {
8884: nf = (NDV)BDY(r);
8885: if ( nd_f4_td ) SG(nf) = nd_tdeg(nf);
8886: ndv_removecont(m,nf);
8887: if ( !m && nd_nalg ) {
8888: ND nf1;
1.1 noro 8889:
1.65 noro 8890: nf1 = ndvtond(m,nf);
8891: nd_monic(0,&nf1);
8892: nd_removecont(m,nf1);
8893: nf = ndtondv(m,nf1);
8894: }
8895: nh = ndv_newps(m,nf,0);
8896: d = update_pairs(d,g,nh,0);
8897: g = update_base(g,nh);
8898: }
8899: if ( DP_Print ) {
8900: fprintf(asir_out,"f4red=%d,gblen=%d\n",f4red,length(g)); fflush(asir_out);
8901: }
8902: if ( nd_gentrace ) {
1.1 noro 8903: for ( t = ll, tn0 = 0; t; t = NEXT(t) ) {
8904: NEXTNODE(tn0,tn);
1.65 noro 8905: STOZ(t->i1,i1); STOZ(t->i2,i2);
8906: node = mknode(2,i1,i2); MKLIST(l0,node);
1.1 noro 8907: BDY(tn) = l0;
8908: }
8909: if ( tn0 ) NEXT(tn) = 0; MKLIST(l0,tn0);
1.65 noro 8910: STOZ(sugar,sugarq); node = mknode(2,sugarq,l0); MKLIST(l1,node);
8911: MKNODE(node,l1,nzlist); nzlist = node;
1.1 noro 8912: }
1.65 noro 8913: if ( nd_nzlist ) nzlist_t = NEXT(nzlist_t);
8914: f4red++;
8915: if ( nd_f4red && f4red > nd_f4red ) break;
8916: if ( nd_rank0 && !nflist ) break;
8917: }
8918: if ( nd_gentrace ) {
8919: MKLIST(l0,reverse_node(nzlist));
8920: MKNODE(nd_alltracelist,l0,0);
8921: }
1.1 noro 8922: #if 0
1.65 noro 8923: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
1.1 noro 8924: #endif
1.12 noro 8925: if ( DP_Print ) {
1.65 noro 8926: fprintf(asir_out,"number of red=%d,",Nf4_red);
8927: fprintf(asir_out,"symb=%.3fsec,conv=%.3fsec,elim1=%.3fsec,elim2=%.3fsec\n",
8928: f4_symb.exectime,f4_conv.exectime,f4_elim1.exectime,f4_elim2.exectime);
8929: fprintf(asir_out,"number of removed pairs=%d\n,",NcriB+NcriMF+Ncri2);
1.12 noro 8930: }
1.1 noro 8931: conv_ilist(nd_demand,0,g,indp);
1.65 noro 8932: return g;
1.1 noro 8933: }
8934:
8935: NODE nd_f4_trace(int m,int **indp)
8936: {
1.65 noro 8937: int i,nh,stat;
1.1 noro 8938: NODE r,g;
8939: ND_pairs d,l,l0,t;
1.65 noro 8940: NDV nfqv,nfv;
8941: NODE rp0,nflist;
8942: int col;
8943: UINT *s0vect;
1.1 noro 8944: int sugar;
8945: PGeoBucket bucket;
8946: struct oEGT eg0,eg1,eg_f4;
8947:
8948: g = 0; d = 0;
8949: for ( i = 0; i < nd_psn; i++ ) {
8950: d = update_pairs(d,g,i,0);
8951: g = update_base(g,i);
8952: }
8953: while ( d ) {
8954: get_eg(&eg0);
8955: l = nd_minsugarp(d,&d);
8956: sugar = SG(l);
8957: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
8958: bucket = create_pbucket();
8959: stat = nd_sp_f4(m,0,l,bucket);
8960: if ( !stat ) {
8961: for ( t = l; NEXT(t); t = NEXT(t) );
8962: NEXT(t) = d; d = l;
8963: d = nd_reconstruct(1,d);
8964: continue;
8965: }
8966: if ( bucket->m < 0 ) continue;
8967: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
8968: if ( !col ) {
8969: for ( t = l; NEXT(t); t = NEXT(t) );
8970: NEXT(t) = d; d = l;
8971: d = nd_reconstruct(1,d);
8972: continue;
8973: }
8974: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
8975: if ( DP_Print )
1.3 noro 8976: fprintf(asir_out,"\nsugar=%d,symb=%.3fsec,",
1.5 noro 8977: sugar,eg_f4.exectime);
1.1 noro 8978: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
8979: if ( !l0 ) continue;
8980: l = l0;
8981:
8982: /* over Q */
8983: bucket = create_pbucket();
8984: stat = nd_sp_f4(0,1,l,bucket);
8985: if ( !stat ) {
8986: for ( t = l; NEXT(t); t = NEXT(t) );
8987: NEXT(t) = d; d = l;
8988: d = nd_reconstruct(1,d);
8989: continue;
8990: }
8991: if ( bucket->m < 0 ) continue;
8992: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
8993: if ( !col ) {
8994: for ( t = l; NEXT(t); t = NEXT(t) );
8995: NEXT(t) = d; d = l;
8996: d = nd_reconstruct(1,d);
8997: continue;
8998: }
8999: nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0);
9000: /* adding new bases */
9001: for ( r = nflist; r; r = NEXT(r) ) {
9002: nfqv = (NDV)BDY(r);
9003: ndv_removecont(0,nfqv);
1.6 noro 9004: if ( !remqi((Q)HCZ(nfqv),m) ) return 0;
1.1 noro 9005: if ( nd_nalg ) {
9006: ND nf1;
9007:
9008: nf1 = ndvtond(m,nfqv);
9009: nd_monic(0,&nf1);
9010: nd_removecont(0,nf1);
9011: nfqv = ndtondv(0,nf1); nd_free(nf1);
9012: }
9013: nfv = ndv_dup(0,nfqv);
9014: ndv_mod(m,nfv);
9015: ndv_removecont(m,nfv);
1.24 noro 9016: nh = ndv_newps(0,nfv,nfqv);
1.1 noro 9017: d = update_pairs(d,g,nh,0);
9018: g = update_base(g,nh);
9019: }
9020: }
9021: #if 0
9022: fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc);
9023: #endif
9024: conv_ilist(nd_demand,1,g,indp);
9025: return g;
9026: }
9027:
9028: int rref(matrix mat,int *sugar)
9029: {
9030: int row,col,i,j,k,l,s,wcol,wj;
9031: unsigned long bj;
9032: unsigned long **a;
9033: unsigned long *ai,*ak,*as,*t;
9034: int *pivot;
9035:
9036: row = mat->row;
9037: col = mat->col;
9038: a = mat->a;
9039: wcol = (col+BLEN-1)/BLEN;
9040: pivot = (int *)MALLOC_ATOMIC(row*sizeof(int));
9041: i = 0;
9042: for ( j = 0; j < col; j++ ) {
9043: wj = j/BLEN; bj = 1L<<(j%BLEN);
9044: for ( k = i; k < row; k++ )
9045: if ( a[k][wj] & bj ) break;
9046: if ( k == row ) continue;
9047: pivot[i] = j;
9048: if ( k != i ) {
9049: t = a[i]; a[i] = a[k]; a[k] = t;
9050: s = sugar[i]; sugar[i] = sugar[k]; sugar[k] = s;
9051: }
9052: ai = a[i];
9053: for ( k = i+1; k < row; k++ ) {
9054: ak = a[k];
9055: if ( ak[wj] & bj ) {
9056: for ( l = wj; l < wcol; l++ )
9057: ak[l] ^= ai[l];
9058: sugar[k] = MAX(sugar[k],sugar[i]);
9059: }
9060: }
9061: i++;
9062: }
9063: for ( k = i-1; k >= 0; k-- ) {
9064: j = pivot[k]; wj = j/BLEN; bj = 1L<<(j%BLEN);
9065: ak = a[k];
9066: for ( s = 0; s < k; s++ ) {
9067: as = a[s];
9068: if ( as[wj] & bj ) {
9069: for ( l = wj; l < wcol; l++ )
9070: as[l] ^= ak[l];
9071: sugar[s] = MAX(sugar[s],sugar[k]);
9072: }
9073: }
9074: }
9075: return i;
9076: }
9077:
9078: void print_matrix(matrix mat)
9079: {
9080: int row,col,i,j;
9081: unsigned long *ai;
9082:
9083: row = mat->row;
9084: col = mat->col;
9085: printf("%d x %d\n",row,col);
9086: for ( i = 0; i < row; i++ ) {
9087: ai = mat->a[i];
9088: for ( j = 0; j < col; j++ ) {
9089: if ( ai[j/BLEN] & (1L<<(j%BLEN)) ) putchar('1');
9090: else putchar('0');
9091: }
9092: putchar('\n');
9093: }
9094: }
9095:
9096: NDV vect_to_ndv_2(unsigned long *vect,int col,UINT *s0vect);
9097:
9098: void red_by_vect_2(matrix mat,int *sugar,unsigned long *v,int rhead,int rsugar)
9099: {
9100: int row,col,wcol,wj,i,j;
9101: unsigned long bj;
9102: unsigned long *ai;
9103: unsigned long **a;
9104: int len;
9105: int *pos;
9106:
9107: row = mat->row;
9108: col = mat->col;
9109: wcol = (col+BLEN-1)/BLEN;
9110: pos = (int *)MALLOC(wcol*sizeof(int));
9111: bzero(pos,wcol*sizeof(int));
9112: for ( i = j = 0; i < wcol; i++ )
9113: if ( v[i] ) pos[j++] = i;;
9114: len = j;
9115: wj = rhead/BLEN;
9116: bj = 1L<<rhead%BLEN;
9117: a = mat->a;
9118: for ( i = 0; i < row; i++ ) {
9119: ai = a[i];
9120: if ( ai[wj]&bj ) {
9121: for ( j = 0; j < len; j++ )
9122: ai[pos[j]] ^= v[pos[j]];
9123: sugar[i] = MAX(sugar[i],rsugar);
9124: }
9125: }
9126: }
9127:
9128: NODE nd_f4_red_2(ND_pairs sp0,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
9129: {
1.65 noro 9130: int nsp,i,rank;
9131: NODE r0,rp;
9132: ND_pairs sp;
1.1 noro 9133: ND spol;
9134: NM_ind_pair rt;
1.65 noro 9135: int *s0hash;
1.1 noro 9136: UINT *s;
1.65 noro 9137: int *sugar;
1.1 noro 9138: matrix mat;
1.65 noro 9139: NODE r;
1.1 noro 9140: struct oEGT eg0,eg1,eg2,eg_elim1,eg_elim2;
9141: int rhead,rsugar,size;
1.65 noro 9142: unsigned long *v;
1.1 noro 9143:
1.65 noro 9144: get_eg(&eg0);
9145: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
9146: // nred = length(rp0);
9147: mat = alloc_matrix(nsp,col);
9148: s0hash = (int *)MALLOC(col*sizeof(int));
9149: for ( i = 0, s = s0vect; i < col; i++, s += nd_wpd )
9150: s0hash[i] = ndl_hash_value(s);
1.1 noro 9151:
9152: sugar = (int *)MALLOC(nsp*sizeof(int));
9153: for ( i = 0, sp = sp0; sp; sp = NEXT(sp) ) {
9154: nd_sp(2,0,sp,&spol);
9155: if ( spol ) {
9156: mat->a[i] = nd_to_vect_2(s0vect,col,s0hash,spol);
9157: sugar[i] = SG(spol);
9158: i++;
9159: }
9160: }
9161: mat->row = i;
9162: if ( DP_Print ) {
9163: fprintf(asir_out,"%dx%d,",mat->row,mat->col); fflush(asir_out);
9164: }
9165: size = ((col+BLEN-1)/BLEN)*sizeof(unsigned long);
9166: v = CALLOC((col+BLEN-1)/BLEN,sizeof(unsigned long));
9167: for ( rp = rp0, i = 0; rp; rp = NEXT(rp), i++ ) {
9168: rt = (NM_ind_pair)BDY(rp);
9169: bzero(v,size);
9170: rhead = nd_nm_to_vect_2(s0vect,col,s0hash,nd_ps[rt->index],rt->mul,v);
9171: rsugar = SG(nd_ps[rt->index])+TD(DL(rt->mul));
9172: red_by_vect_2(mat,sugar,v,rhead,rsugar);
9173: }
9174:
9175: get_eg(&eg1);
9176: init_eg(&eg_elim1); add_eg(&eg_elim1,&eg0,&eg1);
9177: rank = rref(mat,sugar);
9178:
9179: for ( i = 0, r0 = 0; i < rank; i++ ) {
9180: NEXTNODE(r0,r);
9181: BDY(r) = (pointer)vect_to_ndv_2(mat->a[i],col,s0vect);
9182: SG((NDV)BDY(r)) = sugar[i];
9183: }
9184: if ( r0 ) NEXT(r) = 0;
9185: get_eg(&eg2);
9186: init_eg(&eg_elim2); add_eg(&eg_elim2,&eg1,&eg2);
9187: if ( DP_Print ) {
9188: fprintf(asir_out,"elim1=%.3fsec,elim2=%.3fsec,",
1.5 noro 9189: eg_elim1.exectime,eg_elim2.exectime);
1.1 noro 9190: fflush(asir_out);
9191: }
9192: return r0;
9193: }
9194:
9195:
9196: NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz)
9197: {
9198: IndArray *imat;
1.11 noro 9199: int nsp,nred,i,start;
1.1 noro 9200: int *rhead;
9201: NODE r0,rp;
9202: ND_pairs sp;
9203: NM_ind_pair *rvect;
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;
1.65 noro 9254: int i,j,k,rank;
1.1 noro 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: {
1.65 noro 9339: int sprow,a;
9340: int i,rank;
1.40 noro 9341: NODE r0,r;
9342: ND_pairs sp;
9343: ND spol;
9344: UINT **spmat;
1.65 noro 9345: UINT *svect;
1.40 noro 9346: int *colstat;
9347: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9348: int maxrs;
9349: int *spsugar;
9350: SIG *spsig;
9351:
9352: get_eg(&eg0);
9353: /* elimination (1st step) */
9354: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9355: spsugar = (int *)MALLOC(nsp*sizeof(int));
9356: spsig = (SIG *)MALLOC(nsp*sizeof(SIG));
9357: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9358: nd_sp(m,0,sp,&spol);
9359: if ( !spol ) {
9360: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
9361: continue;
9362: }
9363: svect = (UINT *)MALLOC(col*sizeof(UINT));
9364: nd_to_vect(m,s0vect,col,spol,svect);
9365: maxrs = ndv_reduce_vect(m,svect,col,imat,rvect,nred,spol->sig);
9366: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9367: if ( i < col ) {
9368: spmat[sprow] = svect;
9369: spsugar[sprow] = MAX(maxrs,SG(spol));
9370: spsig[sprow] = sp->sig;
9371: sprow++;
9372: } else {
9373: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
9374: }
9375: nd_free(spol);
9376: }
9377: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
9378: if ( DP_Print ) {
9379: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
9380: fflush(asir_out);
9381: }
9382: /* free index arrays */
9383: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9384:
9385: /* elimination (2nd step) */
9386: colstat = (int *)MALLOC(col*sizeof(int));
9387: rank = nd_gauss_elim_mod_s(spmat,spsugar,0,sprow,col,m,colstat,spsig);
9388: r0 = 0;
9389: for ( i = 0; i < sprow; i++ ) {
9390: if ( spsugar[i] >= 0 ) {
9391: NEXTNODE(r0,r);
9392: BDY(r) = vect_to_ndv_s(spmat[i],col,s0vect);
9393: SG((NDV)BDY(r)) = spsugar[i];
9394: ((NDV)BDY(r))->sig = spsig[i];
9395: } else
9396: syzlistp[spsig[i]->pos] = insert_sig(syzlistp[spsig[i]->pos],spsig[i]);
9397: GCFREE(spmat[i]);
9398: }
9399: if ( r0 ) NEXT(r) = 0;
9400: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
9401: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9402: if ( DP_Print ) {
9403: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
9404: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9405: nsp,nred,sprow,col,rank);
9406: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
9407: }
9408: return r0;
9409: }
9410:
1.1 noro 9411:
9412: /* for small finite fields */
9413:
9414: NODE nd_f4_red_sf_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
9415: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
9416: {
9417: int spcol,sprow,a;
1.65 noro 9418: int i,j,k,rank;
1.1 noro 9419: NODE r0,r;
9420: ND_pairs sp;
9421: ND spol;
9422: UINT **spmat;
9423: UINT *svect,*v;
9424: int *colstat;
9425: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9426: int maxrs;
9427: int *spsugar;
9428: ND_pairs *spactive;
9429:
9430: spcol = col-nred;
9431: get_eg(&eg0);
9432: /* elimination (1st step) */
9433: spmat = (UINT **)MALLOC(nsp*sizeof(UINT *));
9434: svect = (UINT *)MALLOC(col*sizeof(UINT));
9435: spsugar = (int *)MALLOC(nsp*sizeof(int));
9436: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
9437: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9438: nd_sp(m,0,sp,&spol);
9439: if ( !spol ) continue;
9440: nd_to_vect(m,s0vect,col,spol,svect);
9441: maxrs = ndv_reduce_vect_sf(m,svect,col,imat,rvect,nred);
9442: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9443: if ( i < col ) {
9444: spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT));
9445: for ( j = k = 0; j < col; j++ )
9446: if ( !rhead[j] ) v[k++] = svect[j];
9447: spsugar[sprow] = MAX(maxrs,SG(spol));
9448: if ( nz )
9449: spactive[sprow] = sp;
9450: sprow++;
9451: }
9452: nd_free(spol);
9453: }
9454: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9455: if ( DP_Print ) {
1.5 noro 9456: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9457: fflush(asir_out);
9458: }
9459: /* free index arrays */
9460: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
9461:
9462: /* elimination (2nd step) */
9463: colstat = (int *)MALLOC(spcol*sizeof(int));
9464: rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat);
9465: r0 = 0;
9466: for ( i = 0; i < rank; i++ ) {
9467: NEXTNODE(r0,r); BDY(r) =
9468: (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect);
9469: SG((NDV)BDY(r)) = spsugar[i];
9470: GCFREE(spmat[i]);
9471: }
9472: if ( r0 ) NEXT(r) = 0;
9473:
9474: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
9475: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9476: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9477: if ( DP_Print ) {
1.5 noro 9478: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9479: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9480: nsp,nred,sprow,spcol,rank);
1.5 noro 9481: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9482: }
9483: if ( nz ) {
9484: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
9485: if ( rank > 0 ) {
9486: NEXT(spactive[rank-1]) = 0;
9487: *nz = spactive[0];
9488: } else
9489: *nz = 0;
9490: }
9491: return r0;
9492: }
9493:
9494: NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
9495: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
9496: {
9497: int spcol,sprow,a;
1.65 noro 9498: int i,j,k,rank;
1.1 noro 9499: NODE r0,r;
9500: ND_pairs sp;
9501: ND spol;
9502: mpz_t **spmat;
9503: mpz_t *svect,*v;
9504: int *colstat;
9505: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9506: int maxrs;
9507: int *spsugar;
9508: pointer *w;
9509:
9510: spcol = col-nred;
9511: get_eg(&eg0);
9512: /* elimination (1st step) */
9513: spmat = (mpz_t **)MALLOC(nsp*sizeof(mpz_t *));
9514: svect = (mpz_t *)MALLOC(col*sizeof(mpz_t));
9515: spsugar = (int *)MALLOC(nsp*sizeof(int));
9516: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9517: nd_sp(m,trace,sp,&spol);
9518: if ( !spol ) continue;
9519: nd_to_vect_lf(s0vect,col,spol,svect);
9520: maxrs = ndv_reduce_vect_lf(svect,trace,col,imat,rvect,nred);
9521: for ( i = 0; i < col; i++ ) if ( mpz_sgn(svect[i]) ) break;
9522: if ( i < col ) {
9523: spmat[sprow] = v = (mpz_t *)MALLOC(spcol*sizeof(mpz_t));
9524: for ( j = k = 0; j < col; j++ )
9525: if ( !rhead[j] ) v[k++][0] = svect[j][0];
9526: spsugar[sprow] = MAX(maxrs,SG(spol));
9527: sprow++;
9528: }
9529: /* nd_free(spol); */
9530: }
9531: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9532: if ( DP_Print ) {
1.5 noro 9533: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9534: fflush(asir_out);
9535: }
9536: /* free index arrays */
9537: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
9538:
9539: /* elimination (2nd step) */
9540: colstat = (int *)MALLOC(spcol*sizeof(int));
9541: rank = nd_gauss_elim_lf(spmat,spsugar,sprow,spcol,colstat);
9542: w = (pointer *)MALLOC(rank*sizeof(pointer));
9543: for ( i = 0; i < rank; i++ ) {
9544: #if 0
9545: w[rank-i-1] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
9546: SG((NDV)w[rank-i-1]) = spsugar[i];
9547: #else
9548: w[i] = (pointer)vect_to_ndv_lf(spmat[i],spcol,col,rhead,s0vect);
9549: SG((NDV)w[i]) = spsugar[i];
9550: #endif
9551: /* GCFREE(spmat[i]); */
9552:
9553: }
9554: #if 0
9555: qsort(w,rank,sizeof(NDV),
9556: (int (*)(const void *,const void *))ndv_compare);
9557: #endif
9558: r0 = 0;
9559: for ( i = 0; i < rank; i++ ) {
9560: NEXTNODE(r0,r); BDY(r) = w[i];
9561: }
9562: if ( r0 ) NEXT(r) = 0;
9563:
9564: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
9565: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9566: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9567: if ( DP_Print ) {
1.5 noro 9568: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9569: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9570: nsp,nred,sprow,spcol,rank);
1.5 noro 9571: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9572: }
9573: return r0;
9574: }
9575:
9576: NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col,
9577: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred)
9578: {
9579: int spcol,sprow,a;
1.65 noro 9580: int i,j,k,rank;
1.1 noro 9581: NODE r0,r;
9582: ND_pairs sp;
9583: ND spol;
9584: Z **spmat;
9585: Z *svect,*v;
9586: int *colstat;
9587: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
9588: int maxrs;
9589: int *spsugar;
9590: pointer *w;
9591:
9592: spcol = col-nred;
9593: get_eg(&eg0);
9594: /* elimination (1st step) */
9595: spmat = (Z **)MALLOC(nsp*sizeof(Q *));
9596: svect = (Z *)MALLOC(col*sizeof(Q));
9597: spsugar = (int *)MALLOC(nsp*sizeof(int));
9598: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
9599: nd_sp(0,trace,sp,&spol);
9600: if ( !spol ) continue;
9601: nd_to_vect_q(s0vect,col,spol,svect);
9602: maxrs = ndv_reduce_vect_q(svect,trace,col,imat,rvect,nred);
9603: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
9604: if ( i < col ) {
9605: spmat[sprow] = v = (Z *)MALLOC(spcol*sizeof(Q));
9606: for ( j = k = 0; j < col; j++ )
9607: if ( !rhead[j] ) v[k++] = svect[j];
9608: spsugar[sprow] = MAX(maxrs,SG(spol));
9609: sprow++;
9610: }
9611: /* nd_free(spol); */
9612: }
9613: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1);
9614: if ( DP_Print ) {
1.5 noro 9615: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
1.1 noro 9616: fflush(asir_out);
9617: }
9618: /* free index arrays */
9619: /* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */
9620:
9621: /* elimination (2nd step) */
9622: colstat = (int *)MALLOC(spcol*sizeof(int));
9623: rank = nd_gauss_elim_q(spmat,spsugar,sprow,spcol,colstat);
9624: w = (pointer *)MALLOC(rank*sizeof(pointer));
9625: for ( i = 0; i < rank; i++ ) {
9626: #if 0
9627: w[rank-i-1] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
9628: SG((NDV)w[rank-i-1]) = spsugar[i];
9629: #else
9630: w[i] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect);
9631: SG((NDV)w[i]) = spsugar[i];
9632: #endif
9633: /* GCFREE(spmat[i]); */
9634: }
9635: #if 0
9636: qsort(w,rank,sizeof(NDV),
9637: (int (*)(const void *,const void *))ndv_compare);
9638: #endif
9639: r0 = 0;
9640: for ( i = 0; i < rank; i++ ) {
9641: NEXTNODE(r0,r); BDY(r) = w[i];
9642: }
9643: if ( r0 ) NEXT(r) = 0;
9644:
9645: /* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */
9646: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2);
9647: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
9648: if ( DP_Print ) {
1.5 noro 9649: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
1.1 noro 9650: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
9651: nsp,nred,sprow,spcol,rank);
1.5 noro 9652: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
1.1 noro 9653: }
9654: return r0;
9655: }
9656:
9657: FILE *nd_write,*nd_read;
9658:
9659: void nd_send_int(int a) {
9660: write_int(nd_write,(unsigned int *)&a);
9661: }
9662:
9663: void nd_send_intarray(int *p,int len) {
9664: write_intarray(nd_write,(unsigned int *)p,len);
9665: }
9666:
9667: int nd_recv_int() {
9668: int a;
9669:
9670: read_int(nd_read,(unsigned int *)&a);
9671: return a;
9672: }
9673:
9674: void nd_recv_intarray(int *p,int len) {
9675: read_intarray(nd_read,(unsigned int *)p,len);
9676: }
9677:
9678: void nd_send_ndv(NDV p) {
9679: int len,i;
9680: NMV m;
9681:
9682: if ( !p ) nd_send_int(0);
9683: else {
9684: len = LEN(p);
9685: nd_send_int(len);
9686: m = BDY(p);
9687: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
9688: nd_send_int(CM(m));
9689: nd_send_intarray((int *)DL(m),nd_wpd);
9690: }
9691: }
9692: }
9693:
9694: void nd_send_nd(ND p) {
9695: int len,i;
9696: NM m;
9697:
9698: if ( !p ) nd_send_int(0);
9699: else {
9700: len = LEN(p);
9701: nd_send_int(len);
9702: m = BDY(p);
9703: for ( i = 0; i < len; i++, m = NEXT(m) ) {
9704: nd_send_int(CM(m));
9705: nd_send_intarray((int *)DL(m),nd_wpd);
9706: }
9707: }
9708: }
9709:
9710: NDV nd_recv_ndv()
9711: {
9712: int len,i;
9713: NMV m,m0;
9714: NDV r;
9715:
9716: len = nd_recv_int();
9717: if ( !len ) return 0;
9718: else {
9719: m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
9720: #if 0
9721: ndv_alloc += len*nmv_adv;
9722: #endif
9723: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
9724: CM(m) = nd_recv_int();
9725: nd_recv_intarray((int *)DL(m),nd_wpd);
9726: }
9727: MKNDV(nd_nvar,m0,len,r);
9728: return r;
9729: }
9730: }
9731:
9732: int nd_gauss_elim_q(Z **mat0,int *sugar,int row,int col,int *colstat)
9733: {
1.65 noro 9734: int i,j,c,rank;
1.1 noro 9735: int *ci,*ri;
9736: Z dn;
9737: MAT m,nm;
9738:
9739: NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0;
9740: rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci);
9741: for ( i = 0; i < row; i++ )
9742: for ( j = 0; j < col; j++ )
9743: mat0[i][j] = 0;
9744: c = col-rank;
9745: for ( i = 0; i < rank; i++ ) {
9746: mat0[i][ri[i]] = dn;
9747: for ( j = 0; j < c; j++ )
9748: mat0[i][ci[j]] = (Z)BDY(nm)[i][j];
9749: }
9750: return rank;
9751: }
9752:
9753: int nd_gauss_elim_mod(UINT **mat0,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
9754: {
9755: int i,j,k,l,inv,a,rank,s;
9756: unsigned int *t,*pivot,*pk;
9757: unsigned int **mat;
9758: ND_pairs pair;
9759:
9760: mat = (unsigned int **)mat0;
9761: for ( rank = 0, j = 0; j < col; j++ ) {
9762: for ( i = rank; i < row; i++ )
9763: mat[i][j] %= md;
9764: for ( i = rank; i < row; i++ )
9765: if ( mat[i][j] )
9766: break;
9767: if ( i == row ) {
9768: colstat[j] = 0;
9769: continue;
9770: } else
9771: colstat[j] = 1;
9772: if ( i != rank ) {
9773: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
9774: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
9775: if ( spactive ) {
9776: pair = spactive[i]; spactive[i] = spactive[rank];
9777: spactive[rank] = pair;
9778: }
9779: }
9780: pivot = mat[rank];
9781: s = sugar[rank];
9782: inv = invm(pivot[j],md);
9783: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
9784: if ( *pk ) {
9785: if ( *pk >= (unsigned int)md )
9786: *pk %= md;
9787: DMAR(*pk,inv,0,md,*pk)
9788: }
9789: for ( i = rank+1; i < row; i++ ) {
9790: t = mat[i];
9791: if ( (a = t[j]) != 0 ) {
9792: sugar[i] = MAX(sugar[i],s);
9793: red_by_vect(md,t+j,pivot+j,md-a,col-j);
9794: }
9795: }
9796: rank++;
9797: }
9798: for ( j = col-1, l = rank-1; j >= 0; j-- )
9799: if ( colstat[j] ) {
9800: pivot = mat[l];
9801: s = sugar[l];
9802: for ( i = 0; i < l; i++ ) {
9803: t = mat[i];
9804: t[j] %= md;
9805: if ( (a = t[j]) != 0 ) {
9806: sugar[i] = MAX(sugar[i],s);
9807: red_by_vect(md,t+j,pivot+j,md-a,col-j);
9808: }
9809: }
9810: l--;
9811: }
9812: for ( j = 0, l = 0; l < rank; j++ )
9813: if ( colstat[j] ) {
9814: t = mat[l];
9815: for ( k = j; k < col; k++ )
9816: if ( t[k] >= (unsigned int)md )
9817: t[k] %= md;
9818: l++;
9819: }
9820: return rank;
9821: }
9822:
1.40 noro 9823: int nd_gauss_elim_mod_s(UINT **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat,SIG *sig)
9824: {
1.65 noro 9825: int i,j,k,rank,s;
1.40 noro 9826: UINT inv;
9827: UINT a;
1.65 noro 9828: UINT *pk;
1.40 noro 9829: int *used;
9830:
9831: used = (int *)MALLOC(row*sizeof(int));
9832: for ( j = 0; j < col; j++ ) {
9833: for ( i = 0; i < row; i++ )
9834: a = mat[i][j] %= md;
9835: for ( i = 0; i < row; i++ )
9836: if ( !used[i] && mat[i][j] ) break;
9837: if ( i == row ) {
9838: colstat[j] = 0;
9839: continue;
9840: } else {
9841: colstat[j] = 1;
9842: used[i] = 1;
9843: }
9844: /* column j is normalized */
9845: s = sugar[i];
9846: inv = invm(mat[i][j],md);
9847: /* normalize pivot row */
1.65 noro 9848: for ( k = j, pk = mat[i]+j; k < col; k++, pk++ ) {
1.40 noro 9849: DMAR(*pk,inv,0,md,*pk);
9850: }
9851: for ( k = i+1; k < row; k++ ) {
9852: if ( (a = mat[k][j]) != 0 ) {
9853: sugar[k] = MAX(sugar[k],s);
9854: red_by_vect(md,mat[k]+j,mat[i]+j,(int)(md-a),col-j);
9855: Nf4_red++;
9856: }
9857: }
9858: }
9859: rank = 0;
9860: for ( i = 0; i < row; i++ ) {
9861: for ( j = 0; j < col; j++ )
9862: if ( mat[i][j] ) break;
9863: if ( j == col ) sugar[i] = -1;
9864: else rank++;
9865: }
9866: return rank;
9867: }
9868:
1.1 noro 9869:
1.7 noro 9870: int nd_gauss_elim_sf(UINT **mat0,int *sugar,int row,int col,int md,int *colstat)
1.1 noro 9871: {
1.7 noro 9872: int i,j,k,l,inv,a,rank,s;
9873: unsigned int *t,*pivot,*pk;
9874: unsigned int **mat;
9875:
9876: mat = (unsigned int **)mat0;
9877: for ( rank = 0, j = 0; j < col; j++ ) {
9878: for ( i = rank; i < row; i++ )
9879: if ( mat[i][j] )
9880: break;
9881: if ( i == row ) {
9882: colstat[j] = 0;
9883: continue;
9884: } else
9885: colstat[j] = 1;
9886: if ( i != rank ) {
9887: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
9888: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
9889: }
9890: pivot = mat[rank];
9891: s = sugar[rank];
9892: inv = _invsf(pivot[j]);
9893: for ( k = j, pk = pivot+k; k < col; k++, pk++ )
9894: if ( *pk )
9895: *pk = _mulsf(*pk,inv);
9896: for ( i = rank+1; i < row; i++ ) {
9897: t = mat[i];
9898: if ( (a = t[j]) != 0 ) {
9899: sugar[i] = MAX(sugar[i],s);
9900: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
9901: }
9902: }
9903: rank++;
9904: }
9905: for ( j = col-1, l = rank-1; j >= 0; j-- )
9906: if ( colstat[j] ) {
9907: pivot = mat[l];
9908: s = sugar[l];
9909: for ( i = 0; i < l; i++ ) {
9910: t = mat[i];
9911: if ( (a = t[j]) != 0 ) {
9912: sugar[i] = MAX(sugar[i],s);
9913: red_by_vect_sf(md,t+j,pivot+j,_chsgnsf(a),col-j);
9914: }
9915: }
9916: l--;
9917: }
9918: return rank;
9919: }
1.1 noro 9920:
1.7 noro 9921: int ndv_ishomo(NDV p)
9922: {
9923: NMV m;
9924: int len,h;
1.1 noro 9925:
9926: if ( !p ) return 1;
9927: len = LEN(p);
9928: m = BDY(p);
9929: h = TD(DL(m));
9930: NMV_ADV(m);
9931: for ( len--; len; len--, NMV_ADV(m) )
1.20 noro 9932: if ( TD(DL(m)) != h ) {
9933: return 0;
9934: }
1.1 noro 9935: return 1;
9936: }
9937:
9938: void ndv_save(NDV p,int index)
9939: {
9940: FILE *s;
9941: char name[BUFSIZ];
9942: short id;
1.65 noro 9943: int nv,sugar,len,i,td,e,j;
1.1 noro 9944: NMV m;
9945: unsigned int *dl;
9946: int mpos;
9947:
9948: sprintf(name,"%s/%d",Demand,index);
9949: s = fopen(name,"w");
9950: savevl(s,0);
9951: if ( !p ) {
9952: saveobj(s,0);
9953: return;
9954: }
9955: id = O_DP;
9956: nv = NV(p);
9957: sugar = SG(p);
9958: len = LEN(p);
9959: write_short(s,(unsigned short *)&id); write_int(s,(unsigned int *)&nv); write_int(s,(unsigned int *)&sugar);
9960: write_int(s,(unsigned int *)&len);
9961:
9962: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 9963: saveobj(s,(Obj)CZ(m));
1.1 noro 9964: dl = DL(m);
9965: td = TD(dl);
9966: write_int(s,(unsigned int *)&td);
9967: for ( j = 0; j < nv; j++ ) {
9968: e = GET_EXP(dl,j);
9969: write_int(s,(unsigned int *)&e);
9970: }
9971: if ( nd_module ) {
9972: mpos = MPOS(dl); write_int(s,(unsigned int *)&mpos);
9973: }
9974: }
9975: fclose(s);
9976: }
9977:
9978: void nd_save_mod(ND p,int index)
9979: {
9980: FILE *s;
9981: char name[BUFSIZ];
9982: int nv,sugar,len,c;
9983: NM m;
9984:
9985: sprintf(name,"%s/%d",Demand,index);
9986: s = fopen(name,"w");
9987: if ( !p ) {
9988: len = 0;
9989: write_int(s,(unsigned int *)&len);
9990: fclose(s);
9991: return;
9992: }
9993: nv = NV(p);
9994: sugar = SG(p);
9995: len = LEN(p);
9996: write_int(s,(unsigned int *)&nv); write_int(s,(unsigned int *)&sugar); write_int(s,(unsigned int *)&len);
9997: for ( m = BDY(p); m; m = NEXT(m) ) {
9998: c = CM(m); write_int(s,(unsigned int *)&c);
9999: write_intarray(s,(unsigned int *)DL(m),nd_wpd);
10000: }
10001: fclose(s);
10002: }
10003:
10004: NDV ndv_load(int index)
10005: {
10006: FILE *s;
10007: char name[BUFSIZ];
10008: short id;
1.65 noro 10009: int nv,sugar,len,i,td,e,j;
1.1 noro 10010: NDV d;
10011: NMV m0,m;
10012: unsigned int *dl;
10013: Obj obj;
10014: int mpos;
10015:
10016: sprintf(name,"%s/%d",Demand,index);
10017: s = fopen(name,"r");
10018: if ( !s ) return 0;
10019:
10020: skipvl(s);
10021: read_short(s,(unsigned short *)&id);
10022: if ( !id ) return 0;
10023: read_int(s,(unsigned int *)&nv);
10024: read_int(s,(unsigned int *)&sugar);
10025: read_int(s,(unsigned int *)&len);
10026:
10027: m0 = m = MALLOC(len*nmv_adv);
10028: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
1.6 noro 10029: loadobj(s,&obj); CZ(m) = (Z)obj;
1.1 noro 10030: dl = DL(m);
10031: ndl_zero(dl);
10032: read_int(s,(unsigned int *)&td); TD(dl) = td;
10033: for ( j = 0; j < nv; j++ ) {
10034: read_int(s,(unsigned int *)&e);
10035: PUT_EXP(dl,j,e);
10036: }
10037: if ( nd_module ) {
10038: read_int(s,(unsigned int *)&mpos); MPOS(dl) = mpos;
10039: }
10040: if ( nd_blockmask ) ndl_weight_mask(dl);
10041: }
10042: fclose(s);
10043: MKNDV(nv,m0,len,d);
10044: SG(d) = sugar;
10045: return d;
10046: }
10047:
10048: ND nd_load_mod(int index)
10049: {
10050: FILE *s;
10051: char name[BUFSIZ];
10052: int nv,sugar,len,i,c;
10053: ND d;
10054: NM m0,m;
10055:
10056: sprintf(name,"%s/%d",Demand,index);
10057: s = fopen(name,"r");
10058: /* if the file does not exist, it means p[index]=0 */
10059: if ( !s ) return 0;
10060:
10061: read_int(s,(unsigned int *)&nv);
10062: if ( !nv ) { fclose(s); return 0; }
10063:
10064: read_int(s,(unsigned int *)&sugar);
10065: read_int(s,(unsigned int *)&len);
10066: for ( m0 = 0, i = 0; i < len; i++ ) {
10067: NEXTNM(m0,m);
10068: read_int(s,(unsigned int *)&c); CM(m) = c;
10069: read_intarray(s,(unsigned int *)DL(m),nd_wpd);
10070: }
10071: NEXT(m) = 0;
10072: MKND(nv,m0,len,d);
10073: SG(d) = sugar;
10074: fclose(s);
10075: return d;
10076: }
10077:
10078: void nd_det(int mod,MAT f,P *rp)
10079: {
10080: VL fv,tv;
10081: int n,i,j,max,e,nvar,sgn,k0,l0,len0,len,k,l,a;
10082: pointer **m;
10083: P **w;
10084: P mp,r;
10085: NDV **dm;
10086: NDV *t,*mi,*mj;
10087: NDV d,s,mij,mjj;
10088: ND u;
10089: NMV nmv;
10090: UINT *bound;
10091: PGeoBucket bucket;
10092: struct order_spec *ord;
10093: Z dq,dt,ds;
10094: Z mone;
10095: Z gn,qn,dn0,nm,dn;
10096:
10097: create_order_spec(0,0,&ord);
10098: nd_init_ord(ord);
10099: get_vars((Obj)f,&fv);
10100: if ( f->row != f->col )
10101: error("nd_det : non-square matrix");
10102: n = f->row;
10103: m = f->body;
10104: for ( nvar = 0, tv = fv; tv; tv = NEXT(tv), nvar++ );
10105:
10106: if ( !nvar ) {
10107: if ( !mod )
10108: detp(CO,(P **)m,n,rp);
10109: else {
10110: w = (P **)almat_pointer(n,n);
10111: for ( i = 0; i < n; i++ )
10112: for ( j = 0; j < n; j++ )
10113: ptomp(mod,(P)m[i][j],&w[i][j]);
10114: detmp(CO,mod,w,n,&mp);
10115: mptop(mp,rp);
10116: }
10117: return;
10118: }
10119:
10120: if ( !mod ) {
10121: w = (P **)almat_pointer(n,n);
10122: dq = ONE;
10123: for ( i = 0; i < n; i++ ) {
10124: dn0 = ONE;
10125: for ( j = 0; j < n; j++ ) {
10126: if ( !m[i][j] ) continue;
10127: lgp(m[i][j],&nm,&dn);
1.6 noro 10128: gcdz(dn0,dn,&gn); divsz(dn0,gn,&qn); mulz(qn,dn,&dn0);
1.1 noro 10129: }
10130: if ( !UNIZ(dn0) ) {
10131: ds = dn0;
10132: for ( j = 0; j < n; j++ )
10133: mulp(CO,(P)m[i][j],(P)ds,&w[i][j]);
10134: mulz(dq,ds,&dt); dq = dt;
10135: } else
10136: for ( j = 0; j < n; j++ )
10137: w[i][j] = (P)m[i][j];
10138: }
10139: m = (pointer **)w;
10140: }
10141:
10142: for ( i = 0, max = 1; i < n; i++ )
10143: for ( j = 0; j < n; j++ )
10144: for ( tv = fv; tv; tv = NEXT(tv) ) {
10145: e = getdeg(tv->v,(P)m[i][j]);
10146: max = MAX(e,max);
10147: }
10148: nd_setup_parameters(nvar,max);
10149: dm = (NDV **)almat_pointer(n,n);
10150: for ( i = 0, max = 1; i < n; i++ )
10151: for ( j = 0; j < n; j++ ) {
10152: dm[i][j] = ptondv(CO,fv,m[i][j]);
10153: if ( mod ) ndv_mod(mod,dm[i][j]);
10154: if ( dm[i][j] && !LEN(dm[i][j]) ) dm[i][j] = 0;
10155: }
10156: d = ptondv(CO,fv,(P)ONE);
10157: if ( mod ) ndv_mod(mod,d);
10158: chsgnz(ONE,&mone);
10159: for ( j = 0, sgn = 1; j < n; j++ ) {
10160: if ( DP_Print ) {
10161: fprintf(asir_out,".");
10162: }
10163: for ( i = j; i < n && !dm[i][j]; i++ );
10164: if ( i == n ) {
10165: *rp = 0;
10166: return;
10167: }
10168: k0 = i; l0 = j; len0 = LEN(dm[k0][l0]);
10169: for ( k = j; k < n; k++ )
10170: for ( l = j; l < n; l++ )
10171: if ( dm[k][l] && LEN(dm[k][l]) < len0 ) {
10172: k0 = k; l0 = l; len0 = LEN(dm[k][l]);
10173: }
10174: if ( k0 != j ) {
10175: t = dm[j]; dm[j] = dm[k0]; dm[k0] = t;
10176: sgn = -sgn;
10177: }
10178: if ( l0 != j ) {
10179: for ( k = j; k < n; k++ ) {
10180: s = dm[k][j]; dm[k][j] = dm[k][l0]; dm[k][l0] = s;
10181: }
10182: sgn = -sgn;
10183: }
10184: bound = nd_det_compute_bound(dm,n,j);
10185: for ( k = 0; k < nd_nvar; k++ )
10186: if ( bound[k]*2 > nd_mask0 ) break;
10187: if ( k < nd_nvar )
10188: nd_det_reconstruct(dm,n,j,d);
10189:
10190: for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) {
10191: /* if ( DP_Print ) fprintf(asir_out," i=%d\n ",i); */
10192: mi = dm[i]; mij = mi[j];
10193: if ( mod )
10194: ndv_mul_c(mod,mij,mod-1);
10195: else
10196: ndv_mul_c_q(mij,mone);
10197: for ( k = j+1; k < n; k++ ) {
10198: /* if ( DP_Print ) fprintf(asir_out,"k=%d ",k); */
10199: bucket = create_pbucket();
10200: if ( mi[k] ) {
10201: nmv = BDY(mjj); len = LEN(mjj);
10202: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
10203: u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d)));
10204: add_pbucket(mod,bucket,u);
10205: }
10206: }
10207: if ( mj[k] && mij ) {
10208: nmv = BDY(mij); len = LEN(mij);
10209: for ( a = 0; a < len; a++, NMV_ADV(nmv) ) {
10210: u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d)));
10211: add_pbucket(mod,bucket,u);
10212: }
10213: }
10214: u = nd_quo(mod,bucket,d);
10215: mi[k] = ndtondv(mod,u);
10216: }
10217: /* if ( DP_Print ) fprintf(asir_out,"\n",k); */
10218: }
10219: d = mjj;
10220: }
10221: if ( DP_Print ) {
10222: fprintf(asir_out,"\n");
10223: }
10224: if ( sgn < 0 ) {
10225: if ( mod )
10226: ndv_mul_c(mod,d,mod-1);
10227: else
10228: ndv_mul_c_q(d,mone);
10229: }
10230: r = ndvtop(mod,CO,fv,d);
10231: if ( !mod && !UNIQ(dq) )
10232: divsp(CO,r,(P)dq,rp);
10233: else
10234: *rp = r;
10235: }
10236:
10237: ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d)
10238: {
10239: NM mr,mr0;
10240: NM tnm;
10241: NMV m;
1.65 noro 10242: UINT *d0;
10243: int c,i,c1,c2,len;
1.1 noro 10244: Z q;
10245: ND r;
10246:
10247: if ( !p ) return 0;
10248: else {
1.65 noro 10249: m = BDY(p); len = LEN(p);
1.1 noro 10250: d0 = DL(m0);
10251: mr0 = 0;
10252: NEWNM(tnm);
10253: if ( mod ) {
10254: c = CM(m0);
10255: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
10256: ndl_add(DL(m),d0,DL(tnm));
10257: if ( ndl_reducible(DL(tnm),d) ) {
10258: NEXTNM(mr0,mr);
10259: c1 = CM(m); DMAR(c1,c,0,mod,c2); CM(mr) = c2;
10260: ndl_copy(DL(tnm),DL(mr));
10261: }
10262: }
10263: } else {
1.6 noro 10264: q = CZ(m0);
1.1 noro 10265: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
10266: ndl_add(DL(m),d0,DL(tnm));
10267: if ( ndl_reducible(DL(tnm),d) ) {
10268: NEXTNM(mr0,mr);
1.6 noro 10269: mulz(CZ(m),q,&CZ(mr));
1.1 noro 10270: ndl_copy(DL(tnm),DL(mr));
10271: }
10272: }
10273: }
10274: if ( !mr0 )
10275: return 0;
10276: else {
10277: NEXT(mr) = 0;
10278: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
10279: MKND(NV(p),mr0,len,r);
10280: SG(r) = SG(p) + TD(d0);
10281: return r;
10282: }
10283: }
10284: }
10285:
10286: void nd_det_reconstruct(NDV **dm,int n,int j,NDV d)
10287: {
1.65 noro 10288: int obpe,oadv,k,l;
1.1 noro 10289: static NM prev_nm_free_list;
10290: EPOS oepos;
10291:
10292: obpe = nd_bpe;
10293: oadv = nmv_adv;
10294: oepos = nd_epos;
10295: if ( obpe < 2 ) nd_bpe = 2;
10296: else if ( obpe < 3 ) nd_bpe = 3;
10297: else if ( obpe < 4 ) nd_bpe = 4;
10298: else if ( obpe < 5 ) nd_bpe = 5;
10299: else if ( obpe < 6 ) nd_bpe = 6;
10300: else if ( obpe < 8 ) nd_bpe = 8;
10301: else if ( obpe < 10 ) nd_bpe = 10;
10302: else if ( obpe < 16 ) nd_bpe = 16;
10303: else if ( obpe < 32 ) nd_bpe = 32;
10304: else error("nd_det_reconstruct : exponent too large");
10305:
10306: nd_setup_parameters(nd_nvar,0);
10307: prev_nm_free_list = _nm_free_list;
10308: _nm_free_list = 0;
10309: for ( k = j; k < n; k++ )
10310: for (l = j; l < n; l++ )
10311: ndv_realloc(dm[k][l],obpe,oadv,oepos);
10312: ndv_realloc(d,obpe,oadv,oepos);
10313: prev_nm_free_list = 0;
10314: #if 0
10315: GC_gcollect();
10316: #endif
10317: }
10318:
10319: /* returns a UINT array containing degree bounds */
10320:
10321: UINT *nd_det_compute_bound(NDV **dm,int n,int j)
10322: {
1.65 noro 10323: UINT *d0,*d;
1.1 noro 10324: int k,l,i;
10325:
10326: d0 = (UINT *)MALLOC(nd_nvar*sizeof(UINT));
10327: for ( k = 0; k < nd_nvar; k++ ) d0[k] = 0;
10328: for ( k = j; k < n; k++ )
10329: for ( l = j; l < n; l++ )
10330: if ( dm[k][l] ) {
10331: d = ndv_compute_bound(dm[k][l]);
10332: for ( i = 0; i < nd_nvar; i++ )
10333: d0[i] = MAX(d0[i],d[i]);
10334: }
10335: return d0;
10336: }
10337:
10338: DL nd_separate_d(UINT *d,UINT *trans)
10339: {
1.65 noro 10340: int td,i,e,j;
1.1 noro 10341: DL a;
10342:
10343: ndl_zero(trans);
10344: td = 0;
10345: for ( i = 0; i < nd_ntrans; i++ ) {
10346: e = GET_EXP(d,i);
10347: PUT_EXP(trans,i,e);
10348: td += MUL_WEIGHT(e,i);
10349: }
10350: if ( nd_ntrans+nd_nalg < nd_nvar ) {
10351: /* homogenized */
10352: i = nd_nvar-1;
10353: e = GET_EXP(d,i);
10354: PUT_EXP(trans,i,e);
10355: td += MUL_WEIGHT(e,i);
10356: }
10357: TD(trans) = td;
10358: if ( nd_blockmask) ndl_weight_mask(trans);
10359: NEWDL(a,nd_nalg);
10360: td = 0;
10361: for ( i = 0; i < nd_nalg; i++ ) {
10362: j = nd_ntrans+i;
10363: e = GET_EXP(d,j);
10364: a->d[i] = e;
10365: td += e;
10366: }
10367: a->td = td;
10368: return a;
10369: }
10370:
10371: int nd_monic(int mod,ND *p)
10372: {
10373: DL alg;
10374: MP mp0,mp;
1.65 noro 10375: NM m,ma0,ma,mb,mr0,mr;
1.1 noro 10376: ND r;
10377: DL dl;
10378: DP nm;
10379: DAlg inv,cd;
10380: Z l,mul;
10381: Z ln;
1.65 noro 10382: int i,e,td,is_lc,len;
1.1 noro 10383: NumberField nf;
10384: struct oEGT eg0,eg1;
10385:
10386: if ( !(nf = get_numberfield()) )
10387: error("nd_monic : current_numberfield is not set");
10388:
10389: /* Q coef -> DAlg coef */
10390: NEWNM(ma0); ma = ma0;
10391: m = BDY(*p);
10392: is_lc = 1;
10393: while ( 1 ) {
10394: NEWMP(mp0); mp = mp0;
1.6 noro 10395: mp->c = (Obj)CZ(m);
1.1 noro 10396: mp->dl = nd_separate_d(DL(m),DL(ma));
10397: NEWNM(mb);
10398: for ( m = NEXT(m); m; m = NEXT(m) ) {
10399: alg = nd_separate_d(DL(m),DL(mb));
10400: if ( !ndl_equal(DL(ma),DL(mb)) )
10401: break;
1.6 noro 10402: NEXTMP(mp0,mp); mp->c = (Obj)CZ(m); mp->dl = alg;
1.1 noro 10403: }
10404: NEXT(mp) = 0;
10405: MKDP(nd_nalg,mp0,nm);
10406: MKDAlg(nm,ONE,cd);
10407: if ( is_lc == 1 ) {
10408: /* if the lc is a rational number, we have nothing to do */
10409: if ( !mp0->dl->td )
10410: return 1;
10411:
10412: get_eg(&eg0);
10413: invdalg(cd,&inv);
10414: get_eg(&eg1); add_eg(&eg_invdalg,&eg0,&eg1);
10415: /* check the validity of inv */
10416: if ( mod && !remqi((Q)inv->dn,mod) )
10417: return 0;
10418: CA(ma) = nf->one;
10419: is_lc = 0;
10420: ln = ONE;
10421: } else {
10422: muldalg(cd,inv,&CA(ma));
10423: lcmz(ln,CA(ma)->dn,&ln);
10424: }
10425: if ( m ) {
10426: NEXT(ma) = mb; ma = mb;
10427: } else {
10428: NEXT(ma) = 0;
10429: break;
10430: }
10431: }
10432: /* l = lcm(denoms) */
10433: l = ln;
10434: for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) {
1.6 noro 10435: divsz(l,CA(m)->dn,&mul);
1.1 noro 10436: for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) {
10437: NEXTNM(mr0,mr);
1.6 noro 10438: mulz((Z)mp->c,mul,&CZ(mr));
1.1 noro 10439: dl = mp->dl;
10440: td = TD(DL(m));
10441: ndl_copy(DL(m),DL(mr));
10442: for ( i = 0; i < nd_nalg; i++ ) {
10443: e = dl->d[i];
10444: PUT_EXP(DL(mr),i+nd_ntrans,e);
10445: td += MUL_WEIGHT(e,i+nd_ntrans);
10446: }
10447: if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m));
10448: TD(DL(mr)) = td;
10449: if ( nd_blockmask) ndl_weight_mask(DL(mr));
10450: }
10451: }
10452: NEXT(mr) = 0;
10453: for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ );
10454: MKND(NV(*p),mr0,len,r);
10455: /* XXX */
10456: SG(r) = SG(*p);
10457: nd_free(*p);
10458: *p = r;
10459: return 1;
10460: }
10461:
10462: NODE reverse_node(NODE n)
10463: {
10464: NODE t,t1;
10465:
10466: for ( t = 0; n; n = NEXT(n) ) {
10467: MKNODE(t1,BDY(n),t); t = t1;
10468: }
10469: return t;
10470: }
10471:
10472: P ndc_div(int mod,union oNDC a,union oNDC b)
10473: {
10474: union oNDC c;
10475: int inv,t;
10476:
10477: if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m));
1.10 noro 10478: else if ( mod == -2 ) divlf(a.z,b.z,&c.z);
1.1 noro 10479: else if ( mod ) {
10480: inv = invm(b.m,mod);
10481: DMAR(a.m,inv,0,mod,t); c.m = t;
10482: } else if ( nd_vc )
10483: divsp(nd_vc,a.p,b.p,&c.p);
10484: else
10485: divsz(a.z,b.z,&c.z);
10486: return ndctop(mod,c);
10487: }
10488:
10489: P ndctop(int mod,union oNDC c)
10490: {
10491: Z q;
10492: int e;
10493: GFS gfs;
10494:
10495: if ( mod == -1 ) {
10496: e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs;
10497: } else if ( mod == -2 ) {
1.10 noro 10498: q = c.z; return (P)q;
1.1 noro 10499: } else if ( mod > 0 ) {
1.6 noro 10500: STOZ(c.m,q); return (P)q;
1.1 noro 10501: } else
10502: return (P)c.p;
10503: }
10504:
10505: /* [0,0,0,cont] = p -> p/cont */
10506:
10507: void finalize_tracelist(int i,P cont)
10508: {
10509: LIST l;
10510: NODE node;
10511: Z iq;
10512:
10513: if ( !UNIQ(cont) ) {
10514: node = mknode(4,NULLP,NULLP,NULLP,cont);
10515: MKLIST(l,node); MKNODE(node,l,nd_tracelist);
10516: nd_tracelist = node;
10517: }
1.6 noro 10518: STOZ(i,iq);
1.1 noro 10519: nd_tracelist = reverse_node(nd_tracelist);
10520: MKLIST(l,nd_tracelist);
10521: node = mknode(2,iq,l); MKLIST(l,node);
10522: MKNODE(node,l,nd_alltracelist); MKLIST(l,node);
10523: nd_alltracelist = node; nd_tracelist = 0;
10524: }
10525:
10526: void conv_ilist(int demand,int trace,NODE g,int **indp)
10527: {
10528: int n,i,j;
10529: int *ind;
10530: NODE t;
10531:
10532: n = length(g);
10533: ind = (int *)MALLOC(n*sizeof(int));
10534: for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) {
10535: j = (long)BDY(t); ind[i] = j;
10536: BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j]));
10537: }
10538: if ( indp ) *indp = ind;
10539: }
10540:
1.30 noro 10541: NODE conv_ilist_s(int demand,int trace,int **indp)
10542: {
1.65 noro 10543: int n,i;
1.30 noro 10544: int *ind;
10545: NODE g0,g;
10546:
10547: n = nd_psn;
10548: ind = (int *)MALLOC(n*sizeof(int));
10549: g0 = 0;
10550: for ( i = 0; i < n; i++ ) {
10551: ind[i] = i;
10552: NEXTNODE(g0,g);
10553: BDY(g) = (pointer)(demand?ndv_load(i):(trace?nd_ps_trace[i]:nd_ps[i]));
10554: }
10555: if ( g0 ) NEXT(g) = 0;
10556: if ( indp ) *indp = ind;
10557: return g0;
10558: }
10559:
1.46 noro 10560: void parse_nd_option(VL vl,NODE opt)
1.1 noro 10561: {
1.38 noro 10562: NODE t,p,u;
1.1 noro 10563: int i,s,n;
1.38 noro 10564: char *key;
10565: Obj value;
1.46 noro 10566: VL oldvl;
1.1 noro 10567:
1.41 noro 10568: nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_norb = 0; nd_gbblock = 0;
1.1 noro 10569: nd_newelim = 0; nd_intersect = 0; nd_nzlist = 0;
10570: nd_splist = 0; nd_check_splist = 0;
1.38 noro 10571: nd_sugarweight = 0; nd_f4red =0; nd_rank0 = 0;
10572: nd_f4_td = 0; nd_sba_f4step = 2; nd_sba_pot = 0; nd_sba_largelcm = 0;
1.41 noro 10573: nd_sba_dontsort = 0; nd_top = 0; nd_sba_redundant_check = 0;
1.46 noro 10574: nd_sba_syz = 0; nd_sba_modord = 0; nd_sba_inputisgb = 0;
1.63 noro 10575: nd_hpdata = 0; nd_sba_heu = 0;
1.39 noro 10576:
1.38 noro 10577: for ( t = opt; t; t = NEXT(t) ) {
10578: p = BDY((LIST)BDY(t));
10579: key = BDY((STRING)BDY(p));
10580: value = (Obj)BDY(NEXT(p));
10581: if ( !strcmp(key,"gentrace") )
10582: nd_gentrace = value?1:0;
10583: else if ( !strcmp(key,"gensyz") )
10584: nd_gensyz = value?1:0;
10585: else if ( !strcmp(key,"nora") )
10586: nd_nora = value?1:0;
1.41 noro 10587: else if ( !strcmp(key,"norb") )
10588: nd_norb = value?1:0;
1.38 noro 10589: else if ( !strcmp(key,"gbblock") ) {
10590: if ( value && OID(value) == O_LIST ) {
1.1 noro 10591: u = BDY((LIST)value);
1.38 noro 10592: nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int));
1.1 noro 10593: for ( i = 0; u; u = NEXT(u) ) {
10594: p = BDY((LIST)BDY(u));
1.65 noro 10595: s = nd_gbblock[i++] = (int)ZTOS((Q)BDY(p));
10596: nd_gbblock[i++] = (int)(s+ZTOS((Q)BDY(NEXT(p)))-1);
1.1 noro 10597: }
10598: nd_gbblock[i] = -1;
1.38 noro 10599: } else
10600: nd_gbblock = 0;
1.1 noro 10601: } else if ( !strcmp(key,"newelim") )
10602: nd_newelim = value?1:0;
10603: else if ( !strcmp(key,"intersect") )
10604: nd_intersect = value?1:0;
1.17 noro 10605: else if ( !strcmp(key,"syzgen") )
1.65 noro 10606: nd_intersect = (int)ZTOS((Q)value);
1.1 noro 10607: else if ( !strcmp(key,"lf") )
10608: nd_lf = value?1:0;
10609: else if ( !strcmp(key,"trace") ) {
1.38 noro 10610: if ( value ) {
10611: u = BDY((LIST)value);
10612: nd_nzlist = BDY((LIST)ARG2(u));
1.65 noro 10613: nd_bpe = (int)ZTOS((Q)ARG3(u));
1.38 noro 10614: }
1.1 noro 10615: } else if ( !strcmp(key,"f4red") ) {
1.65 noro 10616: nd_f4red = (int)ZTOS((Q)value);
1.1 noro 10617: } else if ( !strcmp(key,"rank0") ) {
1.38 noro 10618: nd_rank0 = value?1:0;
1.1 noro 10619: } else if ( !strcmp(key,"splist") ) {
1.38 noro 10620: nd_splist = value?1:0;
1.1 noro 10621: } else if ( !strcmp(key,"check_splist") ) {
10622: nd_check_splist = BDY((LIST)value);
1.49 noro 10623: } else if ( !strcmp(key,"hpdata") ) {
1.50 noro 10624: if ( value )
10625: nd_hpdata = BDY((LIST)value);
1.1 noro 10626: } else if ( !strcmp(key,"sugarweight") ) {
10627: u = BDY((LIST)value);
1.38 noro 10628: n = length(u);
10629: nd_sugarweight = MALLOC(n*sizeof(int));
1.1 noro 10630: for ( i = 0; i < n; i++, u = NEXT(u) )
1.65 noro 10631: nd_sugarweight[i] = (int)ZTOS((Q)BDY(u));
1.38 noro 10632: } else if ( !strcmp(key,"f4_td") ) {
10633: nd_f4_td = value?1:0;
10634: } else if ( !strcmp(key,"sba_f4step") ) {
1.65 noro 10635: nd_sba_f4step = value?(int)ZTOS((Q)value):0;
1.38 noro 10636: } else if ( !strcmp(key,"sba_pot") ) {
1.65 noro 10637: nd_sba_pot = (int)ZTOS((Q)value);
1.38 noro 10638: } else if ( !strcmp(key,"sba_largelcm") ) {
10639: nd_sba_largelcm = value?1:0;
1.39 noro 10640: } else if ( !strcmp(key,"sba_dontsort") ) {
10641: nd_sba_dontsort = value?1:0;
1.44 noro 10642: } else if ( !strcmp(key,"sba_syz") ) {
10643: nd_sba_syz = value?1:0;
1.63 noro 10644: } else if ( !strcmp(key,"sba_heu") ) {
10645: nd_sba_heu = value?1:0;
1.46 noro 10646: } else if ( !strcmp(key,"sba_modord") ) {
10647: // value=[vlist,ordspec,weight]
10648: u = BDY((LIST)value);
10649: pltovl((LIST)ARG0(u),&oldvl);
10650: nd_sba_modord = create_comp_sig_spec(vl,oldvl,(Obj)ARG1(u),argc(u)==3?ARG2(u):0);
10651: } else if ( !strcmp(key,"sba_gbinput") ) {
10652: nd_sba_inputisgb = value?1:0;
10653: if ( nd_sba_inputisgb != 0 ) {
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: }
1.41 noro 10659: } else if ( !strcmp(key,"sba_redundant_check") ) {
10660: nd_sba_redundant_check = value?1:0;
1.39 noro 10661: } else if ( !strcmp(key,"top") ) {
10662: nd_top = value?1:0;
1.1 noro 10663: }
1.38 noro 10664: }
1.44 noro 10665: if ( nd_sba_syz ) nd_sba_dontsort = 1;
1.1 noro 10666: }
10667:
10668: ND mdptond(DP d);
10669: ND nd_mul_nm(int mod,NM m0,ND p);
10670: ND nd_mul_nm_lf(NM m0,ND p);
10671: ND *btog(NODE ti,ND **p,int nb,int mod);
10672: ND btog_one(NODE ti,ND *p,int nb,int mod);
10673: MAT nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,MAT *rp);
10674: VECT nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos,MAT *rp);
10675:
10676: /* d:monomial */
10677: ND mdptond(DP d)
10678: {
10679: NM m;
10680: ND r;
10681:
10682: if ( OID(d) == 1 )
10683: r = ptond(CO,CO,(P)d);
10684: else {
10685: NEWNM(m);
10686: dltondl(NV(d),BDY(d)->dl,DL(m));
1.6 noro 10687: CZ(m) = (Z)BDY(d)->c;
1.1 noro 10688: NEXT(m) = 0;
10689: MKND(NV(d),m,1,r);
10690: }
10691: return r;
10692: }
10693:
10694: ND nd_mul_nm(int mod,NM m0,ND p)
10695: {
10696: UINT *d0;
10697: int c0,c1,c;
10698: NM tm,mr,mr0;
10699: ND r;
10700:
10701: if ( !p ) return 0;
10702: d0 = DL(m0);
10703: c0 = CM(m0);
10704: mr0 = 0;
10705: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
10706: NEXTNM(mr0,mr);
10707: c = CM(tm); DMAR(c0,c,0,mod,c1); CM(mr) = c1;
10708: ndl_add(d0,DL(tm),DL(mr));
10709: }
10710: NEXT(mr) = 0;
10711: MKND(NV(p),mr0,LEN(p),r);
10712: return r;
10713: }
10714:
10715: ND nd_mul_nm_lf(NM m0,ND p)
10716: {
10717: UINT *d0;
1.65 noro 10718: Z c0,c1;
1.1 noro 10719: NM tm,mr,mr0;
10720: ND r;
10721:
10722: if ( !p ) return 0;
10723: d0 = DL(m0);
10724: c0 = CZ(m0);
10725: mr0 = 0;
10726: for ( tm = BDY(p); tm; tm = NEXT(tm) ) {
10727: NEXTNM(mr0,mr);
1.65 noro 10728: mullf(c0,CZ(tm),&c1); CZ(mr) = c1;
1.1 noro 10729: ndl_add(d0,DL(tm),DL(mr));
10730: }
10731: NEXT(mr) = 0;
10732: MKND(NV(p),mr0,LEN(p),r);
10733: return r;
10734: }
10735:
10736: ND *btog(NODE ti,ND **p,int nb,int mod)
10737: {
10738: PGeoBucket *r;
10739: int i,ci;
10740: NODE t,s;
10741: ND m,tp;
10742: ND *pi,*rd;
10743: P c;
10744:
10745: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
10746: for ( i = 0; i < nb; i++ )
10747: r[i] = create_pbucket();
10748: for ( t = ti; t; t = NEXT(t) ) {
10749: s = BDY((LIST)BDY(t));
10750: if ( ARG0(s) ) {
10751: m = mdptond((DP)ARG2(s));
1.6 noro 10752: ptomp(mod,(P)HCZ(m),&c);
1.1 noro 10753: if ( (ci = ((MQ)c)->cont) != 0 ) {
10754: HCM(m) = ci;
1.6 noro 10755: pi = p[ZTOS((Q)ARG1(s))];
1.1 noro 10756: for ( i = 0; i < nb; i++ ) {
10757: tp = nd_mul_nm(mod,BDY(m),pi[i]);
10758: add_pbucket(mod,r[i],tp);
10759: }
10760: }
10761: ci = 1;
10762: } else {
10763: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
10764: ci = invm(ci,mod);
10765: }
10766: }
10767: rd = (ND *)MALLOC(nb*sizeof(ND));
10768: for ( i = 0; i < nb; i++ )
10769: rd[i] = normalize_pbucket(mod,r[i]);
10770: if ( ci != 1 )
10771: for ( i = 0; i < nb; i++ ) nd_mul_c(mod,rd[i],ci);
10772: return rd;
10773: }
10774:
10775: /* YYY */
10776: ND *btog_lf(NODE ti,ND **p,int nb)
10777: {
10778: PGeoBucket *r;
10779: int i;
10780: NODE t,s;
10781: ND m,tp;
10782: ND *pi,*rd;
10783: LM lm;
10784: Z lf,c;
10785:
10786: r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket));
10787: for ( i = 0; i < nb; i++ )
10788: r[i] = create_pbucket();
10789: for ( t = ti; t; t = NEXT(t) ) {
10790: s = BDY((LIST)BDY(t));
10791: if ( ARG0(s) ) {
10792: m = mdptond((DP)ARG2(s));
1.6 noro 10793: simp_ff((Obj)HCZ(m),(Obj *)&lm);
1.1 noro 10794: if ( lm ) {
10795: lmtolf(lm,&lf); HCZ(m) = lf;
1.6 noro 10796: pi = p[ZTOS((Q)ARG1(s))];
1.1 noro 10797: for ( i = 0; i < nb; i++ ) {
10798: tp = nd_mul_nm_lf(BDY(m),pi[i]);
10799: add_pbucket(-2,r[i],tp);
10800: }
10801: }
10802: c = ONE;
10803: } else {
10804: simp_ff((Obj)ARG3(s),(Obj *)&lm); lmtolf(lm,&lf); invz(lf,current_mod_lf,&c);
10805: }
10806: }
10807: rd = (ND *)MALLOC(nb*sizeof(ND));
10808: for ( i = 0; i < nb; i++ )
10809: rd[i] = normalize_pbucket(-2,r[i]);
10810: for ( i = 0; i < nb; i++ ) nd_mul_c_lf(rd[i],c);
10811: return rd;
10812: }
10813:
10814: ND btog_one(NODE ti,ND *p,int nb,int mod)
10815: {
10816: PGeoBucket r;
1.65 noro 10817: int ci,j;
1.1 noro 10818: NODE t,s;
10819: ND m,tp;
10820: ND pi,rd;
10821: P c;
10822:
10823: r = create_pbucket();
10824: for ( t = ti; t; t = NEXT(t) ) {
10825: s = BDY((LIST)BDY(t));
10826: if ( ARG0(s) ) {
10827: m = mdptond((DP)ARG2(s));
1.6 noro 10828: ptomp(mod,(P)HCZ(m),&c);
1.1 noro 10829: if ( (ci = ((MQ)c)->cont) != 0 ) {
10830: HCM(m) = ci;
1.65 noro 10831: pi = p[j=(int)ZTOS((Q)ARG1(s))];
1.1 noro 10832: if ( !pi ) {
10833: pi = nd_load_mod(j);
10834: tp = nd_mul_nm(mod,BDY(m),pi);
10835: nd_free(pi);
10836: add_pbucket(mod,r,tp);
10837: } else {
10838: tp = nd_mul_nm(mod,BDY(m),pi);
10839: add_pbucket(mod,r,tp);
10840: }
10841: }
10842: ci = 1;
10843: } else {
10844: ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont;
10845: ci = invm(ci,mod);
10846: }
10847: }
10848: rd = normalize_pbucket(mod,r);
10849: free_pbucket(r);
10850: if ( ci != 1 ) nd_mul_c(mod,rd,ci);
10851: return rd;
10852: }
10853:
10854: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp);
10855:
10856: MAT nd_btog(LIST f,LIST v,int mod,struct order_spec *ord,LIST tlist,MAT *rp)
10857: {
10858: int i,j,n,m,nb,pi0,pi1,nvar;
10859: VL fv,tv,vv;
10860: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
10861: ND **p;
10862: ND *c;
10863: ND u;
10864: P inv;
10865: MAT mat;
10866:
10867: if ( mod == -2 )
10868: return nd_btog_lf(f,v,ord,tlist,rp);
10869:
10870: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 10871: parse_nd_option(vv,current_option);
1.1 noro 10872: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
10873: switch ( ord->id ) {
10874: case 1:
10875: if ( ord->nv != nvar )
10876: error("nd_check : invalid order specification");
10877: break;
10878: default:
10879: break;
10880: }
10881: nd_init_ord(ord);
10882: #if 0
1.6 noro 10883: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 10884: #else
10885: nd_bpe = 32;
10886: #endif
10887: nd_setup_parameters(nvar,0);
10888: permtrace = BDY((LIST)ARG2(BDY(tlist)));
10889: intred = BDY((LIST)ARG3(BDY(tlist)));
10890: ind = BDY((LIST)ARG4(BDY(tlist)));
10891: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
10892: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.65 noro 10893: j = (int)ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 10894: if ( j > i ) i = j;
10895: }
10896: n = i+1;
10897: nb = length(BDY(f));
10898: p = (ND **)MALLOC(n*sizeof(ND *));
10899: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
10900: pi = BDY((LIST)BDY(t));
1.65 noro 10901: pi0 = (int)ZTOS((Q)ARG0(pi)); pi1 = (int)ZTOS((Q)ARG1(pi));
1.1 noro 10902: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
10903: ptomp(mod,(P)ARG2(pi),&inv);
10904: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
10905: u = ptond(CO,vv,(P)ONE);
10906: HCM(u) = ((MQ)inv)->cont;
10907: c[pi1] = u;
10908: }
10909: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
10910: printf("%d ",i); fflush(stdout);
10911: ti = BDY((LIST)BDY(t));
1.65 noro 10912: p[j=(int)ZTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 10913: }
10914: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
10915: printf("%d ",i); fflush(stdout);
10916: ti = BDY((LIST)BDY(t));
1.65 noro 10917: p[j=(int)ZTOS((Q)ARG0(ti))] = btog(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 10918: }
10919: m = length(ind);
10920: MKMAT(mat,nb,m);
10921: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
1.6 noro 10922: for ( i = 0, c = p[ZTOS((Q)BDY(t))]; i < nb; i++ )
1.1 noro 10923: BDY(mat)[i][j] = ndtodp(mod,c[i]);
10924: return mat;
10925: }
10926:
10927: MAT nd_btog_lf(LIST f,LIST v,struct order_spec *ord,LIST tlist,MAT *rp)
10928: {
10929: int i,j,n,m,nb,pi0,pi1,nvar;
10930: VL fv,tv,vv;
10931: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
10932: ND **p;
10933: ND *c;
10934: ND u;
10935: MAT mat;
10936: LM lm;
10937: Z lf,inv;
10938:
10939: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 10940: parse_nd_option(vv,current_option);
1.1 noro 10941: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
10942: switch ( ord->id ) {
10943: case 1:
10944: if ( ord->nv != nvar )
10945: error("nd_check : invalid order specification");
10946: break;
10947: default:
10948: break;
10949: }
10950: nd_init_ord(ord);
10951: #if 0
1.6 noro 10952: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 10953: #else
10954: nd_bpe = 32;
10955: #endif
10956: nd_setup_parameters(nvar,0);
10957: permtrace = BDY((LIST)ARG2(BDY(tlist)));
10958: intred = BDY((LIST)ARG3(BDY(tlist)));
10959: ind = BDY((LIST)ARG4(BDY(tlist)));
10960: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
10961: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.65 noro 10962: j = (int)ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 10963: if ( j > i ) i = j;
10964: }
10965: n = i+1;
10966: nb = length(BDY(f));
10967: p = (ND **)MALLOC(n*sizeof(ND *));
10968: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
10969: pi = BDY((LIST)BDY(t));
1.65 noro 10970: pi0 = (int)ZTOS((Q)ARG0(pi)); pi1 = (int)ZTOS((Q)ARG1(pi));
1.1 noro 10971: p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND));
10972: simp_ff((Obj)ARG2(pi),(Obj *)&lm); lmtolf(lm,&lf); invz(lf,current_mod_lf,&inv);
10973: u = ptond(CO,vv,(P)ONE);
10974: HCZ(u) = inv;
10975: c[pi1] = u;
10976: }
10977: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
10978: printf("%d ",i); fflush(stdout);
10979: ti = BDY((LIST)BDY(t));
1.65 noro 10980: p[j=(int)ZTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
1.1 noro 10981: }
10982: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
10983: printf("%d ",i); fflush(stdout);
10984: ti = BDY((LIST)BDY(t));
1.65 noro 10985: p[j=(int)ZTOS((Q)ARG0(ti))] = btog_lf(BDY((LIST)ARG1(ti)),p,nb);
1.1 noro 10986: }
10987: m = length(ind);
10988: MKMAT(mat,nb,m);
10989: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) )
1.6 noro 10990: for ( i = 0, c = p[ZTOS((Q)BDY(t))]; i < nb; i++ )
1.1 noro 10991: BDY(mat)[i][j] = ndtodp(-2,c[i]);
10992: return mat;
10993: }
10994:
10995: VECT nd_btog_one(LIST f,LIST v,int mod,struct order_spec *ord,
10996: LIST tlist,int pos,MAT *rp)
10997: {
10998: int i,j,n,m,nb,pi0,pi1,nvar;
10999: VL fv,tv,vv;
11000: NODE permtrace,perm,trace,intred,ind,t,pi,ti;
11001: ND *p;
11002: ND u;
11003: P inv;
11004: VECT vect;
11005:
11006: if ( mod == -2 )
11007: error("nd_btog_one : not implemented yet for a large finite field");
11008:
11009: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11010: parse_nd_option(vv,current_option);
1.1 noro 11011: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11012: switch ( ord->id ) {
11013: case 1:
11014: if ( ord->nv != nvar )
11015: error("nd_check : invalid order specification");
11016: break;
11017: default:
11018: break;
11019: }
11020: nd_init_ord(ord);
11021: #if 0
1.6 noro 11022: nd_bpe = ZTOS((Q)ARG7(BDY(tlist)));
1.1 noro 11023: #else
11024: nd_bpe = 32;
11025: #endif
11026: nd_setup_parameters(nvar,0);
11027: permtrace = BDY((LIST)ARG2(BDY(tlist)));
11028: intred = BDY((LIST)ARG3(BDY(tlist)));
11029: ind = BDY((LIST)ARG4(BDY(tlist)));
11030: perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace);
11031: for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) {
1.65 noro 11032: j = (int)ZTOS((Q)BDY(BDY((LIST)BDY(t))));
1.1 noro 11033: if ( j > i ) i = j;
11034: }
11035: n = i+1;
11036: nb = length(BDY(f));
11037: p = (ND *)MALLOC(n*sizeof(ND *));
11038: for ( t = perm, i = 0; t; t = NEXT(t), i++ ) {
11039: pi = BDY((LIST)BDY(t));
1.65 noro 11040: pi0 = (int)ZTOS((Q)ARG0(pi)); pi1 = (int)ZTOS((Q)ARG1(pi));
1.1 noro 11041: if ( pi1 == pos ) {
11042: ptomp(mod,(P)ARG2(pi),&inv);
11043: ((MQ)inv)->cont = invm(((MQ)inv)->cont,mod);
11044: u = ptond(CO,vv,(P)ONE);
11045: HCM(u) = ((MQ)inv)->cont;
11046: p[pi0] = u;
11047: }
11048: }
11049: for ( t = trace,i=0; t; t = NEXT(t), i++ ) {
11050: printf("%d ",i); fflush(stdout);
11051: ti = BDY((LIST)BDY(t));
1.65 noro 11052: p[j=(int)ZTOS((Q)ARG0(ti))] = btog_one(BDY((LIST)ARG1(ti)),p,nb,mod);
1.1 noro 11053: if ( Demand ) {
11054: nd_save_mod(p[j],j); nd_free(p[j]); p[j] = 0;
11055: }
11056: }
11057: for ( t = intred, i=0; t; t = NEXT(t), i++ ) {
11058: printf("%d ",i); fflush(stdout);
11059: ti = BDY((LIST)BDY(t));
1.65 noro 11060: p[j=(int)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: m = length(ind);
11066: MKVECT(vect,m);
11067: for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) {
1.6 noro 11068: u = p[ZTOS((Q)BDY(t))];
1.1 noro 11069: if ( !u ) {
1.65 noro 11070: u = nd_load_mod((int)ZTOS((Q)BDY(t)));
1.1 noro 11071: BDY(vect)[j] = ndtodp(mod,u);
11072: nd_free(u);
11073: } else
11074: BDY(vect)[j] = ndtodp(mod,u);
11075: }
11076: return vect;
11077: }
11078:
11079: void ndv_print_lf(NDV p)
11080: {
11081: NMV m;
11082: int i,len;
11083:
11084: if ( !p ) printf("0\n");
11085: else {
11086: len = LEN(p);
11087: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
11088: printf("+");
11089: mpz_out_str(asir_out,10,BDY(CZ(m)));
11090: printf("*");
11091: ndl_print(DL(m));
11092: }
11093: printf("\n");
11094: }
11095: }
11096:
11097: void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp)
11098: {
1.65 noro 11099: VL tv,fv,vv;
11100: NODE fd,fd0,in0,in,r,t,s,cand;
11101: int m,nvar,mindex,e,max;
1.1 noro 11102: NDV c;
11103: NMV a;
11104: EPOS oepos;
1.65 noro 11105: int obpe,oadv,wmax,i,len,cbpe,ishomo,mrank,trank,ompos;
1.1 noro 11106: struct order_spec *ord1;
11107: struct oEGT eg_check,eg0,eg1;
11108: int *perm;
1.65 noro 11109: int ret;
1.1 noro 11110: NODE retn;
11111:
11112: nd_module = 0;
11113: get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc);
1.46 noro 11114: parse_nd_option(vv,current_option);
1.1 noro 11115: if ( nd_vc )
11116: error("nd_f4_lf_trace : computation over a rational function field is not implemented");
11117: for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ );
11118: switch ( ord->id ) {
11119: case 1:
11120: if ( ord->nv != nvar )
11121: error("nd_f4_lf_trace : invalid order specification");
11122: break;
11123: default:
11124: break;
11125: }
11126:
11127: nd_ntrans = nvar;
11128: nd_nalg = 0;
11129:
1.65 noro 11130: // nocheck = 0;
1.1 noro 11131: mindex = 0;
11132:
11133: /* do not use on-demand load/save */
11134: nd_demand = 0;
11135: m = trace > 1 ? trace : get_lprime(mindex);
11136: nd_init_ord(ord);
11137: mrank = 0;
11138: for ( t = BDY(f), max = 1; t; t = NEXT(t) )
11139: for ( tv = vv; tv; tv = NEXT(tv) ) {
11140: if ( nd_module ) {
11141: s = BDY((LIST)BDY(t));
11142: trank = length(s);
11143: mrank = MAX(mrank,trank);
11144: for ( ; s; s = NEXT(s) ) {
11145: e = getdeg(tv->v,(P)BDY(s));
11146: max = MAX(e,max);
11147: }
11148: } else {
11149: e = getdeg(tv->v,(P)BDY(t));
11150: max = MAX(e,max);
11151: }
11152: }
11153: nd_setup_parameters(nvar,max);
11154: obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos;
11155: ishomo = 1;
11156: /* XXX */
11157: for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
11158: if ( nd_module ) {
11159: c = (pointer)pltondv(CO,vv,(LIST)BDY(t));
11160: } else {
11161: c = (pointer)ptondv(CO,vv,(P)BDY(t));
11162: }
11163: if ( ishomo )
11164: ishomo = ishomo && ndv_ishomo(c);
11165: if ( c ) {
11166: NEXTNODE(fd0,fd); BDY(fd) = (pointer)ndv_dup(0,c);
11167: ndv_mod(-2,c);
11168: NEXTNODE(in0,in); BDY(in) = (pointer)c;
11169: }
11170: }
11171: if ( in0 ) NEXT(in) = 0;
11172: if ( fd0 ) NEXT(fd) = 0;
11173: if ( !ishomo && homo ) {
11174: for ( t = in0, wmax = max; t; t = NEXT(t) ) {
11175: c = (NDV)BDY(t); len = LEN(c);
11176: for ( a = BDY(c), i = 0; i < len; i++, NMV_ADV(a) )
1.65 noro 11177: wmax = MAX((int)TD(DL(a)),wmax);
1.1 noro 11178: }
11179: homogenize_order(ord,nvar,&ord1);
11180: nd_init_ord(ord1);
11181: nd_setup_parameters(nvar+1,wmax);
11182: for ( t = fd0; t; t = NEXT(t) )
11183: ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos);
11184: }
1.65 noro 11185: // if ( MaxDeg > 0 ) nocheck = 1;
1.24 noro 11186: ret = ndv_setup(-2,m,fd0,nd_gbblock?1:0,0,0);
1.1 noro 11187: if ( ret )
11188: cand = nd_f4_lf_trace_main(m,&perm);
11189: if ( !ret || !cand ) {
11190: *rp = 0; return;
11191: }
11192: if ( !ishomo && homo ) {
11193: /* dehomogenization */
11194: for ( t = cand; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord);
11195: nd_init_ord(ord);
11196: nd_setup_parameters(nvar,0);
11197: }
11198: cand = ndv_reducebase(cand,perm);
11199: cand = ndv_reduceall(-2,cand);
11200: cbpe = nd_bpe;
11201: get_eg(&eg0);
11202: if ( (ret = ndv_check_membership(-2,in0,obpe,oadv,oepos,cand)) != 0 ) {
11203: /* gbcheck : cand is a GB of Id(cand) ? */
11204: retn = nd_f4(-2,0,0);
1.65 noro 11205: if ( !retn ) {
11206: /* failure */
11207: *rp = 0; return;
11208: }
1.1 noro 11209: }
11210: get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1);
11211: if ( DP_Print )
1.5 noro 11212: fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime);
1.1 noro 11213: /* dp->p */
11214: nd_bpe = cbpe;
11215: nd_setup_parameters(nd_nvar,0);
11216: for ( r = cand; r; r = NEXT(r) ) {
11217: if ( nd_module ) BDY(r) = ndvtopl(-2,CO,vv,BDY(r),mrank);
11218: else BDY(r) = (pointer)ndvtop(-2,CO,vv,BDY(r));
11219: }
11220: MKLIST(*rp,cand);
11221: }
11222:
11223: NODE nd_f4_lf_trace_main(int m,int **indp)
11224: {
1.65 noro 11225: int i,nh,stat;
1.1 noro 11226: NODE r,rm,g;
11227: ND_pairs d,l,l0,t;
1.65 noro 11228: NDV nfqv,nfv;
11229: NODE rp0,nflist,nflist_lf;
11230: UINT *s0vect;
11231: int col;
1.1 noro 11232: int sugar;
11233: PGeoBucket bucket;
11234: struct oEGT eg0,eg1,eg_f4;
11235:
11236: g = 0; d = 0;
11237: for ( i = 0; i < nd_psn; i++ ) {
11238: d = update_pairs(d,g,i,0);
11239: g = update_base(g,i);
11240: }
11241: while ( d ) {
11242: get_eg(&eg0);
11243: l = nd_minsugarp(d,&d);
11244: sugar = SG(l);
11245: if ( MaxDeg > 0 && sugar > MaxDeg ) break;
11246: bucket = create_pbucket();
11247: stat = nd_sp_f4(m,0,l,bucket);
11248: if ( !stat ) {
11249: for ( t = l; NEXT(t); t = NEXT(t) );
11250: NEXT(t) = d; d = l;
11251: d = nd_reconstruct(1,d);
11252: continue;
11253: }
11254: if ( bucket->m < 0 ) continue;
11255: col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0);
11256: if ( !col ) {
11257: for ( t = l; NEXT(t); t = NEXT(t) );
11258: NEXT(t) = d; d = l;
11259: d = nd_reconstruct(1,d);
11260: continue;
11261: }
11262: get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1);
11263: if ( DP_Print )
1.5 noro 11264: fprintf(asir_out,"\nsugar=%d,symb=%.3fsec,",sugar,eg_f4.exectime);
1.1 noro 11265: nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0);
11266: if ( !l0 ) continue;
11267: l = l0;
11268:
11269: /* over LF */
11270: bucket = create_pbucket();
11271: stat = nd_sp_f4(-2,1,l,bucket);
11272: if ( !stat ) {
11273: for ( t = l; NEXT(t); t = NEXT(t) );
11274: NEXT(t) = d; d = l;
11275: d = nd_reconstruct(1,d);
11276: continue;
11277: }
11278: if ( bucket->m < 0 ) continue;
11279: col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0);
11280: if ( !col ) {
11281: for ( t = l; NEXT(t); t = NEXT(t) );
11282: NEXT(t) = d; d = l;
11283: d = nd_reconstruct(1,d);
11284: continue;
11285: }
11286: nflist_lf = nd_f4_red(-2,l,1,s0vect,col,rp0,0);
11287: /* adding new bases */
11288: for ( rm = nflist, r = nflist_lf; r && rm; rm = NEXT(rm), r = NEXT(r) ) {
11289: nfv = (NDV)BDY(rm);
11290: nfqv = (NDV)BDY(r);
11291: if ( DL_COMPARE(HDL(nfv),HDL(nfqv)) ) return 0;
11292: ndv_removecont(m,nfv);
11293: ndv_removecont(-2,nfqv);
1.24 noro 11294: nh = ndv_newps(-2,nfv,nfqv);
1.1 noro 11295: d = update_pairs(d,g,nh,0);
11296: g = update_base(g,nh);
11297: }
11298: if ( r || rm ) return 0;
11299: }
11300: conv_ilist(nd_demand,1,g,indp);
11301: return g;
11302: }
11303:
1.7 noro 11304: #if SIZEOF_LONG==8
11305:
11306: NDV vect64_to_ndv(mp_limb_t *vect,int spcol,int col,int *rhead,UINT *s0vect)
11307: {
11308: int j,k,len;
11309: UINT *p;
11310: UINT c;
11311: NDV r;
11312: NMV mr0,mr;
11313:
11314: for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++;
11315: if ( !len ) return 0;
11316: else {
11317: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
11318: #if 0
11319: ndv_alloc += nmv_adv*len;
11320: #endif
11321: mr = mr0;
11322: p = s0vect;
11323: for ( j = k = 0; j < col; j++, p += nd_wpd )
11324: if ( !rhead[j] ) {
11325: if ( (c = (UINT)vect[k++]) != 0 ) {
11326: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
11327: }
11328: }
11329: MKNDV(nd_nvar,mr0,len,r);
11330: return r;
11331: }
11332: }
11333:
1.28 noro 11334: NDV vect64_to_ndv_s(mp_limb_t *vect,int col,UINT *s0vect)
11335: {
11336: int j,k,len;
11337: UINT *p;
11338: UINT c;
11339: NDV r;
11340: NMV mr0,mr;
11341:
11342: for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++;
11343: if ( !len ) return 0;
11344: else {
11345: mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len);
11346: mr = mr0;
11347: p = s0vect;
11348: for ( j = k = 0; j < col; j++, p += nd_wpd )
11349: if ( (c = (UINT)vect[k++]) != 0 ) {
11350: ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr);
11351: }
11352: MKNDV(nd_nvar,mr0,len,r);
11353: return r;
11354: }
11355: }
11356:
1.7 noro 11357: int nd_to_vect64(int mod,UINT *s0,int n,ND d,mp_limb_t *r)
11358: {
11359: NM m;
1.11 noro 11360: UINT *t,*s,*u;
11361: int i,st,ed,md,prev,c;
1.7 noro 11362:
11363: for ( i = 0; i < n; i++ ) r[i] = 0;
1.11 noro 11364: prev = 0;
11365: for ( i = 0, m = BDY(d); m; m = NEXT(m) ) {
11366: t = DL(m);
11367: st = prev;
11368: ed = n;
11369: while ( ed > st ) {
11370: md = (st+ed)/2;
11371: u = s0+md*nd_wpd;
11372: c = DL_COMPARE(u,t);
11373: if ( c == 0 ) break;
11374: else if ( c > 0 ) st = md;
11375: else ed = md;
11376: }
11377: r[md] = (mp_limb_t)CM(m);
11378: prev = md;
1.7 noro 11379: }
11380: for ( i = 0; !r[i]; i++ );
11381: return i;
11382: }
11383:
11384: #define MOD128(a,c,m) ((a)=(((c)!=0||((a)>=(m)))?(((((U128)(c))<<64)+(a))%(m)):(a)))
11385:
1.28 noro 11386: 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 11387: {
11388: int i,j,k,len,pos,prev;
11389: mp_limb_t a,c,c1,c2;
11390: IndArray ivect;
11391: unsigned char *ivc;
11392: unsigned short *ivs;
11393: unsigned int *ivi;
11394: NDV redv;
11395: NMV mr;
11396: NODE rp;
11397: int maxrs;
11398:
11399: for ( i = 0; i < col; i++ ) cvect[i] = 0;
11400: maxrs = 0;
11401: for ( i = 0; i < nred; i++ ) {
11402: ivect = imat[i];
11403: k = ivect->head;
11404: a = svect[k]; c = cvect[k];
11405: MOD128(a,c,m);
11406: svect[k] = a; cvect[k] = 0;
1.28 noro 11407: if ( (c = svect[k]) != 0 && (sig == 0 || comp_sig(sig,rp0[i]->sig) > 0 ) ) {
1.11 noro 11408: Nf4_red++;
1.7 noro 11409: maxrs = MAX(maxrs,rp0[i]->sugar);
11410: c = m-c; redv = nd_ps[rp0[i]->index];
11411: len = LEN(redv); mr = BDY(redv);
11412: svect[k] = 0; prev = k;
11413: switch ( ivect->width ) {
11414: case 1:
11415: ivc = ivect->index.c;
11416: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11417: pos = prev+ivc[j]; c1 = CM(mr); prev = pos;
1.12 noro 11418: c2 = svect[pos]+c1*c;
11419: if ( c2 < svect[pos] ) cvect[pos]++;
11420: svect[pos] = c2;
1.7 noro 11421: }
11422: break;
11423: case 2:
11424: ivs = ivect->index.s;
11425: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11426: pos = prev+ivs[j]; c1 = CM(mr); prev = pos;
1.12 noro 11427: c2 = svect[pos]+c1*c;
11428: if ( c2 < svect[pos] ) cvect[pos]++;
11429: svect[pos] = c2;
1.7 noro 11430: }
11431: break;
11432: case 4:
11433: ivi = ivect->index.i;
11434: for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) {
11435: pos = prev+ivi[j]; c1 = CM(mr); prev = pos;
1.12 noro 11436: c2 = svect[pos]+c1*c;
11437: if ( c2 < svect[pos] ) cvect[pos]++;
11438: svect[pos] = c2;
1.7 noro 11439: }
11440: break;
11441: }
11442: }
11443: }
11444: for ( i = 0; i < col; i++ ) {
11445: a = svect[i]; c = cvect[i]; MOD128(a,c,m); svect[i] = a;
11446: }
11447: return maxrs;
11448: }
11449:
11450: /* for Fp, 2^15=<p<2^29 */
11451:
11452: NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
11453: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz)
11454: {
11455: int spcol,sprow,a;
11456: int i,j,k,l,rank;
11457: NODE r0,r;
11458: ND_pairs sp;
11459: ND spol;
11460: mp_limb_t **spmat;
11461: mp_limb_t *svect,*cvect;
11462: mp_limb_t *v;
11463: int *colstat;
11464: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
11465: int maxrs;
11466: int *spsugar;
11467: ND_pairs *spactive;
11468:
11469: spcol = col-nred;
11470: get_eg(&eg0);
11471: /* elimination (1st step) */
11472: spmat = (mp_limb_t **)MALLOC(nsp*sizeof(mp_limb_t *));
11473: svect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11474: cvect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11475: spsugar = (int *)MALLOC(nsp*sizeof(int));
11476: spactive = !nz?0:(ND_pairs *)MALLOC(nsp*sizeof(ND_pairs));
11477: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
11478: nd_sp(m,0,sp,&spol);
11479: if ( !spol ) continue;
11480: nd_to_vect64(m,s0vect,col,spol,svect);
1.28 noro 11481: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred,0);
1.7 noro 11482: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
11483: if ( i < col ) {
11484: spmat[sprow] = v = (mp_limb_t *)MALLOC_ATOMIC(spcol*sizeof(mp_limb_t));
11485: for ( j = k = 0; j < col; j++ )
11486: if ( !rhead[j] ) v[k++] = (UINT)svect[j];
11487: spsugar[sprow] = MAX(maxrs,SG(spol));
11488: if ( nz )
11489: spactive[sprow] = sp;
11490: sprow++;
11491: }
11492: nd_free(spol);
11493: }
1.12 noro 11494: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
1.7 noro 11495: if ( DP_Print ) {
11496: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
11497: fflush(asir_out);
11498: }
11499: /* free index arrays */
11500: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
11501:
11502: /* elimination (2nd step) */
11503: colstat = (int *)MALLOC(spcol*sizeof(int));
11504: rank = nd_gauss_elim_mod64(spmat,spsugar,spactive,sprow,spcol,m,colstat);
11505: r0 = 0;
11506: for ( i = 0; i < rank; i++ ) {
11507: NEXTNODE(r0,r); BDY(r) =
11508: (pointer)vect64_to_ndv(spmat[i],spcol,col,rhead,s0vect);
11509: SG((NDV)BDY(r)) = spsugar[i];
11510: GCFREE(spmat[i]);
11511: }
11512: if ( r0 ) NEXT(r) = 0;
11513:
11514: for ( ; i < sprow; i++ ) GCFREE(spmat[i]);
1.12 noro 11515: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
1.7 noro 11516: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
11517: if ( DP_Print ) {
11518: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
11519: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
11520: nsp,nred,sprow,spcol,rank);
11521: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
11522: }
11523: if ( nz ) {
11524: for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1];
11525: if ( rank > 0 ) {
11526: NEXT(spactive[rank-1]) = 0;
11527: *nz = spactive[0];
11528: } else
11529: *nz = 0;
11530: }
11531: return r0;
11532: }
11533:
11534: int nd_gauss_elim_mod64(mp_limb_t **mat,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat)
11535: {
11536: int i,j,k,l,rank,s;
11537: mp_limb_t inv;
11538: mp_limb_t a;
11539: UINT c;
11540: mp_limb_t *t,*pivot,*pk;
11541: UINT *ck;
11542: UINT **cmat;
11543: UINT *ct;
11544: ND_pairs pair;
11545:
11546: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
11547: for ( i = 0; i < row; i++ ) {
11548: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
11549: bzero(cmat[i],col*sizeof(UINT));
11550: }
11551:
11552: for ( rank = 0, j = 0; j < col; j++ ) {
11553: for ( i = rank; i < row; i++ ) {
11554: a = mat[i][j]; c = cmat[i][j];
11555: MOD128(a,c,md);
11556: mat[i][j] = a; cmat[i][j] = 0;
11557: }
11558: for ( i = rank; i < row; i++ )
11559: if ( mat[i][j] )
11560: break;
11561: if ( i == row ) {
11562: colstat[j] = 0;
11563: continue;
11564: } else
11565: colstat[j] = 1;
11566: if ( i != rank ) {
11567: t = mat[i]; mat[i] = mat[rank]; mat[rank] = t;
11568: ct = cmat[i]; cmat[i] = cmat[rank]; cmat[rank] = ct;
11569: s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s;
11570: if ( spactive ) {
11571: pair = spactive[i]; spactive[i] = spactive[rank];
11572: spactive[rank] = pair;
11573: }
11574: }
11575: /* column j is normalized */
11576: s = sugar[rank];
11577: inv = invm((UINT)mat[rank][j],md);
11578: /* normalize pivot row */
11579: for ( k = j, pk = mat[rank]+j, ck = cmat[rank]+j; k < col; k++, pk++, ck++ ) {
11580: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
11581: }
11582: for ( i = rank+1; i < row; i++ ) {
11583: if ( (a = mat[i][j]) != 0 ) {
11584: sugar[i] = MAX(sugar[i],s);
11585: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[rank]+j,(int)(md-a),col-j);
1.11 noro 11586: Nf4_red++;
1.7 noro 11587: }
11588: }
11589: rank++;
11590: }
11591: for ( j = col-1, l = rank-1; j >= 0; j-- )
11592: if ( colstat[j] ) {
11593: for ( k = j, pk = mat[l]+j, ck = cmat[l]+j; k < col; k++, pk++, ck++ ) {
11594: a = *pk; c = *ck; MOD128(a,c,md); *pk = a; *ck = 0;
11595: }
11596: s = sugar[l];
11597: for ( i = 0; i < l; i++ ) {
11598: a = mat[i][j]; c = cmat[i][j]; MOD128(a,c,md); mat[i][j] = a; cmat[i][j] = 0;
11599: if ( a ) {
11600: sugar[i] = MAX(sugar[i],s);
11601: red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[l]+j,(int)(md-a),col-j);
1.11 noro 11602: Nf4_red++;
1.7 noro 11603: }
11604: }
11605: l--;
11606: }
11607: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
11608: GCFREE(cmat);
11609: return rank;
11610: }
11611:
1.28 noro 11612: 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)
11613: {
11614: int i,j,k,l,rank,s,imin;
11615: mp_limb_t inv;
11616: mp_limb_t a;
11617: UINT c;
11618: mp_limb_t *t,*pivot,*pk;
11619: UINT *ck;
11620: UINT **cmat;
11621: UINT *ct;
11622: ND_pairs pair;
11623: SIG sg;
1.31 noro 11624: int *used;
1.28 noro 11625:
1.31 noro 11626: used = (int *)MALLOC(row*sizeof(int));
1.28 noro 11627: cmat = (UINT **)MALLOC(row*sizeof(UINT *));
11628: for ( i = 0; i < row; i++ ) {
11629: cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT));
11630: bzero(cmat[i],col*sizeof(UINT));
11631: }
11632:
1.31 noro 11633: for ( j = 0; j < col; j++ ) {
11634: for ( i = 0; i < row; i++ ) {
1.28 noro 11635: a = mat[i][j]; c = cmat[i][j];
11636: MOD128(a,c,md);
11637: mat[i][j] = a; cmat[i][j] = 0;
11638: }
1.31 noro 11639: for ( i = 0; i < row; i++ )
11640: if ( !used[i] && mat[i][j] ) break;
11641: if ( i == row ) {
1.28 noro 11642: colstat[j] = 0;
11643: continue;
1.31 noro 11644: } else {
1.28 noro 11645: colstat[j] = 1;
1.31 noro 11646: used[i] = 1;
1.28 noro 11647: }
11648: /* column j is normalized */
1.31 noro 11649: s = sugar[i];
11650: inv = invm((UINT)mat[i][j],md);
1.28 noro 11651: /* normalize pivot row */
1.31 noro 11652: for ( k = j, pk = mat[i]+j, ck = cmat[i]+j; k < col; k++, pk++, ck++ ) {
1.28 noro 11653: a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0;
11654: }
1.31 noro 11655: for ( k = i+1; k < row; k++ ) {
11656: if ( (a = mat[k][j]) != 0 ) {
11657: sugar[k] = MAX(sugar[k],s);
11658: red_by_vect64(md,mat[k]+j,cmat[k]+j,mat[i]+j,(int)(md-a),col-j);
1.28 noro 11659: Nf4_red++;
11660: }
11661: }
11662: }
1.31 noro 11663: rank = 0;
11664: for ( i = 0; i < row; i++ ) {
11665: for ( j = 0; j < col; j++ )
11666: if ( mat[i][j] ) break;
11667: if ( j == col ) sugar[i] = -1;
11668: else rank++;
11669: }
1.28 noro 11670: for ( i = 0; i < row; i++ ) GCFREE(cmat[i]);
11671: GCFREE(cmat);
11672: return rank;
11673: }
11674:
11675: NODE nd_f4_red_mod64_main_s(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col,
11676: NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,NODE *syzlistp)
11677: {
11678: int spcol,sprow,a;
11679: int i,j,k,l,rank;
11680: NODE r0,r;
11681: ND_pairs sp;
11682: ND spol;
11683: mp_limb_t **spmat;
11684: mp_limb_t *svect,*cvect;
11685: mp_limb_t *v;
11686: int *colstat;
11687: struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2;
11688: int maxrs;
11689: int *spsugar;
11690: ND_pairs *spactive;
11691: SIG *spsig;
11692:
11693: get_eg(&eg0);
11694: /* elimination (1st step) */
11695: spmat = (mp_limb_t **)MALLOC(nsp*sizeof(mp_limb_t *));
11696: cvect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11697: spsugar = (int *)MALLOC(nsp*sizeof(int));
11698: spsig = (SIG *)MALLOC(nsp*sizeof(SIG));
11699: for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) {
11700: nd_sp(m,0,sp,&spol);
11701: if ( !spol ) {
1.29 noro 11702: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
1.28 noro 11703: continue;
11704: }
11705: svect = (mp_limb_t *)MALLOC(col*sizeof(mp_limb_t));
11706: nd_to_vect64(m,s0vect,col,spol,svect);
11707: maxrs = ndv_reduce_vect64(m,svect,cvect,col,imat,rvect,nred,spol->sig);
11708: for ( i = 0; i < col; i++ ) if ( svect[i] ) break;
11709: if ( i < col ) {
11710: spmat[sprow] = svect;
11711: spsugar[sprow] = MAX(maxrs,SG(spol));
11712: spsig[sprow] = sp->sig;
11713: sprow++;
11714: } else {
1.29 noro 11715: syzlistp[sp->sig->pos] = insert_sig(syzlistp[sp->sig->pos],sp->sig);
1.28 noro 11716: }
11717: nd_free(spol);
11718: }
11719: get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); add_eg(&f4_elim1,&eg0,&eg1);
11720: if ( DP_Print ) {
11721: fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime);
11722: fflush(asir_out);
11723: }
11724: /* free index arrays */
11725: for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c);
11726:
11727: /* elimination (2nd step) */
11728: colstat = (int *)MALLOC(col*sizeof(int));
11729: rank = nd_gauss_elim_mod64_s(spmat,spsugar,0,sprow,col,m,colstat,spsig);
11730: r0 = 0;
1.31 noro 11731: for ( i = 0; i < sprow; i++ ) {
11732: if ( spsugar[i] >= 0 ) {
11733: NEXTNODE(r0,r);
11734: BDY(r) = vect64_to_ndv_s(spmat[i],col,s0vect);
11735: SG((NDV)BDY(r)) = spsugar[i];
11736: ((NDV)BDY(r))->sig = spsig[i];
11737: } else
11738: syzlistp[spsig[i]->pos] = insert_sig(syzlistp[spsig[i]->pos],spsig[i]);
1.28 noro 11739: GCFREE(spmat[i]);
11740: }
11741: if ( r0 ) NEXT(r) = 0;
11742: get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); add_eg(&f4_elim2,&eg1,&eg2);
11743: init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2);
11744: if ( DP_Print ) {
11745: fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime);
11746: fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ",
11747: nsp,nred,sprow,col,rank);
11748: fprintf(asir_out,"%.3fsec,",eg_f4.exectime);
11749: }
11750: return r0;
11751: }
1.40 noro 11752: #endif
1.28 noro 11753:
11754: NODE nd_f4_red_s(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,NODE *syzlistp)
11755: {
11756: IndArray *imat;
11757: int nsp,nred,i,start;
11758: int *rhead;
11759: NODE r0,rp;
11760: ND_pairs sp;
11761: NM_ind_pair *rvect;
11762: struct oEGT eg0,eg1,eg_conv;
11763:
11764: for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ );
11765: nred = length(rp0);
11766: imat = (IndArray *)MALLOC(nred*sizeof(IndArray));
11767: rhead = (int *)MALLOC(col*sizeof(int));
11768: for ( i = 0; i < col; i++ ) rhead[i] = 0;
11769:
11770: /* construction of index arrays */
11771: get_eg(&eg0);
11772: if ( DP_Print ) {
11773: fprintf(asir_out,"%dx%d,",nsp+nred,col);
11774: fflush(asir_out);
11775: }
11776: rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair));
11777: for ( start = 0, rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) {
11778: rvect[i] = (NM_ind_pair)BDY(rp);
11779: imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,rvect[i],start);
11780: rhead[imat[i]->head] = 1;
11781: start = imat[i]->head;
11782: }
11783: get_eg(&eg1); init_eg(&eg_conv); add_eg(&eg_conv,&eg0,&eg1); add_eg(&f4_conv,&eg0,&eg1);
11784: if ( DP_Print ) {
11785: fprintf(asir_out,"conv=%.3fsec,",eg_conv.exectime);
11786: fflush(asir_out);
11787: }
11788: if ( m > 0 )
1.40 noro 11789: #if SIZEOF_LONG==8
1.28 noro 11790: r0 = nd_f4_red_mod64_main_s(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,syzlistp);
1.40 noro 11791: #else
11792: r0 = nd_f4_red_main_s(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,syzlistp);
11793: #endif
1.65 noro 11794: else {
1.28 noro 11795: // r0 = nd_f4_red_q_main_s(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred);
1.65 noro 11796: r0 = 0;
1.28 noro 11797: error("nd_f4_red_q_main_s : not implemented yet");
1.65 noro 11798: }
1.28 noro 11799: return r0;
11800: }
11801:
11802: INLINE int ndl_find_reducer_minsig(UINT *dg)
11803: {
11804: RHist r;
1.65 noro 11805: int i,imin;
1.28 noro 11806: SIG t;
11807: static int wpd,nvar;
11808: static SIG quo,quomin;
11809: static UINT *tmp;
11810:
11811: if ( !quo || nvar != nd_nvar ) { NEWSIG(quo); NEWSIG(quomin); }
11812: if ( wpd != nd_wpd ) {
11813: wpd = nd_wpd;
11814: tmp = (UINT *)MALLOC(wpd*sizeof(UINT));
11815: }
11816: #if 0
11817: d = ndl_hash_value(dg);
11818: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
11819: if ( ndl_equal(dg,DL(r)) ) {
11820: return r->index;
11821: }
11822: }
11823: #endif
11824: imin = -1;
11825: for ( i = 0; i < nd_psn; i++ ) {
11826: r = nd_psh[i];
11827: if ( ndl_reducible(dg,DL(r)) ) {
11828: ndl_sub(dg,DL(r),tmp);
11829: _ndltodl(tmp,DL(quo));
11830: _addtodl(nd_nvar,DL(nd_psh[i]->sig),DL(quo));
11831: quo->pos = nd_psh[i]->sig->pos;
1.55 noro 11832: _adddl(nd_nvar,DL(quo),nd_sba_hm[quo->pos],DL2(quo));
1.28 noro 11833: if ( imin < 0 || comp_sig(quomin,quo) > 0 ) {
11834: t = quo; quo = quomin; quomin = t;
11835: imin = i;
11836: }
11837: }
11838: }
11839: if ( imin == -1 ) return nd_psn;
11840: else {
11841: #if 0
11842: nd_append_red(dg,i);
11843: #endif
11844: return imin;
11845: }
11846: }
11847:
11848: int nd_symbolic_preproc_s(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r)
11849: {
11850: NODE rp0,rp;
11851: NM mul,head,s0,s;
11852: int index,col,i,sugar;
11853: RHist h;
11854: UINT *s0v,*p;
11855: NM_ind_pair pair;
11856: ND red;
11857: NDV *ps;
11858: SIG sig;
11859:
11860: s0 = 0; rp0 = 0; col = 0;
11861: if ( nd_demand )
11862: ps = trace?nd_ps_trace_sym:nd_ps_sym;
11863: else
11864: ps = trace?nd_ps_trace:nd_ps;
11865: while ( 1 ) {
11866: head = remove_head_pbucket_symbolic(bucket);
11867: if ( !head ) break;
11868: if ( !s0 ) s0 = head;
11869: else NEXT(s) = head;
11870: s = head;
11871: index = ndl_find_reducer_minsig(DL(head));
11872: if ( index >= 0 && index < nd_psn ) {
11873: h = nd_psh[index];
11874: NEWNM(mul);
11875: ndl_sub(DL(head),DL(h),DL(mul));
11876: if ( ndl_check_bound2(index,DL(mul)) )
11877: return 0;
11878: sugar = TD(DL(mul))+SG(ps[index]);
11879: NEWSIG(sig);
11880: _ndltodl(DL(mul),DL(sig));
11881: _addtodl(nd_nvar,DL(nd_psh[index]->sig),DL(sig));
11882: sig->pos = nd_psh[index]->sig->pos;
1.55 noro 11883: _adddl(nd_nvar,DL(sig),nd_sba_hm[sig->pos],DL2(sig));
1.28 noro 11884: MKNM_ind_pair(pair,mul,index,sugar,sig);
11885: red = ndv_mul_nm_symbolic(mul,ps[index]);
11886: add_pbucket_symbolic(bucket,nd_remove_head(red));
11887: NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair;
11888: }
11889: col++;
11890: }
11891: if ( rp0 ) NEXT(rp) = 0;
11892: NEXT(s) = 0;
11893: s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT));
11894: for ( i = 0, p = s0v, s = s0; i < col;
11895: i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p);
11896: *s0vect = s0v;
11897: *r = rp0;
11898:
11899: return col;
11900: }
11901:
11902: NODE nd_sba_f4(int m,int **indp)
11903: {
1.65 noro 11904: int i,nh,stat,f4red,f4step;
11905: int col,psugar,ms;
1.33 noro 11906: NODE r,g,rp0,nflist;
1.41 noro 11907: ND_pairs d,l,t,l1;
1.33 noro 11908: ND h,nf;
11909: NDV nfv;
1.65 noro 11910: // union oNDC hc;
1.33 noro 11911: UINT *s0vect;
1.28 noro 11912: PGeoBucket bucket;
1.33 noro 11913: NODE *syzlist;
11914: SIG sig;
1.65 noro 11915: struct oEGT eg1;
11916: struct oEGT eg2,eg_remove,eg_nf,eg_nfzero;
1.28 noro 11917:
11918: Nf4_red=0;
1.30 noro 11919: d = 0;
1.29 noro 11920: syzlist = (NODE *)MALLOC(nd_psn*sizeof(NODE));
1.28 noro 11921: for ( i = 0; i < nd_psn; i++ ) {
1.30 noro 11922: d = update_pairs_s(d,i,syzlist);
1.28 noro 11923: }
1.30 noro 11924: nd_nbase = nd_psn;
1.28 noro 11925: f4red = 1;
1.33 noro 11926: psugar = 0;
1.34 noro 11927: f4step = 0;
1.28 noro 11928: while ( d ) {
1.33 noro 11929: for ( t = d, ms = SG(d); t; t = NEXT(t) )
11930: if ( SG(t) < ms ) ms = SG(t);
1.38 noro 11931: if ( ms == psugar && f4step >= nd_sba_f4step ) {
1.33 noro 11932: again:
11933: l = d; d = d->next;
1.41 noro 11934: #if 0
1.33 noro 11935: if ( small_lcm(l) ) {
11936: if ( DP_Print ) fprintf(asir_out,"M");
11937: continue;
11938: }
11939: sig = l->sig;
11940: stat = nd_sp(m,0,l,&h);
1.41 noro 11941: #else
11942: l1 = find_smallest_lcm(l);
11943: if ( l1 == 0 ) {
11944: if ( DP_Print ) fprintf(asir_out,"M");
11945: continue;
11946: }
11947: sig = l1->sig;
11948: stat = nd_sp(m,0,l1,&h);
11949: #endif
1.33 noro 11950: if ( !stat ) {
11951: NEXT(l) = d; d = l;
11952: d = nd_reconstruct(0,d);
11953: goto again;
11954: }
11955: get_eg(&eg1);
11956: #if USE_GEOBUCKET
1.39 noro 11957: 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 11958: #else
1.39 noro 11959: stat = nd_nf_s(m,0,h,nd_ps,!nd_top&&!Top,&nf);
1.33 noro 11960: #endif
11961: get_eg(&eg2);
11962: if ( !stat ) {
11963: NEXT(l) = d; d = l;
11964: d = nd_reconstruct(0,d);
11965: goto again;
11966: } else if ( stat == -1 ) {
11967: if ( DP_Print ) { printf("S"); fflush(stdout); }
11968: FREENDP(l);
11969: } else if ( nf ) {
11970: if ( DP_Print ) { printf("+"); fflush(stdout); }
11971: add_eg(&eg_nf,&eg1,&eg2);
1.65 noro 11972: // hc = HCU(nf);
1.33 noro 11973: nd_removecont(m,nf);
11974: nfv = ndtondv(m,nf); nd_free(nf);
11975: nh = ndv_newps(m,nfv,0);
11976:
1.30 noro 11977: d = update_pairs_s(d,nh,syzlist);
11978: nd_sba_pos[sig->pos] = append_one(nd_sba_pos[sig->pos],nh);
1.33 noro 11979: FREENDP(l);
1.28 noro 11980: } else {
1.33 noro 11981: add_eg(&eg_nfzero,&eg1,&eg2);
11982: // syzygy
11983: get_eg(&eg1);
11984: d = remove_spair_s(d,sig);
11985: get_eg(&eg2); add_eg(&eg_remove,&eg1,&eg2);
1.29 noro 11986: syzlist[sig->pos] = insert_sig(syzlist[sig->pos],sig);
1.33 noro 11987: if ( DP_Print ) { printf("."); fflush(stdout); }
11988: FREENDP(l);
11989: }
11990: } else {
1.34 noro 11991: if ( ms != psugar ) f4step = 1;
11992: else f4step++;
1.33 noro 11993: again2:
11994: psugar = ms;
11995: l = nd_minsugarp_s(d,&d);
1.65 noro 11996: // sugar = nd_sugarweight?d->sugar2:SG(d);
1.33 noro 11997: bucket = create_pbucket();
11998: stat = nd_sp_f4(m,0,l,bucket);
11999: if ( !stat ) {
12000: for ( t = l; NEXT(t); t = NEXT(t) );
12001: NEXT(t) = d; d = l;
12002: d = nd_reconstruct(0,d);
12003: goto again2;
12004: }
12005: if ( bucket->m < 0 ) continue;
12006: col = nd_symbolic_preproc_s(bucket,0,&s0vect,&rp0);
12007: if ( !col ) {
1.37 noro 12008: for ( t = l; NEXT(t); t = NEXT(t) )
12009: ;
12010: NEXT(t) = d; d = l;
1.33 noro 12011: d = nd_reconstruct(0,d);
12012: goto again2;
12013: }
1.34 noro 12014: if ( DP_Print ) fprintf(asir_out,"\nsugar=%d,",psugar);
1.33 noro 12015: nflist = nd_f4_red_s(m,l,0,s0vect,col,rp0,syzlist);
12016: /* adding new bases */
12017: for ( r = nflist; r; r = NEXT(r) ) {
12018: nfv = (NDV)BDY(r);
1.38 noro 12019: if ( nd_f4_td ) SG(nfv) = nd_tdeg(nfv);
1.33 noro 12020: ndv_removecont(m,nfv);
12021: nh = ndv_newps(m,nfv,0);
12022: d = update_pairs_s(d,nh,syzlist);
12023: nd_sba_pos[nfv->sig->pos] = append_one(nd_sba_pos[nfv->sig->pos],nh);
12024: }
12025: for ( i = 0; i < nd_nbase; i++ )
12026: for ( r = syzlist[i]; r; r = NEXT(r) )
12027: d = remove_spair_s(d,(SIG)BDY(r));
12028: d = remove_large_lcm(d);
12029: if ( DP_Print ) {
1.34 noro 12030: fprintf(asir_out,"f4red=%d,gblen=%d",f4red,nd_psn); fflush(asir_out);
1.33 noro 12031: }
12032: f4red++;
1.28 noro 12033: }
12034: }
12035: if ( DP_Print ) {
1.34 noro 12036: fprintf(asir_out,"\nnumber of red=%d,",Nf4_red);
1.28 noro 12037: }
1.30 noro 12038: g = conv_ilist_s(nd_demand,0,indp);
1.28 noro 12039: return g;
12040: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>