=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.146 retrieving revision 1.156 diff -u -p -r1.146 -r1.156 --- OpenXM_contrib2/asir2000/engine/nd.c 2006/11/27 07:31:25 1.146 +++ OpenXM_contrib2/asir2000/engine/nd.c 2008/05/23 01:24:21 1.156 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.145 2006/08/26 05:38:06 noro Exp $ */ +/* $OpenXM$ */ #include "nd.h" @@ -8,6 +8,7 @@ int nd_dcomp; NM _nm_free_list; ND _nd_free_list; ND_pairs _ndp_free_list; +NODE nd_hcf; static NODE nd_subst; static VL nd_vc; @@ -49,9 +50,12 @@ static int nd_demand; NumberField get_numberfield(); UINT *nd_det_compute_bound(NDV **dm,int n,int j); void nd_det_reconstruct(NDV **dm,int n,int j,NDV d); +void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr); int nd_monic(int m,ND *p); NDV plain_vect_to_ndv_q(Q *mat,int col,UINT *s0vect); +extern int Denominator,DP_Multiple; + void nd_free_private_storage() { _nm_free_list = 0; @@ -209,7 +213,7 @@ void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepo { int w,i,e,n,omask0; - omask0 = (1<body->c.p; + if ( !nd_vc || NUM(hc) ) return; + fctrp(nd_vc,hc,&dc); + for ( t = dc; t; t = NEXT(t) ) { + h = t->c; + if ( NUM(h) ) continue; + for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) { + c = compp(nd_vc,h,(P)BDY(l)); + if ( c >= 0 ) break; + } + if ( !l || c > 0 ) { + MKNODE(l1,h,l); + if ( !prev ) + nd_hcf = l1; + else + NEXT(prev) = l1; + } + } +} +#else +void register_hcf(NDV p) +{ + DCP dc,t; + P hc,h,q; + Q dmy; + int c; + NODE l,l1,prev; + + hc = p->body->c.p; + if ( NUM(hc) ) return; + ptozp(hc,1,&dmy,&h); +#if 1 + for ( l = nd_hcf; l; l = NEXT(l) ) { + while ( 1 ) { + if ( divtpz(nd_vc,h,(P)BDY(l),&q) ) h = q; + else break; + } + } + if ( NUM(h) ) return; +#endif + for ( prev = 0, l = nd_hcf; l; prev = l, l = NEXT(l) ) { + c = compp(nd_vc,h,(P)BDY(l)); + if ( c >= 0 ) break; + } + if ( !l || c > 0 ) { + MKNODE(l1,h,l); + if ( !prev ) + nd_hcf = l1; + else + NEXT(prev) = l1; + } +} +#endif + int do_diagonalize(int sugar,int m) { int i,nh,stat; @@ -1592,6 +1658,7 @@ int do_diagonalize(int sugar,int m) nfv = ndtondv(m,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); + if ( !m ) register_hcf(nfv); if ( nd_demand ) { ndv_save(nfv,i); ndv_free(nfv); @@ -1685,6 +1752,7 @@ again: else for ( t = g; t; t = NEXT(t) ) BDY(t) = (pointer)nd_ps[(int)BDY(t)]; + if ( !checkonly && DP_Print ) { printf("nd_gb done.\n"); fflush(stdout); } return g; } @@ -1721,6 +1789,7 @@ int do_diagonalize_trace(int sugar,int m) nfv = ndtondv(0,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); + register_hcf(nfv); if ( nd_demand ) { ndv_save(nfv,i); ndv_free(nfv); @@ -1733,6 +1802,17 @@ int do_diagonalize_trace(int sugar,int m) static struct oEGT eg_invdalg; struct oEGT eg_le; +void nd_subst_vector(VL vl,P p,NODE subst,P *r) +{ + NODE tn; + P p1; + + for ( tn = subst; tn; tn = NEXT(NEXT(tn)) ) { + substp(vl,p,BDY(tn),BDY(NEXT(tn)),&p1); p = p1; + } + *r = p; +} + NODE nd_gb_trace(int m,int ishomo) { int i,nh,sugar,stat; @@ -1742,6 +1822,7 @@ NODE nd_gb_trace(int m,int ishomo) ND h,nf,nfq,s,head; NDV nfv,nfqv; Q q,den,num; + P hc; union oNDC dn; struct oEGT eg_monic,egm0,egm1; int diag_count = 0; @@ -1761,7 +1842,9 @@ again: if ( SG(l) != sugar ) { #if 1 if ( ishomo ) { + if ( DP_Print > 2 ) fprintf(asir_out,"|"); stat = do_diagonalize_trace(sugar,m); + if ( DP_Print > 2 ) fprintf(asir_out,"|"); diag_count = 0; if ( !stat ) { NEXT(l) = d; d = l; @@ -1803,7 +1886,11 @@ again: } if ( nfq ) { /* m|HC(nfq) => failure */ - if ( !rem(NM(HCQ(nfq)),m) ) return 0; + if ( nd_vc ) { + nd_subst_vector(nd_vc,HCP(nfq),nd_subst,&hc); q = (Q)hc; + } else + q = HCQ(nfq); + if ( !rem(NM(q),m) ) return 0; if ( DP_Print ) { printf("+"); fflush(stdout); } if ( nd_nalg ) { @@ -1820,7 +1907,9 @@ again: nh = ndv_newps(0,nfv,nfqv); if ( ishomo && ++diag_count == diag_period ) { diag_count = 0; + if ( DP_Print > 2 ) fprintf(asir_out,"|"); stat = do_diagonalize_trace(sugar,m); + if ( DP_Print > 2 ) fprintf(asir_out,"|"); if ( !stat ) { NEXT(l) = d; d = l; d = nd_reconstruct(1,d); @@ -1848,6 +1937,7 @@ again: print_eg("invdalg",&eg_invdalg); print_eg("le",&eg_le); } + if ( DP_Print ) { printf("nd_gb_trace done.\n"); fflush(stdout); } return g; } @@ -1878,7 +1968,7 @@ NODE ndv_reduceall(int m,NODE f) (int (*)(const void *,const void *))ndv_compare); for ( t = f, i = 0; t; i++, t = NEXT(t) ) BDY(t) = (pointer)w[i]; #endif - ndv_setup(m,0,f,0); + ndv_setup(m,0,f,0,1); for ( i = 0; i < n; ) { g = ndvtond(m,nd_ps[i]); g = nd_separate_head(g,&head); @@ -2191,9 +2281,11 @@ int ndv_newps(int m,NDV a,NDV aq) nd_ps[nd_psn] = a; if ( aq ) { nd_ps_trace[nd_psn] = aq; + register_hcf(aq); nd_bound[nd_psn] = ndv_compute_bound(aq); SG(r) = SG(aq); ndl_copy(HDL(aq),DL(r)); } else { + if ( !m ) register_hcf(a); nd_bound[nd_psn] = ndv_compute_bound(a); SG(r) = SG(a); ndl_copy(HDL(a),DL(r)); } @@ -2209,7 +2301,7 @@ int ndv_newps(int m,NDV a,NDV aq) return nd_psn++; } -void ndv_setup(int mod,int trace,NODE f,int dont_sort) +void ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont) { int i,j,td,len,max; NODE s,s0,f0; @@ -2237,6 +2329,7 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort) nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist)); nd_bound = (UINT **)MALLOC(nd_pslen*sizeof(UINT *)); + nd_hcf = 0; if ( trace && nd_vc ) makesubst(nd_vc,&nd_subst); @@ -2249,13 +2342,15 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort) for ( i = 0; i < nd_psn; i++ ) { if ( trace ) { a = nd_ps_trace[i] = ndv_dup(0,w[i]); - ndv_removecont(0,a); + if ( !dont_removecont) ndv_removecont(0,a); + register_hcf(a); am = nd_ps[i] = ndv_dup(mod,a); ndv_mod(mod,am); ndv_removecont(mod,am); } else { a = nd_ps[i] = ndv_dup(mod,w[i]); - ndv_removecont(mod,a); + if ( mod || !dont_removecont ) ndv_removecont(mod,a); + if ( !mod ) register_hcf(a); } NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r)); nd_bound[i] = ndv_compute_bound(a); @@ -2395,6 +2490,8 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe if ( !m && Demand ) nd_demand = 1; else nd_demand = 0; + if ( DP_Multiple ) + nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); #if 0 ndv_alloc = 0; #endif @@ -2440,7 +2537,7 @@ 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); + ndv_setup(m,0,fd0,0,0); x = f4?nd_f4(m):nd_gb(m,ishomo,0); nd_demand = 0; x = ndv_reducebase(x); @@ -2515,7 +2612,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; } } if ( fd0 ) NEXT(fd) = 0; - ndv_setup(m,0,fd0,0); + ndv_setup(m,0,fd0,0,1); for ( x = 0, i = 0; i < nd_psn; i++ ) x = update_base(x,i); if ( do_check ) { @@ -2559,6 +2656,9 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int struct order_spec *ord1; struct oEGT eg_check,eg0,eg1; + if ( DP_Multiple ) + nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); + 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 ) { @@ -2630,7 +2730,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int while ( 1 ) { if ( Demand ) nd_demand = 1; - ndv_setup(m,1,fd0,0); + ndv_setup(m,1,fd0,0,0); cand = f4?nd_f4_trace(m):nd_gb_trace(m,ishomo || homo); if ( !cand ) { /* failure */ @@ -2809,7 +2909,7 @@ void nd_removecont(int mod,ND p) v.len = n; v.body = (pointer *)w; for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) w[i] = CQ(m); - removecont_array((P *)w,n); + removecont_array((P *)w,n,1); for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ ) CQ(m) = w[i]; } } @@ -2823,22 +2923,23 @@ void nd_removecont2(ND p1,ND p2) struct oVECT v; N q,r; - if ( !p1 ) { - nd_removecont(0,p2); return; - } else if ( !p2 ) { - nd_removecont(0,p1); return; - } n1 = nd_length(p1); n2 = nd_length(p2); n = n1+n2; w = (Q *)ALLOCA(n*sizeof(Q)); v.len = n; v.body = (pointer *)w; - for ( m = BDY(p1), i = 0; i < n1; m = NEXT(m), i++ ) w[i] = CQ(m); - for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CQ(m); - removecont_array((P *)w,n); - for ( m = BDY(p1), i = 0; i < n1; m = NEXT(m), i++ ) CQ(m) = w[i]; - for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CQ(m) = w[i]; + i = 0; + if ( p1 ) + for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = CQ(m); + if ( p2 ) + for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = CQ(m); + removecont_array((P *)w,n,1); + i = 0; + if ( p1 ) + for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) CQ(m) = w[i]; + if ( p2 ) + for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) CQ(m) = w[i]; } void ndv_removecont(int mod,NDV p) @@ -2863,7 +2964,7 @@ void ndv_removecont(int mod,NDV p) all_p = all_p && !NUM(w[i]); } if ( all_p ) { - qltozl(c,len,&dvr); heu_nezgcdnpz(nd_vc,w,len,&g); + qltozl(c,len,&dvr); nd_heu_nezgcdnpz(nd_vc,w,len,1,&g); mulp(nd_vc,(P)dvr,g,&cont); for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) { divsp(nd_vc,CP(m),cont,&tp); CP(m) = tp; @@ -2924,8 +3025,40 @@ void ndv_dehomogenize(NDV p,struct order_spec *ord) NV(p)--; } -void removecont_array(P *p,int n) +void nd_heu_nezgcdnpz(VL vl,P *pl,int m,int full,P *pr) { + int i; + P *tpl,*tpl1; + NODE l; + P h,gcd,t; + + tpl = (P *)ALLOCA(m*sizeof(P)); + tpl1 = (P *)ALLOCA(m*sizeof(P)); + bcopy(pl,tpl,m*sizeof(P)); + gcd = (P)ONE; + for ( l = nd_hcf; l; l = NEXT(l) ) { + h = (P)BDY(l); + while ( 1 ) { + for ( i = 0; i < m; i++ ) + if ( !divtpz(vl,tpl[i],h,&tpl1[i]) ) + break; + if ( i == m ) { + bcopy(tpl1,tpl,m*sizeof(P)); + mulp(vl,gcd,h,&t); gcd = t; + } else + break; + } + } + if ( DP_Print > 2 ){fprintf(asir_out,"[%d]",nmonop(gcd)); fflush(asir_out);} + if ( full ) { + heu_nezgcdnpz(vl,tpl,m,&t); + mulp(vl,gcd,t,pr); + } else + *pr = gcd; +} + +void removecont_array(P *p,int n,int full) +{ int all_p,all_q,i; Q *c; P *w; @@ -2942,7 +3075,7 @@ void removecont_array(P *p,int n) ptozp(p[i],1,&c[i],&w[i]); } removecont_array_q(c,n); - heu_nezgcdnpz(nd_vc,w,n,&t); + nd_heu_nezgcdnpz(nd_vc,w,n,full,&t); for ( i = 0; i < n; i++ ) { divsp(nd_vc,w[i],t,&s); mulp(nd_vc,s,(P)c[i],&p[i]); } @@ -3298,10 +3431,12 @@ ND nd_copy(ND p) int nd_sp(int mod,int trace,ND_pairs p,ND *rp) { - NM m; + NM m1,m2; NDV p1,p2; ND t1,t2; UINT *lcm; + P gp,tp; + Q g,t; int td; if ( !mod && nd_demand ) { @@ -3314,23 +3449,29 @@ int nd_sp(int mod,int trace,ND_pairs p,ND *rp) } } lcm = LCM(p); - NEWNM(m); - CQ(m) = HCQ(p2); - ndl_sub(lcm,HDL(p1),DL(m)); - if ( ndl_check_bound2(p->i1,DL(m)) ) - return 0; - t1 = ndv_mul_nm(mod,m,p1); - if ( mod == -1 ) CM(m) = _chsgnsf(HCM(p1)); - else if ( mod ) CM(m) = mod-HCM(p1); - else chsgnp(HCP(p1),&CP(m)); - ndl_sub(lcm,HDL(p2),DL(m)); - if ( ndl_check_bound2(p->i2,DL(m)) ) { - nd_free(t1); - return 0; + NEWNM(m1); ndl_sub(lcm,HDL(p1),DL(m1)); + if ( ndl_check_bound2(p->i1,DL(m1)) ) { + FREENM(m1); return 0; } - t2 = ndv_mul_nm(mod,m,p2); + NEWNM(m2); ndl_sub(lcm,HDL(p2),DL(m2)); + if ( ndl_check_bound2(p->i2,DL(m2)) ) { + FREENM(m1); FREENM(m2); return 0; + } + + if ( mod == -1 ) { + CM(m1) = HCM(p2); CM(m2) = _chsgnsf(HCM(p1)); + } else if ( mod ) { + CM(m1) = HCM(p2); CM(m2) = mod-HCM(p1); + } else if ( nd_vc ) { + ezgcdpz(nd_vc,HCP(p1),HCP(p2),&gp); + divsp(nd_vc,HCP(p2),gp,&CP(m1)); + divsp(nd_vc,HCP(p1),gp,&tp); chsgnp(tp,&CP(m2)); + } else { + igcd_cofactor(HCQ(p1),HCQ(p2),&g,&t,&CQ(m1)); chsgnq(t,&CQ(m2)); + } + t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2); *rp = nd_add(mod,t1,t2); - FREENM(m); + FREENM(m1); FREENM(m2); return 1; } @@ -3710,9 +3851,8 @@ void ndv_mod(int mod,NDV p) NMV t,d; int r,s,u; int i,len,dlen; + P cp; Q c; - P cp,cp1; - NODE tn; Obj gfs; if ( !p ) return; @@ -3730,9 +3870,7 @@ void ndv_mod(int mod,NDV p) else for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) { if ( nd_vc ) { - for ( tn = nd_subst, cp = CP(t); tn; tn = NEXT(NEXT(tn)) ) { - substp(nd_vc,cp,BDY(tn),BDY(NEXT(tn)),&cp1); cp = cp1; - } + nd_subst_vector(nd_vc,CP(t),nd_subst,&cp); c = (Q)cp; } else c = CQ(t); @@ -4137,8 +4275,8 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec if ( m ) ndv_mod(m,(NDV)BDY(in)); NEXT(in) = 0; - /* dont sort */ - ndv_setup(m,0,in0,1); + /* dont sort, dont removecont */ + ndv_setup(m,0,in0,1,1); nd_psn--; nd_scale=2; while ( 1 ) { @@ -4336,14 +4474,14 @@ int ndv_reduce_vect_q(Q *svect,int trace,int col,IndAr if ( j == col ) break; if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) { nz = compress_array(svect,cvect,col); - removecont_array((P *)cvect,nz); + removecont_array((P *)cvect,nz,1); expand_array(svect,cvect,nz); hmag = ((double)p_mag((P)svect[j]))*nd_scale; } } } nz = compress_array(svect,cvect,col); - removecont_array((P *)cvect,nz); + removecont_array((P *)cvect,nz,1); expand_array(svect,cvect,nz); if ( DP_Print ) { fprintf(asir_out,"-"); fflush(asir_out); @@ -5668,7 +5806,9 @@ void nd_det(int mod,MAT f,P *rp) sgn = -sgn; } bound = nd_det_compute_bound(dm,n,j); - if ( ndl_check_bound(bound,bound) ) + for ( k = 0; k < nd_nvar; k++ ) + if ( bound[k]*2 > nd_mask0 ) break; + if ( k < nd_nvar ) nd_det_reconstruct(dm,n,j,d); for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) { @@ -5798,24 +5938,23 @@ void nd_det_reconstruct(NDV **dm,int n,int j,NDV d) #endif } +/* returns a UINT array containing degree bounds */ + UINT *nd_det_compute_bound(NDV **dm,int n,int j) { UINT *d0,*d1,*d,*t,*r; - int k,l; + int k,l,i; - d0 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); - d1 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); - for ( k = 0; k < nd_wpd; k++ ) d0[k] = 0; + d0 = (UINT *)MALLOC(nd_nvar*sizeof(UINT)); + for ( k = 0; k < nd_nvar; k++ ) d0[k] = 0; for ( k = j; k < n; k++ ) for ( l = j; l < n; l++ ) if ( dm[k][l] ) { d = ndv_compute_bound(dm[k][l]); - ndl_lcm(d,d0,d1); - t = d1; d1 = d0; d0 = t; + for ( i = 0; i < nd_nvar; i++ ) + d0[i] = MAX(d0[i],d[i]); } - r = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); - for ( k = 0; k < nd_wpd; k++ ) r[k] = d0[k]; - return r; + return d0; } DL nd_separate_d(UINT *d,UINT *trans)