=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.189 retrieving revision 1.199 diff -u -p -r1.189 -r1.199 --- OpenXM_contrib2/asir2000/engine/nd.c 2010/05/06 09:22:09 1.189 +++ OpenXM_contrib2/asir2000/engine/nd.c 2012/08/27 05:38:00 1.199 @@ -1,7 +1,9 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.188 2010/04/26 01:10:04 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.198 2012/04/10 07:15:07 noro Exp $ */ #include "nd.h" +struct oEGT eg_search; + int diag_period = 6; int (*ndl_compare_function)(UINT *a1,UINT *a2); int nd_dcomp; @@ -49,7 +51,7 @@ static int nd_demand; 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; +static int nd_gentrace,nd_gensyz,nd_nora,nd_newelim,nd_intersect; static int *nd_gbblock; NumberField get_numberfield(); @@ -70,6 +72,8 @@ 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); extern int Denominator,DP_Multiple; @@ -1343,7 +1347,7 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND 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 || nd_gentrace ) { @@ -1918,6 +1922,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); @@ -1928,7 +1937,7 @@ again: 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; } @@ -2130,7 +2139,7 @@ again: 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; } @@ -2306,6 +2315,7 @@ ND_pairs nd_newpairs( NODE g, int t ) 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; @@ -2797,7 +2807,7 @@ NODE postprocess_algcoef(VL av,NODE alist,NODE r) return u0; } -void nd_gr(LIST f,LIST v,int m,int homo,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; @@ -2815,10 +2825,10 @@ void nd_gr(LIST f,LIST v,int m,int homo,int f4,struct 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; + int obpe,oadv,ompos,cbpe; nd_module = 0; if ( !m && Demand ) nd_demand = 1; @@ -2910,6 +2920,9 @@ void nd_gr(LIST f,LIST v,int m,int homo,int f4,struct MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0); } 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); @@ -2917,24 +2930,35 @@ void nd_gr(LIST f,LIST v,int m,int homo,int f4,struct 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 ( 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); - if ( nd_gentrace ) { - tl3 = nd_alltracelist; nd_alltracelist = 0; - } else tl3 = 0; - nd_gb(m,0,1,nd_gensyz?1:0,0)!=0; - if ( nd_gentrace && nd_gensyz ) { + 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 ) @@ -2956,9 +2980,10 @@ void nd_gr(LIST f,LIST v,int m,int homo,int f4,struct 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); MKLIST(l4,tl3); - MKLIST(l5,tl4); - tr = mknode(7,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5); 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); @@ -2981,6 +3006,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 ) { @@ -3053,6 +3079,147 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s MKLIST(*rp,r0); } +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"); +} + 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; @@ -3075,7 +3242,7 @@ 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); @@ -3257,7 +3424,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,(!ishomo&&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); } } @@ -4675,6 +4843,27 @@ 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; +} + void ndv_print(NDV p) { NMV m; @@ -4928,16 +5117,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; @@ -4946,47 +5136,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 = 1; 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) @@ -5055,6 +5246,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); @@ -5062,11 +5254,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; @@ -5447,6 +5641,7 @@ int nd_symbolic_preproc(PGeoBucket bucket,int trace,UI return col; } + NODE nd_f4(int m,int **indp) { int i,nh,stat,index; @@ -5739,7 +5934,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)); @@ -5757,6 +5952,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; } @@ -6600,24 +6796,16 @@ void nd_det(int mod,MAT f,P *rp) bucket = create_pbucket(); if ( mi[k] ) { nmv = BDY(mjj); len = LEN(mjj); - fprintf(stderr,"len=%d\n",len); for ( a = 0; a < len; a++, NMV_ADV(nmv) ) { - fprintf(stderr,"."); u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d))); add_pbucket(mod,bucket,u); - if ( !(a%1000) ) - fprintf(stderr,"%d\n",a); } } if ( mj[k] && mij ) { nmv = BDY(mij); len = LEN(mij); - fprintf(stderr,"len=%d\n",len); for ( a = 0; a < len; a++, NMV_ADV(nmv) ) { - fprintf(stderr,"."); u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d))); add_pbucket(mod,bucket,u); - if ( !(a%1000) ) - fprintf(stderr,"%d\n",a); } } u = nd_quo(mod,bucket,d); @@ -6918,7 +7106,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; } @@ -6953,6 +7141,7 @@ void parse_nd_option(NODE opt) 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)); @@ -6974,6 +7163,9 @@ void parse_nd_option(NODE opt) 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; } }