=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.174 retrieving revision 1.187 diff -u -p -r1.174 -r1.187 --- OpenXM_contrib2/asir2000/engine/nd.c 2009/06/01 07:31:54 1.174 +++ OpenXM_contrib2/asir2000/engine/nd.c 2010/04/26 01:06:22 1.187 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.173 2009/02/15 09:22:07 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.186 2010/04/23 07:35:44 noro Exp $ */ #include "nd.h" @@ -50,6 +50,7 @@ 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_gbblock; NumberField get_numberfield(); UINT *nd_det_compute_bound(NDV **dm,int n,int j); @@ -2300,7 +2301,7 @@ 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]); @@ -2308,6 +2309,18 @@ ND_pairs nd_newpairs( NODE g, int t ) 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 ) { + fprintf(stderr,"(%d,%d)",t0,t); + continue; + } + } NEXTND_pairs(r0,r); r->i1 = (long)BDY(h); r->i2 = t; @@ -2594,8 +2607,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; @@ -2649,6 +2663,8 @@ 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); @@ -2675,6 +2691,7 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort, } } if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0; + return 1; } struct order_spec *append_block(struct order_spec *spec, @@ -2782,13 +2799,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 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; @@ -2841,7 +2859,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)); @@ -2875,11 +2893,31 @@ 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 ( !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 ( !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; x = ndv_reducebase(x,perm); if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } @@ -2922,7 +2960,7 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe } MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3); MKLIST(l5,tl4); - tr = mknode(7,*rp,0,l1,l2,l3,l4,l5); MKLIST(*rp,tr); + tr = mknode(7,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5); MKLIST(*rp,tr); } #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); @@ -2971,7 +3009,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); @@ -2997,8 +3035,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); @@ -3078,7 +3121,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)); @@ -3128,14 +3171,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); + 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); @@ -3438,7 +3483,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); @@ -4042,7 +4087,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; @@ -4097,7 +4144,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; } } @@ -4109,7 +4158,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; } @@ -4898,7 +4949,7 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec 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 ( 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); @@ -5579,6 +5630,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; @@ -6087,31 +6241,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; @@ -6121,19 +6257,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; } @@ -6421,7 +6544,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]); @@ -6429,7 +6552,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]); @@ -6479,16 +6602,24 @@ 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); @@ -6818,11 +6949,12 @@ void conv_ilist(int demand,int trace,NODE g,int **indp void parse_nd_option(NODE opt) { - NODE t,p; + NODE t,p,u; + int i,s; char *key; Obj value; - nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; + nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_gbblock = 0; for ( t = opt; t; t = NEXT(t) ) { p = BDY((LIST)BDY(t)); key = BDY((STRING)BDY(p)); @@ -6833,5 +6965,17 @@ void parse_nd_option(NODE opt) 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(t)+1); + 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; + } } }