=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.165 retrieving revision 1.182 diff -u -p -r1.165 -r1.182 --- OpenXM_contrib2/asir2000/engine/nd.c 2009/02/02 02:40:42 1.165 +++ OpenXM_contrib2/asir2000/engine/nd.c 2010/02/22 02:20:43 1.182 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.164 2009/01/07 05:33:18 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.181 2010/02/05 05:18:38 noro Exp $ */ #include "nd.h" @@ -46,7 +46,10 @@ 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; NumberField get_numberfield(); UINT *nd_det_compute_bound(NDV **dm,int n,int j); @@ -59,6 +62,13 @@ 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); extern int Denominator,DP_Multiple; @@ -399,8 +409,8 @@ int ndl_weight(UINT *d) for ( j = 0; j < nd_epw; j++, u>>=nd_bpe ) t += (u&nd_mask0); } - if ( nd_module && current_module_weight_vector && MPOS(d) ) - t += current_module_weight_vector[MPOS(d)]; + if ( nd_module && current_module_weight_vector && MPOS(d) ) + t += current_module_weight_vector[MPOS(d)]; return t; } @@ -571,12 +581,20 @@ 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; } 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 ( c = ndl_lex_compare(d1,d2) ) return c; if ( !nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; @@ -594,7 +612,7 @@ int ndl_module_glex_compare(UINT *d1,UINT *d2) } 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 ( c = ndl_lex_compare(d1,d2) ) return c; if ( !nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; @@ -610,7 +628,7 @@ int ndl_module_lex_compare(UINT *d1,UINT *d2) if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; } - if ( c = ndl_lex_compare(d1,d2) ) return c; + if ( c = ndl_lex_compare(d1,d2) ) return c; if ( !nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; @@ -723,7 +741,7 @@ INLINE void ndl_add(UINT *d1,UINT *d2,UINT *d) if ( nd_module ) { if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) ) - error("ndl_add : invalid operation"); + error("ndl_add : invalid operation"); } #if 1 switch ( nd_wpd ) { @@ -1231,18 +1249,20 @@ ND nd_add_sf(ND p1,ND p2) } } -ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn) +ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp) { int c,c1,c2; Q cg,cred,gcd,tq; P cgp,credp,gcdp; Obj tr,tr1; - if ( mod == -1 ) + if ( mod == -1 ) { CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g))); - else if ( mod ) { + *divp = (Obj)ONE; + } else if ( mod ) { c1 = invm(HCM(p),mod); c2 = mod-HCM(g); DMAR(c1,c2,0,mod,c); CM(mul) = c; + *divp = (Obj)ONE; } else if ( nd_vc ) { ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp); divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp); @@ -1252,6 +1272,7 @@ ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn) mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr); reductr(nd_vc,tr,&tr1); dn->r = (R)tr1; } + *divp = (Obj)credp; } else { igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred); chsgnq(cg,&CQ(mul)); @@ -1259,6 +1280,7 @@ ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn) if ( dn ) { mulq(dn->z,cred,&tq); dn->z = tq; } + *divp = (Obj)cred; } return nd_add(mod,g,ndv_mul_nm(mod,mul,p)); } @@ -1272,10 +1294,15 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND int c,c1,c2,dummy; RHist h; NDV p,red; - Q cg,cred,gcd,tq,qq; + Q cg,cred,gcd,tq,qq,iq; + DP dmul; + NODE node; + LIST hist; double hmag; P tp,tp1; - Obj tr,tr1; + Obj tr,tr1,div; + union oNDC hg; + P cont; if ( dn ) { if ( mod ) @@ -1306,23 +1333,33 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND return 0; } p = nd_demand ? ndv_load(index) : ps[index]; - g = nd_reduce2(mod,d,g,p,mul,dn); + /* d+g -> div*(d+g)+mul*p */ + g = nd_reduce2(mod,d,g,p,mul,dn,&div); + 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) ) { - tp = HCP(g); + hg = HCU(g); nd_removecont2(d,g); - if ( dn ) { - if ( nd_vc ) { - divsp(nd_vc,tp,HCP(g),&tp1); - divr(nd_vc,(Obj)dn->r,(Obj)tp1,&tr); - reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1; - } else { - divq((Q)tp,HCQ(g),&qq); - divq(dn->z,qq,&tq); dn->z = tq; + if ( dn || nd_gentrace ) { + /* overwrite cont : Trace=[div,index,mul,cont] */ + cont = ndc_div(mod,hg,HCU(g)); + if ( dn ) { + if ( nd_vc ) { + divr(nd_vc,(Obj)dn->r,(Obj)cont,&tr); + reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1; + } else divq(dn->z,(Q)cont,&dn->z); } + if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont; } hmag = ((double)p_mag(HCP(g)))*nd_scale; } + MKLIST(hist,node); + MKNODE(node,hist,nd_tracelist); nd_tracelist = node; } else if ( !full ) { *rp = g; return 1; @@ -1449,36 +1486,44 @@ 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; NDV r; NODE t,s; union oNDC dn; + Q q; + LIST list; - ndv_setup(0,0,cand,0,1); + ndv_setup(m,0,cand,nd_gentrace?1:0,1); n = length(cand); + if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; } /* membercheck : list is a subset of Id(cand) ? */ - for ( t = input; t; t = NEXT(t) ) { + for ( t = input, i = 0; t; t = NEXT(t), i++ ) { again: + nd_tracelist = 0; if ( nd_bpe > obpe ) 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 ( nd_gentrace ) { + nd_tracelist = reverse_node(nd_tracelist); + MKLIST(list,nd_tracelist); + STOQ(i,q); s = mknode(2,q,list); MKLIST(list,s); + MKNODE(s,list,nd_alltracelist); + nd_alltracelist = s; nd_tracelist = 0; + } if ( DP_Print ) { printf("."); fflush(stdout); } } if ( DP_Print ) { printf("\n"); } - /* gbcheck : cand is a GB of Id(cand) ? */ - if ( !nd_gb(0,0,1) ) return 0; - /* XXX */ return 1; } @@ -1779,9 +1824,18 @@ int do_diagonalize(int sugar,int m) ND h,nf,s,head; NDV nfv; Q q,num,den; - P nm,nmp,dn,mnp,dnp; + P nm,nmp,dn,mnp,dnp,cont,cont1; + union oNDC hc; + NODE node; + LIST l; + Q iq; for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) { + 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); + } if ( nd_demand ) nfv = ndv_load(i); else @@ -1791,7 +1845,9 @@ int do_diagonalize(int sugar,int m) stat = nd_nf(m,head,s,nd_ps,1,0,&nf); if ( !stat ) return 0; ndv_free(nfv); - nd_removecont(m,nf); + hc = HCU(nf); nd_removecont(m,nf); + cont = ndc_div(m,hc,HCU(nf)); + if ( nd_gentrace ) finalize_tracelist(i,cont); nfv = ndtondv(m,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); @@ -1807,7 +1863,7 @@ int do_diagonalize(int sugar,int m) /* return value = 0 => input is not a GB */ -NODE nd_gb(int m,int ishomo,int checkonly) +NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp) { int i,nh,sugar,stat; NODE r,g,t; @@ -1816,12 +1872,14 @@ NODE nd_gb(int m,int ishomo,int checkonly) ND h,nf,s,head,nf1; NDV nfv; Q q,num,den; - union oNDC dn; + union oNDC dn,hc; int diag_count = 0; + P cont; + LIST list; g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,gensyz); g = update_base(g,i); } sugar = 0; @@ -1848,7 +1906,8 @@ again: goto again; } #if USE_GEOBUCKET - stat = m?nd_nf_pbucket(m,h,nd_ps,!Top,&nf):nd_nf(m,0,h,nd_ps,!Top,0,&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); #endif @@ -1857,13 +1916,22 @@ again: d = nd_reconstruct(0,d); goto again; } else if ( nf ) { - if ( checkonly ) return 0; + if ( checkonly || gensyz ) return 0; if ( DP_Print ) { printf("+"); fflush(stdout); } + hc = HCU(nf); nd_removecont(m,nf); if ( !m && nd_nalg ) { nd_monic(0,&nf); nd_removecont(m,nf); } + if ( nd_gentrace ) { + cont = ndc_div(m,hc,HCU(nf)); + if ( m || !UNIQ(cont) ) { + t = mknode(4,0,0,0,cont); + MKLIST(list,t); MKNODE(t,list,nd_tracelist); + nd_tracelist = t; + } + } nfv = ndtondv(m,nf); nd_free(nf); nh = ndv_newps(m,nfv,0); if ( !m && (ishomo && ++diag_count == diag_period) ) { @@ -1875,20 +1943,22 @@ again: goto again; } } - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); FREENDP(l); } else { + 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); + MKNODE(t,list,nd_alltracelist); + nd_alltracelist = t; nd_tracelist = 0; + } if ( DP_Print ) { printf("."); fflush(stdout); } FREENDP(l); } } - if ( nd_demand ) - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)ndv_load((long)BDY(t)); - else - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)nd_ps[(long)BDY(t)]; + conv_ilist(nd_demand,0,g,indp); if ( !checkonly && DP_Print ) { printf("nd_gb done.\n"); fflush(stdout); } return g; } @@ -1900,8 +1970,18 @@ int do_diagonalize_trace(int sugar,int m) ND h,nf,nfq,s,head; NDV nfv,nfqv; Q q,den,num; + union oNDC hc; + NODE node; + LIST l; + Q iq; + P cont,cont1; for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) { + 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); + } /* for nd_ps */ s = ndvtond(m,nd_ps[i]); s = nd_separate_head(s,&head); @@ -1922,7 +2002,9 @@ int do_diagonalize_trace(int sugar,int m) stat = nd_nf(0,head,s,nd_ps_trace,1,0,&nf); if ( !stat ) return 0; ndv_free(nfv); - nd_removecont(0,nf); + hc = HCU(nf); nd_removecont(0,nf); + cont = ndc_div(0,hc,HCU(nf)); + if ( nd_gentrace ) finalize_tracelist(i,cont); nfv = ndtondv(0,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); @@ -1950,7 +2032,7 @@ void nd_subst_vector(VL vl,P p,NODE subst,P *r) *r = p; } -NODE nd_gb_trace(int m,int ishomo) +NODE nd_gb_trace(int m,int ishomo,int **indp) { int i,nh,sugar,stat; NODE r,g,t; @@ -1960,16 +2042,18 @@ NODE nd_gb_trace(int m,int ishomo) NDV nfv,nfqv; Q q,den,num; P hc; - union oNDC dn; + union oNDC dn,hnfq; struct oEGT eg_monic,egm0,egm1; int diag_count = 0; + P cont; + LIST list; init_eg(&eg_monic); init_eg(&eg_invdalg); init_eg(&eg_le); g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,0); g = update_base(g,i); } sugar = 0; @@ -2030,6 +2114,7 @@ again: if ( !rem(NM(q),m) ) return 0; if ( DP_Print ) { printf("+"); fflush(stdout); } + hnfq = HCU(nfq); if ( nd_nalg ) { /* m|DN(HC(nf)^(-1)) => failure */ get_eg(&egm0); @@ -2041,6 +2126,14 @@ again: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); } + if ( nd_gentrace ) { + cont = ndc_div(0,hnfq,HCU(nfqv)); + if ( !UNIQ(cont) ) { + t = mknode(4,0,0,0,cont); + MKLIST(list,t); MKNODE(t,list,nd_tracelist); + nd_tracelist = t; + } + } nh = ndv_newps(0,nfv,nfqv); if ( ishomo && ++diag_count == diag_period ) { diag_count = 0; @@ -2053,7 +2146,7 @@ again: goto again; } } - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } else { if ( DP_Print ) { printf("*"); fflush(stdout); } @@ -2063,17 +2156,12 @@ again: } FREENDP(l); } - if ( nd_demand ) - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)ndv_load((long)BDY(t)); - else - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)nd_ps_trace[(long)BDY(t)]; if ( nd_nalg ) { print_eg("monic",&eg_monic); print_eg("invdalg",&eg_invdalg); print_eg("le",&eg_le); } + conv_ilist(nd_demand,1,g,indp); if ( DP_Print ) { printf("nd_gb_trace done.\n"); fflush(stdout); } return g; } @@ -2088,25 +2176,44 @@ int ndv_compare_rev(NDV *p1,NDV *p2) return -DL_COMPARE(HDL(*p1),HDL(*p2)); } +int ndvi_compare(NDVI p1,NDVI p2) +{ + return DL_COMPARE(HDL(p1->p),HDL(p2->p)); +} + +int ndvi_compare_rev(NDVI p1,NDVI p2) +{ + return -DL_COMPARE(HDL(p1->p),HDL(p2->p)); +} + NODE ndv_reduceall(int m,NODE f) { - int i,n,stat; + int i,j,n,stat; ND nf,g,head; NODE t,a0,a; union oNDC dn; - NDV *w; Q q,num,den; + NODE node; + LIST l; + Q iq,jq; + int *perm; + union oNDC hc; + P cont,cont1; + if ( nd_nora ) return f; n = length(f); -#if 0 - w = (NDV *)ALLOCA(n*sizeof(NDV)); - for ( i = 0, t = f; i < n; i++, t = NEXT(t) ) w[i] = (NDV)BDY(t); - qsort(w,n,sizeof(NDV), - (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,1); + perm = (int *)MALLOC(n*sizeof(int)); + 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 ( 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); + } g = ndvtond(m,nd_ps[i]); g = nd_separate_head(g,&head); stat = nd_nf(m,head,g,nd_ps,1,0,&nf); @@ -2115,7 +2222,15 @@ NODE ndv_reduceall(int m,NODE f) else { if ( DP_Print ) { printf("."); fflush(stdout); } ndv_free(nd_ps[i]); - nd_removecont(m,nf); + hc = HCU(nf); nd_removecont(m,nf); + 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; + } + cont = ndc_div(m,hc,HCU(nf)); + finalize_tracelist(perm[i],cont); + } nd_ps[i] = ndtondv(m,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nd_ps[i]); i++; @@ -2124,22 +2239,38 @@ NODE ndv_reduceall(int m,NODE f) if ( DP_Print ) { printf("\n"); } for ( a0 = 0, i = 0; i < n; i++ ) { NEXTNODE(a0,a); - 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]; + } } NEXT(a) = 0; return a0; } -ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t) +ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz) { ND_pairs d1,nd,cur,head,prev,remove; if ( !g ) return d; + /* for testing */ + if ( gensyz && nd_gensyz == 2 ) { + d1 = nd_newpairs(g,t); + if ( !d ) + return d1; + else { + nd = d; + while ( NEXT(nd) ) nd = NEXT(nd); + NEXT(nd) = d1; + return d; + } + } d = crit_B(d,t); d1 = nd_newpairs(g,t); d1 = crit_M(d1); d1 = crit_F(d1); - if ( do_weyl ) + if ( gensyz || do_weyl ) head = d1; else { prev = 0; cur = head = d1; @@ -2205,22 +2336,22 @@ ND_pairs crit_B( ND_pairs d, int s ) tl = cur->lcm; if ( ndl_reducible(tl,t) ) { ndl_lcm(DL(nd_psh[cur->i1]),t,lcm); - if ( !ndl_equal(lcm,tl) ) { - ndl_lcm(DL(nd_psh[cur->i2]),t,lcm); - if (!ndl_equal(lcm,tl)) { - remove = cur; - if ( !prev ) { - head = cur = NEXT(cur); - } else { - cur = NEXT(prev) = NEXT(cur); - } - FREENDP(remove); - } else { - prev = cur; cur = NEXT(cur); - } - } else { - prev = cur; cur = NEXT(cur); - } + if ( !ndl_equal(lcm,tl) ) { + ndl_lcm(DL(nd_psh[cur->i2]),t,lcm); + if (!ndl_equal(lcm,tl)) { + remove = cur; + if ( !prev ) { + head = cur = NEXT(cur); + } else { + cur = NEXT(prev) = NEXT(cur); + } + FREENDP(remove); + } else { + prev = cur; cur = NEXT(cur); + } + } else { + prev = cur; cur = NEXT(cur); + } } else { prev = cur; cur = NEXT(cur); } @@ -2420,6 +2551,9 @@ int ndv_newps(int m,NDV a,NDV aq) int len; RHist r; NDV b; + NODE tn; + LIST l; + Q iq; if ( nd_psn == nd_pslen ) { nd_pslen *= 2; @@ -2450,31 +2584,48 @@ int ndv_newps(int m,NDV a,NDV aq) nd_ps[nd_psn] = 0; } } + 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); + MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0; + } return nd_psn++; } -void ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont) +/* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */ +/* return 1 if success, 0 if failure (HC(a mod p)) */ + +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; + NODE s,s0,f0,tn; UINT *d; RHist r; - NDV *w; + NDVI w; NDV a,am; + union oNDC hc; + NODE node; + P hcp; + Q iq,jq,hcq; + LIST l; nd_found = 0; nd_notfirst = 0; nd_create = 0; + /* initialize the tracelist */ + nd_tracelist = 0; for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++; - w = (NDV *)ALLOCA(nd_psn*sizeof(NDV)); - for ( i = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) w[i++] = BDY(s); + w = (NDVI)ALLOCA(nd_psn*sizeof(struct oNDVI)); + for ( i = j = 0, s = f; s; s = NEXT(s), j++ ) + if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; } if ( !dont_sort ) { /* XXX heuristic */ if ( !nd_ord->id && (nd_ord->ord.simple<2) ) - qsort(w,nd_psn,sizeof(NDV), - (int (*)(const void *,const void *))ndv_compare_rev); + qsort(w,nd_psn,sizeof(struct oNDVI), + (int (*)(const void *,const void *))ndvi_compare_rev); else - qsort(w,nd_psn,sizeof(NDV), - (int (*)(const void *,const void *))ndv_compare); + qsort(w,nd_psn,sizeof(struct oNDVI), + (int (*)(const void *,const void *))ndvi_compare); } nd_pslen = 2*nd_psn; nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); @@ -2492,18 +2643,27 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort, nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist)); for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0; for ( i = 0; i < nd_psn; i++ ) { + hc = HCU(w[i].p); if ( trace ) { - a = nd_ps_trace[i] = ndv_dup(0,w[i]); + a = nd_ps_trace[i] = ndv_dup(0,w[i].p); if ( !dont_removecont) ndv_removecont(0,a); 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]); + a = nd_ps[i] = ndv_dup(mod,w[i].p); if ( mod || !dont_removecont ) ndv_removecont(mod,a); if ( !mod ) register_hcf(a); } + 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)); + MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l; + } NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r)); nd_bound[i] = ndv_compute_bound(a); nd_psh[i] = r; @@ -2517,6 +2677,8 @@ 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, @@ -2552,7 +2714,7 @@ void preprocess_algcoef(VL vv,VL av,struct order_spec } NEXT(t) = 0; - /* simplification, makeing polynomials monic */ + /* simplification, making polynomials monic */ setfield_dalg(alist); obj_algtodalg(f,&f1); for ( t = BDY(f); t; t = NEXT(t) ) { @@ -2638,10 +2800,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,tl3,tl4; + LIST l1,l2,l3,l4,l5; + int j; + Q jq; + int *perm; + EPOS oepos; + int obpe,oadv,ompos; - nd_module = 0; + 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); @@ -2675,7 +2845,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)); @@ -2691,15 +2861,18 @@ 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 ) { - pltozpl((LIST)BDY(t),&dmy,&zpl); + if ( nd_module ) { + if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); + else zpl = (LIST)BDY(t); b = (pointer)pltondv(CO,vv,zpl); } else { - 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); - } + } if ( ishomo ) ishomo = ishomo && ndv_ishomo(b); if ( m ) ndv_mod(m,b); @@ -2707,19 +2880,54 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe } if ( fd0 ) NEXT(fd) = 0; ndv_setup(m,0,fd0,0,0); - x = f4?nd_f4(m):nd_gb(m,ishomo,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); nd_demand = 0; - x = ndv_reducebase(x); + x = ndv_reducebase(x,perm); + if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } x = ndv_reduceall(m,x); + 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 ) { + tl4 = nd_alltracelist; nd_alltracelist = 0; + } else tl4 = 0; + } for ( r0 = 0, t = x; t; t = NEXT(t) ) { NEXTNODE(r0,r); - if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank); + if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank); 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 ( 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,*,*],...] */ + s = BDY((LIST)BDY(t)); + j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq; + for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) { + j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq); + ARG1(BDY((LIST)BDY(s))) = (pointer)jq; + } + } + 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,0,l1,l2,l3,l4,l5); MKLIST(*rp,tr); + } #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); #endif @@ -2739,6 +2947,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s Obj obj; NumberField nf; struct order_spec *ord1; + int *perm; get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc); for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); @@ -2766,7 +2975,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); @@ -2786,16 +2995,21 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s for ( x = 0, i = 0; i < nd_psn; i++ ) x = update_base(x,i); if ( do_check ) { - x = nd_gb(m,ishomo,1); + x = nd_gb(m,ishomo,1,0,&perm); if ( !x ) { *rp = 0; 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); + x = ndv_reducebase(x,perm); x = ndv_reduceall(m,x); for ( r0 = 0, t = x; t; t = NEXT(t) ) { NEXTNODE(r0,r); @@ -2825,8 +3039,14 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int NumberField nf; struct order_spec *ord1; struct oEGT eg_check,eg0,eg1; + NODE tr,tl1,tl2,tl3,tl4; + LIST l1,l2,l3,l4,l5; + int *perm; + int j,ret; + Q jq; - nd_module = 0; + nd_module = 0; + parse_nd_option(current_option); if ( DP_Multiple ) nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); @@ -2867,7 +3087,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)); @@ -2886,13 +3106,15 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos; ishomo = 1; for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { - if ( nd_module ) { - pltozpl((LIST)BDY(t),&dmy,&zpl); + if ( nd_module ) { + if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); + else zpl = (LIST)BDY(t); c = (pointer)pltondv(CO,vv,zpl); } else { - 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); - } + } if ( ishomo ) ishomo = ishomo && ndv_ishomo(c); if ( c ) { @@ -2917,9 +3139,13 @@ 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,0); - cand = f4?nd_f4_trace(m):nd_gb_trace(m,ishomo || homo); - if ( !cand ) { + ret = ndv_setup(m,1,fd0,0,0); + if ( nd_gentrace ) { + MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0); + } + 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); @@ -2932,15 +3158,25 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int nd_setup_parameters(nvar,0); } nd_demand = 0; - cand = ndv_reducebase(cand); + cand = ndv_reducebase(cand,perm); + if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } cand = ndv_reduceall(0,cand); cbpe = nd_bpe; + if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; } + get_eg(&eg0); if ( nocheck ) break; - get_eg(&eg0); - if ( ndv_check_candidate(in0,obpe,oadv,oepos,cand) ) - /* success */ - break; + 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,nd_gensyz?1:0,0)!=0; + if ( nd_gentrace && nd_gensyz ) { + tl4 = nd_alltracelist; nd_alltracelist = 0; + } else tl4 = 0; + } + if ( ret ) break; else if ( trace > 1 ) { /* failure */ *rp = 0; return; @@ -2964,12 +3200,32 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int nd_bpe = cbpe; nd_setup_parameters(nd_nvar,0); for ( r = cand; r; r = NEXT(r) ) { - if ( nd_module ) BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank); + if ( nd_module ) BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank); else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r)); } if ( nalg ) cand = postprocess_algcoef(av,alist,cand); MKLIST(*rp,cand); + 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,*,*],...] */ + s = BDY((LIST)BDY(t)); + j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq; + for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) { + j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq); + ARG1(BDY((LIST)BDY(s))) = (pointer)jq; + } + } + for ( j = length(cand)-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); + } } /* XXX : module element is not considered */ @@ -3020,6 +3276,18 @@ DL ndltodl(int n,UINT *ndl) return dl; } +void nmtodp(int mod,NM m,DP *r) +{ + DP dp; + MP mr; + + NEWMP(mr); + mr->dl = ndltodl(nd_nvar,DL(m)); + mr->c = ndctop(mod,m->c); + NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td; + *r = dp; +} + void ndl_print(UINT *dl) { int n; @@ -3180,7 +3448,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); @@ -3198,7 +3466,7 @@ void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos void ndv_dehomogenize(NDV p,struct order_spec *ord) { int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos; - int pos; + int pos; Q *w; Q dvr,t; NMV m,r; @@ -3206,7 +3474,7 @@ void ndv_dehomogenize(NDV p,struct order_spec *ord) len = p->len; newnvar = nd_nvar-1; newexporigin = nd_get_exporigin(ord); - if ( nd_module ) newmpos = newexporigin-1; + if ( nd_module ) newmpos = newexporigin-1; newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin; for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) ndl_dehomogenize(DL(m)); @@ -3214,13 +3482,13 @@ void ndv_dehomogenize(NDV p,struct order_spec *ord) newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT)); for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) { CQ(r) = CQ(m); - if ( nd_module ) pos = MPOS(DL(m)); + if ( nd_module ) pos = MPOS(DL(m)); for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j]; adj = nd_exporigin-newexporigin; for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj]; - if ( nd_module ) { - DL(r)[newmpos] = pos; - } + if ( nd_module ) { + DL(r)[newmpos] = pos; + } } } NV(p)--; @@ -3646,8 +3914,11 @@ int nd_sp(int mod,int trace,ND_pairs p,ND *rp) ND t1,t2; UINT *lcm; P gp,tp; - Q g,t; + Q g,t,iq; int td; + LIST hist; + NODE node; + DP d; if ( !mod && nd_demand ) { p1 = ndv_load(p->i1); p2 = ndv_load(p->i2); @@ -3681,6 +3952,14 @@ 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 ( 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); + STOQ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE); + MKLIST(hist,node); MKNODE(node,hist,nd_tracelist); + nd_tracelist = node; + } FREENM(m1); FREENM(m2); return 1; } @@ -3767,10 +4046,15 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta for ( i = 0; i < tlen; i++ ) tab[i] = 0; if ( !m0 || !m1 ) return; d0 = DL(m0); d1 = DL(m1); n2 = n>>1; + if ( nd_module ) + if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation"); + 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; @@ -3781,11 +4065,6 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta TD(DL(m)) = h; if ( nd_blockmask ) ndl_weight_mask(DL(m)); } - if ( nd_module ) { - mpos = MPOS(d1); - TD(d1) = ndl_weight(d1); - if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation"); - } tab[0] = m; NEWNM(m); d = DL(m); for ( i = 0, curlen = 1; i < n2; i++ ) { @@ -3799,10 +4078,6 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta if ( t = tab[j] ) { dt = DL(t); PUT_EXP(dt,i,a); PUT_EXP(dt,n2+i,b); TD(dt) += s; - if ( nd_module ) { - MPOS(dt) = mpos; - TD(dt) = ndl_weight(dt); - } if ( nd_blockmask ) ndl_weight_mask(dt); } curlen *= k+1; @@ -3824,10 +4099,6 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta TD(d) = s; PUT_EXP(d,n-1,s-h); } else TD(d) = h; - if ( nd_module ) { - MPOS(d) = mpos; - TD(d) = ndl_weight(d); - } if ( nd_blockmask ) ndl_weight_mask(d); if ( mod ) c = ctab[j]; else q = ctab_q[j]; @@ -3838,7 +4109,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; } } @@ -3850,7 +4123,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; } @@ -3860,6 +4135,15 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta curlen *= k+1; } FREENM(m); + if ( nd_module ) { + mpos = MPOS(d1); + for ( i = 0; i < tlen; i++ ) + if ( tab[i] ) { + d = DL(tab[i]); + MPOS(d) = mpos; + TD(d) = ndl_weight(d); + } + } } ND ndv_mul_nm_symbolic(NM m0,NDV p) @@ -4170,8 +4454,8 @@ NDV pltondv(VL vl,VL dvl,LIST p) ri = ptond(vl,dvl,(P)BDY(t)); if ( ri ) for ( m = BDY(ri); m; m = NEXT(m) ) { - MPOS(DL(m)) = i; - TD(DL(m)) = ndl_weight(DL(m)); + MPOS(DL(m)) = i; + TD(DL(m)) = ndl_weight(DL(m)); if ( nd_blockmask ) ndl_weight_mask(DL(m)); } r = nd_add(0,r,ri); @@ -4393,24 +4677,29 @@ void ndv_print_q(NDV p) } } -NODE ndv_reducebase(NODE x) +NODE ndv_reducebase(NODE x,int *perm) { int len,i,j; - NDV *w; + NDVI w; NODE t,t0; len = length(x); - w = (NDV *)ALLOCA(len*sizeof(NDV)); - for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) w[i] = BDY(t); + w = (NDVI)ALLOCA(len*sizeof(struct oNDVI)); + for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) { + w[i].p = BDY(t); w[i].i = perm[i]; + } for ( i = 0; i < len; i++ ) { for ( j = 0; j < i; j++ ) { - if ( w[i] && w[j] ) - if ( ndl_reducible(HDL(w[i]),HDL(w[j])) ) w[i] = 0; - else if ( ndl_reducible(HDL(w[j]),HDL(w[i])) ) w[j] = 0; + if ( w[i].p && w[j].p ) + if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0; + else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0; } } - for ( i = len-1, t0 = 0; i >= 0; i-- ) { - if ( w[i] ) { NEXTNODE(t0,t); BDY(t) = (pointer)w[i]; } + for ( i = j = 0, t0 = 0; i < len; i++ ) { + if ( w[i].p ) { + NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p; + perm[j++] = w[i].i; + } } NEXT(t) = 0; x = t0; return x; @@ -4475,18 +4764,19 @@ 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: - nd_isrlex = 1; + nd_isrlex = 1; ndl_compare_function = ndl_module_grlex_compare; break; case 1: - nd_isrlex = 0; + nd_isrlex = 0; ndl_compare_function = ndl_module_glex_compare; break; case 2: - nd_isrlex = 0; + nd_isrlex = 0; ndl_compare_function = ndl_module_lex_compare; break; default: @@ -4495,16 +4785,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; @@ -4581,7 +4883,7 @@ EPOS nd_create_epos(struct order_spec *ord) /* matrix order */ case 3: /* composite order */ - default: + default: for ( i = 0; i < nd_nvar; i++ ) { epos[i].i = nd_exporigin + i/nd_epw; epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe; @@ -4612,7 +4914,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); @@ -5112,7 +5414,7 @@ int nd_symbolic_preproc(PGeoBucket bucket,int trace,UI return col; } -NODE nd_f4(int m) +NODE nd_f4(int m,int **indp) { int i,nh,stat,index; NODE r,g; @@ -5138,7 +5440,7 @@ NODE nd_f4(int m) #endif g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,0); g = update_base(g,i); } while ( d ) { @@ -5182,18 +5484,18 @@ NODE nd_f4(int m) nf = ndtondv(m,nf1); } nh = ndv_newps(m,nf,0); - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } } - for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps[(long)BDY(r)]; #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); #endif + conv_ilist(0,0,g,indp); return g; } -NODE nd_f4_trace(int m) +NODE nd_f4_trace(int m,int **indp) { int i,nh,stat,index; NODE r,g; @@ -5216,7 +5518,7 @@ NODE nd_f4_trace(int m) g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,0); g = update_base(g,i); } while ( d ) { @@ -5282,17 +5584,120 @@ NODE nd_f4_trace(int m) ndv_mod(m,nfv); ndv_removecont(m,nfv); nh = ndv_newps(0,nfv,nfqv); - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } } - for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps_trace[(long)BDY(r)]; #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); #endif + conv_ilist(0,1,g,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; @@ -5801,31 +6206,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; @@ -5835,19 +6222,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; } @@ -6135,7 +6509,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]); @@ -6143,7 +6517,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]); @@ -6452,4 +6826,100 @@ int nd_monic(int mod,ND *p) nd_free(*p); *p = r; return 1; +} + +NODE reverse_node(NODE n) +{ + NODE t,t1; + + for ( t = 0; n; n = NEXT(n) ) { + MKNODE(t1,BDY(n),t); t = t1; + } + return t; +} + +P ndc_div(int mod,union oNDC a,union oNDC b) +{ + union oNDC c; + int inv,t; + + if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m)); + else if ( mod ) { + inv = invm(b.m,mod); + DMAR(a.m,inv,0,mod,t); c.m = t; + } else if ( nd_vc ) + divsp(nd_vc,a.p,b.p,&c.p); + else + divq(a.z,b.z,&c.z); + return ndctop(mod,c); +} + +P ndctop(int mod,union oNDC c) +{ + Q q; + int e; + GFS gfs; + + if ( mod == -1 ) { + e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs; + } else if ( mod ) { + STOQ(c.m,q); return (P)q; + } else + return (P)c.p; +} + +/* [0,0,0,cont] = p -> p/cont */ + +void finalize_tracelist(int i,P cont) +{ + LIST l; + NODE node; + Q iq; + + if ( !UNIQ(cont) ) { + node = mknode(4,0,0,0,cont); + MKLIST(l,node); MKNODE(node,l,nd_tracelist); + nd_tracelist = node; + } + STOQ(i,iq); + nd_tracelist = reverse_node(nd_tracelist); + MKLIST(l,nd_tracelist); + node = mknode(2,iq,l); MKLIST(l,node); + MKNODE(node,l,nd_alltracelist); MKLIST(l,node); + nd_alltracelist = node; nd_tracelist = 0; +} + +void conv_ilist(int demand,int trace,NODE g,int **indp) +{ + int n,i,j; + int *ind; + NODE t; + + n = length(g); + ind = (int *)MALLOC(n*sizeof(int)); + for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) { + j = (long)BDY(t); ind[i] = j; + 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; + char *key; + Obj value; + + nd_gentrace = 0; nd_gensyz = 0; nd_nora = 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; + } }