=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.129 retrieving revision 1.135 diff -u -p -r1.129 -r1.135 --- OpenXM_contrib2/asir2000/engine/nd.c 2006/04/17 04:35:20 1.129 +++ OpenXM_contrib2/asir2000/engine/nd.c 2006/06/06 09:00:38 1.135 @@ -1,7 +1,8 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.128 2005/08/03 06:10:47 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.134 2006/06/06 07:14:16 noro Exp $ */ #include "nd.h" +int diag_period = 6; int (*ndl_compare_function)(UINT *a1,UINT *a2); int nd_dcomp; NM _nm_free_list; @@ -1719,6 +1720,7 @@ NODE nd_gb_trace(int m,int ishomo) Q q,den,num; union oNDC dn; struct oEGT eg_monic,egm0,egm1; + int diag_count = 0; init_eg(&eg_monic); init_eg(&eg_invdalg); @@ -1733,14 +1735,17 @@ NODE nd_gb_trace(int m,int ishomo) again: l = nd_minp(d,&d); if ( SG(l) != sugar ) { +#if 1 if ( ishomo ) { stat = do_diagonalize_trace(sugar,m); + diag_count = 0; if ( !stat ) { NEXT(l) = d; d = l; d = nd_reconstruct(1,d); goto again; } } +#endif sugar = SG(l); if ( DP_Print ) fprintf(asir_out,"%d",sugar); } @@ -1789,6 +1794,15 @@ again: nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); } nh = ndv_newps(0,nfv,nfqv); + if ( ishomo && ++diag_count == diag_period ) { + diag_count = 0; + stat = do_diagonalize_trace(sugar,m); + if ( !stat ) { + NEXT(l) = d; d = l; + d = nd_reconstruct(1,d); + goto again; + } + } d = update_pairs(d,g,nh); g = update_base(g,nh); } else { @@ -2496,7 +2510,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s MKLIST(*rp,r0); } -void nd_gr_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp) +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; NODE fd,fd0,in0,in,r,r0,t,s,cand,alist; @@ -2584,7 +2598,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,stru if ( Demand ) nd_demand = 1; ndv_setup(m,1,fd0,0); - cand = nd_gb_trace(m,ishomo || homo); + cand = f4?nd_f4_trace(m):nd_gb_trace(m,ishomo || homo); if ( !cand ) { /* failure */ if ( trace > 1 ) { *rp = 0; return; } @@ -4154,10 +4168,26 @@ IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0 return r; } +int compress_array(Q *svect,Q *cvect,int n) +{ + int i,j; -int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred) + for ( i = j = 0; i < n; i++ ) + if ( svect[i] ) cvect[j++] = svect[i]; + return j; +} + +void expand_array(Q *svect,Q *cvect,int n) { - int i,j,k,len,pos,prev; + int i,j; + + for ( i = j = 0; j < n; i++ ) + if ( svect[i] ) svect[i] = cvect[j++]; +} + +int ndv_reduce_vect_q(Q *svect,int trace,int col,IndArray *imat,NM_ind_pair *rp0,int nred) +{ + int i,j,k,len,pos,prev,nz; Q cs,mcs,c1,c2,cr,gcd,t; IndArray ivect; unsigned char *ivc; @@ -4167,14 +4197,20 @@ int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat, NMV mr; NODE rp; int maxrs; + double hmag; + Q *cvect; maxrs = 0; + for ( i = 0; i < col && !svect[i]; i++ ); + if ( i == col ) return maxrs; + hmag = p_mag((P)svect[i])*nd_scale; + cvect = (Q *)ALLOCA(col*sizeof(Q)); for ( i = 0; i < nred; i++ ) { ivect = imat[i]; k = ivect->head; if ( svect[k] ) { maxrs = MAX(maxrs,rp0[i]->sugar); - redv = nd_ps[rp0[i]->index]; + redv = trace?nd_ps_trace[rp0[i]->index]:nd_ps[rp0[i]->index]; len = LEN(redv); mr = BDY(redv); igcd_cofactor(svect[k],CQ(mr),&gcd,&cs,&cr); chsgnq(cs,&mcs); @@ -4207,8 +4243,22 @@ int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat, } break; } + for ( j = k+1; j < col && !svect[j]; j++ ); + if ( j == col ) break; + if ( hmag && ((double)p_mag((P)svect[j]) > hmag) ) { + nz = compress_array(svect,cvect,col); + removecont_array(cvect,nz); + expand_array(svect,cvect,nz); + hmag = ((double)p_mag((P)svect[j]))*nd_scale; + } } } + nz = compress_array(svect,cvect,col); + removecont_array(cvect,nz); + expand_array(svect,cvect,nz); + if ( DP_Print ) { + fprintf(asir_out,"-"); fflush(asir_out); + } return maxrs; } @@ -4413,7 +4463,7 @@ NDV plain_vect_to_ndv_q(Q *vect,int col,UINT *s0vect) } } -int nd_sp_f4(int m,ND_pairs l,PGeoBucket bucket) +int nd_sp_f4(int m,int trace,ND_pairs l,PGeoBucket bucket) { ND_pairs t; NODE sp0,sp; @@ -4421,7 +4471,7 @@ int nd_sp_f4(int m,ND_pairs l,PGeoBucket bucket) ND spol; for ( t = l; t; t = NEXT(t) ) { - stat = nd_sp(m,0,t,&spol); + stat = nd_sp(m,trace,t,&spol); if ( !stat ) return 0; if ( spol ) { add_pbucket_symbolic(bucket,spol); @@ -4430,7 +4480,7 @@ int nd_sp_f4(int m,ND_pairs l,PGeoBucket bucket) return 1; } -int nd_symbolic_preproc(PGeoBucket bucket,UINT **s0vect,NODE *r) +int nd_symbolic_preproc(PGeoBucket bucket,int trace,UINT **s0vect,NODE *r) { NODE rp0,rp; NM mul,head,s0,s; @@ -4439,8 +4489,10 @@ int nd_symbolic_preproc(PGeoBucket bucket,UINT **s0vec UINT *s0v,*p; NM_ind_pair pair; ND red; + NDV *ps; s0 = 0; rp0 = 0; col = 0; + ps = trace?nd_ps_trace:nd_ps; while ( 1 ) { head = remove_head_pbucket_symbolic(bucket); if ( !head ) break; @@ -4453,9 +4505,9 @@ int nd_symbolic_preproc(PGeoBucket bucket,UINT **s0vec NEWNM(mul); ndl_sub(DL(head),DL(h),DL(mul)); if ( ndl_check_bound2(index,DL(mul)) ) return 0; - sugar = TD(DL(mul))+SG(nd_ps[index]); + sugar = TD(DL(mul))+SG(ps[index]); MKNM_ind_pair(pair,mul,index,sugar); - red = ndv_mul_nm_symbolic(mul,nd_ps[index]); + red = ndv_mul_nm_symbolic(mul,ps[index]); add_pbucket_symbolic(bucket,nd_remove_head(red)); NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair; } @@ -4505,7 +4557,7 @@ NODE nd_f4(int m) l = nd_minsugarp(d,&d); sugar = SG(l); bucket = create_pbucket(); - stat = nd_sp_f4(m,l,bucket); + stat = nd_sp_f4(m,0,l,bucket); if ( !stat ) { for ( t = l; NEXT(t); t = NEXT(t) ); NEXT(t) = d; d = l; @@ -4513,7 +4565,7 @@ NODE nd_f4(int m) continue; } if ( bucket->m < 0 ) continue; - col = nd_symbolic_preproc(bucket,&s0vect,&rp0); + col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0); if ( !col ) { for ( t = l; NEXT(t); t = NEXT(t) ); NEXT(t) = d; d = l; @@ -4525,9 +4577,9 @@ NODE nd_f4(int m) fprintf(asir_out,"sugar=%d,symb=%fsec,", sugar,eg_f4.exectime+eg_f4.gctime); if ( 1 ) - nflist = nd_f4_red(m,l,s0vect,col,rp0); + nflist = nd_f4_red(m,l,0,s0vect,col,rp0,0); else - nflist = nd_f4_red_dist(m,l,s0vect,col,rp0); + nflist = nd_f4_red_dist(m,l,s0vect,col,rp0,0); /* adding new bases */ for ( r = nflist; r; r = NEXT(r) ) { nf = (NDV)BDY(r); @@ -4552,9 +4604,109 @@ NODE nd_f4(int m) return g; } -NODE nd_f4_red(int m,ND_pairs sp0,UINT *s0vect,int col,NODE rp0) +NODE nd_f4_trace(int m) { + 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); + 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 */ + 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); + g = update_base(g,nh); + } + } + for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps_trace[(int)BDY(r)]; +#if 0 + fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); +#endif + return g; +} + +NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz) +{ + IndArray *imat; int nsp,nred,i; int *rhead; NODE r0,rp; @@ -4575,14 +4727,14 @@ NODE nd_f4_red(int m,ND_pairs sp0,UINT *s0vect,int col rhead[imat[i]->head] = 1; } if ( m ) - r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred); + r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz); else - r0 = nd_f4_red_q_main(sp0,nsp,s0vect,col,rvect,rhead,imat,nred); + r0 = nd_f4_red_q_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred); return r0; } NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col, - NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred) + NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz) { int spcol,sprow,a; int i,j,k,l,rank; @@ -4595,6 +4747,7 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s struct oEGT eg0,eg1,eg2,eg_f4,eg_f4_1,eg_f4_2; int maxrs; int *spsugar; + ND_pairs *spactive; spcol = col-nred; get_eg(&eg0); @@ -4602,6 +4755,7 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s spmat = (int **)ALLOCA(nsp*sizeof(UINT *)); svect = (UINT *)ALLOCA(col*sizeof(UINT)); spsugar = (int *)ALLOCA(nsp*sizeof(UINT)); + spactive = !nz?0:(ND_pairs *)ALLOCA(nsp*sizeof(ND_pairs)); for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) { nd_sp(m,0,sp,&spol); if ( !spol ) continue; @@ -4616,6 +4770,8 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s for ( j = k = 0; j < col; j++ ) if ( !rhead[j] ) v[k++] = svect[j]; spsugar[sprow] = MAX(maxrs,SG(spol)); + if ( nz ) + spactive[sprow] = sp; sprow++; } nd_free(spol); @@ -4633,7 +4789,7 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s if ( m == -1 ) rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat); else - rank = nd_gauss_elim_mod(spmat,spsugar,sprow,spcol,m,colstat); + rank = nd_gauss_elim_mod(spmat,spsugar,spactive,sprow,spcol,m,colstat); r0 = 0; for ( i = 0; i < rank; i++ ) { NEXTNODE(r0,r); BDY(r) = @@ -4642,6 +4798,7 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s GC_free(spmat[i]); } if ( r0 ) NEXT(r) = 0; + for ( ; i < sprow; i++ ) GC_free(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); @@ -4651,11 +4808,19 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s nsp,nred,sprow,spcol,rank); fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime); } + if ( nz ) { + for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1]; + if ( rank > 0 ) { + NEXT(spactive[rank-1]) = 0; + *nz = spactive[0]; + } else + *nz = 0; + } return r0; } -#if 0 -NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vect,int col, +#if 1 +NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col, NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred) { int spcol,sprow,a; @@ -4677,10 +4842,10 @@ NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec svect = (Q *)ALLOCA(col*sizeof(Q)); spsugar = (int *)ALLOCA(nsp*sizeof(Q)); for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) { - nd_sp(0,0,sp,&spol); + nd_sp(0,trace,sp,&spol); if ( !spol ) continue; nd_to_vect_q(s0vect,col,spol,svect); - maxrs = ndv_reduce_vect_q(svect,col,imat,rvect,nred); + maxrs = ndv_reduce_vect_q(svect,trace,col,imat,rvect,nred); for ( i = 0; i < col; i++ ) if ( svect[i] ) break; if ( i < col ) { spmat[sprow] = v = (Q *)MALLOC(spcol*sizeof(Q)); @@ -4709,8 +4874,8 @@ NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec SG((NDV)BDY(r)) = spsugar[i]; /* GC_free(spmat[i]); */ } - if ( r0 ) NEXT(r) = 0; + if ( r0 ) NEXT(r) = 0; /* for ( ; i < sprow; i++ ) GC_free(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); @@ -4874,7 +5039,7 @@ int ox_exec_f4_red(Q proc) return s; } -NODE nd_f4_red_dist(int m,ND_pairs sp0,UINT *s0vect,int col,NODE rp0) +NODE nd_f4_red_dist(int m,ND_pairs sp0,UINT *s0vect,int col,NODE rp0,ND_pairs *nz) { int nsp,nred; int i,rank,s; @@ -5028,7 +5193,7 @@ void nd_exec_f4_red_dist() if ( m == -1 ) rank = nd_gauss_elim_sf(spmat,spsugar,sprow,spcol,m,colstat); else - rank = nd_gauss_elim_mod(spmat,spsugar,sprow,spcol,m,colstat); + rank = nd_gauss_elim_mod(spmat,spsugar,0,sprow,spcol,m,colstat); nd_send_int(rank); for ( i = 0; i < rank; i++ ) { nf = vect_to_ndv(spmat[i],spcol,col,rhead,s0vect); @@ -5059,7 +5224,7 @@ int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int co wmat[i][j] = 0; } } - rank0 = nd_gauss_elim_mod(wmat,sugar,row,col,mod,colstat); + 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 ) @@ -5089,11 +5254,12 @@ int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int co return rank; } -int nd_gauss_elim_mod(int **mat0,int *sugar,int row,int col,int md,int *colstat) +int nd_gauss_elim_mod(int **mat0,int *sugar,ND_pairs *spactive,int row,int col,int md,int *colstat) { int i,j,k,l,inv,a,rank,s; unsigned int *t,*pivot,*pk; unsigned int **mat; + ND_pairs pair; mat = (unsigned int **)mat0; for ( rank = 0, j = 0; j < col; j++ ) { @@ -5110,6 +5276,10 @@ int nd_gauss_elim_mod(int **mat0,int *sugar,int row,in if ( i != rank ) { t = mat[i]; mat[i] = mat[rank]; mat[rank] = t; s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s; + if ( spactive ) { + pair = spactive[i]; spactive[i] = spactive[rank]; + spactive[rank] = pair; + } } pivot = mat[rank]; s = sugar[rank];