version 1.64, 2003/09/12 01:12:40 |
version 1.69, 2003/09/15 09:49:44 |
|
|
/* $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.68 2003/09/12 15:07:11 noro Exp $ */ |
|
|
#include "ca.h" |
#include "ca.h" |
#include "inline.h" |
#include "inline.h" |
|
|
typedef unsigned int UINT; |
typedef unsigned int UINT; |
|
|
#define USE_GEOBUCKET 1 |
#define USE_GEOBUCKET 1 |
|
#define USE_UNROLL 1 |
|
|
#define REDTAB_LEN 32003 |
#define REDTAB_LEN 32003 |
|
|
Line 41 typedef struct oNDV { |
|
Line 42 typedef struct oNDV { |
|
int sugar; |
int sugar; |
} *NDV; |
} *NDV; |
|
|
|
typedef union oNDC { |
|
int m; |
|
Q z; |
|
P p; |
|
} *NDC; |
|
|
/* monomial; linked list rep. */ |
/* monomial; linked list rep. */ |
typedef struct oNM { |
typedef struct oNM { |
struct oNM *next; |
struct oNM *next; |
union { |
union oNDC c; |
int m; |
|
Q z; |
|
P p; |
|
} c; |
|
UINT dl[1]; |
UINT dl[1]; |
} *NM; |
} *NM; |
|
|
/* monomial; array rep. */ |
/* monomial; array rep. */ |
typedef struct oNMV { |
typedef struct oNMV { |
union { |
union oNDC c; |
int m; |
|
Q z; |
|
P p; |
|
} c; |
|
UINT dl[1]; |
UINT dl[1]; |
} *NMV; |
} *NMV; |
|
|
Line 102 typedef struct oNM_ind_pair |
|
Line 101 typedef struct oNM_ind_pair |
|
int index; |
int index; |
} *NM_ind_pair; |
} *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); |
int (*ndl_compare_function)(UINT *a1,UINT *a2); |
|
|
|
static int nd_f4_nsp=0x7fffffff; |
static double nd_scale=2; |
static double nd_scale=2; |
static UINT **nd_bound; |
static UINT **nd_bound; |
static struct order_spec *nd_ord; |
static struct order_spec *nd_ord; |
Line 273 INLINE int ndl_hash_value(UINT *d); |
|
Line 283 INLINE int ndl_hash_value(UINT *d); |
|
|
|
/* normal forms */ |
/* normal forms */ |
INLINE int ndl_find_reducer(UINT *g); |
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_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_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 */ |
/* finalizers */ |
NODE ndv_reducebase(NODE x); |
NODE ndv_reducebase(NODE x); |
Line 300 void ndp_print(ND_pairs d); |
|
Line 308 void ndp_print(ND_pairs d); |
|
/* setup, reconstruct */ |
/* setup, reconstruct */ |
void nd_init_ord(struct order_spec *spec); |
void nd_init_ord(struct order_spec *spec); |
ND_pairs nd_reconstruct(int mod,int trace,ND_pairs ndp); |
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 ndv_setup(int mod,int trace,NODE f); |
void nd_setup_parameters(int nvar,int max); |
void nd_setup_parameters(int nvar,int max); |
BlockMask nd_create_blockmask(struct order_spec *ord); |
BlockMask nd_create_blockmask(struct order_spec *ord); |
Line 316 void nd_mul_c(int mod,ND p,int mul); |
|
Line 323 void nd_mul_c(int mod,ND p,int mul); |
|
void nd_mul_c_q(ND p,Q mul); |
void nd_mul_c_q(ND p,Q mul); |
void nd_mul_c_p(VL vl,ND p,P mul); |
void nd_mul_c_p(VL vl,ND p,P mul); |
ND nd_remove_head(ND p); |
ND nd_remove_head(ND p); |
|
ND nd_separate_head(ND p,ND *head); |
int nd_length(ND p); |
int nd_length(ND p); |
void nd_append_red(UINT *d,int i); |
void nd_append_red(UINT *d,int i); |
UINT *ndv_compute_bound(NDV p); |
UINT *ndv_compute_bound(NDV p); |
Line 348 P ndvtop(int mod,VL vl,VL dvl,NDV p); |
|
Line 356 P ndvtop(int mod,VL vl,VL dvl,NDV p); |
|
NDV ndtondv(int mod,ND p); |
NDV ndtondv(int mod,ND p); |
ND ndvtond(int mod,NDV 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); |
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); |
int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r); |
|
|
void nd_free_private_storage() |
void nd_free_private_storage() |
Line 413 INLINE int ndl_reducible(UINT *d1,UINT *d2) |
|
Line 421 INLINE int ndl_reducible(UINT *d1,UINT *d2) |
|
int i,j; |
int i,j; |
|
|
if ( TD(d1) < TD(d2) ) return 0; |
if ( TD(d1) < TD(d2) ) return 0; |
|
#if USE_UNROLL |
switch ( nd_bpe ) { |
switch ( nd_bpe ) { |
#if 0 |
|
case 3: |
case 3: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u1 = d1[i]; u2 = d2[i]; |
u1 = d1[i]; u2 = d2[i]; |
Line 479 INLINE int ndl_reducible(UINT *d1,UINT *d2) |
|
Line 487 INLINE int ndl_reducible(UINT *d1,UINT *d2) |
|
if ( d1[i] < d2[i] ) return 0; |
if ( d1[i] < d2[i] ) return 0; |
return 1; |
return 1; |
break; |
break; |
#endif |
|
default: |
default: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u1 = d1[i]; u2 = d2[i]; |
u1 = d1[i]; u2 = d2[i]; |
Line 488 INLINE int ndl_reducible(UINT *d1,UINT *d2) |
|
Line 495 INLINE int ndl_reducible(UINT *d1,UINT *d2) |
|
} |
} |
return 1; |
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 |
} |
} |
|
|
/* |
/* |
Line 555 void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) |
|
Line 570 void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) |
|
UINT t1,t2,u,u1,u2; |
UINT t1,t2,u,u1,u2; |
int i,j,l; |
int i,j,l; |
|
|
|
#if USE_UNROLL |
switch ( nd_bpe ) { |
switch ( nd_bpe ) { |
#if 0 |
|
case 3: |
case 3: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u1 = d1[i]; u2 = d2[i]; |
u1 = d1[i]; u2 = d2[i]; |
Line 622 void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) |
|
Line 637 void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) |
|
d[i] = u1>u2?u1:u2; |
d[i] = u1>u2?u1:u2; |
} |
} |
break; |
break; |
#endif |
|
default: |
default: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u1 = d1[i]; u2 = d2[i]; |
u1 = d1[i]; u2 = d2[i]; |
Line 633 void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) |
|
Line 647 void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) |
|
} |
} |
break; |
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); |
TD(d) = ndl_weight(d); |
if ( nd_blockmask ) ndl_weight_mask(d); |
if ( nd_blockmask ) ndl_weight_mask(d); |
} |
} |
Line 838 int ndl_disjoint(UINT *d1,UINT *d2) |
|
Line 861 int ndl_disjoint(UINT *d1,UINT *d2) |
|
UINT t1,t2,u,u1,u2; |
UINT t1,t2,u,u1,u2; |
int i,j; |
int i,j; |
|
|
|
#if USE_UNROLL |
switch ( nd_bpe ) { |
switch ( nd_bpe ) { |
#if 0 |
|
case 3: |
case 3: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u1 = d1[i]; u2 = d2[i]; |
u1 = d1[i]; u2 = d2[i]; |
Line 904 int ndl_disjoint(UINT *d1,UINT *d2) |
|
Line 927 int ndl_disjoint(UINT *d1,UINT *d2) |
|
if ( d1[i] && d2[i] ) return 0; |
if ( d1[i] && d2[i] ) return 0; |
return 1; |
return 1; |
break; |
break; |
#endif |
|
default: |
default: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u1 = d1[i]; u2 = d2[i]; |
u1 = d1[i]; u2 = d2[i]; |
Line 916 int ndl_disjoint(UINT *d1,UINT *d2) |
|
Line 938 int ndl_disjoint(UINT *d1,UINT *d2) |
|
return 1; |
return 1; |
break; |
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) |
int ndl_check_bound2(int index,UINT *d2) |
Line 926 int ndl_check_bound2(int index,UINT *d2) |
|
Line 958 int ndl_check_bound2(int index,UINT *d2) |
|
|
|
d1 = nd_bound[index]; |
d1 = nd_bound[index]; |
ind = 0; |
ind = 0; |
|
#if USE_UNROLL |
switch ( nd_bpe ) { |
switch ( nd_bpe ) { |
#if 0 |
|
case 3: |
case 3: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u2 = d2[i]; |
u2 = d2[i]; |
Line 992 int ndl_check_bound2(int index,UINT *d2) |
|
Line 1024 int ndl_check_bound2(int index,UINT *d2) |
|
if ( d1[i]+d2[i]<d1[i] ) return 1; |
if ( d1[i]+d2[i]<d1[i] ) return 1; |
return 0; |
return 0; |
break; |
break; |
#endif |
|
default: |
default: |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
u2 = d2[i]; |
u2 = d2[i]; |
Line 1003 int ndl_check_bound2(int index,UINT *d2) |
|
Line 1034 int ndl_check_bound2(int index,UINT *d2) |
|
return 0; |
return 0; |
break; |
break; |
} |
} |
} |
#else |
|
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
int ndl_check_bound2_direct(UINT *d1,UINT *d2) |
u2 = d2[i]; |
{ |
k = (nd_epw-1)*nd_bpe; |
UINT u2; |
for ( j = 0; j < nd_epw; j++, k -= nd_bpe ) |
int i,j,ind,k; |
if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1; |
|
|
ind = 0; |
|
switch ( nd_bpe ) { |
|
#if 0 |
|
case 3: |
|
for ( i = nd_exporigin; i < nd_wpd; i++ ) { |
|
u2 = d2[i]; |
|
if ( d1[ind++]+((u2>>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]<d1[i] ) return 1; |
|
return 0; |
|
break; |
|
#endif |
|
default: |
|
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; |
|
break; |
|
} |
} |
|
return 0; |
|
#endif |
} |
} |
|
|
INLINE int ndl_hash_value(UINT *d) |
INLINE int ndl_hash_value(UINT *d) |
Line 1135 INLINE int ndl_find_reducer(UINT *dg) |
|
Line 1090 INLINE int ndl_find_reducer(UINT *dg) |
|
return -1; |
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) |
ND nd_merge(ND p1,ND p2) |
{ |
{ |
int n,c; |
int n,c; |
Line 1295 ND nd_add_q(ND p1,ND p2) |
|
Line 1229 ND nd_add_q(ND p1,ND p2) |
|
} |
} |
|
|
/* ret=1 : success, ret=0 : overflow */ |
/* 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; |
ND d; |
NM m,mrd,tail; |
NM m,mrd,tail; |
Line 1304 int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) |
|
Line 1238 int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) |
|
int c,c1,c2,dummy; |
int c,c1,c2,dummy; |
RHist h; |
RHist h; |
NDV p,red; |
NDV p,red; |
Q cg,cred,gcd; |
Q cg,cred,gcd,tq,qq; |
double hmag; |
double hmag; |
|
|
|
if ( dn ) { |
|
if ( mod ) |
|
dn->m = 1; |
|
else |
|
dn->z = ONE; |
|
} |
if ( !g ) { |
if ( !g ) { |
*rp = 0; |
*rp = 0; |
return 1; |
return 1; |
Line 1333 int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) |
|
Line 1273 int nd_nf(int mod,ND g,NDV *ps,int full,ND *rp) |
|
igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred); |
igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred); |
chsgnq(cg,&CQ(mul)); |
chsgnq(cg,&CQ(mul)); |
nd_mul_c_q(d,cred); nd_mul_c_q(g,cred); |
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)); |
g = nd_add(mod,g,ndv_mul_nm(mod,mul,p)); |
sugar = MAX(sugar,SG(p)+TD(DL(mul))); |
sugar = MAX(sugar,SG(p)+TD(DL(mul))); |
if ( !mod && hmag && g && ((double)(p_mag((P)HCQ(g))) > hmag) ) { |
if ( !mod && hmag && g && ((double)(p_mag((P)HCQ(g))) > hmag) ) { |
|
tq = HCQ(g); |
nd_removecont2(d,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; |
hmag = ((double)p_mag((P)HCQ(g)))*nd_scale; |
} |
} |
} else if ( !full ) { |
} else if ( !full ) { |
Line 1457 int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp |
|
Line 1404 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 */ |
/* 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_candidate(NODE input,int obpe,int oadv,EPOS oepos,NODE cand) |
Line 1542 int ndv_check_candidate(NODE input,int obpe,int oadv,E |
|
Line 1412 int ndv_check_candidate(NODE input,int obpe,int oadv,E |
|
ND nf,d; |
ND nf,d; |
NDV r; |
NDV r; |
NODE t,s; |
NODE t,s; |
|
union oNDC dn; |
|
|
ndv_setup(0,0,cand); |
ndv_setup(0,0,cand); |
n = length(cand); |
n = length(cand); |
|
|
else |
else |
r = (NDV)BDY(t); |
r = (NDV)BDY(t); |
d = ndvtond(0,r); |
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 ) { |
if ( !stat ) { |
nd_reconstruct(0,0,0); |
nd_reconstruct(0,0,0); |
goto again; |
goto again; |
Line 1582 ND nd_remove_head(ND p) |
|
Line 1453 ND nd_remove_head(ND p) |
|
return 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 create_pbucket() |
{ |
{ |
PGeoBucket g; |
PGeoBucket g; |
Line 1784 NODE nd_gb(int m,int checkonly) |
|
Line 1673 NODE nd_gb(int m,int checkonly) |
|
ND_pairs l; |
ND_pairs l; |
ND h,nf; |
ND h,nf; |
NDV nfv; |
NDV nfv; |
|
union oNDC dn; |
|
|
g = 0; d = 0; |
g = 0; d = 0; |
for ( i = 0; i < nd_psn; i++ ) { |
for ( i = 0; i < nd_psn; i++ ) { |
|
|
goto again; |
goto again; |
} |
} |
#if USE_GEOBUCKET |
#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 |
#else |
stat = nd_nf(m,h,nd_ps,!Top,&nf); |
stat = nd_nf(m,h,nd_ps,!Top,0,&nf); |
#endif |
#endif |
if ( !stat ) { |
if ( !stat ) { |
NEXT(l) = d; d = l; |
NEXT(l) = d; d = l; |
Line 1839 NODE nd_gb_trace(int m) |
|
Line 1729 NODE nd_gb_trace(int m) |
|
ND_pairs l; |
ND_pairs l; |
ND h,nf,nfq; |
ND h,nf,nfq; |
NDV nfv,nfqv; |
NDV nfv,nfqv; |
|
union oNDC dn; |
|
|
g = 0; d = 0; |
g = 0; d = 0; |
for ( i = 0; i < nd_psn; i++ ) { |
for ( i = 0; i < nd_psn; i++ ) { |
|
|
#if USE_GEOBUCKET |
#if USE_GEOBUCKET |
stat = nd_nf_pbucket(m,h,nd_ps,!Top,&nf); |
stat = nd_nf_pbucket(m,h,nd_ps,!Top,&nf); |
#else |
#else |
stat = nd_nf(m,h,nd_ps,!Top,&nf); |
stat = nd_nf(m,h,nd_ps,!Top,0,&nf); |
#endif |
#endif |
if ( !stat ) { |
if ( !stat ) { |
NEXT(l) = d; d = l; |
NEXT(l) = d; d = l; |
|
|
} else if ( nf ) { |
} else if ( nf ) { |
/* overflow does not occur */ |
/* overflow does not occur */ |
nd_sp(0,1,l,&h); |
nd_sp(0,1,l,&h); |
nd_nf(0,h,nd_ps_trace,!Top,&nfq); |
nd_nf(0,h,nd_ps_trace,!Top,0,&nfq); |
if ( nfq ) { |
if ( nfq ) { |
/* failure; m|HC(nfq) */ |
/* failure; m|HC(nfq) */ |
if ( !rem(NM(HCQ(nfq)),m) ) return 0; |
if ( !rem(NM(HCQ(nfq)),m) ) return 0; |
Line 1907 int ndv_compare_rev(NDV *p1,NDV *p2) |
|
Line 1798 int ndv_compare_rev(NDV *p1,NDV *p2) |
|
|
|
NODE ndv_reduceall(int m,NODE f) |
NODE ndv_reduceall(int m,NODE f) |
{ |
{ |
int i,j,n,stat; |
int i,n,stat; |
NDV *w,*ps; |
ND nf,g,head; |
ND nf,g; |
|
NODE t,a0,a; |
NODE t,a0,a; |
struct oBaseSet base; |
union oNDC dn; |
UINT **bound; |
NDV *w; |
|
Q q; |
|
|
for ( n = 0, t = f; t; t = NEXT(t), n++ ); |
n = length(f); |
ps = (NDV *)ALLOCA(n*sizeof(NDV)); |
#if 0 |
bound = (UINT **)ALLOCA(n*sizeof(UINT *)); |
w = (NDV *)ALLOCA(n*sizeof(NDV)); |
for ( i = 0, t = f; i < n; i++, t = NEXT(t) ) ps[i] = (NDV)BDY(t); |
for ( i = 0, t = f; i < n; i++, t = NEXT(t) ) w[i] = (NDV)BDY(t); |
qsort(ps,n,sizeof(NDV),(int (*)(const void *,const void *))ndv_compare); |
qsort(w,n,sizeof(NDV), |
for ( i = 0; i < n; i++ ) bound[i] = ndv_compute_bound(ps[i]); |
(int (*)(const void *,const void *))ndv_compare); |
base.ps = (NDV *)ALLOCA((n-1)*sizeof(NDV)); |
for ( t = f, i = 0; t; i++, t = NEXT(t) ) BDY(t) = (pointer)w[i]; |
base.bound = (UINT **)ALLOCA((n-1)*sizeof(UINT *)); |
#endif |
base.len = n-1; |
ndv_setup(m,0,f); |
i = 0; |
for ( i = 0; i < n; ) { |
while ( i < n ) { |
g = ndvtond(m,nd_ps[i]); |
for ( j = 0; j < i; j++ ) { |
g = nd_separate_head(g,&head); |
base.ps[j] = ps[j]; base.bound[j] = bound[j]; |
stat = nd_nf(m,g,nd_ps,1,&dn,&nf); |
} |
|
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); |
|
if ( !stat ) |
if ( !stat ) |
nd_reconstruct_direct(m,ps,n); |
nd_reconstruct(m,0,0); |
else if ( !nf ) { |
else { |
printf("."); fflush(stdout); |
printf("."); fflush(stdout); |
ndv_free(ps[i]); |
if ( !m ) { mulq(HCQ(head),dn.z,&q); HCQ(head) = q; } |
for ( j = i+1; j < n; j++ ) { |
nf = nd_add(m,head,nf); |
ps[j-1] = ps[j]; bound[j-1] = bound[j]; |
ndv_free(nd_ps[i]); |
} |
|
n--; |
|
base.len = n-1; |
|
} else { |
|
printf("."); fflush(stdout); |
|
ndv_free(ps[i]); |
|
nd_removecont(m,nf); |
nd_removecont(m,nf); |
ps[i] = ndtondv(m,nf); |
nd_ps[i] = ndtondv(m,nf); nd_free(nf); |
bound[i] = ndv_compute_bound(ps[i]); |
nd_bound[i] = ndv_compute_bound(nd_ps[i]); |
nd_free(nf); |
|
i++; |
i++; |
} |
} |
} |
} |
printf("\n"); |
printf("\n"); |
for ( a0 = 0, i = 0; i < n; i++ ) { |
for ( a0 = 0, i = 0; i < n; i++ ) { |
NEXTNODE(a0,a); |
NEXTNODE(a0,a); |
BDY(a) = (pointer)ps[i]; |
BDY(a) = (pointer)nd_ps[i]; |
} |
} |
NEXT(a) = 0; |
NEXT(a) = 0; |
return a0; |
return a0; |
Line 2202 ND_pairs nd_minp( ND_pairs d, ND_pairs *prest ) |
|
Line 2080 ND_pairs nd_minp( ND_pairs d, ND_pairs *prest ) |
|
|
|
ND_pairs nd_minsugarp( 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; |
ND_pairs t,dm0,dm,dr0,dr; |
|
|
for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) ) |
for ( msugar = SG(d), t = NEXT(d); t; t = NEXT(t) ) |
if ( SG(t) < msugar ) msugar = SG(t); |
if ( SG(t) < msugar ) msugar = SG(t); |
dm0 = 0; dr0 = 0; |
dm0 = 0; dr0 = 0; |
for ( t = d; t; t = NEXT(t) ) |
for ( i = 0, t = d; t; t = NEXT(t) ) |
if ( SG(t) == msugar ) { |
if ( i < nd_f4_nsp && SG(t) == msugar ) { |
if ( dm0 ) NEXT(dm) = t; |
if ( dm0 ) NEXT(dm) = t; |
else dm0 = t; |
else dm0 = t; |
dm = t; |
dm = t; |
|
i++; |
} else { |
} else { |
if ( dr0 ) NEXT(dr) = t; |
if ( dr0 ) NEXT(dr) = t; |
else dr0 = t; |
else dr0 = t; |
Line 2257 void ndv_setup(int mod,int trace,NODE f) |
|
Line 2136 void ndv_setup(int mod,int trace,NODE f) |
|
NODE s,s0,f0; |
NODE s,s0,f0; |
UINT *d; |
UINT *d; |
RHist r; |
RHist r; |
|
NDV *w; |
NDV a,am; |
NDV a,am; |
|
|
nd_found = 0; nd_notfirst = 0; nd_create = 0; |
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 = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); |
nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); |
nd_ps_trace = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); |
nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist)); |
nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist)); |
Line 2271 void ndv_setup(int mod,int trace,NODE f) |
|
Line 2156 void ndv_setup(int mod,int trace,NODE f) |
|
nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist)); |
nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist)); |
bzero(nd_red,REDTAB_LEN*sizeof(RHist)); |
bzero(nd_red,REDTAB_LEN*sizeof(RHist)); |
nd_free_private_storage(); |
nd_free_private_storage(); |
for ( i = 0; i < nd_psn; i++, f = NEXT(f) ) { |
for ( i = 0; i < nd_psn; i++ ) { |
if ( trace ) { |
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); |
ndv_removecont(0,a); |
am = nd_ps[i] = ndv_dup(mod,a); |
am = nd_ps[i] = ndv_dup(mod,a); |
ndv_mod(mod,am); |
ndv_mod(mod,am); |
ndv_removecont(mod,am); |
ndv_removecont(mod,am); |
} else { |
} else { |
a = nd_ps[i] = ndv_dup(mod,(NDV)BDY(f)); |
a = nd_ps[i] = ndv_dup(mod,w[i]); |
if ( mod ) ndv_mod(mod,a); |
|
ndv_removecont(mod,a); |
ndv_removecont(mod,a); |
} |
} |
NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r)); |
NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r)); |
Line 2294 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
Line 2178 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
VL tv,fv,vv,vc; |
VL tv,fv,vv,vc; |
NODE fd,fd0,r,r0,t,x,s,xx; |
NODE fd,fd0,r,r0,t,x,s,xx; |
int e,max,nvar; |
int e,max,nvar; |
ND b; |
NDV b; |
|
|
get_vars((Obj)f,&fv); pltovl(v,&vv); |
get_vars((Obj)f,&fv); pltovl(v,&vv); |
nvar = length(vv); |
nvar = length(vv); |
Line 2307 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
Line 2191 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
nd_setup_parameters(nvar,max); |
nd_setup_parameters(nvar,max); |
for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { |
for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { |
b = (pointer)ptondv(CO,vv,(P)BDY(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 ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; } |
} |
} |
if ( fd0 ) NEXT(fd) = 0; |
if ( fd0 ) NEXT(fd) = 0; |
Line 2902 ND_pairs nd_reconstruct(int mod,int trace,ND_pairs d) |
|
Line 2787 ND_pairs nd_reconstruct(int mod,int trace,ND_pairs d) |
|
return s0; |
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) |
void ndl_reconstruct(UINT *d,UINT *r,int obpe,EPOS oepos) |
{ |
{ |
int n,i,ei,oepw,omask0,j,s,ord_l,l; |
int n,i,ei,oepw,omask0,j,s,ord_l,l; |
Line 3664 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
Line 3514 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
NDV ndv; |
NDV ndv; |
VL vv,tv; |
VL vv,tv; |
int stat,nvar,max,e; |
int stat,nvar,max,e; |
|
union oNDC dn; |
|
|
pltovl(v,&vv); |
pltovl(v,&vv); |
nvar = length(vv); |
nvar = length(vv); |
Line 3686 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
Line 3537 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) ) { |
for ( in0 = 0, t = BDY(g); t; t = NEXT(t) ) { |
NEXTNODE(in0,in); |
NEXTNODE(in0,in); |
BDY(in) = (pointer)ptondv(CO,vv,(P)BDY(t)); |
BDY(in) = (pointer)ptondv(CO,vv,(P)BDY(t)); |
|
if ( m ) ndv_mod(m,(NDV)BDY(in)); |
} |
} |
NEXTNODE(in0,in); |
NEXTNODE(in0,in); |
BDY(in) = (pointer)ptondv(CO,vv,f); |
BDY(in) = (pointer)ptondv(CO,vv,f); |
|
if ( m ) ndv_mod(m,(NDV)BDY(in)); |
NEXT(in) = 0; |
NEXT(in) = 0; |
|
|
ndv_setup(m,0,in0); |
ndv_setup(m,0,in0); |
Line 3696 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
Line 3549 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
nd_scale=2; |
nd_scale=2; |
while ( 1 ) { |
while ( 1 ) { |
nd = (pointer)ndvtond(m,nd_ps[nd_psn]); |
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 ) { |
if ( !stat ) { |
nd_psn++; |
nd_psn++; |
nd_reconstruct(m,0,0); |
nd_reconstruct(m,0,0); |
Line 3746 int nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_ |
|
Line 3599 int nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_ |
|
return i; |
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; |
NM m; |
NMV mr; |
NMV mr; |
UINT *d,*t,*s; |
UINT *d,*t,*s; |
NDV p; |
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; |
m = pair->mul; |
d = DL(m); |
d = DL(m); |
p = nd_ps[pair->index]; |
p = nd_ps[pair->index]; |
len = LEN(p); |
len = LEN(p); |
t = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); |
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) ) { |
for ( i = j = 0, s = s0, mr = BDY(p); j < len; j++, NMV_ADV(mr) ) { |
ndl_add(d,DL(mr),t); |
ndl_add(d,DL(mr),t); |
for ( ; !ndl_equal(t,s); s += nd_wpd, i++ ); |
for ( ; !ndl_equal(t,s); s += nd_wpd, i++ ); |
r[j] = CM(mr); |
v[j] = i; |
ind[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) |
NODE nd_f4(int m) |
{ |
{ |
int i,nh,stat,index; |
int i,nh,stat,index; |
NODE r,g; |
NODE r,g; |
ND_pairs d,l,t; |
ND_pairs d,l,t; |
ND spol,red; |
ND spol,red; |
NDV nf; |
NDV nf,redv; |
NM_ind_pair pair,pair1,pair2; |
|
NM s0,s; |
NM s0,s; |
NODE sp0,sp,rp0,rp; |
NODE sp0,sp,rp0,rp; |
RHist h; |
int nsp,nred,col,rank,len,k,j,a; |
int nsp,nred,col,rank,len,k,j; |
UINT c; |
NMV mr0,mr; |
UINT *s0vect,*svect,*p,*v; |
UINT c,c1,c2,c3; |
|
NM mul,head; |
|
UINT **spmat; |
|
UINT *s0vect,*rvect,*svect,*p,*ivect; |
|
int *colstat; |
int *colstat; |
int sugar,pos; |
IndArray *imat; |
|
int *rhead; |
|
int spcol,sprow; |
|
int sugar; |
PGeoBucket bucket; |
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 ) |
if ( !m ) |
error("nd_f4 : not implemented"); |
error("nd_f4 : not implemented"); |
Line 3797 NODE nd_f4(int m) |
|
Line 3821 NODE nd_f4(int m) |
|
d = update_pairs(d,g,i); |
d = update_pairs(d,g,i); |
g = update_base(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 ) { |
while ( d ) { |
|
get_eg(&eg0); |
l = nd_minsugarp(d,&d); |
l = nd_minsugarp(d,&d); |
sugar = SG(l); |
sugar = SG(l); |
sp0 = 0; |
|
bucket = create_pbucket(); |
bucket = create_pbucket(); |
t_0 = clock(); |
stat = nd_sp_f4(m,l,bucket,&sp0); |
for ( t = l, nsp = 0; t; t = NEXT(t) ) { |
if ( !stat ) { |
stat = nd_sp(m,0,t,&spol); |
for ( t = l; NEXT(t); t = NEXT(t) ); |
if ( !stat ) goto again; |
NEXT(t) = d; d = l; |
if ( spol ) { |
d = nd_reconstruct(m,0,d); |
NEXTNODE(sp0,sp); BDY(sp) = (pointer)nd_dup(spol); |
continue; |
add_pbucket_symbolic(bucket,spol); |
|
nsp++; |
|
} |
|
} |
} |
if ( sp0 ) NEXT(sp) = 0; |
if ( !sp0 ) continue; |
s0 = 0; |
col = nd_symbolic_preproc(bucket,&s0vect,&rp0); |
rp0 = 0; |
if ( !col ) { |
while ( 1 ) { |
for ( t = l; NEXT(t); t = NEXT(t) ); |
head = remove_head_pbucket_symbolic(bucket); |
NEXT(t) = d; d = l; |
if ( !head ) break; |
d = nd_reconstruct(m,0,d); |
if ( !s0 ) s0 = head; |
continue; |
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++; |
|
} |
|
} |
} |
t_1 = clock(); |
|
if ( s0 ) NEXT(s) = 0; |
nsp = length(sp0); nred = length(rp0); spcol = col-nred; |
for ( i = 0, s = s0; s; s = NEXT(s), i++ ); |
imat = (IndArray *)MALLOC(nred*sizeof(IndArray)); |
col = i; |
rhead = (int *)MALLOC_ATOMIC(col*sizeof(int)); |
s0vect = (UINT *)MALLOC(col*nd_wpd*sizeof(UINT)); |
for ( i = 0; i < col; i++ ) rhead[i] = 0; |
for ( i = 0, p = s0vect, s = s0; i < col; |
|
i++, p += nd_wpd, s = NEXT(s) ) ndl_copy(DL(s),p); |
/* construction of index arrays */ |
spmat = (UINT **)MALLOC(nsp*sizeof(UINT *)); |
for ( rp = rp0, i = 0; rp; i++, rp = NEXT(rp) ) { |
for ( i = 0, sp = sp0; i < nsp; i++, sp = NEXT(sp) ) { |
imat[i] = nm_ind_pair_to_vect_compress(m,s0vect,col,(NM_ind_pair)BDY(rp)); |
spmat[i] = (UINT *)MALLOC(col*sizeof(UINT)); |
rhead[imat[i]->head] = 1; |
nd_to_vect(m,s0vect,col,BDY(sp),spmat[i]); |
|
} |
} |
t_2 = clock(); |
|
t_c = 0; |
/* elimination (1st step) */ |
t_e = 0; |
svect = (UINT *)MALLOC_ATOMIC(col*sizeof(UINT)); |
rvect = (UINT *)ALLOCA(col*sizeof(UINT)); |
if ( spcol > spblen ) { |
ivect = (int *)ALLOCA(col*sizeof(int)); |
spblen = spcol; |
for ( rp = rp0; rp; rp = NEXT(rp) ) { |
spb = REALLOC(spb,spblen*nd_f4_nsp*sizeof(UINT)); |
t_20 = clock(); |
} |
nm_ind_pair_to_vect_compress(m,s0vect,col,(NM_ind_pair)BDY(rp),rvect,ivect); |
|
t_21 = clock(); |
for ( a = sprow = 0, sp = sp0, p = spb; a < nsp; a++, sp = NEXT(sp) ) { |
t_c += t_21-t_20; |
nd_to_vect(m,s0vect,col,BDY(sp),svect); |
k = ivect[0]; |
ndv_reduce_vect(m,svect,col,imat,rp0); |
len = LEN(nd_ps[((NM_ind_pair)BDY(rp))->index]); |
for ( i = 0; i < col; i++ ) if ( svect[i] ) break; |
for ( i = 0; i < nsp; i++ ) { |
if ( i < col ) { |
svect = spmat[i]; |
spmat[sprow] = p; |
if ( c = svect[k] ) |
v = spmat[sprow]; |
for ( j = 0; j < len; j++ ) { |
for ( j = k = 0; j < col; j++ ) |
pos = ivect[j]; |
if ( !rhead[j] ) v[k++] = svect[j]; |
c1 = m-rvect[j]; |
sprow++; |
c2 = svect[pos]; DMAR(c1,c,c2,m,c3); |
p += k; |
svect[pos] = c3; |
|
} |
|
} |
} |
t_e += clock()-t_21; |
|
} |
} |
t_4 = clock(); |
/* free index arrays */ |
colstat = (int *)ALLOCA(col*sizeof(int)); |
for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); |
rank = generic_gauss_elim_mod(spmat,nsp,col,m,colstat); |
|
t_5 = clock(); |
/* elimination (2nd step) */ |
fprintf(asir_out,"sugar=%d,rank=%d ",sugar,rank); |
colstat = (int *)ALLOCA(spcol*sizeof(int)); |
fprintf(asir_out,"symb=%f,conv1=%f,conv2=%f,elim1=%f,elim2=%f\n", |
rank = generic_gauss_elim_mod(spmat,sprow,spcol,m,colstat); |
(t_1-t_0)/(double)CLOCKS_PER_SEC, |
|
(t_2-t_1)/(double)CLOCKS_PER_SEC, |
get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); |
(t_c)/(double)CLOCKS_PER_SEC, |
fprintf(asir_out,"sugar=%d,nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ", |
(t_e)/(double)CLOCKS_PER_SEC, |
sugar,nsp,nred,sprow,spcol,rank); |
(t_5-t_4)/(double)CLOCKS_PER_SEC); |
fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime); |
if ( rank ) |
|
for ( j = 0, i = 0; j < col; j++ ) { |
/* adding new bases */ |
if ( colstat[j] ) { |
for ( i = 0; i < rank; i++ ) { |
for ( k = j, len = 0; k < col; k++ ) |
nf = vect_to_ndv(spmat[i],spcol,col,rhead,s0vect); |
if ( spmat[i][k] ) len++; |
SG(nf) = sugar; |
mr0 = (NMV)MALLOC_ATOMIC(nmv_adv*len); |
ndv_removecont(m,nf); |
mr = mr0; |
nh = ndv_newps(nf,0); |
p = s0vect+nd_wpd*j; |
d = update_pairs(d,g,nh); |
for ( k = j; k < col; k++, p += nd_wpd ) |
g = update_base(g,nh); |
if ( spmat[i][k] ) { |
} |
ndl_copy(p,DL(mr)); |
} |
CM(mr) = spmat[i][k]; |
for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps[(int)BDY(r)]; |
NMV_ADV(mr); |
return g; |
} |
} |
MKNDV(nd_nvar,mr0,len,nf); |
#else |
SG(nf) = sugar; |
NODE nd_f4(int m) |
ndv_removecont(m,nf); |
{ |
nh = ndv_newps(nf,0); |
int i,nh,stat,index; |
d = update_pairs(d,g,nh); |
NODE r,g; |
g = update_base(g,nh); |
ND_pairs d,l,t; |
i++; |
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: |
/* elimination (2nd step) */ |
for ( t = l; NEXT(t); t = NEXT(t) ); |
colstat = (int *)ALLOCA(spcol*sizeof(int)); |
NEXT(t) = d; d = l; |
rank = generic_gauss_elim_mod(spmat,sprow,spcol,m,colstat); |
d = nd_reconstruct(m,0,d); |
|
NEWNM(mul); |
get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); |
|
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)]; |
for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps[(int)BDY(r)]; |
return g; |
return g; |
} |
} |
|
#endif |