=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.64 retrieving revision 1.71 diff -u -p -r1.64 -r1.71 --- OpenXM_contrib2/asir2000/engine/nd.c 2003/09/12 01:12:40 1.64 +++ OpenXM_contrib2/asir2000/engine/nd.c 2003/09/17 07:16:53 1.71 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.63 2003/09/11 09:03:53 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.70 2003/09/15 10:51:45 noro Exp $ */ #include "ca.h" #include "inline.h" @@ -15,6 +15,7 @@ typedef unsigned int UINT; #define USE_GEOBUCKET 1 +#define USE_UNROLL 1 #define REDTAB_LEN 32003 @@ -41,24 +42,22 @@ typedef struct oNDV { int sugar; } *NDV; +typedef union oNDC { + int m; + Q z; + P p; +} *NDC; + /* monomial; linked list rep. */ typedef struct oNM { struct oNM *next; - union { - int m; - Q z; - P p; - } c; + union oNDC c; UINT dl[1]; } *NM; /* monomial; array rep. */ typedef struct oNMV { - union { - int m; - Q z; - P p; - } c; + union oNDC c; UINT dl[1]; } *NMV; @@ -102,9 +101,20 @@ typedef struct oNM_ind_pair int index; } *NM_ind_pair; +typedef struct oIndArray +{ + char width; + int head; + union { + unsigned char *c; + unsigned short *s; + unsigned int *i; + } index; +} *IndArray; int (*ndl_compare_function)(UINT *a1,UINT *a2); +static int nd_f4_nsp=0x7fffffff; static double nd_scale=2; static UINT **nd_bound; static struct order_spec *nd_ord; @@ -133,7 +143,7 @@ static int nmv_adv; static int nd_dcomp; extern VL CO; -extern int Top,Reverse,dp_nelim,do_weyl; +extern int Top,Reverse,DP_Print,dp_nelim,do_weyl; extern int *current_weyl_weight_vector; /* fundamental macros */ @@ -214,7 +224,9 @@ if(!(r)){NEWND_pairs(r);(c)=(r);}else{NEWND_pairs(NEXT #define NMV_OPREV(m) (m = (NMV)(((char *)m)-oadv)) /* external functions */ +#if 1 void GC_gcollect(); +#endif NODE append_one(NODE,int); /* manipulation of coefficients */ @@ -273,11 +285,9 @@ INLINE int ndl_hash_value(UINT *d); /* normal forms */ INLINE int ndl_find_reducer(UINT *g); -INLINE int ndl_find_reducer_direct(UINT *g,NDV *ps,int len); int nd_sp(int mod,int trace,ND_pairs p,ND *nf); -int nd_nf(int mod,ND g,NDV *ps,int full,ND *nf); +int nd_nf(int mod,ND g,NDV *ps,int full,NDC dn,ND *nf); int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *nf); -int nd_nf_direct(int mod,ND g,BaseSet base,int full,ND *rp); /* finalizers */ NODE ndv_reducebase(NODE x); @@ -300,7 +310,6 @@ void ndp_print(ND_pairs d); /* setup, reconstruct */ void nd_init_ord(struct order_spec *spec); ND_pairs nd_reconstruct(int mod,int trace,ND_pairs ndp); -void nd_reconstruct_direct(int mod,NDV *ps,int len); void ndv_setup(int mod,int trace,NODE f); void nd_setup_parameters(int nvar,int max); BlockMask nd_create_blockmask(struct order_spec *ord); @@ -316,6 +325,7 @@ void nd_mul_c(int mod,ND p,int mul); void nd_mul_c_q(ND p,Q mul); void nd_mul_c_p(VL vl,ND p,P mul); ND nd_remove_head(ND p); +ND nd_separate_head(ND p,ND *head); int nd_length(ND p); void nd_append_red(UINT *d,int i); UINT *ndv_compute_bound(NDV p); @@ -323,6 +333,7 @@ ND nd_copy(ND p); ND nd_merge(ND p1,ND p2); ND nd_add(int mod,ND p1,ND p2); ND nd_add_q(ND p1,ND p2); +ND nd_add_sf(ND p1,ND p2); INLINE int nd_length(ND p); /* NDV functions */ @@ -348,16 +359,16 @@ P ndvtop(int mod,VL vl,VL dvl,NDV p); NDV ndtondv(int mod,ND p); ND ndvtond(int mod,NDV p); int nm_ind_pair_to_vect(int m,UINT *s0,int n,NM_ind_pair pair,UINT *r); -void nm_ind_pair_to_vect_compress(int m,UINT *s0,int n,NM_ind_pair pair,UINT *r,int *ind); +IndArray nm_ind_pair_to_vect_compress(int m,UINT *s0,int n,NM_ind_pair pair); int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r); void nd_free_private_storage() { - _nd_free_list = 0; _nm_free_list = 0; _ndp_free_list = 0; - bzero(nd_red,sizeof(REDTAB_LEN*sizeof(RHist))); +#if 0 GC_gcollect(); +#endif } void _NM_alloc() @@ -413,8 +424,8 @@ INLINE int ndl_reducible(UINT *d1,UINT *d2) int i,j; if ( TD(d1) < TD(d2) ) return 0; +#if USE_UNROLL switch ( nd_bpe ) { -#if 0 case 3: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u1 = d1[i]; u2 = d2[i]; @@ -479,7 +490,6 @@ INLINE int ndl_reducible(UINT *d1,UINT *d2) if ( d1[i] < d2[i] ) return 0; return 1; break; -#endif default: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u1 = d1[i]; u2 = d2[i]; @@ -488,6 +498,14 @@ INLINE int ndl_reducible(UINT *d1,UINT *d2) } return 1; } +#else + for ( i = nd_exporigin; i < nd_wpd; i++ ) { + u1 = d1[i]; u2 = d2[i]; + for ( j = 0; j < nd_epw; j++ ) + if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0; + } + return 1; +#endif } /* @@ -555,8 +573,8 @@ void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) UINT t1,t2,u,u1,u2; int i,j,l; +#if USE_UNROLL switch ( nd_bpe ) { -#if 0 case 3: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u1 = d1[i]; u2 = d2[i]; @@ -622,7 +640,6 @@ void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) d[i] = u1>u2?u1:u2; } break; -#endif default: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u1 = d1[i]; u2 = d2[i]; @@ -633,6 +650,15 @@ void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) } break; } +#else + for ( i = nd_exporigin; i < nd_wpd; i++ ) { + u1 = d1[i]; u2 = d2[i]; + for ( j = 0, u = 0; j < nd_epw; j++ ) { + t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2; + } + d[i] = u; + } +#endif TD(d) = ndl_weight(d); if ( nd_blockmask ) ndl_weight_mask(d); } @@ -838,8 +864,8 @@ int ndl_disjoint(UINT *d1,UINT *d2) UINT t1,t2,u,u1,u2; int i,j; +#if USE_UNROLL switch ( nd_bpe ) { -#if 0 case 3: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u1 = d1[i]; u2 = d2[i]; @@ -904,7 +930,6 @@ int ndl_disjoint(UINT *d1,UINT *d2) if ( d1[i] && d2[i] ) return 0; return 1; break; -#endif default: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u1 = d1[i]; u2 = d2[i]; @@ -916,6 +941,16 @@ int ndl_disjoint(UINT *d1,UINT *d2) return 1; break; } +#else + for ( i = nd_exporigin; i < nd_wpd; i++ ) { + u1 = d1[i]; u2 = d2[i]; + for ( j = 0; j < nd_epw; j++ ) { + if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0; + u1 >>= nd_bpe; u2 >>= nd_bpe; + } + } + return 1; +#endif } int ndl_check_bound2(int index,UINT *d2) @@ -926,8 +961,8 @@ int ndl_check_bound2(int index,UINT *d2) d1 = nd_bound[index]; ind = 0; +#if USE_UNROLL switch ( nd_bpe ) { -#if 0 case 3: for ( i = nd_exporigin; i < nd_wpd; i++ ) { u2 = d2[i]; @@ -992,7 +1027,6 @@ int ndl_check_bound2(int index,UINT *d2) if ( d1[i]+d2[i]>27)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>24)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>21)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>18)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>15)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>12)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>9)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>6)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+((u2>>3)&0x7) >= 0x8 ) return 1; - if ( d1[ind++]+(u2&0x7) >= 0x8 ) return 1; - } - return 0; - break; - case 4: - for ( i = nd_exporigin; i < nd_wpd; i++ ) { - u2 = d2[i]; - if ( d1[ind++]+((u2>>28)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+((u2>>24)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+((u2>>20)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+((u2>>16)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+((u2>>12)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+((u2>>8)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+((u2>>4)&0xf) >= 0x10 ) return 1; - if ( d1[ind++]+(u2&0xf) >= 0x10 ) return 1; - } - return 0; - break; - case 6: - for ( i = nd_exporigin; i < nd_wpd; i++ ) { - u2 = d2[i]; - if ( d1[ind++]+((u2>>24)&0x3f) >= 0x40 ) return 1; - if ( d1[ind++]+((u2>>18)&0x3f) >= 0x40 ) return 1; - if ( d1[ind++]+((u2>>12)&0x3f) >= 0x40 ) return 1; - if ( d1[ind++]+((u2>>6)&0x3f) >= 0x40 ) return 1; - if ( d1[ind++]+(u2&0x3f) >= 0x40 ) return 1; - } - return 0; - break; - case 8: - for ( i = nd_exporigin; i < nd_wpd; i++ ) { - u2 = d2[i]; - if ( d1[ind++]+((u2>>24)&0xff) >= 0x100 ) return 1; - if ( d1[ind++]+((u2>>16)&0xff) >= 0x100 ) return 1; - if ( d1[ind++]+((u2>>8)&0xff) >= 0x100 ) return 1; - if ( d1[ind++]+(u2&0xff) >= 0x100 ) return 1; - } - return 0; - break; - case 16: - for ( i = nd_exporigin; i < nd_wpd; i++ ) { - u2 = d2[i]; - if ( d1[ind++]+((u2>>16)&0xffff) > 0x10000 ) return 1; - if ( d1[ind++]+(u2&0xffff) > 0x10000 ) return 1; - } - return 0; - break; - case 32: - for ( i = nd_exporigin; i < nd_wpd; i++ ) - if ( d1[i]+d2[i]>k)&nd_mask0) > nd_mask0 ) return 1; - } - return 0; - break; +#else + for ( i = nd_exporigin; i < nd_wpd; i++ ) { + u2 = d2[i]; + k = (nd_epw-1)*nd_bpe; + for ( j = 0; j < nd_epw; j++, k -= nd_bpe ) + if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1; } + return 0; +#endif } INLINE int ndl_hash_value(UINT *d) @@ -1135,27 +1093,6 @@ INLINE int ndl_find_reducer(UINT *dg) return -1; } -INLINE int ndl_find_reducer_direct(UINT *dg,NDV *ps,int len) -{ - NDV r; - RHist s; - int d,k,i; - - if ( Reverse ) - for ( i = len-1; i >= 0; i-- ) { - r = ps[i]; - if ( ndl_reducible(dg,HDL(r)) ) - return i; - } - else - for ( i = 0; i < len; i++ ) { - r = ps[i]; - if ( ndl_reducible(dg,HDL(r)) ) - return i; - } - return -1; -} - ND nd_merge(ND p1,ND p2) { int n,c; @@ -1207,6 +1144,7 @@ ND nd_add(int mod,ND p1,ND p2) if ( !p1 ) return p2; else if ( !p2 ) return p1; + else if ( mod == -1 ) return nd_add_sf(p1,p2); else if ( !mod ) return nd_add_q(p1,p2); else { can = 0; @@ -1294,8 +1232,55 @@ ND nd_add_q(ND p1,ND p2) } } +ND nd_add_sf(ND p1,ND p2) +{ + int n,c,can; + ND r; + NM m1,m2,mr0,mr,s; + int t; + + if ( !p1 ) return p2; + else if ( !p2 ) return p1; + else { + can = 0; + for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) { + c = DL_COMPARE(DL(m1),DL(m2)); + switch ( c ) { + case 0: + t = _addsf(CM(m1),CM(m2)); + s = m1; m1 = NEXT(m1); + if ( t ) { + can++; NEXTNM2(mr0,mr,s); CM(mr) = (t); + } else { + can += 2; FREENM(s); + } + s = m2; m2 = NEXT(m2); FREENM(s); + break; + case 1: + s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s); + break; + case -1: + s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s); + break; + } + } + if ( !mr0 ) + if ( m1 ) mr0 = m1; + else if ( m2 ) mr0 = m2; + else return 0; + else if ( m1 ) NEXT(mr) = m1; + else if ( m2 ) NEXT(mr) = m2; + else NEXT(mr) = 0; + BDY(p1) = mr0; + SG(p1) = MAX(SG(p1),SG(p2)); + LEN(p1) = LEN(p1)+LEN(p2)-can; + FREEND(p2); + return p1; + } +} + /* ret=1 : success, ret=0 : overflow */ -int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) +int nd_nf(int mod,ND g,NDV *ps,int full,NDC dn,ND *rp) { ND d; NM m,mrd,tail; @@ -1304,9 +1289,15 @@ int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) int c,c1,c2,dummy; RHist h; NDV p,red; - Q cg,cred,gcd; + Q cg,cred,gcd,tq,qq; double hmag; + if ( dn ) { + if ( mod ) + dn->m = 1; + else + dn->z = ONE; + } if ( !g ) { *rp = 0; return 1; @@ -1326,18 +1317,27 @@ int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) return 0; } p = ps[index]; - if ( mod ) { + if ( mod == -1 ) + CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g))); + else if ( mod ) { c1 = invm(HCM(p),mod); c2 = mod-HCM(g); DMAR(c1,c2,0,mod,c); CM(mul) = c; } else { igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred); chsgnq(cg,&CQ(mul)); nd_mul_c_q(d,cred); nd_mul_c_q(g,cred); + if ( dn ) { + mulq(dn->z,cred,&tq); dn->z = tq; + } } g = nd_add(mod,g,ndv_mul_nm(mod,mul,p)); sugar = MAX(sugar,SG(p)+TD(DL(mul))); if ( !mod && hmag && g && ((double)(p_mag((P)HCQ(g))) > hmag) ) { + tq = HCQ(g); nd_removecont2(d,g); + if ( dn ) { + divq(tq,HCQ(g),&qq); divq(dn->z,qq,&tq); dn->z = tq; + } hmag = ((double)p_mag((P)HCQ(g)))*nd_scale; } } else if ( !full ) { @@ -1406,7 +1406,9 @@ int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp return 0; } p = ps[index]; - if ( mod ) { + if ( mod == -1 ) + CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g))); + else if ( mod ) { c1 = invm(HCM(p),mod); c2 = mod-HCM(g); DMAR(c1,c2,0,mod,c); CM(mul) = c; } else { @@ -1457,83 +1459,6 @@ int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp } } -int nd_nf_direct(int mod,ND g,BaseSet base,int full,ND *rp) -{ - ND d; - NM m,mrd,tail; - NM mul; - NDV *ps; - int n,sugar,psugar,sugar0,stat,index,len; - int c,c1,c2; - UINT **bound; - RHist h; - NDV p,red; - Q cg,cred,gcd; - double hmag; - - if ( !g ) { - *rp = 0; - return 1; - } -#if 0 - if ( !mod ) - hmag = ((double)p_mag((P)HCQ(g)))*nd_scale; -#else - /* XXX */ - hmag = 0; -#endif - - ps = base->ps; - bound = base->bound; - len = base->len; - sugar0 = sugar = SG(g); - n = NV(g); - mul = (NM)ALLOCA(sizeof(struct oNM)+(nd_wpd-1)*sizeof(UINT)); - for ( d = 0; g; ) { - index = ndl_find_reducer_direct(HDL(g),ps,len); - if ( index >= 0 ) { - p = ps[index]; - ndl_sub(HDL(g),HDL(p),DL(mul)); - if ( ndl_check_bound2_direct(bound[index],DL(mul)) ) { - nd_free(g); nd_free(d); - return 0; - } - if ( mod ) { - c1 = invm(HCM(p),mod); c2 = mod-HCM(g); - DMAR(c1,c2,0,mod,c); CM(mul) = c; - } else { - igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred); - chsgnq(cg,&CQ(mul)); - nd_mul_c_q(d,cred); nd_mul_c_q(g,cred); - } - g = nd_add(mod,g,ndv_mul_nm(mod,mul,p)); - sugar = MAX(sugar,SG(p)+TD(DL(mul))); - if ( !mod && hmag && g && ((double)(p_mag((P)HCQ(g))) > hmag) ) { - nd_removecont2(d,g); - hmag = ((double)p_mag((P)HCQ(g)))*nd_scale; - } - } else if ( !full ) { - *rp = g; - return 1; - } else { - m = BDY(g); - if ( NEXT(m) ) { - BDY(g) = NEXT(m); NEXT(m) = 0; LEN(g)--; - } else { - FREEND(g); g = 0; - } - if ( d ) { - NEXT(tail)=m; tail=m; LEN(d)++; - } else { - MKND(n,m,1,d); tail = BDY(d); - } - } - } - if ( d ) SG(d) = sugar; - *rp = d; - return 1; -} - /* input : list of NDV, cand : list of NDV */ int ndv_check_candidate(NODE input,int obpe,int oadv,EPOS oepos,NODE cand) @@ -1542,6 +1467,7 @@ int ndv_check_candidate(NODE input,int obpe,int oadv,E ND nf,d; NDV r; NODE t,s; + union oNDC dn; ndv_setup(0,0,cand); n = length(cand); @@ -1554,14 +1480,14 @@ again: else r = (NDV)BDY(t); d = ndvtond(0,r); - stat = nd_nf(0,d,nd_ps,0,&nf); + stat = nd_nf(0,d,nd_ps,0,0,&nf); if ( !stat ) { nd_reconstruct(0,0,0); goto again; } else if ( nf ) return 0; - printf("."); fflush(stdout); + if ( DP_Print ) { printf("."); fflush(stdout); } } - printf("\n"); + if ( DP_Print ) { printf("\n"); } /* gbcheck : cand is a GB of Id(cand) ? */ if ( !nd_gb(0,1) ) return 0; /* XXX */ @@ -1582,6 +1508,24 @@ ND nd_remove_head(ND p) return p; } +ND nd_separate_head(ND p,ND *head) +{ + NM m,m0; + ND r; + + m = BDY(p); + if ( !NEXT(m) ) { + *head = p; p = 0; + } else { + m0 = m; + BDY(p) = NEXT(m); LEN(p)--; + NEXT(m0) = 0; + MKND(NV(p),m0,1,r); + *head = r; + } + return p; +} + PGeoBucket create_pbucket() { PGeoBucket g; @@ -1705,8 +1649,12 @@ int head_pbucket(int mod,PGeoBucket g) dj = HDL(gj); sum = HCM(gj); } else if ( c == 0 ) { - sum = sum+HCM(gi)-mod; - if ( sum < 0 ) sum += mod; + if ( mod == -1 ) + sum = _addsf(sum,HCM(gi)); + else { + sum = sum+HCM(gi)-mod; + if ( sum < 0 ) sum += mod; + } g->body[i] = nd_remove_head(gi); } } @@ -1784,6 +1732,7 @@ NODE nd_gb(int m,int checkonly) ND_pairs l; ND h,nf; NDV nfv; + union oNDC dn; g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { @@ -1796,7 +1745,7 @@ again: l = nd_minp(d,&d); if ( SG(l) != sugar ) { sugar = SG(l); - fprintf(asir_out,"%d",sugar); + if ( DP_Print ) fprintf(asir_out,"%d",sugar); } stat = nd_sp(m,0,l,&h); if ( !stat ) { @@ -1805,9 +1754,9 @@ again: goto again; } #if USE_GEOBUCKET - stat = m?nd_nf_pbucket(m,h,nd_ps,!Top,&nf):nd_nf(m,h,nd_ps,!Top,&nf); + stat = m?nd_nf_pbucket(m,h,nd_ps,!Top,&nf):nd_nf(m,h,nd_ps,!Top,0,&nf); #else - stat = nd_nf(m,h,nd_ps,!Top,&nf); + stat = nd_nf(m,h,nd_ps,!Top,0,&nf); #endif if ( !stat ) { NEXT(l) = d; d = l; @@ -1815,7 +1764,7 @@ again: goto again; } else if ( nf ) { if ( checkonly ) return 0; - printf("+"); fflush(stdout); + if ( DP_Print ) { printf("+"); fflush(stdout); } nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); nh = ndv_newps(nfv,0); @@ -1823,7 +1772,7 @@ again: g = update_base(g,nh); FREENDP(l); } else { - printf("."); fflush(stdout); + if ( DP_Print ) { printf("."); fflush(stdout); } FREENDP(l); } } @@ -1839,6 +1788,7 @@ NODE nd_gb_trace(int m) ND_pairs l; ND h,nf,nfq; NDV nfv,nfqv; + union oNDC dn; g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { @@ -1851,7 +1801,7 @@ again: l = nd_minp(d,&d); if ( SG(l) != sugar ) { sugar = SG(l); - fprintf(asir_out,"%d",sugar); + if ( DP_Print ) fprintf(asir_out,"%d",sugar); } stat = nd_sp(m,0,l,&h); if ( !stat ) { @@ -1862,31 +1812,33 @@ again: #if USE_GEOBUCKET stat = nd_nf_pbucket(m,h,nd_ps,!Top,&nf); #else - stat = nd_nf(m,h,nd_ps,!Top,&nf); + stat = nd_nf(m,h,nd_ps,!Top,0,&nf); #endif if ( !stat ) { NEXT(l) = d; d = l; d = nd_reconstruct(m,1,d); goto again; } else if ( nf ) { - /* overflow does not occur */ - nd_sp(0,1,l,&h); - nd_nf(0,h,nd_ps_trace,!Top,&nfq); + if ( !nd_sp(0,1,l,&h) || !nd_nf(0,h,nd_ps_trace,!Top,0,&nfq) ) { + NEXT(l) = d; d = l; + d = nd_reconstruct(m,1,d); + goto again; + } if ( nfq ) { - /* failure; m|HC(nfq) */ + /* m|HC(nfq) => failure */ if ( !rem(NM(HCQ(nfq)),m) ) return 0; - printf("+"); fflush(stdout); + if ( DP_Print ) { printf("+"); fflush(stdout); } nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); nh = ndv_newps(nfv,nfqv); d = update_pairs(d,g,nh); g = update_base(g,nh); } else { - printf("*"); fflush(stdout); + if ( DP_Print ) { printf("*"); fflush(stdout); } } } else { - printf("."); fflush(stdout); + if ( DP_Print ) { printf("."); fflush(stdout); } } FREENDP(l); } @@ -1907,56 +1859,43 @@ int ndv_compare_rev(NDV *p1,NDV *p2) NODE ndv_reduceall(int m,NODE f) { - int i,j,n,stat; - NDV *w,*ps; - ND nf,g; + int i,n,stat; + ND nf,g,head; NODE t,a0,a; - struct oBaseSet base; - UINT **bound; + union oNDC dn; + NDV *w; + Q q; - for ( n = 0, t = f; t; t = NEXT(t), n++ ); - ps = (NDV *)ALLOCA(n*sizeof(NDV)); - bound = (UINT **)ALLOCA(n*sizeof(UINT *)); - for ( i = 0, t = f; i < n; i++, t = NEXT(t) ) ps[i] = (NDV)BDY(t); - qsort(ps,n,sizeof(NDV),(int (*)(const void *,const void *))ndv_compare); - for ( i = 0; i < n; i++ ) bound[i] = ndv_compute_bound(ps[i]); - base.ps = (NDV *)ALLOCA((n-1)*sizeof(NDV)); - base.bound = (UINT **)ALLOCA((n-1)*sizeof(UINT *)); - base.len = n-1; - i = 0; - while ( i < n ) { - for ( j = 0; j < i; j++ ) { - base.ps[j] = ps[j]; base.bound[j] = bound[j]; - } - for ( j = i+1; j < n; j++ ) { - base.ps[j-1] = ps[j]; base.bound[j-1] = bound[j]; - } - g = ndvtond(m,ps[i]); - stat = nd_nf_direct(m,g,&base,1,&nf); + 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); + for ( i = 0; i < n; ) { + g = ndvtond(m,nd_ps[i]); + g = nd_separate_head(g,&head); + stat = nd_nf(m,g,nd_ps,1,&dn,&nf); if ( !stat ) - nd_reconstruct_direct(m,ps,n); - else if ( !nf ) { - printf("."); fflush(stdout); - ndv_free(ps[i]); - for ( j = i+1; j < n; j++ ) { - ps[j-1] = ps[j]; bound[j-1] = bound[j]; - } - n--; - base.len = n-1; - } else { - printf("."); fflush(stdout); - ndv_free(ps[i]); + nd_reconstruct(m,0,0); + else { + if ( DP_Print ) { printf("."); fflush(stdout); } + if ( !m ) { mulq(HCQ(head),dn.z,&q); HCQ(head) = q; } + nf = nd_add(m,head,nf); + ndv_free(nd_ps[i]); nd_removecont(m,nf); - ps[i] = ndtondv(m,nf); - bound[i] = ndv_compute_bound(ps[i]); - nd_free(nf); + nd_ps[i] = ndtondv(m,nf); nd_free(nf); + nd_bound[i] = ndv_compute_bound(nd_ps[i]); i++; } } - printf("\n"); + if ( DP_Print ) { printf("\n"); } for ( a0 = 0, i = 0; i < n; i++ ) { NEXTNODE(a0,a); - BDY(a) = (pointer)ps[i]; + BDY(a) = (pointer)nd_ps[i]; } NEXT(a) = 0; return a0; @@ -2202,17 +2141,18 @@ ND_pairs nd_minp( ND_pairs d, ND_pairs *prest ) ND_pairs nd_minsugarp( ND_pairs d, ND_pairs *prest ) { - int msugar; + int msugar,i; ND_pairs t,dm0,dm,dr0,dr; for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) ) if ( SG(t) < msugar ) msugar = SG(t); dm0 = 0; dr0 = 0; - for ( t = d; t; t = NEXT(t) ) - if ( SG(t) == msugar ) { + for ( i = 0, t = d; t; t = NEXT(t) ) + if ( i < nd_f4_nsp && SG(t) == msugar ) { if ( dm0 ) NEXT(dm) = t; else dm0 = t; dm = t; + i++; } else { if ( dr0 ) NEXT(dr) = t; else dr0 = t; @@ -2257,11 +2197,17 @@ void ndv_setup(int mod,int trace,NODE f) NODE s,s0,f0; UINT *d; RHist r; + NDV *w; NDV a,am; nd_found = 0; nd_notfirst = 0; nd_create = 0; - nd_psn = length(f); nd_pslen = 2*nd_psn; + 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); + qsort(w,nd_psn,sizeof(NDV), + (int (*)(const void *,const void *))ndv_compare); + nd_pslen = 2*nd_psn; nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist)); @@ -2269,18 +2215,16 @@ void ndv_setup(int mod,int trace,NODE f) if ( !nd_red ) nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist)); - bzero(nd_red,REDTAB_LEN*sizeof(RHist)); - nd_free_private_storage(); - for ( i = 0; i < nd_psn; i++, f = NEXT(f) ) { + for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0; + for ( i = 0; i < nd_psn; i++ ) { if ( trace ) { - a = nd_ps_trace[i] = ndv_dup(0,(NDV)BDY(f)); + a = nd_ps_trace[i] = ndv_dup(0,w[i]); ndv_removecont(0,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,(NDV)BDY(f)); - if ( mod ) ndv_mod(mod,a); + a = nd_ps[i] = ndv_dup(mod,w[i]); ndv_removecont(mod,a); } NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r)); @@ -2294,8 +2238,9 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe VL tv,fv,vv,vc; NODE fd,fd0,r,r0,t,x,s,xx; int e,max,nvar; - ND b; + NDV b; + nd_free_private_storage(); get_vars((Obj)f,&fv); pltovl(v,&vv); nvar = length(vv); nd_init_ord(ord); @@ -2307,6 +2252,7 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe nd_setup_parameters(nvar,max); for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { b = (pointer)ptondv(CO,vv,(P)BDY(t)); + if ( m ) ndv_mod(m,b); if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; } } if ( fd0 ) NEXT(fd) = 0; @@ -2339,6 +2285,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,stru nocheck = 0; mindex = 0; + nd_free_private_storage(); /* setup modulus */ if ( trace < 0 ) { trace = -trace; @@ -2496,7 +2443,8 @@ void nd_print(ND p) printf("0\n"); else { for ( m = BDY(p); m; m = NEXT(m) ) { - printf("+%d*",CM(m)); + if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m))); + else printf("+%d*",CM(m)); ndl_print(DL(m)); } printf("\n"); @@ -2537,7 +2485,8 @@ void nd_removecont(int mod,ND p) struct oVECT v; N q,r; - if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod)); + if ( mod == -1 ) nd_mul_c(mod,p,_invsf(HCM(p))); + else if ( mod ) nd_mul_c(mod,p,invm(HCM(p),mod)); else { for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ ); w = (Q *)ALLOCA(n*sizeof(Q)); @@ -2583,7 +2532,9 @@ void ndv_removecont(int mod,NDV p) Q dvr,t; NMV m; - if ( mod ) + if ( mod == -1 ) + ndv_mul_c(mod,p,_invsf(HCM(p))); + else if ( mod ) ndv_mul_c(mod,p,invm(HCM(p),mod)); else { len = p->len; @@ -2684,11 +2635,13 @@ void nd_mul_c(int mod,ND p,int mul) int c,c1; if ( !p ) return; - for ( m = BDY(p); m; m = NEXT(m) ) { - c1 = CM(m); - DMAR(c1,mul,0,mod,c); - CM(m) = c; - } + if ( mod == -1 ) + for ( m = BDY(p); m; m = NEXT(m) ) + CM(m) = _mulsf(CM(m),mul); + else + for ( m = BDY(p); m; m = NEXT(m) ) { + c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c; + } } void nd_mul_c_q(ND p,Q mul) @@ -2834,11 +2787,12 @@ void nd_setup_parameters(int nvar,int max) { ND_pairs nd_reconstruct(int mod,int trace,ND_pairs d) { int i,obpe,oadv,h; - NM prev_nm_free_list; + static NM prev_nm_free_list; + static ND_pairs prev_ndp_free_list; RHist mr0,mr; RHist r; RHist *old_red; - ND_pairs s0,s,t,prev_ndp_free_list; + ND_pairs s0,s,t; EPOS oepos; obpe = nd_bpe; @@ -2898,45 +2852,12 @@ ND_pairs nd_reconstruct(int mod,int trace,ND_pairs d) if ( s0 ) NEXT(s) = 0; prev_nm_free_list = 0; prev_ndp_free_list = 0; +#if 0 GC_gcollect(); +#endif return s0; } -void nd_reconstruct_direct(int mod,NDV *ps,int len) -{ - int i,obpe,oadv,h; - UINT **bound; - NM prev_nm_free_list; - RHist mr0,mr; - RHist r; - RHist *old_red; - ND_pairs s0,s,t,prev_ndp_free_list; - EPOS oepos; - - obpe = nd_bpe; - oadv = nmv_adv; - oepos = nd_epos; - if ( obpe < 2 ) nd_bpe = 2; - else if ( obpe < 3 ) nd_bpe = 3; - else if ( obpe < 4 ) nd_bpe = 4; - else if ( obpe < 5 ) nd_bpe = 5; - else if ( obpe < 6 ) nd_bpe = 6; - else if ( obpe < 8 ) nd_bpe = 8; - else if ( obpe < 10 ) nd_bpe = 10; - else if ( obpe < 16 ) nd_bpe = 16; - else if ( obpe < 32 ) nd_bpe = 32; - else error("nd_reconstruct_direct : exponent too large"); - - nd_setup_parameters(0,0); - prev_nm_free_list = _nm_free_list; - prev_ndp_free_list = _ndp_free_list; - _nm_free_list = 0; _ndp_free_list = 0; - for ( i = len-1; i >= 0; i-- ) ndv_realloc(ps[i],obpe,oadv,oepos); - prev_nm_free_list = 0; - prev_ndp_free_list = 0; - GC_gcollect(); -} - void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos) { int n,i,ei,oepw,omask0,j,s,ord_l,l; @@ -3008,7 +2929,8 @@ int nd_sp(int mod,int trace,ND_pairs p,ND *rp) if ( ndl_check_bound2(p->i1,DL(m)) ) return 0; t1 = ndv_mul_nm(mod,m,p1); - if ( mod ) CM(m) = mod-HCM(p1); + if ( mod == -1 ) CM(m) = _chsgnsf(HCM(p1)); + else if ( mod ) CM(m) = mod-HCM(p1); else chsgnq(HCQ(p1),&CQ(m)); ndl_sub(lcm,HDL(p2),DL(m)); if ( ndl_check_bound2(p->i2,DL(m)) ) { @@ -3028,9 +2950,13 @@ void ndv_mul_c(int mod,NDV p,int mul) if ( !p ) return; len = LEN(p); - for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) { - c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c; - } + if ( mod == -1 ) + for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) + CM(m) = _mulsf(CM(m),mul); + else + for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) { + c1 = CM(m); DMAR(c1,mul,0,mod,c); CM(m) = c; + } } void ndv_mul_c_q(NDV p,Q mul) @@ -3220,17 +3146,27 @@ ND ndv_mul_nm(int mod,NM m0,NDV p) if ( !p ) return 0; else if ( do_weyl ) - return weyl_ndv_mul_nm(mod,m0,p); + if ( mod == -1 ) + error("ndv_mul_nm : not implemented (weyl)"); + else + return weyl_ndv_mul_nm(mod,m0,p); else { n = NV(p); m = BDY(p); d = DL(m0); len = LEN(p); mr0 = 0; td = TD(d); - if ( mod ) { + if ( mod == -1 ) { c = CM(m0); for ( i = 0; i < len; i++, NMV_ADV(m) ) { NEXTNM(mr0,mr); + CM(mr) = _mulsf(CM(m),c); + ndl_add(DL(m),d,DL(mr)); + } + } else if ( mod ) { + c = CM(m0); + for ( i = 0; i < len; i++, NMV_ADV(m) ) { + NEXTNM(mr0,mr); c1 = CM(m); DMAR(c1,c,0,mod,c2); CM(mr) = c2; @@ -3335,21 +3271,32 @@ void ndv_mod(int mod,NDV p) NMV t,d; int r; int i,len,dlen; + Obj gfs; if ( !p ) return; len = LEN(p); dlen = 0; - for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) { - r = rem(NM(CQ(t)),mod); - if ( r ) { - if ( SGN(CQ(t)) < 0 ) - r = mod-r; + if ( mod == -1 ) + for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) { + simp_ff((Obj)CP(t),&gfs); + r = FTOIF(CONT((GFS)gfs)); CM(d) = r; ndl_copy(DL(t),DL(d)); NMV_ADV(d); dlen++; } - } + else + for ( t = d = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) { + r = rem(NM(CQ(t)),mod); + if ( r ) { + if ( SGN(CQ(t)) < 0 ) + r = mod-r; + CM(d) = r; + ndl_copy(DL(t),DL(d)); + NMV_ADV(d); + dlen++; + } + } LEN(p) = dlen; } @@ -3424,6 +3371,7 @@ P ndvtop(int mod,VL vl,VL dvl,NDV p) P c; UINT *d; P s,r,u,t,w; + GFS gfs; if ( !p ) return 0; else { @@ -3431,7 +3379,9 @@ P ndvtop(int mod,VL vl,VL dvl,NDV p) n = NV(p); m = (NMV)(((char *)BDY(p))+nmv_adv*(len-1)); for ( j = len-1, s = 0; j >= 0; j--, NMV_PREV(m) ) { - if ( mod ) { + if ( mod == -1 ) { + e = IFTOF(CM(m)); MKGFS(e,gfs); c = (P)gfs; + } else if ( mod ) { STOQ(CM(m),q); c = (P)q; } else c = CP(m); @@ -3495,7 +3445,8 @@ void ndv_print(NDV p) else { len = LEN(p); for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) { - printf("+%d*",CM(m)); + if ( CM(m) & 0x80000000 ) printf("+@_%d*",IFTOF(CM(m))); + else printf("+%d*",CM(m)); ndl_print(DL(m)); } printf("\n"); @@ -3664,6 +3615,7 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec NDV ndv; VL vv,tv; int stat,nvar,max,e; + union oNDC dn; pltovl(v,&vv); nvar = length(vv); @@ -3686,9 +3638,11 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) { NEXTNODE(in0,in); BDY(in) = (pointer)ptondv(CO,vv,(P)BDY(t)); + 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; ndv_setup(m,0,in0); @@ -3696,7 +3650,7 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec nd_scale=2; while ( 1 ) { nd = (pointer)ndvtond(m,nd_ps[nd_psn]); - stat = nd_nf(m,nd,nd_ps,1,&nf); + stat = nd_nf(m,nd,nd_ps,1,0,&nf); if ( !stat ) { nd_psn++; nd_reconstruct(m,0,0); @@ -3746,48 +3700,219 @@ int nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_ return i; } -void nm_ind_pair_to_vect_compress(int mod,UINT *s0,int n,NM_ind_pair pair,UINT *r,int *ind) +IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0,int n,NM_ind_pair pair) { NM m; NMV mr; UINT *d,*t,*s; NDV p; - int i,j,len; + unsigned char *ivc; + unsigned short *ivs; + UINT *v,*ivi; + int i,j,len,prev,diff,cdiff; + IndArray r; m = pair->mul; d = DL(m); p = nd_ps[pair->index]; len = LEN(p); t = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); + r = (IndArray)MALLOC(sizeof(struct oIndArray)); + v = (unsigned int *)ALLOCA(len*sizeof(unsigned int)); 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++ ); - r[j] = CM(mr); - ind[j] = i; + v[j] = i; } + r->head = v[0]; + diff = 0; + for ( i = 1; i < len; i++ ) { + cdiff = v[i]-v[i-1]; diff = MAX(cdiff,diff); + } + if ( diff < 256 ) { + r->width = 1; + ivc = (unsigned char *)MALLOC_ATOMIC(len*sizeof(unsigned char)); + r->index.c = ivc; + for ( i = 1, ivc[0] = 0; i < len; i++ ) ivc[i] = v[i]-v[i-1]; + } else if ( diff < 65536 ) { + r->width = 2; + ivs = (unsigned short *)MALLOC_ATOMIC(len*sizeof(unsigned short)); + r->index.s = ivs; + for ( i = 1, ivs[0] = 0; i < len; i++ ) ivs[i] = v[i]-v[i-1]; + } else { + r->width = 4; + ivi = (unsigned int *)MALLOC_ATOMIC(len*sizeof(unsigned int)); + r->index.i = ivi; + for ( i = 1, ivi[0] = 0; i < len; i++ ) ivi[i] = v[i]-v[i-1]; + } + return r; } + +void ndv_reduce_vect(int m,UINT *svect,int col,IndArray *imat,NODE rp0) +{ + int i,j,k,len,pos,prev; + UINT c,c1,c2,c3,up,lo,dmy; + IndArray ivect; + unsigned char *ivc; + unsigned short *ivs; + unsigned int *ivi; + NDV redv; + NMV mr; + NODE rp; + + for ( rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) { + ivect = imat[i]; + k = ivect->head; svect[k] %= m; + if ( c = svect[k] ) { + c = m-c; redv = nd_ps[((NM_ind_pair)BDY(rp))->index]; + len = LEN(redv); mr = BDY(redv); + svect[k] = 0; prev = k; + switch ( ivect->width ) { + case 1: + ivc = ivect->index.c; + for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { + pos = prev+ivc[j]; c1 = CM(mr); c2 = svect[pos]; + prev = pos; + DMA(c1,c,c2,up,lo); + if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3; + } else svect[pos] = lo; + } + break; + case 2: + ivs = ivect->index.s; + for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { + pos = prev+ivs[j]; c1 = CM(mr); c2 = svect[pos]; + prev = pos; + DMA(c1,c,c2,up,lo); + if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3; + } else svect[pos] = lo; + } + break; + case 4: + ivi = ivect->index.i; + for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { + pos = prev+ivi[j]; c1 = CM(mr); c2 = svect[pos]; + prev = pos; + DMA(c1,c,c2,up,lo); + if ( up ) { DSAB(m,up,lo,dmy,c3); svect[pos] = c3; + } else svect[pos] = lo; + } + break; + } + } + } + for ( i = 0; i < col; i++ ) + if ( svect[i] >= (UINT)m ) svect[i] %= m; +} + +NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhead,UINT *s0vect) +{ + int j,k,len; + UINT *p; + UINT c; + NDV r; + NMV mr0,mr; + + for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++; + if ( !len ) return 0; + else { + mr0 = (NMV)MALLOC_ATOMIC(nmv_adv*len); + mr = mr0; + p = s0vect; + for ( j = k = 0; j < col; j++, p += nd_wpd ) + if ( !rhead[j] ) { + if ( c = vect[k++] ) { + ndl_copy(p,DL(mr)); CM(mr) = c; NMV_ADV(mr); + } + } + MKNDV(nd_nvar,mr0,len,r); + return r; + } +} + +int nd_sp_f4(int m,ND_pairs l,PGeoBucket bucket,NODE *s) +{ + ND_pairs t; + NODE sp0,sp; + int stat; + ND spol; + + sp0 = 0; + for ( t = l; t; t = NEXT(t) ) { + stat = nd_sp(m,0,t,&spol); + if ( !stat ) return 0; + if ( spol ) { + NEXTNODE(sp0,sp); BDY(sp) = (pointer)nd_dup(spol); + add_pbucket_symbolic(bucket,spol); + } + } + *s = sp0; + return 1; +} + +int nd_symbolic_preproc(PGeoBucket bucket,UINT **s0vect,NODE *r) +{ + NODE rp0,rp; + NM mul,head,s0,s; + int index,col,i; + RHist h; + UINT *s0v,*p; + NM_ind_pair pair; + ND red; + + s0 = 0; rp0 = 0; col = 0; + while ( 1 ) { + head = remove_head_pbucket_symbolic(bucket); + if ( !head ) break; + if ( !s0 ) s0 = head; + else NEXT(s) = head; + s = head; + index = ndl_find_reducer(DL(head)); + if ( index >= 0 ) { + h = nd_psh[index]; + NEWNM(mul); + ndl_sub(DL(head),DL(h),DL(mul)); + if ( ndl_check_bound2(index,DL(mul)) ) return 0; + MKNM_ind_pair(pair,mul,index); + red = ndv_mul_nm_symbolic(mul,nd_ps[index]); + add_pbucket_symbolic(bucket,nd_remove_head(red)); + NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair; + } + col++; + } + NEXT(rp) = 0; NEXT(s) = 0; + s0v = (UINT *)MALLOC_ATOMIC(col*nd_wpd*sizeof(UINT)); + for ( i = 0, p = s0v, s = s0; i < col; + i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p); + *s0vect = s0v; + *r = rp0; + return col; +} + +#if 0 NODE nd_f4(int m) { int i,nh,stat,index; NODE r,g; ND_pairs d,l,t; ND spol,red; - NDV nf; - NM_ind_pair pair,pair1,pair2; + NDV nf,redv; NM s0,s; NODE sp0,sp,rp0,rp; - RHist h; - int nsp,nred,col,rank,len,k,j; - NMV mr0,mr; - UINT c,c1,c2,c3; - NM mul,head; - UINT **spmat; - UINT *s0vect,*rvect,*svect,*p,*ivect; + int nsp,nred,col,rank,len,k,j,a; + UINT c; + UINT *s0vect,*svect,*p,*v; int *colstat; - int sugar,pos; + IndArray *imat; + int *rhead; + int spcol,sprow; + int sugar; PGeoBucket bucket; - int t_0,t_1,t_2,t_3,t_4,t_5,t_c,t_e,t_20,t_21; + struct oEGT eg0,eg1,eg_f4; + static UINT **spmat; + static UINT *spb; + static int spblen; if ( !m ) error("nd_f4 : not implemented"); @@ -3797,121 +3922,193 @@ NODE nd_f4(int m) d = update_pairs(d,g,i); g = update_base(g,i); } + if ( !spmat ) { + spmat = (UINT **)MALLOC(nd_f4_nsp*sizeof(UINT *)); + spblen = 10000; + spb = (UINT *)MALLOC_ATOMIC(nd_f4_nsp*spblen*sizeof(UINT)); + } while ( d ) { + get_eg(&eg0); l = nd_minsugarp(d,&d); sugar = SG(l); - sp0 = 0; bucket = create_pbucket(); - t_0 = clock(); - for ( t = l, nsp = 0; t; t = NEXT(t) ) { - stat = nd_sp(m,0,t,&spol); - if ( !stat ) goto again; - if ( spol ) { - NEXTNODE(sp0,sp); BDY(sp) = (pointer)nd_dup(spol); - add_pbucket_symbolic(bucket,spol); - nsp++; - } + stat = nd_sp_f4(m,l,bucket,&sp0); + if ( !stat ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(m,0,d); + continue; } - if ( sp0 ) NEXT(sp) = 0; - s0 = 0; - rp0 = 0; - while ( 1 ) { - head = remove_head_pbucket_symbolic(bucket); - if ( !head ) break; - if ( !s0 ) s0 = head; - else NEXT(s) = head; - s = head; - index = ndl_find_reducer(DL(head)); - if ( index >= 0 ) { - h = nd_psh[index]; - NEWNM(mul); - ndl_sub(DL(head),DL(h),DL(mul)); - if ( ndl_check_bound2(index,DL(mul)) ) goto again; - MKNM_ind_pair(pair,mul,index); - red = ndv_mul_nm_symbolic(mul,nd_ps[index]); - add_pbucket_symbolic(bucket,nd_remove_head(red)); - NEXTNODE(rp0,rp); BDY(rp) = (pointer)pair; - nred++; - } + if ( !sp0 ) continue; + col = nd_symbolic_preproc(bucket,&s0vect,&rp0); + if ( !col ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(m,0,d); + continue; } - t_1 = clock(); - if ( s0 ) NEXT(s) = 0; - for ( i = 0, s = s0; s; s = NEXT(s), i++ ); - col = i; - s0vect = (UINT *)MALLOC(col*nd_wpd*sizeof(UINT)); - for ( i = 0, p = s0vect, s = s0; i < col; - i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p); - spmat = (UINT **)MALLOC(nsp*sizeof(UINT *)); - for ( i = 0, sp = sp0; i < nsp; i++, sp = NEXT(sp) ) { - spmat[i] = (UINT *)MALLOC(col*sizeof(UINT)); - nd_to_vect(m,s0vect,col,BDY(sp),spmat[i]); + + nsp = length(sp0); nred = length(rp0); spcol = col-nred; + imat = (IndArray *)MALLOC(nred*sizeof(IndArray)); + rhead = (int *)MALLOC_ATOMIC(col*sizeof(int)); + for ( i = 0; i < col; i++ ) rhead[i] = 0; + + /* construction of index arrays */ + for ( rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) { + imat[i] = nm_ind_pair_to_vect_compress(m,s0vect,col,(NM_ind_pair)BDY(rp)); + rhead[imat[i]->head] = 1; } - t_2 = clock(); - t_c = 0; - t_e = 0; - rvect = (UINT *)ALLOCA(col*sizeof(UINT)); - ivect = (int *)ALLOCA(col*sizeof(int)); - for ( rp = rp0; rp; rp = NEXT(rp) ) { - t_20 = clock(); - nm_ind_pair_to_vect_compress(m,s0vect,col,(NM_ind_pair)BDY(rp),rvect,ivect); - t_21 = clock(); - t_c += t_21-t_20; - k = ivect[0]; - len = LEN(nd_ps[((NM_ind_pair)BDY(rp))->index]); - for ( i = 0; i < nsp; i++ ) { - svect = spmat[i]; - if ( c = svect[k] ) - for ( j = 0; j < len; j++ ) { - pos = ivect[j]; - c1 = m-rvect[j]; - c2 = svect[pos]; DMAR(c1,c,c2,m,c3); - svect[pos] = c3; - } + + /* elimination (1st step) */ + svect = (UINT *)MALLOC_ATOMIC(col*sizeof(UINT)); + if ( spcol > spblen ) { + spblen = spcol; + spb = REALLOC(spb,spblen*nd_f4_nsp*sizeof(UINT)); + } + + for ( a = sprow = 0, sp = sp0, p = spb; a < nsp; a++, sp = NEXT(sp) ) { + nd_to_vect(m,s0vect,col,BDY(sp),svect); + ndv_reduce_vect(m,svect,col,imat,rp0); + for ( i = 0; i < col; i++ ) if ( svect[i] ) break; + if ( i < col ) { + spmat[sprow] = p; + v = spmat[sprow]; + for ( j = k = 0; j < col; j++ ) + if ( !rhead[j] ) v[k++] = svect[j]; + sprow++; + p += k; } - t_e += clock()-t_21; } - t_4 = clock(); - colstat = (int *)ALLOCA(col*sizeof(int)); - rank = generic_gauss_elim_mod(spmat,nsp,col,m,colstat); - t_5 = clock(); - fprintf(asir_out,"sugar=%d,rank=%d ",sugar,rank); - fprintf(asir_out,"symb=%f,conv1=%f,conv2=%f,elim1=%f,elim2=%f\n", - (t_1-t_0)/(double)CLOCKS_PER_SEC, - (t_2-t_1)/(double)CLOCKS_PER_SEC, - (t_c)/(double)CLOCKS_PER_SEC, - (t_e)/(double)CLOCKS_PER_SEC, - (t_5-t_4)/(double)CLOCKS_PER_SEC); - if ( rank ) - for ( j = 0, i = 0; j < col; j++ ) { - if ( colstat[j] ) { - for ( k = j, len = 0; k < col; k++ ) - if ( spmat[i][k] ) len++; - mr0 = (NMV)MALLOC_ATOMIC(nmv_adv*len); - mr = mr0; - p = s0vect+nd_wpd*j; - for ( k = j; k < col; k++, p += nd_wpd ) - if ( spmat[i][k] ) { - ndl_copy(p,DL(mr)); - CM(mr) = spmat[i][k]; - NMV_ADV(mr); - } - MKNDV(nd_nvar,mr0,len,nf); - SG(nf) = sugar; - ndv_removecont(m,nf); - nh = ndv_newps(nf,0); - d = update_pairs(d,g,nh); - g = update_base(g,nh); - i++; - } + /* free index arrays */ + for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); + + /* elimination (2nd step) */ + colstat = (int *)ALLOCA(spcol*sizeof(int)); + rank = generic_gauss_elim_mod(spmat,sprow,spcol,m,colstat); + + get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); + if ( DP_Print ) { + fprintf(asir_out,"sugar=%d,nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ", + sugar,nsp,nred,sprow,spcol,rank); + fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime); + } + + /* adding new bases */ + for ( i = 0; i < rank; i++ ) { + nf = vect_to_ndv(spmat[i],spcol,col,rhead,s0vect); + SG(nf) = sugar; + ndv_removecont(m,nf); + nh = ndv_newps(nf,0); + d = update_pairs(d,g,nh); + g = update_base(g,nh); + } + } + for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps[(int)BDY(r)]; + return g; +} +#else +NODE nd_f4(int m) +{ + int i,nh,stat,index; + NODE r,g; + ND_pairs d,l,t; + ND spol,red; + NDV nf,redv; + NM s0,s; + NODE sp0,sp,rp0,rp; + 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; + + if ( !m ) + error("nd_f4 : not implemented"); + + 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,l,bucket,&sp0); + if ( !stat ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(m,0,d); + continue; + } + if ( !sp0 ) continue; + col = nd_symbolic_preproc(bucket,&s0vect,&rp0); + if ( !col ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(m,0,d); + continue; + } + + nsp = length(sp0); nred = length(rp0); spcol = col-nred; + imat = (IndArray *)MALLOC(nred*sizeof(IndArray)); + rhead = (int *)MALLOC_ATOMIC(col*sizeof(int)); + for ( i = 0; i < col; i++ ) rhead[i] = 0; + + /* construction of index arrays */ + for ( rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) { + imat[i] = nm_ind_pair_to_vect_compress(m,s0vect,col,(NM_ind_pair)BDY(rp)); + rhead[imat[i]->head] = 1; + } + + /* elimination (1st step) */ + spmat = (UINT **)MALLOC(nsp*sizeof(UINT *)); + svect = (UINT *)MALLOC_ATOMIC(col*sizeof(UINT)); + for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) { + nd_to_vect(m,s0vect,col,BDY(sp),svect); + ndv_reduce_vect(m,svect,col,imat,rp0); + for ( i = 0; i < col; i++ ) if ( svect[i] ) break; + if ( i < col ) { + spmat[sprow] = v = (UINT *)MALLOC_ATOMIC(spcol*sizeof(UINT)); + for ( j = k = 0; j < col; j++ ) + if ( !rhead[j] ) v[k++] = svect[j]; + sprow++; } - continue; + } + /* free index arrays */ + for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); -again: - for ( t = l; NEXT(t); t = NEXT(t) ); - NEXT(t) = d; d = l; - d = nd_reconstruct(m,0,d); - NEWNM(mul); + /* elimination (2nd step) */ + colstat = (int *)ALLOCA(spcol*sizeof(int)); + rank = generic_gauss_elim_mod(spmat,sprow,spcol,m,colstat); + + get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); + if ( DP_Print ) { + fprintf(asir_out,"sugar=%d,nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ", + sugar,nsp,nred,sprow,spcol,rank); + fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime); + } + + /* adding new bases */ + for ( i = 0; i < rank; i++ ) { + nf = vect_to_ndv(spmat[i],spcol,col,rhead,s0vect); + SG(nf) = sugar; + ndv_removecont(m,nf); + nh = ndv_newps(nf,0); + d = update_pairs(d,g,nh); + g = update_base(g,nh); + GC_free(spmat[i]); + } + for ( ; i < sprow; i++ ) GC_free(spmat[i]); } for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps[(int)BDY(r)]; return g; } +#endif