=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.168 retrieving revision 1.205 diff -u -p -r1.168 -r1.205 --- OpenXM_contrib2/asir2000/engine/nd.c 2009/02/09 10:21:29 1.168 +++ OpenXM_contrib2/asir2000/engine/nd.c 2013/09/09 09:47:09 1.205 @@ -1,8 +1,11 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.167 2009/02/08 02:47:09 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.204 2013/09/09 07:29:25 noro Exp $ */ #include "nd.h" +struct oEGT eg_search; + int diag_period = 6; +int weight_check = 1; int (*ndl_compare_function)(UINT *a1,UINT *a2); int nd_dcomp; NM _nm_free_list; @@ -46,9 +49,11 @@ static int nd_worb_len; static int nd_found,nd_create,nd_notfirst; static int nmv_adv; static int nd_demand; -static int nd_module,nd_ispot,nd_mpos; +static int nd_module,nd_ispot,nd_mpos,nd_pot_nelim; static NODE nd_tracelist; static NODE nd_alltracelist; +static int nd_gentrace,nd_gensyz,nd_nora,nd_newelim,nd_intersect; +static int *nd_gbblock; NumberField get_numberfield(); UINT *nd_det_compute_bound(NDV **dm,int n,int j); @@ -60,13 +65,16 @@ LIST ndvtopl(int mod,VL vl,VL dvl,NDV p,int rank); NDV pltondv(VL vl,VL dvl,LIST p); void pltozpl(LIST l,Q *cont,LIST *pp); void ndl_max(UINT *d1,unsigned *d2,UINT *d); -pointer GC_malloc_atomic_ignore_off_page(int); void nmtodp(int mod,NM m,DP *r); NODE reverse_node(NODE n); P ndc_div(int mod,union oNDC a,union oNDC b); P ndctop(int mod,union oNDC c); void finalize_tracelist(int i,P cont); void conv_ilist(int demand,int trace,NODE g,int **indp); +void parse_nd_option(NODE opt); +void dltondl(int n,DL dl,UINT *r); +DP ndvtodp(int mod,NDV p); +DP ndtodp(int mod,ND p); extern int Denominator,DP_Multiple; @@ -85,7 +93,7 @@ void _NM_alloc() int i; for ( i = 0; i < 1024; i++ ) { - p = (NM)GC_malloc(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT)); + p = (NM)MALLOC(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT)); p->next = _nm_free_list; _nm_free_list = p; } } @@ -96,7 +104,7 @@ void _ND_alloc() int i; for ( i = 0; i < 1024; i++ ) { - p = (ND)GC_malloc(sizeof(struct oND)); + p = (ND)MALLOC(sizeof(struct oND)); p->body = (NM)_nd_free_list; _nd_free_list = p; } } @@ -107,7 +115,7 @@ void _NDP_alloc() int i; for ( i = 0; i < 1024; i++ ) { - p = (ND_pairs)GC_malloc(sizeof(struct oND_pairs) + p = (ND_pairs)MALLOC(sizeof(struct oND_pairs) +(nd_wpd-1)*sizeof(UINT)); p->next = _ndp_free_list; _ndp_free_list = p; } @@ -579,6 +587,14 @@ int ndl_module_grlex_compare(UINT *d1,UINT *d2) int i,c; if ( nd_ispot ) { + if ( nd_pot_nelim && MPOS(d1)>=nd_pot_nelim+1 && MPOS(d2) >= nd_pot_nelim+1 ) { + if ( TD(d1) > TD(d2) ) return 1; + else if ( TD(d1) < TD(d2) ) return -1; + if ( c = ndl_lex_compare(d1,d2) ) return c; + if ( MPOS(d1) < MPOS(d2) ) return 1; + else if ( MPOS(d1) > MPOS(d2) ) return -1; + return 0; + } if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; } @@ -1325,17 +1341,17 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND p = nd_demand ? ndv_load(index) : ps[index]; /* d+g -> div*(d+g)+mul*p */ g = nd_reduce2(mod,d,g,p,mul,dn,&div); - if ( GenTrace ) { + if ( nd_gentrace ) { /* Trace=[div,index,mul,ONE] */ STOQ(index,iq); nmtodp(mod,mul,&dmul); node = mknode(4,div,iq,dmul,ONE); } sugar = MAX(sugar,SG(p)+TD(DL(mul))); - if ( !mod && g && ((double)(p_mag(HCP(g))) > hmag) ) { + if ( !mod && g && !nd_vc && ((double)(p_mag(HCP(g))) > hmag) ) { hg = HCU(g); nd_removecont2(d,g); - if ( dn || GenTrace ) { + if ( dn || nd_gentrace ) { /* overwrite cont : Trace=[div,index,mul,cont] */ cont = ndc_div(mod,hg,HCU(g)); if ( dn ) { @@ -1344,7 +1360,7 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1; } else divq(dn->z,(Q)cont,&dn->z); } - if ( GenTrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont; + if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont; } hmag = ((double)p_mag(HCP(g)))*nd_scale; } @@ -1476,7 +1492,7 @@ int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp /* input : list of NDV, cand : list of NDV */ -int ndv_check_candidate(NODE input,int obpe,int oadv,EPOS oepos,NODE cand) +int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand) { int n,i,stat; ND nf,d; @@ -1486,10 +1502,10 @@ int ndv_check_candidate(NODE input,int obpe,int oadv,E Q q; LIST list; - ndv_setup(0,0,cand,GenTrace?1:0,1); + ndv_setup(m,0,cand,nd_gentrace?1:0,1); n = length(cand); - if ( GenTrace ) { nd_alltracelist = 0; nd_tracelist = 0; } + if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; } /* membercheck : list is a subset of Id(cand) ? */ for ( t = input, i = 0; t; t = NEXT(t), i++ ) { again: @@ -1498,13 +1514,13 @@ again: r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos); else r = (NDV)BDY(t); - d = ndvtond(0,r); - stat = nd_nf(0,0,d,nd_ps,0,0,&nf); + d = ndvtond(m,r); + stat = nd_nf(m,0,d,nd_ps,0,0,&nf); if ( !stat ) { nd_reconstruct(0,0); goto again; } else if ( nf ) return 0; - if ( GenTrace ) { + if ( nd_gentrace ) { nd_tracelist = reverse_node(nd_tracelist); MKLIST(list,nd_tracelist); STOQ(i,q); s = mknode(2,q,list); MKLIST(list,s); @@ -1566,7 +1582,7 @@ void free_pbucket(PGeoBucket b) { nd_free(b->body[i]); b->body[i] = 0; } - GC_free(b); + GCFREE(b); } void add_pbucket_symbolic(PGeoBucket g,ND d) @@ -1821,7 +1837,7 @@ int do_diagonalize(int sugar,int m) Q iq; for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) { - if ( GenTrace ) { + if ( nd_gentrace ) { /* Trace = [1,index,1,1] */ STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE); MKLIST(l,node); MKNODE(nd_tracelist,l,0); @@ -1837,7 +1853,7 @@ int do_diagonalize(int sugar,int m) ndv_free(nfv); hc = HCU(nf); nd_removecont(m,nf); cont = ndc_div(m,hc,HCU(nf)); - if ( GenTrace ) finalize_tracelist(i,cont); + if ( nd_gentrace ) finalize_tracelist(i,cont); nfv = ndtondv(m,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); @@ -1896,7 +1912,7 @@ again: goto again; } #if USE_GEOBUCKET - stat = (m&&!GenTrace)?nd_nf_pbucket(m,h,nd_ps,!Top,&nf) + stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!Top,&nf) :nd_nf(m,0,h,nd_ps,!Top,0,&nf); #else stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf); @@ -1907,6 +1923,11 @@ again: goto again; } else if ( nf ) { if ( checkonly || gensyz ) return 0; + if ( nd_newelim ) { + if ( nd_module ) { + if ( MPOS(HDL(nf)) > 1 ) return 0; + } else if ( !(HDL(nf)[nd_exporigin] & nd_mask[0]) ) return 0; + } if ( DP_Print ) { printf("+"); fflush(stdout); } hc = HCU(nf); nd_removecont(m,nf); @@ -1914,10 +1935,10 @@ again: nd_monic(0,&nf); nd_removecont(m,nf); } - if ( GenTrace ) { + if ( nd_gentrace ) { cont = ndc_div(m,hc,HCU(nf)); if ( m || !UNIQ(cont) ) { - t = mknode(4,0,0,0,cont); + t = mknode(4,NULLP,NULLP,NULLP,cont); MKLIST(list,t); MKNODE(t,list,nd_tracelist); nd_tracelist = t; } @@ -1937,7 +1958,7 @@ again: g = update_base(g,nh); FREENDP(l); } else { - if ( GenTrace && gensyz ) { + if ( nd_gentrace && gensyz ) { nd_tracelist = reverse_node(nd_tracelist); MKLIST(list,nd_tracelist); STOQ(-1,q); t = mknode(2,q,list); MKLIST(list,t); @@ -1967,7 +1988,7 @@ int do_diagonalize_trace(int sugar,int m) P cont,cont1; for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) { - if ( GenTrace ) { + if ( nd_gentrace ) { /* Trace = [1,index,1,1] */ STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE); MKLIST(l,node); MKNODE(nd_tracelist,l,0); @@ -1994,7 +2015,7 @@ int do_diagonalize_trace(int sugar,int m) ndv_free(nfv); hc = HCU(nf); nd_removecont(0,nf); cont = ndc_div(0,hc,HCU(nf)); - if ( GenTrace ) finalize_tracelist(i,cont); + if ( nd_gentrace ) finalize_tracelist(i,cont); nfv = ndtondv(0,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); @@ -2116,10 +2137,10 @@ again: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); } - if ( GenTrace ) { + if ( nd_gentrace ) { cont = ndc_div(0,hnfq,HCU(nfqv)); if ( !UNIQ(cont) ) { - t = mknode(4,0,0,0,cont); + t = mknode(4,NULLP,NULLP,NULLP,cont); MKLIST(list,t); MKNODE(t,list,nd_tracelist); nd_tracelist = t; } @@ -2190,15 +2211,16 @@ NODE ndv_reduceall(int m,NODE f) union oNDC hc; P cont,cont1; + if ( nd_nora ) return f; n = length(f); ndv_setup(m,0,f,0,1); perm = (int *)MALLOC(n*sizeof(int)); - if ( GenTrace ) { + if ( nd_gentrace ) { for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) ) perm[i] = QTOS((Q)ARG1(BDY((LIST)BDY(t)))); } for ( i = 0; i < n; ) { - if ( GenTrace ) { + if ( nd_gentrace ) { /* Trace = [1,index,1,1] */ STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE); MKLIST(l,node); MKNODE(nd_tracelist,l,0); @@ -2212,7 +2234,7 @@ NODE ndv_reduceall(int m,NODE f) if ( DP_Print ) { printf("."); fflush(stdout); } ndv_free(nd_ps[i]); hc = HCU(nf); nd_removecont(m,nf); - if ( GenTrace ) { + if ( nd_gentrace ) { for ( t = nd_tracelist; t; t = NEXT(t) ) { jq = ARG1(BDY((LIST)BDY(t))); j = QTOS(jq); STOQ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq; @@ -2228,7 +2250,7 @@ NODE ndv_reduceall(int m,NODE f) if ( DP_Print ) { printf("\n"); } for ( a0 = 0, i = 0; i < n; i++ ) { NEXTNODE(a0,a); - if ( !GenTrace ) BDY(a) = (pointer)nd_ps[i]; + if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i]; else { for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break; BDY(a) = (pointer)nd_ps[j]; @@ -2244,7 +2266,7 @@ ND_pairs update_pairs( ND_pairs d, NODE /* of index */ if ( !g ) return d; /* for testing */ - if ( gensyz && GenSyz == 2 ) { + if ( gensyz && nd_gensyz == 2 ) { d1 = nd_newpairs(g,t); if ( !d ) return d1; @@ -2289,14 +2311,25 @@ ND_pairs nd_newpairs( NODE g, int t ) { NODE h; UINT *dl; - int ts,s; + int ts,s,i,t0,min,max; ND_pairs r,r0; dl = DL(nd_psh[t]); ts = SG(nd_psh[t]) - TD(dl); + if ( nd_module && nd_intersect && (MPOS(dl) > 1) ) return 0; for ( r0 = 0, h = g; h; h = NEXT(h) ) { if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) ) continue; + if ( nd_gbblock ) { + t0 = (long)BDY(h); + for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) { + min = nd_gbblock[i]; max = nd_gbblock[i+1]; + if ( t0 >= min && t0 <= max && t >= min && t <= max ) + break; + } + if ( nd_gbblock[i] >= 0 ) + continue; + } NEXTND_pairs(r0,r); r->i1 = (long)BDY(h); r->i2 = t; @@ -2573,7 +2606,7 @@ int ndv_newps(int m,NDV a,NDV aq) nd_ps[nd_psn] = 0; } } - if ( GenTrace ) { + if ( nd_gentrace ) { /* reverse the tracelist and append it to alltracelist */ nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist); STOQ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn); @@ -2583,8 +2616,9 @@ int ndv_newps(int m,NDV a,NDV aq) } /* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */ +/* return 1 if success, 0 if failure (HC(a mod p)) */ -void ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont) +int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont) { int i,j,td,len,max; NODE s,s0,f0,tn; @@ -2638,13 +2672,15 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort, register_hcf(a); am = nd_ps[i] = ndv_dup(mod,a); ndv_mod(mod,am); + if ( DL_COMPARE(HDL(am),HDL(a)) ) + return 0; ndv_removecont(mod,am); } else { a = nd_ps[i] = ndv_dup(mod,w[i].p); if ( mod || !dont_removecont ) ndv_removecont(mod,a); if ( !mod ) register_hcf(a); } - if ( GenTrace ) { + if ( nd_gentrace ) { STOQ(i,iq); STOQ(w[i].i,jq); node = mknode(3,iq,jq,ONE); if ( !dont_removecont ) ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a)); @@ -2663,7 +2699,8 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort, } } } - if ( GenTrace && nd_tracelist ) NEXT(tn) = 0; + if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0; + return 1; } struct order_spec *append_block(struct order_spec *spec, @@ -2771,13 +2808,14 @@ NODE postprocess_algcoef(VL av,NODE alist,NODE r) return u0; } -void nd_gr(LIST f,LIST v,int m,int f4,struct order_spec *ord,LIST *rp) +void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int f4,struct order_spec *ord,LIST *rp) { VL tv,fv,vv,vc,av; NODE fd,fd0,r,r0,t,x,s,xx,alist; int e,max,nvar,i; NDV b; - int ishomo,nalg,mrank,trank; + int ishomo,nalg,mrank,trank,wmax,len; + NMV a; Alg alpha,dp; P p,zp; Q dmy; @@ -2785,15 +2823,18 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe Obj obj; NumberField nf; struct order_spec *ord1; - NODE tr,tl1,tl2; - LIST l1,l2,l3; + NODE tr,tl1,tl2,tl3,tl4; + LIST l1,l2,l3,l4,l5; int j; - Q jq; + Q jq,bpe; int *perm; + EPOS oepos; + int obpe,oadv,ompos,cbpe; nd_module = 0; if ( !m && Demand ) nd_demand = 1; else nd_demand = 0; + parse_nd_option(current_option); if ( DP_Multiple ) nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); @@ -2827,7 +2868,7 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe } nd_init_ord(ord); mrank = 0; - for ( t = BDY(f), max = 0; t; t = NEXT(t) ) + for ( t = BDY(f), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { if ( nd_module ) { s = BDY((LIST)BDY(t)); @@ -2843,14 +2884,15 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe } } nd_setup_parameters(nvar,max); + obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos; ishomo = 1; for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { if ( nd_module ) { - if ( !m && !GenTrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); + if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); else zpl = (LIST)BDY(t); b = (pointer)pltondv(CO,vv,zpl); } else { - if ( !m && !GenTrace ) ptozp((P)BDY(t),1,&dmy,&zp); + if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp); else zp = (P)BDY(t); b = (pointer)ptondv(CO,vv,zp); } @@ -2860,27 +2902,72 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; } } if ( fd0 ) NEXT(fd) = 0; - ndv_setup(m,0,fd0,0,0); - if ( GenTrace ) { + + if ( !ishomo && homo ) { + for ( t = fd0, wmax = max; t; t = NEXT(t) ) { + b = (NDV)BDY(t); len = LEN(b); + for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) ) + wmax = MAX(TD(DL(a)),wmax); + } + homogenize_order(ord,nvar,&ord1); + nd_init_ord(ord1); + nd_setup_parameters(nvar+1,wmax); + for ( t = fd0; t; t = NEXT(t) ) + ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos); + } + + ndv_setup(m,0,fd0,nd_gbblock?1:0,0); + if ( nd_gentrace ) { MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0); } - x = f4?nd_f4(m,&perm):nd_gb(m,ishomo,0,0,&perm); + x = f4?nd_f4(m,&perm):nd_gb(m,ishomo || homo,0,0,&perm); + if ( !x ) { + *rp = 0; return; + } + if ( !ishomo && homo ) { + /* dehomogenization */ + for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord); + nd_init_ord(ord); + nd_setup_parameters(nvar,0); + } nd_demand = 0; + if ( nd_module && nd_intersect ) { + for ( j = nd_psn-1, x = 0; j >= 0; j-- ) + if ( MPOS(DL(nd_psh[j])) > 1 ) { + MKNODE(xx,(pointer)j,x); x = xx; + } + conv_ilist(nd_demand,0,x,0); + goto FINAL; + } x = ndv_reducebase(x,perm); - if ( GenTrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } + if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } x = ndv_reduceall(m,x); + cbpe = nd_bpe; + if ( nd_gentrace ) { + tl2 = nd_alltracelist; nd_alltracelist = 0; + ndv_check_membership(m,fd0,obpe,oadv,oepos,x); + tl3 = nd_alltracelist; nd_alltracelist = 0; + if ( nd_gensyz ) { + nd_gb(m,0,1,1,0); + tl4 = nd_alltracelist; nd_alltracelist = 0; + } else tl4 = 0; + } + nd_bpe = cbpe; + nd_setup_parameters(nd_nvar,0); +FINAL: for ( r0 = 0, t = x; t; t = NEXT(t) ) { NEXTNODE(r0,r); - if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank); - else BDY(r) = ndvtop(m,CO,vv,BDY(t)); + if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank); + else if ( retdp ) BDY(r) = ndvtodp(m,BDY(t)); + else BDY(r) = ndvtop(m,CO,vv,BDY(t)); } if ( r0 ) NEXT(r) = 0; if ( nalg ) r0 = postprocess_algcoef(av,alist,r0); MKLIST(*rp,r0); - if ( GenTrace ) { - tl2 = nd_alltracelist; nd_alltracelist = 0; + if ( nd_gentrace ) { tl1 = reverse_node(tl1); tl2 = reverse_node(tl2); + tl3 = reverse_node(tl3); /* tl2 = [[i,[[*,j,*,*],...]],...] */ for ( t = tl2; t; t = NEXT(t) ) { /* s = [i,[*,j,*,*],...] */ @@ -2894,8 +2981,10 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe for ( j = length(x)-1, t = 0; j >= 0; j-- ) { STOQ(perm[j],jq); MKNODE(s,jq,t); t = s; } - MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); - tr = mknode(5,*rp,0,l1,l2,l3); MKLIST(*rp,tr); + MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3); + MKLIST(l5,tl4); + STOQ(nd_bpe,bpe); + tr = mknode(8,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe); MKLIST(*rp,tr); } #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); @@ -2918,6 +3007,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s struct order_spec *ord1; int *perm; + parse_nd_option(current_option); get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc); for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); switch ( ord->id ) { @@ -2944,7 +3034,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s nvar += nalg; } nd_init_ord(ord); - for ( t = BDY(f), max = 0; t; t = NEXT(t) ) + for ( t = BDY(f), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { e = getdeg(tv->v,(P)BDY(t)); max = MAX(e,max); @@ -2970,8 +3060,13 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s return; } } else { +#if 0 + /* bug ? */ for ( t = x; t; t = NEXT(t) ) BDY(t) = (pointer)nd_ps[(long)BDY(t)]; +#else + conv_ilist(0,0,x,&perm); +#endif } x = ndv_reducebase(x,perm); x = ndv_reduceall(m,x); @@ -2985,6 +3080,149 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s MKLIST(*rp,r0); } +#if 0 +NDV recompute_trace(NODE trace,NDV *p,int m); +void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp); + +NDV recompute_trace(NODE ti,NDV *p,int mod) +{ + int c,c1,c2,i; + NM mul,m,tail; + ND d,r,rm; + NODE sj; + NDV red; + Obj mj; + static int afo=0; + + afo++; + mul = (NM)ALLOCA(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT)); + CM(mul) = 1; + tail = 0; + for ( i = 0, d = r = 0; ti; ti = NEXT(ti), i++ ) { + sj = BDY((LIST)BDY(ti)); + if ( ARG0(sj) ) { + red = p[QTOS((Q)ARG1(sj))]; + mj = (Obj)ARG2(sj); + if ( OID(mj) != O_DP ) ndl_zero(DL(mul)); + else dltondl(nd_nvar,BDY((DP)mj)->dl,DL(mul)); + rm = ndv_mul_nm(mod,mul,red); + if ( !r ) r = rm; + else { + for ( m = BDY(r); m && !ndl_equal(m->dl,BDY(rm)->dl); m = NEXT(m), LEN(r)-- ) { + if ( d ) { + NEXT(tail) = m; tail = m; LEN(d)++; + } else { + MKND(nd_nvar,m,1,d); tail = BDY(d); + } + } + if ( !m ) return 0; /* failure */ + else { + BDY(r) = m; + c1 = invm(HCM(rm),mod); c2 = mod-HCM(r); + DMAR(c1,c2,0,mod,c); + nd_mul_c(mod,rm,c); + r = nd_add(mod,r,rm); + } + } + } + } + if ( tail ) NEXT(tail) = 0; + d = nd_add(mod,d,r); + nd_mul_c(mod,d,invm(HCM(d),mod)); + return ndtondv(mod,d); +} + +void nd_gr_recompute_trace(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,LIST *rp) +{ + VL tv,fv,vv,vc,av; + NODE fd,fd0,r,r0,t,x,s,xx,alist; + int e,max,nvar,i; + NDV b; + int ishomo,nalg; + Alg alpha,dp; + P p,zp; + Q dmy; + LIST f1,f2; + Obj obj; + NumberField nf; + struct order_spec *ord1; + NODE permtrace,intred,ind,perm,trace,ti; + int len,n,j; + NDV *db,*pb; + + parse_nd_option(current_option); + get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc); + for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); + switch ( ord->id ) { + case 1: + if ( ord->nv != nvar ) + error("nd_check : invalid order specification"); + break; + default: + break; + } + nd_init_ord(ord); + nd_bpe = QTOS((Q)ARG7(BDY(tlist))); + nd_setup_parameters(nvar,0); + + len = length(BDY(f)); + db = (NDV *)MALLOC(len*sizeof(NDV *)); + for ( i = 0, t = BDY(f); t; i++, t = NEXT(t) ) { + ptozp((P)BDY(t),1,&dmy,&zp); + b = ptondv(CO,vv,zp); + ndv_mod(m,b); + ndv_mul_c(m,b,invm(HCM(b),m)); + db[i] = b; + } + + permtrace = BDY((LIST)ARG2(BDY(tlist))); + intred = BDY((LIST)ARG3(BDY(tlist))); + ind = BDY((LIST)ARG4(BDY(tlist))); + perm = BDY((LIST)ARG0(permtrace)); + trace = NEXT(permtrace); + + for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) { + j = QTOS((Q)ARG0(BDY((LIST)BDY(t)))); + if ( j > i ) i = j; + } + n = i+1; + pb = (NDV *)MALLOC(n*sizeof(NDV *)); + for ( t = perm, i = 0; t; t = NEXT(t), i++ ) { + ti = BDY((LIST)BDY(t)); + pb[QTOS((Q)ARG0(ti))] = db[QTOS((Q)ARG1(ti))]; + } + for ( t = trace; t; t = NEXT(t) ) { + ti = BDY((LIST)BDY(t)); + pb[QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m); + if ( !pb[QTOS((Q)ARG0(ti))] ) { *rp = 0; return; } + if ( DP_Print ) { + fprintf(asir_out,"."); fflush(asir_out); + } + } + for ( t = intred; t; t = NEXT(t) ) { + ti = BDY((LIST)BDY(t)); + pb[QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),pb,m); + if ( !pb[QTOS((Q)ARG0(ti))] ) { *rp = 0; return; } + if ( DP_Print ) { + fprintf(asir_out,"*"); fflush(asir_out); + } + } + for ( r0 = 0, t = ind; t; t = NEXT(t) ) { + NEXTNODE(r0,r); + b = pb[QTOS((Q)BDY(t))]; + ndv_mul_c(m,b,invm(HCM(b),m)); +#if 0 + BDY(r) = ndvtop(m,CO,vv,pb[QTOS((Q)BDY(t))]); +#else + BDY(r) = ndvtodp(m,pb[QTOS((Q)BDY(t))]); +#endif + } + if ( r0 ) NEXT(r) = 0; + MKLIST(*rp,r0); + if ( DP_Print ) fprintf(asir_out,"\n"); +} +#endif + void nd_gr_trace(LIST f,LIST v,int trace,int homo,int f4,struct order_spec *ord,LIST *rp) { VL tv,fv,vv,vc,av; @@ -3007,9 +3245,10 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int LIST l1,l2,l3,l4,l5; int *perm; int j,ret; - Q jq; + Q jq,bpe; nd_module = 0; + parse_nd_option(current_option); if ( DP_Multiple ) nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); @@ -3050,7 +3289,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int m = trace > 1 ? trace : get_lprime(mindex); nd_init_ord(ord); mrank = 0; - for ( t = BDY(f), max = 0; t; t = NEXT(t) ) + for ( t = BDY(f), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { if ( nd_module ) { s = BDY((LIST)BDY(t)); @@ -3070,11 +3309,11 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int ishomo = 1; for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { if ( nd_module ) { - if ( !GenTrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); + if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); else zpl = (LIST)BDY(t); c = (pointer)pltondv(CO,vv,zpl); } else { - if ( !GenTrace ) ptozp((P)BDY(t),1,&dmy,&zp); + if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp); else zp = (P)BDY(t); c = (pointer)ptondv(CO,vv,zp); } @@ -3100,14 +3339,16 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos); } while ( 1 ) { + tl1 = tl2 = tl3 = tl4 = 0; if ( Demand ) nd_demand = 1; - ndv_setup(m,1,fd0,0,0); - if ( GenTrace ) { + ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0); + if ( nd_gentrace ) { MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0); } - cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm); - if ( !cand ) { + if ( ret ) + cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm); + if ( !ret || !cand ) { /* failure */ if ( trace > 1 ) { *rp = 0; return; } else m = get_lprime(++mindex); @@ -3121,20 +3362,20 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int } nd_demand = 0; cand = ndv_reducebase(cand,perm); - if ( GenTrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } + if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } cand = ndv_reduceall(0,cand); cbpe = nd_bpe; - if ( GenTrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; } + if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; } + get_eg(&eg0); if ( nocheck ) break; - get_eg(&eg0); - if ( ret = ndv_check_candidate(in0,obpe,oadv,oepos,cand) ) { - if ( GenTrace ) { + if ( ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand) ) { + if ( nd_gentrace ) { tl3 = nd_alltracelist; nd_alltracelist = 0; } else tl3 = 0; /* gbcheck : cand is a GB of Id(cand) ? */ - ret = nd_gb(0,0,1,GenSyz?1:0,0)!=0; - if ( GenTrace && GenSyz ) { + ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0; + if ( nd_gentrace && nd_gensyz ) { tl4 = nd_alltracelist; nd_alltracelist = 0; } else tl4 = 0; } @@ -3168,7 +3409,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int if ( nalg ) cand = postprocess_algcoef(av,alist,cand); MKLIST(*rp,cand); - if ( GenTrace ) { + if ( nd_gentrace ) { tl1 = reverse_node(tl1); tl2 = reverse_node(tl2); tl3 = reverse_node(tl3); /* tl2 = [[i,[[*,j,*,*],...]],...] */ @@ -3186,7 +3427,8 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int } MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3); MKLIST(l5,tl4); - tr = mknode(7,*rp,homo?ONE:0,l1,l2,l3,l4,l5); MKLIST(*rp,tr); + STOQ(nd_bpe,bpe); + tr = mknode(8,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5,bpe); MKLIST(*rp,tr); } } @@ -3410,7 +3652,7 @@ void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos NMV m,mr0,mr,t; len = p->len; - for ( m = BDY(p), i = 0, max = 0; i < len; NMV_OADV(m), i++ ) + for ( m = BDY(p), i = 0, max = 1; i < len; NMV_OADV(m), i++ ) max = MAX(max,TD(DL(m))); mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p); m = (NMV)((char *)mr0+(len-1)*oadv); @@ -3603,7 +3845,7 @@ void nd_free(ND p) void ndv_free(NDV p) { - GC_free(BDY(p)); + GCFREE(BDY(p)); } void nd_append_red(UINT *d,int i) @@ -3714,6 +3956,31 @@ void nd_setup_parameters(int nvar,int max) { else if ( max < 65536 ) nd_bpe = 16; else nd_bpe = 32; } + if ( !do_weyl && weight_check && (current_dl_weight_vector || nd_matrix) ) { + UINT t; + int st; + int *v; + /* t = max(weights) */ + t = 0; + if ( current_dl_weight_vector ) + for ( i = 0, t = 0; i < nd_nvar; i++ ) { + if ( (st=current_dl_weight_vector[i]) < 0 ) st = -st; + if ( t < st ) t = st; + } + if ( nd_matrix ) + for ( i = 0; i < nd_matrix_len; i++ ) + for ( j = 0, v = nd_matrix[i]; j < nd_nvar; j++ ) { + if ( (st=v[j]) < 0 ) st = -st; + if ( t < st ) t = st; + } + /* i = bitsize of t */ + for ( i = 0; t; t >>=1, i++ ); + /* i += bitsize of nd_nvar */ + for ( t = nd_nvar; t; t >>=1, i++); + /* nd_bpe+i = bitsize of max(weights)*max(exp)*nd_nvar */ + if ( (nd_bpe+i) >= 31 ) + error("nd_setup_parameters : too large weight"); + } nd_epw = (sizeof(UINT)*8)/nd_bpe; elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0); nd_exporigin = nd_get_exporigin(nd_ord); @@ -3914,7 +4181,7 @@ int nd_sp(int mod,int trace,ND_pairs p,ND *rp) } t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2); *rp = nd_add(mod,t1,t2); - if ( GenTrace ) { + if ( nd_gentrace ) { /* nd_tracelist is initialized */ STOQ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE); MKLIST(hist,node); MKNODE(nd_tracelist,hist,0); @@ -4014,7 +4281,9 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta NEWNM(m); d = DL(m); if ( mod ) { c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c; - } else + } else if ( nd_vc ) + mulp(nd_vc,CP(m0),CP(m1),&CP(m)); + else mulq(CQ(m0),CQ(m1),&CQ(m)); for ( i = 0; i < nd_wpd; i++ ) d[i] = 0; homo = n&1 ? 1 : 0; @@ -4069,7 +4338,9 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta ndl_addto(DL(tab[u]),d); if ( mod ) { c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1; - } else { + } else if ( nd_vc ) + mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u])); + else { mulq(CQ(tab[u]),q,&q1); CQ(tab[u]) = q1; } } @@ -4081,7 +4352,9 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta ndl_add(DL(tab[u]),d,DL(t)); if ( mod ) { c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1; - } else + } else if ( nd_vc ) + mulp(nd_vc,CP(tab[u]),(P)q,&CP(t)); + else mulq(CQ(tab[u]),q,&CQ(t)); *p = t; } @@ -4562,7 +4835,7 @@ NDV ndtondv(int mod,ND p) if ( !p ) return 0; len = LEN(p); if ( mod ) - m0 = m = (NMV)GC_malloc_atomic_ignore_off_page(len*nmv_adv); + m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(len*nmv_adv); else m0 = m = MALLOC(len*nmv_adv); #if 0 @@ -4598,6 +4871,48 @@ ND ndvtond(int mod,NDV p) return d; } +DP ndvtodp(int mod,NDV p) +{ + MP m,m0; + DP d; + NMV t; + int i,len; + + if ( !p ) return 0; + m0 = 0; + len = p->len; + for ( t = BDY(p), i = 0; i < len; NMV_ADV(t), i++ ) { + NEXTMP(m0,m); + m->dl = ndltodl(nd_nvar,DL(t)); + m->c = ndctop(mod,t->c); + } + NEXT(m) = 0; + MKDP(nd_nvar,m0,d); + SG(d) = SG(p); + return d; +} + +DP ndtodp(int mod,ND p) +{ + MP m,m0; + DP d; + NM t; + int i,len; + + if ( !p ) return 0; + m0 = 0; + len = p->len; + for ( t = BDY(p); t; t = NEXT(t) ) { + NEXTMP(m0,m); + m->dl = ndltodl(nd_nvar,DL(t)); + m->c = ndctop(mod,t->c); + } + NEXT(m) = 0; + MKDP(nd_nvar,m0,d); + SG(d) = SG(p); + return d; +} + void ndv_print(NDV p) { NMV m; @@ -4666,6 +4981,8 @@ NODE ndv_reducebase(NODE x,int *perm) void nd_init_ord(struct order_spec *ord) { nd_module = (ord->id >= 256); + nd_matrix = 0; + nd_matrix_len = 0; switch ( ord->id ) { case 0: switch ( ord->ord.simple ) { @@ -4720,6 +5037,7 @@ void nd_init_ord(struct order_spec *ord) /* module order */ case 256: nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; nd_dcomp = -1; switch ( ord->ord.simple ) { case 0: @@ -4740,16 +5058,28 @@ void nd_init_ord(struct order_spec *ord) break; case 257: /* block order */ + nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; + nd_dcomp = -1; + nd_isrlex = 0; ndl_compare_function = ndl_module_block_compare; break; case 258: /* matrix order */ + nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; + nd_dcomp = -1; + nd_isrlex = 0; nd_matrix_len = ord->ord.matrix.row; nd_matrix = ord->ord.matrix.matrix; ndl_compare_function = ndl_module_matrix_compare; break; case 259: /* composite order */ + nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; + nd_dcomp = -1; + nd_isrlex = 0; nd_worb_len = ord->ord.composite.length; nd_worb = ord->ord.composite.w_or_b; ndl_compare_function = ndl_module_composite_compare; @@ -4838,16 +5168,17 @@ EPOS nd_create_epos(struct order_spec *ord) /* external interface */ -void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec *ord,P *rp) +void nd_nf_p(Obj f,LIST g,LIST v,int m,struct order_spec *ord,Obj *rp) { NODE t,in0,in; - ND nd,nf; - NDV ndv; + ND ndf,nf; + NDV ndvf; VL vv,tv; - int stat,nvar,max,e; + int stat,nvar,max,mrank; union oNDC dn; Q cont; P pp; + LIST ppl; if ( !f ) { *rp = 0; @@ -4856,47 +5187,48 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec pltovl(v,&vv); for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); - /* get the degree bound */ - for ( t = BDY(g), max = 0; t; t = NEXT(t) ) - for ( tv = vv; tv; tv = NEXT(tv) ) { - e = getdeg(tv->v,(P)BDY(t)); - max = MAX(e,max); - } - for ( tv = vv; tv; tv = NEXT(tv) ) { - e = getdeg(tv->v,f); - max = MAX(e,max); - } + /* max=65536 implies nd_bpe=32 */ + max = 65536; + nd_module = 0; + /* nd_module will be set if ord is a module ordering */ nd_init_ord(ord); nd_setup_parameters(nvar,max); - + if ( nd_module && OID(f) != O_LIST ) + error("nd_nf_p : the first argument must be a list"); + if ( nd_module ) mrank = length(BDY((LIST)f)); /* conversion to ndv */ for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) { NEXTNODE(in0,in); - ptozp((P)BDY(t),1,&cont,&pp); - BDY(in) = (pointer)ptondv(CO,vv,pp); + if ( nd_module ) { + if ( !BDY(t) || OID(BDY(t)) != O_LIST + || length(BDY((LIST)BDY(t))) != mrank ) + error("nd_nf_p : inconsistent basis element"); + if ( !m ) pltozpl((LIST)BDY(t),&cont,&ppl); + else ppl = (LIST)BDY(t); + BDY(in) = (pointer)pltondv(CO,vv,ppl); + } else { + if ( !m ) ptozp((P)BDY(t),1,&cont,&pp); + else pp = (P)BDY(t); + BDY(in) = (pointer)ptondv(CO,vv,pp); + } if ( m ) ndv_mod(m,(NDV)BDY(in)); } - NEXTNODE(in0,in); - BDY(in) = (pointer)ptondv(CO,vv,f); - if ( m ) ndv_mod(m,(NDV)BDY(in)); - NEXT(in) = 0; + if ( in0 ) NEXT(in) = 0; + if ( nd_module ) ndvf = pltondv(CO,vv,(LIST)f); + else ndvf = ptondv(CO,vv,(P)f); + if ( m ) ndv_mod(m,ndvf); + ndf = (pointer)ndvtond(m,ndvf); + /* dont sort, dont removecont */ ndv_setup(m,0,in0,1,1); - nd_psn--; nd_scale=2; - while ( 1 ) { - nd = (pointer)ndvtond(m,nd_ps[nd_psn]); - stat = nd_nf(m,0,nd,nd_ps,1,0,&nf); - if ( !stat ) { - nd_psn++; - nd_reconstruct(0,0); - nd_psn--; - } else - break; - } - *rp = ndvtop(m,CO,vv,ndtondv(m,nf)); + stat = nd_nf(m,0,ndf,nd_ps,1,0,&nf); + if ( !stat ) + error("nd_nf_p : exponent too large"); + if ( nd_module ) *rp = (Obj)ndvtopl(m,CO,vv,ndtondv(m,nf),mrank); + else *rp = (Obj)ndvtop(m,CO,vv,ndtondv(m,nf)); } int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r) @@ -4965,6 +5297,7 @@ IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0 UINT *v,*ivi,*s0v; int i,j,len,prev,diff,cdiff; IndArray r; +struct oEGT eg0,eg1; m = pair->mul; d = DL(m); @@ -4972,11 +5305,13 @@ IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0 len = LEN(p); t = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); v = (unsigned int *)ALLOCA(len*sizeof(unsigned int)); +get_eg(&eg0); for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) { ndl_add(d,DL(mr),t); for ( ; !ndl_equal(t,s); s += nd_wpd, i++ ); v[j] = i; } +get_eg(&eg1); add_eg(&eg_search,&eg0,&eg1); r = (IndArray)MALLOC(sizeof(struct oIndArray)); r->head = v[0]; diff = 0; @@ -5218,7 +5553,7 @@ NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhea for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++; if ( !len ) return 0; else { - mr0 = (NMV)GC_malloc_atomic_ignore_off_page(nmv_adv*len); + mr0 = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len); #if 0 ndv_alloc += nmv_adv*len; #endif @@ -5248,7 +5583,7 @@ NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++; if ( !len ) return 0; else { - mr0 = (NMV)GC_malloc(nmv_adv*len); + mr0 = (NMV)MALLOC(nmv_adv*len); #if 0 ndv_alloc += nmv_adv*len; #endif @@ -5280,7 +5615,7 @@ NDV plain_vect_to_ndv_q(Q *vect,int col,UINT *s0vect) for ( j = 0, len = 0; j < col; j++ ) if ( vect[j] ) len++; if ( !len ) return 0; else { - mr0 = (NMV)GC_malloc(nmv_adv*len); + mr0 = (NMV)MALLOC(nmv_adv*len); #if 0 ndv_alloc += nmv_adv*len; #endif @@ -5357,6 +5692,7 @@ int nd_symbolic_preproc(PGeoBucket bucket,int trace,UI return col; } + NODE nd_f4(int m,int **indp) { int i,nh,stat,index; @@ -5538,6 +5874,109 @@ NODE nd_f4_trace(int m,int **indp) return g; } +NODE nd_f4_pseudo_trace(int m,int **indp) +{ + int i,nh,stat,index; + NODE r,g; + ND_pairs d,l,l0,t; + ND spol,red; + NDV nf,redv,nfqv,nfv; + NM s0,s; + NODE rp0,srp0,nflist; + int nsp,nred,col,rank,len,k,j,a; + UINT c; + UINT **spmat; + UINT *s0vect,*svect,*p,*v; + int *colstat; + IndArray *imat; + int *rhead; + int spcol,sprow; + int sugar; + PGeoBucket bucket; + struct oEGT eg0,eg1,eg_f4; + + g = 0; d = 0; + for ( i = 0; i < nd_psn; i++ ) { + d = update_pairs(d,g,i,0); + g = update_base(g,i); + } + while ( d ) { + get_eg(&eg0); + l = nd_minsugarp(d,&d); + sugar = SG(l); + bucket = create_pbucket(); + stat = nd_sp_f4(m,0,l,bucket); + if ( !stat ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + if ( bucket->m < 0 ) continue; + col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0); + if ( !col ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); + if ( DP_Print ) + fprintf(asir_out,"sugar=%d,symb=%fsec,", + sugar,eg_f4.exectime+eg_f4.gctime); + nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0); + if ( !l0 ) continue; + l = l0; + + /* over Q */ + while ( 1 ) { + bucket = create_pbucket(); + stat = nd_sp_f4(0,1,l,bucket); + if ( !stat ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + if ( bucket->m < 0 ) continue; + col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0); + if ( !col ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0); + } + + /* adding new bases */ + for ( r = nflist; r; r = NEXT(r) ) { + nfqv = (NDV)BDY(r); + ndv_removecont(0,nfqv); + if ( !rem(NM(HCQ(nfqv)),m) ) return 0; + if ( nd_nalg ) { + ND nf1; + + nf1 = ndvtond(m,nfqv); + nd_monic(0,&nf1); + nd_removecont(0,nf1); + nfqv = ndtondv(0,nf1); nd_free(nf1); + } + nfv = ndv_dup(0,nfqv); + ndv_mod(m,nfv); + ndv_removecont(m,nfv); + nh = ndv_newps(0,nfv,nfqv); + d = update_pairs(d,g,nh,0); + g = update_base(g,nh); + } + } +#if 0 + fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); +#endif + conv_ilist(0,1,g,indp); + return g; +} + NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz) { IndArray *imat; @@ -5546,7 +5985,7 @@ NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0ve NODE r0,rp; ND_pairs sp; NM_ind_pair *rvect; - +init_eg(&eg_search); for ( sp = sp0, nsp = 0; sp; sp = NEXT(sp), nsp++ ); nred = length(rp0); imat = (IndArray *)ALLOCA(nred*sizeof(IndArray)); @@ -5564,6 +6003,7 @@ NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0ve r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz); else r0 = nd_f4_red_q_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred); +print_eg("search",&eg_search); return r0; } @@ -5616,7 +6056,7 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s fflush(asir_out); } /* free index arrays */ - for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); + for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); /* elimination (2nd step) */ colstat = (int *)ALLOCA(spcol*sizeof(int)); @@ -5629,11 +6069,11 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s NEXTNODE(r0,r); BDY(r) = (pointer)vect_to_ndv(spmat[i],spcol,col,rhead,s0vect); SG((NDV)BDY(r)) = spsugar[i]; - GC_free(spmat[i]); + GCFREE(spmat[i]); } if ( r0 ) NEXT(r) = 0; - for ( ; i < sprow; i++ ) GC_free(spmat[i]); + for ( ; i < sprow; i++ ) GCFREE(spmat[i]); get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); if ( DP_Print ) { @@ -5697,7 +6137,7 @@ NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,U fflush(asir_out); } /* free index arrays */ -/* for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); */ +/* for ( i = 0; i < nred; i++ ) GCFREE(imat[i]->index.c); */ /* elimination (2nd step) */ colstat = (int *)ALLOCA(spcol*sizeof(int)); @@ -5706,7 +6146,7 @@ NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,U for ( i = 0; i < rank; i++ ) { w[rank-i-1] = (pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect); SG((NDV)w[rank-i-1]) = spsugar[i]; -/* GC_free(spmat[i]); */ +/* GCFREE(spmat[i]); */ } #if 0 qsort(w,rank,sizeof(NDV), @@ -5718,7 +6158,7 @@ NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,U } if ( r0 ) NEXT(r) = 0; -/* for ( ; i < sprow; i++ ) GC_free(spmat[i]); */ +/* for ( ; i < sprow; i++ ) GCFREE(spmat[i]); */ get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); if ( DP_Print ) { @@ -5850,7 +6290,7 @@ NDV nd_recv_ndv() len = nd_recv_int(); if ( !len ) return 0; else { - m0 = m = (NMV)GC_malloc_atomic_ignore_off_page(nmv_adv*len); + m0 = m = (NMV)MALLOC_ATOMIC_IGNORE_OFF_PAGE(nmv_adv*len); #if 0 ndv_alloc += len*nmv_adv; #endif @@ -6046,31 +6486,13 @@ void nd_exec_f4_red_dist() int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int col,int *colstat) { - int mod,i,j,t,c,rank,rank0,inv; + int i,j,t,c,rank,inv; int *ci,*ri; Q dn; MAT m,nm; - int **wmat; - /* XXX */ - mod = 99999989; - wmat = (int **)ALLOCA(row*sizeof(int *)); - for ( i = 0; i < row; i++ ) { - wmat[i] = (int *)ALLOCA(col*sizeof(int)); - for ( j = 0; j < col; j++ ) { - if ( mat0[i][j] ) { - t = rem(NM(mat0[i][j]),mod); - if ( SGN(mat0[i][j]) < 0 ) t = mod-t; - wmat[i][j] = t; - } else - wmat[i][j] = 0; - } - } - rank0 = nd_gauss_elim_mod(wmat,sugar,0,row,col,mod,colstat); NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0; rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci); - if ( rank != rank0 ) - error("afo"); for ( i = 0; i < row; i++ ) for ( j = 0; j < col; j++ ) mat0[i][j] = 0; @@ -6080,19 +6502,6 @@ int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int co for ( j = 0; j < c; j++ ) mat0[i][ci[j]] = (Q)BDY(nm)[i][j]; } - inv = invm(rem(NM(dn),mod),mod); - if ( SGN(dn) < 0 ) inv = mod-inv; - for ( i = 0; i < row; i++ ) - for ( j = 0; j < col; j++ ) { - if ( mat0[i][j] ) { - t = rem(NM(mat0[i][j]),mod); - if ( SGN(mat0[i][j]) < 0 ) t = mod-t; - } else - t = 0; - c = dmar(t,inv,0,mod); - if ( wmat[i][j] != c ) - error("afo"); - } return rank; } @@ -6380,7 +6789,7 @@ void nd_det(int mod,MAT f,P *rp) m = (pointer **)w; } - for ( i = 0, max = 0; i < n; i++ ) + for ( i = 0, max = 1; i < n; i++ ) for ( j = 0; j < n; j++ ) for ( tv = fv; tv; tv = NEXT(tv) ) { e = getdeg(tv->v,(P)m[i][j]); @@ -6388,7 +6797,7 @@ void nd_det(int mod,MAT f,P *rp) } nd_setup_parameters(nvar,max); dm = (NDV **)almat_pointer(n,n); - for ( i = 0, max = 0; i < n; i++ ) + for ( i = 0, max = 1; i < n; i++ ) for ( j = 0; j < n; j++ ) { dm[i][j] = ptondv(CO,fv,m[i][j]); if ( mod ) ndv_mod(mod,dm[i][j]); @@ -6748,7 +7157,7 @@ void finalize_tracelist(int i,P cont) Q iq; if ( !UNIQ(cont) ) { - node = mknode(4,0,0,0,cont); + node = mknode(4,NULLP,NULLP,NULLP,cont); MKLIST(l,node); MKNODE(node,l,nd_tracelist); nd_tracelist = node; } @@ -6773,4 +7182,297 @@ void conv_ilist(int demand,int trace,NODE g,int **indp BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j])); } if ( indp ) *indp = ind; +} + +void parse_nd_option(NODE opt) +{ + NODE t,p,u; + int i,s; + char *key; + Obj value; + + nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_gbblock = 0; + nd_newelim = 0; nd_intersect = 0; + for ( t = opt; t; t = NEXT(t) ) { + p = BDY((LIST)BDY(t)); + key = BDY((STRING)BDY(p)); + value = (Obj)BDY(NEXT(p)); + if ( !strcmp(key,"gentrace") ) + nd_gentrace = value?1:0; + else if ( !strcmp(key,"gensyz") ) + nd_gensyz = value?1:0; + else if ( !strcmp(key,"nora") ) + nd_nora = value?1:0; + else if ( !strcmp(key,"gbblock") ) { + if ( !value || OID(value) != O_LIST ) + error("nd_* : invalid value for gbblock option"); + u = BDY((LIST)value); + nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int)); + for ( i = 0; u; u = NEXT(u) ) { + p = BDY((LIST)BDY(u)); + s = nd_gbblock[i++] = QTOS((Q)BDY(p)); + nd_gbblock[i++] = s+QTOS((Q)BDY(NEXT(p)))-1; + } + nd_gbblock[i] = -1; + } else if ( !strcmp(key,"newelim") ) + nd_newelim = value?1:0; + else if ( !strcmp(key,"intersect") ) + nd_intersect = value?1:0; + } +} + +ND mdptond(DP d); +ND nd_mul_nm(int mod,NM m0,ND p); +ND *recompute_trace(NODE ti,ND **p,int nb,int mod); +ND recompute_trace_one(NODE ti,ND *p,int nb,int mod); +MAT nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,MAT *rp); +VECT nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos,MAT *rp); + +/* d:monomial */ +ND mdptond(DP d) +{ + NM m; + ND r; + + if ( OID(d) == 1 ) + r = ptond(CO,CO,(P)d); + else { + NEWNM(m); + dltondl(NV(d),BDY(d)->dl,DL(m)); + CQ(m) = (Q)BDY(d)->c; + NEXT(m) = 0; + MKND(NV(d),m,1,r); + } + return r; +} + +ND nd_mul_nm(int mod,NM m0,ND p) +{ + UINT *d0; + int c0,c1,c; + NM tm,mr,mr0; + ND r; + + if ( !p ) return 0; + d0 = DL(m0); + c0 = CM(m0); + mr0 = 0; + for ( tm = BDY(p); tm; tm = NEXT(tm) ) { + NEXTNM(mr0,mr); + c = CM(tm); DMAR(c0,c,0,mod,c1); CM(mr) = c1; + ndl_add(d0,DL(tm),DL(mr)); + } + NEXT(mr) = 0; + MKND(NV(p),mr0,LEN(p),r); + return r; +} + +ND *recompute_trace(NODE ti,ND **p,int nb,int mod) +{ + PGeoBucket *r; + int i,ci; + NODE t,s; + ND m,tp; + ND *pi,*rd; + P c; + + r = (PGeoBucket *)MALLOC(nb*sizeof(PGeoBucket)); + for ( i = 0; i < nb; i++ ) + r[i] = create_pbucket(); + for ( t = ti; t; t = NEXT(t) ) { + s = BDY((LIST)BDY(t)); + if ( ARG0(s) ) { + m = mdptond((DP)ARG2(s)); + ptomp(mod,(P)HCQ(m),&c); + if ( ci = ((MQ)c)->cont ) { + HCM(m) = ci; + pi = p[QTOS((Q)ARG1(s))]; + for ( i = 0; i < nb; i++ ) { + tp = nd_mul_nm(mod,BDY(m),pi[i]); + add_pbucket(mod,r[i],tp); + } + } + ci = 1; + } else { + ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont; + ci = invm(ci,mod); + } + } + rd = (ND *)MALLOC(nb*sizeof(ND)); + for ( i = 0; i < nb; i++ ) + rd[i] = normalize_pbucket(mod,r[i]); + if ( ci != 1 ) + for ( i = 0; i < nb; i++ ) nd_mul_c(mod,rd[i],ci); + return rd; +} + +ND recompute_trace_one(NODE ti,ND *p,int nb,int mod) +{ + PGeoBucket r; + int i,ci; + NODE t,s; + ND m,tp; + ND pi,rd; + P c; + + r = create_pbucket(); + for ( t = ti; t; t = NEXT(t) ) { + s = BDY((LIST)BDY(t)); + if ( ARG0(s) ) { + m = mdptond((DP)ARG2(s)); + ptomp(mod,(P)HCQ(m),&c); + if ( ci = ((MQ)c)->cont ) { + HCM(m) = ci; + pi = p[QTOS((Q)ARG1(s))]; + tp = nd_mul_nm(mod,BDY(m),pi); + add_pbucket(mod,r,tp); + } + ci = 1; + } else { + ptomp(mod,(P)ARG3(s),&c); ci = ((MQ)c)->cont; + ci = invm(ci,mod); + } + } + rd = normalize_pbucket(mod,r); + if ( ci != 1 ) nd_mul_c(mod,rd,ci); + return rd; +} + +MAT nd_btog(LIST f,LIST v,int mod,struct order_spec *ord,LIST tlist,MAT *rp) +{ + int i,j,n,m,nb,pi0,pi1,nvar; + VL fv,tv,vv; + NODE permtrace,perm,trace,intred,ind,t,pi,ti; + ND **p; + ND *c; + ND u; + P inv; + MAT mat; + + parse_nd_option(current_option); + get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc); + for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); + switch ( ord->id ) { + case 1: + if ( ord->nv != nvar ) + error("nd_check : invalid order specification"); + break; + default: + break; + } + nd_init_ord(ord); +#if 0 + nd_bpe = QTOS((Q)ARG7(BDY(tlist))); +#else + nd_bpe = 32; +#endif + nd_setup_parameters(nvar,0); + permtrace = BDY((LIST)ARG2(BDY(tlist))); + intred = BDY((LIST)ARG3(BDY(tlist))); + ind = BDY((LIST)ARG4(BDY(tlist))); + perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace); + for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) { + j = QTOS((Q)BDY(BDY((LIST)BDY(t)))); + if ( j > i ) i = j; + } + n = i+1; + nb = length(BDY(f)); + p = (ND **)MALLOC(n*sizeof(ND *)); + for ( t = perm, i = 0; t; t = NEXT(t), i++ ) { + pi = BDY((LIST)BDY(t)); + pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi)); + p[pi0] = c = (ND *)MALLOC(nb*sizeof(ND)); + ptomp(mod,(P)ARG2(pi),&inv); + u = ptond(CO,vv,(P)ONE); + HCM(u) = ((MQ)inv)->cont; + c[pi1] = u; + } + for ( t = trace,i=0; t; t = NEXT(t), i++ ) { + printf("%d ",i); fflush(stdout); + ti = BDY((LIST)BDY(t)); + p[j=QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),p,nb,mod); + if ( j == 441 ) + printf("afo"); + } + for ( t = intred, i=0; t; t = NEXT(t), i++ ) { + printf("%d ",i); fflush(stdout); + ti = BDY((LIST)BDY(t)); + p[j=QTOS((Q)ARG0(ti))] = recompute_trace(BDY((LIST)ARG1(ti)),p,nb,mod); + if ( j == 441 ) + printf("afo"); + } + m = length(ind); + MKMAT(mat,nb,m); + for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) + for ( i = 0, c = p[QTOS((Q)BDY(t))]; i < nb; i++ ) + BDY(mat)[i][j] = ndtodp(mod,c[i]); + return mat; +} + +VECT nd_btog_one(LIST f,LIST v,int mod,struct order_spec *ord, + LIST tlist,int pos,MAT *rp) +{ + int i,j,n,m,nb,pi0,pi1,nvar; + VL fv,tv,vv; + NODE permtrace,perm,trace,intred,ind,t,pi,ti; + ND *p; + ND *c; + ND u; + P inv; + VECT vect; + + parse_nd_option(current_option); + get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc); + for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); + switch ( ord->id ) { + case 1: + if ( ord->nv != nvar ) + error("nd_check : invalid order specification"); + break; + default: + break; + } + nd_init_ord(ord); +#if 0 + nd_bpe = QTOS((Q)ARG7(BDY(tlist))); +#else + nd_bpe = 32; +#endif + nd_setup_parameters(nvar,0); + permtrace = BDY((LIST)ARG2(BDY(tlist))); + intred = BDY((LIST)ARG3(BDY(tlist))); + ind = BDY((LIST)ARG4(BDY(tlist))); + perm = BDY((LIST)BDY(permtrace)); trace =NEXT(permtrace); + for ( i = length(perm)-1, t = trace; t; t = NEXT(t) ) { + j = QTOS((Q)BDY(BDY((LIST)BDY(t)))); + if ( j > i ) i = j; + } + n = i+1; + nb = length(BDY(f)); + p = (ND *)MALLOC(n*sizeof(ND *)); + for ( t = perm, i = 0; t; t = NEXT(t), i++ ) { + pi = BDY((LIST)BDY(t)); + pi0 = QTOS((Q)ARG0(pi)); pi1 = QTOS((Q)ARG1(pi)); + if ( pi1 == pos ) { + ptomp(mod,(P)ARG2(pi),&inv); + u = ptond(CO,vv,(P)ONE); + HCM(u) = ((MQ)inv)->cont; + p[pi0] = u; + } + } + for ( t = trace,i=0; t; t = NEXT(t), i++ ) { + printf("%d ",i); fflush(stdout); + ti = BDY((LIST)BDY(t)); + p[j=QTOS((Q)ARG0(ti))] = recompute_trace_one(BDY((LIST)ARG1(ti)),p,nb,mod); + } + for ( t = intred, i=0; t; t = NEXT(t), i++ ) { + printf("%d ",i); fflush(stdout); + ti = BDY((LIST)BDY(t)); + p[j=QTOS((Q)ARG0(ti))] = recompute_trace_one(BDY((LIST)ARG1(ti)),p,nb,mod); + } + m = length(ind); + MKVECT(vect,m); + for ( j = 0, t = ind; j < m; j++, t = NEXT(t) ) + BDY(vect)[j] = ndtodp(mod,p[QTOS((Q)BDY(t))]); + return vect; }