version 1.107, 2004/09/21 02:34:12 |
version 1.118, 2004/12/04 09:39:27 |
|
|
/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.106 2004/09/21 02:23:49 noro Exp $ */ |
/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.117 2004/12/03 08:57:30 noro Exp $ */ |
|
|
#include "nd.h" |
#include "nd.h" |
|
|
|
|
ND _nd_free_list; |
ND _nd_free_list; |
ND_pairs _ndp_free_list; |
ND_pairs _ndp_free_list; |
|
|
|
static int nd_nalg; |
#if 0 |
#if 0 |
static int ndv_alloc; |
static int ndv_alloc; |
#endif |
#endif |
Line 41 static int nd_found,nd_create,nd_notfirst; |
|
Line 42 static int nd_found,nd_create,nd_notfirst; |
|
static int nmv_adv; |
static int nmv_adv; |
static int nd_demand; |
static int nd_demand; |
|
|
|
UINT *nd_det_compute_bound(NDV **dm,int n,int j); |
|
void nd_det_reconstruct(NDV **dm,int n,int j,NDV d); |
|
int nd_monic(int m,ND *p); |
|
|
void nd_free_private_storage() |
void nd_free_private_storage() |
{ |
{ |
_nm_free_list = 0; |
_nm_free_list = 0; |
Line 724 int ndl_disjoint(UINT *d1,UINT *d2) |
|
Line 729 int ndl_disjoint(UINT *d1,UINT *d2) |
|
#endif |
#endif |
} |
} |
|
|
int ndl_check_bound2(int index,UINT *d2) |
int ndl_check_bound(UINT *d1,UINT *d2) |
{ |
{ |
UINT u2; |
UINT u2; |
UINT *d1; |
|
int i,j,ind,k; |
int i,j,ind,k; |
|
|
d1 = nd_bound[index]; |
|
ind = 0; |
ind = 0; |
#if USE_UNROLL |
#if USE_UNROLL |
switch ( nd_bpe ) { |
switch ( nd_bpe ) { |
Line 819 int ndl_check_bound2(int index,UINT *d2) |
|
Line 822 int ndl_check_bound2(int index,UINT *d2) |
|
#endif |
#endif |
} |
} |
|
|
|
int ndl_check_bound2(int index,UINT *d2) |
|
{ |
|
return ndl_check_bound(nd_bound[index],d2); |
|
} |
|
|
INLINE int ndl_hash_value(UINT *d) |
INLINE int ndl_hash_value(UINT *d) |
{ |
{ |
int i; |
int i; |
Line 1574 NODE nd_gb(int m,int ishomo,int checkonly) |
|
Line 1582 NODE nd_gb(int m,int ishomo,int checkonly) |
|
NODE r,g,t; |
NODE r,g,t; |
ND_pairs d; |
ND_pairs d; |
ND_pairs l; |
ND_pairs l; |
ND h,nf,s,head; |
ND h,nf,s,head,nf1; |
NDV nfv; |
NDV nfv; |
Q q,num,den; |
Q q,num,den; |
union oNDC dn; |
union oNDC dn; |
|
|
if ( checkonly ) return 0; |
if ( checkonly ) return 0; |
if ( DP_Print ) { printf("+"); fflush(stdout); } |
if ( DP_Print ) { printf("+"); fflush(stdout); } |
nd_removecont(m,nf); |
nd_removecont(m,nf); |
|
if ( !m && nd_nalg ) { |
|
nd_monic(0,&nf); |
|
nd_removecont(m,nf); |
|
} |
nfv = ndtondv(m,nf); nd_free(nf); |
nfv = ndtondv(m,nf); nd_free(nf); |
nh = ndv_newps(m,nfv,0); |
nh = ndv_newps(m,nfv,0); |
d = update_pairs(d,g,nh); |
d = update_pairs(d,g,nh); |
Line 1679 void do_diagonalize_trace(int sugar,int m) |
|
Line 1691 void do_diagonalize_trace(int sugar,int m) |
|
} |
} |
} |
} |
|
|
|
static struct oEGT eg_invdalg; |
|
struct oEGT eg_le; |
|
|
NODE nd_gb_trace(int m,int ishomo) |
NODE nd_gb_trace(int m,int ishomo) |
{ |
{ |
int i,nh,sugar,stat; |
int i,nh,sugar,stat; |
Line 1689 NODE nd_gb_trace(int m,int ishomo) |
|
Line 1704 NODE nd_gb_trace(int m,int ishomo) |
|
NDV nfv,nfqv; |
NDV nfv,nfqv; |
Q q,den,num; |
Q q,den,num; |
union oNDC dn; |
union oNDC dn; |
|
struct oEGT eg_monic,egm0,egm1; |
|
|
|
init_eg(&eg_monic); |
|
init_eg(&eg_invdalg); |
|
init_eg(&eg_le); |
g = 0; d = 0; |
g = 0; d = 0; |
for ( i = 0; i < nd_psn; i++ ) { |
for ( i = 0; i < nd_psn; i++ ) { |
d = update_pairs(d,g,i); |
d = update_pairs(d,g,i); |
|
|
if ( !rem(NM(HCQ(nfq)),m) ) return 0; |
if ( !rem(NM(HCQ(nfq)),m) ) return 0; |
|
|
if ( DP_Print ) { printf("+"); fflush(stdout); } |
if ( DP_Print ) { printf("+"); fflush(stdout); } |
nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); |
if ( nd_nalg ) { |
nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); |
/* m|DN(HC(nf)^(-1)) => failure */ |
|
get_eg(&egm0); |
|
if ( !nd_monic(m,&nfq) ) return 0; |
|
get_eg(&egm1); add_eg(&eg_monic,&egm0,&egm1); |
|
nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); |
|
nfv = ndv_dup(0,nfqv); ndv_mod(m,nfv); nd_free(nf); |
|
} else { |
|
nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); |
|
nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); |
|
} |
nh = ndv_newps(0,nfv,nfqv); |
nh = ndv_newps(0,nfv,nfqv); |
d = update_pairs(d,g,nh); |
d = update_pairs(d,g,nh); |
g = update_base(g,nh); |
g = update_base(g,nh); |
|
|
else |
else |
for ( t = g; t; t = NEXT(t) ) |
for ( t = g; t; t = NEXT(t) ) |
BDY(t) = (pointer)nd_ps_trace[(int)BDY(t)]; |
BDY(t) = (pointer)nd_ps_trace[(int)BDY(t)]; |
|
if ( nd_nalg ) { |
|
print_eg("monic",&eg_monic); |
|
print_eg("invdalg",&eg_invdalg); |
|
print_eg("le",&eg_le); |
|
} |
return g; |
return g; |
} |
} |
|
|
Line 2579 void removecont_array(Q *c,int n) |
|
Line 2612 void removecont_array(Q *c,int n) |
|
{ |
{ |
struct oVECT v; |
struct oVECT v; |
Q d0,d1,a,u,u1,gcd; |
Q d0,d1,a,u,u1,gcd; |
int i; |
int i,j; |
N qn,rn,gn; |
N qn,rn,gn; |
Q *q,*r; |
Q *q,*r; |
|
|
Line 2616 void nd_mul_c(int mod,ND p,int mul) |
|
Line 2649 void nd_mul_c(int mod,ND p,int mul) |
|
int c,c1; |
int c,c1; |
|
|
if ( !p ) return; |
if ( !p ) return; |
|
if ( mul == 1 ) return; |
if ( mod == -1 ) |
if ( mod == -1 ) |
for ( m = BDY(p); m; m = NEXT(m) ) |
for ( m = BDY(p); m; m = NEXT(m) ) |
CM(m) = _mulsf(CM(m),mul); |
CM(m) = _mulsf(CM(m),mul); |
Line 2631 void nd_mul_c_q(ND p,Q mul) |
|
Line 2665 void nd_mul_c_q(ND p,Q mul) |
|
Q c; |
Q c; |
|
|
if ( !p ) return; |
if ( !p ) return; |
|
if ( UNIQ(mul) ) return; |
for ( m = BDY(p); m; m = NEXT(m) ) { |
for ( m = BDY(p); m; m = NEXT(m) ) { |
mulq(CQ(m),mul,&c); CQ(m) = c; |
mulq(CQ(m),mul,&c); CQ(m) = c; |
} |
} |
Line 3709 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
Line 3744 void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec |
|
int stat,nvar,max,e; |
int stat,nvar,max,e; |
union oNDC dn; |
union oNDC dn; |
|
|
|
if ( !f ) { |
|
*rp = 0; |
|
return; |
|
} |
pltovl(v,&vv); |
pltovl(v,&vv); |
for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); |
for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); |
|
|
Line 3785 int nd_to_vect_q(UINT *s0,int n,ND d,Q *r) |
|
Line 3824 int nd_to_vect_q(UINT *s0,int n,ND d,Q *r) |
|
return i; |
return i; |
} |
} |
|
|
int nm_ind_pair_to_vect(int mod,UINT *s0,int n,NM_ind_pair pair,UINT *r) |
|
{ |
|
NM m; |
|
NMV mr; |
|
UINT *d,*t,*s; |
|
NDV p; |
|
int i,j,len; |
|
|
|
m = pair->mul; |
|
d = DL(m); |
|
p = nd_ps[pair->index]; |
|
t = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); |
|
for ( i = 0; i < n; i++ ) r[i] = 0; |
|
len = LEN(p); |
|
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[i] = CM(mr); |
|
} |
|
for ( i = 0; !r[i]; i++ ); |
|
return i; |
|
} |
|
|
|
IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0,int n,NM_ind_pair pair) |
IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0,int n,NM_ind_pair pair) |
{ |
{ |
NM m; |
NM m; |
Line 3860 IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0 |
|
Line 3876 IndArray nm_ind_pair_to_vect_compress(int mod,UINT *s0 |
|
int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred) |
int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred) |
{ |
{ |
int i,j,k,len,pos,prev; |
int i,j,k,len,pos,prev; |
Q cs,mcs,c1,c2,cr,gcd; |
Q cs,mcs,c1,c2,cr,gcd,t; |
IndArray ivect; |
IndArray ivect; |
unsigned char *ivc; |
unsigned char *ivc; |
unsigned short *ivs; |
unsigned short *ivs; |
Line 3880 int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat, |
|
Line 3896 int ndv_reduce_vect_q(Q *svect,int col,IndArray *imat, |
|
len = LEN(redv); mr = BDY(redv); |
len = LEN(redv); mr = BDY(redv); |
igcd_cofactor(svect[k],CQ(mr),&gcd,&cs,&cr); |
igcd_cofactor(svect[k],CQ(mr),&gcd,&cs,&cr); |
chsgnq(cs,&mcs); |
chsgnq(cs,&mcs); |
|
if ( !UNIQ(cr) ) { |
|
for ( j = 0; j < col; j++ ) { |
|
mulq(svect[j],cr,&c1); svect[j] = c1; |
|
} |
|
} |
svect[k] = 0; prev = k; |
svect[k] = 0; prev = k; |
switch ( ivect->width ) { |
switch ( ivect->width ) { |
case 1: |
case 1: |
ivc = ivect->index.c; |
ivc = ivect->index.c; |
for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { |
for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { |
pos = prev+ivc[j]; prev = pos; |
pos = prev+ivc[j]; prev = pos; |
mulq(svect[pos],cr,&c1); mulq(CQ(mr),mcs,&c2); addq(c1,c2,&svect[pos]); |
mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t; |
} |
} |
break; |
break; |
case 2: |
case 2: |
ivs = ivect->index.s; |
ivs = ivect->index.s; |
for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { |
for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { |
pos = prev+ivs[j]; prev = pos; |
pos = prev+ivs[j]; prev = pos; |
mulq(svect[pos],cr,&c1); mulq(CQ(mr),mcs,&c2); addq(c1,c2,&svect[pos]); |
mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t; |
} |
} |
break; |
break; |
case 4: |
case 4: |
ivi = ivect->index.i; |
ivi = ivect->index.i; |
for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { |
for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { |
pos = prev+ivi[j]; prev = pos; |
pos = prev+ivi[j]; prev = pos; |
mulq(svect[pos],cr,&c1); mulq(CQ(mr),mcs,&c2); addq(c1,c2,&svect[pos]); |
mulq(CQ(mr),mcs,&c2); addq(svect[pos],c2,&t); svect[pos] = t; |
} |
} |
break; |
break; |
} |
} |
Line 4059 NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead |
|
Line 4080 NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead |
|
for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++; |
for ( j = 0, len = 0; j < spcol; j++ ) if ( vect[j] ) len++; |
if ( !len ) return 0; |
if ( !len ) return 0; |
else { |
else { |
mr0 = (NMV)GC_malloc_atomic_ignore_off_page(nmv_adv*len); |
mr0 = (NMV)GC_malloc(nmv_adv*len); |
#if 0 |
#if 0 |
ndv_alloc += nmv_adv*len; |
ndv_alloc += nmv_adv*len; |
#endif |
#endif |
Line 4068 NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead |
|
Line 4089 NDV vect_to_ndv_q(Q *vect,int spcol,int col,int *rhead |
|
for ( j = k = 0; j < col; j++, p += nd_wpd ) |
for ( j = k = 0; j < col; j++, p += nd_wpd ) |
if ( !rhead[j] ) { |
if ( !rhead[j] ) { |
if ( c = vect[k++] ) { |
if ( c = vect[k++] ) { |
|
if ( DN(c) ) |
|
error("afo"); |
ndl_copy(p,DL(mr)); CQ(mr) = c; NMV_ADV(mr); |
ndl_copy(p,DL(mr)); CQ(mr) = c; NMV_ADV(mr); |
} |
} |
} |
} |
Line 4155 NODE nd_f4(int m) |
|
Line 4178 NODE nd_f4(int m) |
|
PGeoBucket bucket; |
PGeoBucket bucket; |
struct oEGT eg0,eg1,eg_f4; |
struct oEGT eg0,eg1,eg_f4; |
|
|
if ( !m ) |
|
error("nd_f4 : not implemented"); |
|
#if 0 |
#if 0 |
ndv_alloc = 0; |
ndv_alloc = 0; |
#endif |
#endif |
Line 4298 NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s |
|
Line 4319 NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s |
|
SG((NDV)BDY(r)) = spsugar[i]; |
SG((NDV)BDY(r)) = spsugar[i]; |
GC_free(spmat[i]); |
GC_free(spmat[i]); |
} |
} |
|
if ( r0 ) NEXT(r) = 0; |
for ( ; i < sprow; i++ ) GC_free(spmat[i]); |
for ( ; i < sprow; i++ ) GC_free(spmat[i]); |
get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); |
get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); |
init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); |
init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); |
Line 4328 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
Line 4350 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
spcol = col-nred; |
spcol = col-nred; |
get_eg(&eg0); |
get_eg(&eg0); |
/* elimination (1st step) */ |
/* elimination (1st step) */ |
spmat = (Q **)ALLOCA(nsp*sizeof(UINT *)); |
spmat = (Q **)ALLOCA(nsp*sizeof(Q *)); |
svect = (Q *)ALLOCA(col*sizeof(UINT)); |
svect = (Q *)ALLOCA(col*sizeof(Q)); |
spsugar = (int *)ALLOCA(nsp*sizeof(UINT)); |
spsugar = (int *)ALLOCA(nsp*sizeof(Q)); |
for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) { |
for ( a = sprow = 0, sp = sp0; a < nsp; a++, sp = NEXT(sp) ) { |
nd_sp(0,0,sp,&spol); |
nd_sp(0,0,sp,&spol); |
if ( !spol ) continue; |
if ( !spol ) continue; |
Line 4338 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
Line 4360 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
maxrs = ndv_reduce_vect_q(svect,col,imat,rvect,nred); |
maxrs = ndv_reduce_vect_q(svect,col,imat,rvect,nred); |
for ( i = 0; i < col; i++ ) if ( svect[i] ) break; |
for ( i = 0; i < col; i++ ) if ( svect[i] ) break; |
if ( i < col ) { |
if ( i < col ) { |
spmat[sprow] = v = (Q *)MALLOC_ATOMIC(spcol*sizeof(Q)); |
spmat[sprow] = v = (Q *)MALLOC(spcol*sizeof(Q)); |
for ( j = k = 0; j < col; j++ ) |
for ( j = k = 0; j < col; j++ ) |
if ( !rhead[j] ) v[k++] = svect[j]; |
if ( !rhead[j] ) v[k++] = svect[j]; |
spsugar[sprow] = MAX(maxrs,SG(spol)); |
spsugar[sprow] = MAX(maxrs,SG(spol)); |
sprow++; |
sprow++; |
} |
} |
nd_free(spol); |
/* nd_free(spol); */ |
} |
} |
get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); |
get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); |
if ( DP_Print ) { |
if ( DP_Print ) { |
Line 4352 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
Line 4374 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
fflush(asir_out); |
fflush(asir_out); |
} |
} |
/* free index arrays */ |
/* free index arrays */ |
for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); |
/* for ( i = 0; i < nred; i++ ) GC_free(imat[i]->index.c); */ |
|
|
/* elimination (2nd step) */ |
/* elimination (2nd step) */ |
colstat = (int *)ALLOCA(spcol*sizeof(int)); |
colstat = (int *)ALLOCA(spcol*sizeof(int)); |
Line 4362 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
Line 4384 NODE nd_f4_red_q_main(ND_pairs sp0,int nsp,UINT *s0vec |
|
NEXTNODE(r0,r); BDY(r) = |
NEXTNODE(r0,r); BDY(r) = |
(pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect); |
(pointer)vect_to_ndv_q(spmat[i],spcol,col,rhead,s0vect); |
SG((NDV)BDY(r)) = spsugar[i]; |
SG((NDV)BDY(r)) = spsugar[i]; |
GC_free(spmat[i]); |
/* GC_free(spmat[i]); */ |
} |
} |
for ( ; i < sprow; i++ ) GC_free(spmat[i]); |
if ( r0 ) NEXT(r) = 0; |
|
|
|
/* for ( ; i < sprow; i++ ) GC_free(spmat[i]); */ |
get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); |
get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); |
init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); |
init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); |
if ( DP_Print ) { |
if ( DP_Print ) { |
Line 4634 void nd_exec_f4_red_dist() |
|
Line 4658 void nd_exec_f4_red_dist() |
|
|
|
int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int col,int *colstat) |
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 *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,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; |
|
c = col-rank; |
|
for ( i = 0; i < rank; i++ ) { |
|
mat0[i][ri[i]] = dn; |
|
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; |
} |
} |
|
|
int nd_gauss_elim_mod(int **mat0,int *sugar,int row,int col,int md,int *colstat) |
int nd_gauss_elim_mod(int **mat0,int *sugar,int row,int col,int md,int *colstat) |
Line 4854 void nd_det(int mod,MAT f,P *rp) |
|
Line 4926 void nd_det(int mod,MAT f,P *rp) |
|
NDV d,s,mij,mjj; |
NDV d,s,mij,mjj; |
ND u; |
ND u; |
NMV nmv; |
NMV nmv; |
|
UINT *bound; |
PGeoBucket bucket; |
PGeoBucket bucket; |
struct order_spec *ord; |
struct order_spec *ord; |
|
|
Line 4871 void nd_det(int mod,MAT f,P *rp) |
|
Line 4944 void nd_det(int mod,MAT f,P *rp) |
|
e = getdeg(tv->v,(P)m[i][j]); |
e = getdeg(tv->v,(P)m[i][j]); |
max = MAX(e,max); |
max = MAX(e,max); |
} |
} |
nd_setup_parameters(nvar,1024); |
nd_setup_parameters(nvar,max); |
dm = (NDV **)almat_pointer(n,n); |
dm = (NDV **)almat_pointer(n,n); |
for ( i = 0, max = 0; i < n; i++ ) |
for ( i = 0, max = 0; i < n; i++ ) |
for ( j = 0; j < n; j++ ) { |
for ( j = 0; j < n; j++ ) { |
Line 4905 void nd_det(int mod,MAT f,P *rp) |
|
Line 4978 void nd_det(int mod,MAT f,P *rp) |
|
} |
} |
sgn = -sgn; |
sgn = -sgn; |
} |
} |
|
bound = nd_det_compute_bound(dm,n,j); |
|
if ( ndl_check_bound(bound,bound) ) |
|
nd_det_reconstruct(dm,n,j,d); |
|
|
for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) { |
for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) { |
if ( DP_Print ) fprintf(stderr," i=%d\n ",i); |
/* if ( DP_Print ) fprintf(stderr," i=%d\n ",i); */ |
mi = dm[i]; mij = mi[j]; |
mi = dm[i]; mij = mi[j]; |
if ( mod ) |
if ( mod ) |
ndv_mul_c(mod,mij,mod-1); |
ndv_mul_c(mod,mij,mod-1); |
else |
else |
ndv_mul_c_q(mij,mone); |
ndv_mul_c_q(mij,mone); |
for ( k = j+1; k < n; k++ ) { |
for ( k = j+1; k < n; k++ ) { |
if ( DP_Print ) fprintf(stderr,"k=%d ",k); |
/* if ( DP_Print ) fprintf(stderr,"k=%d ",k); */ |
bucket = create_pbucket(); |
bucket = create_pbucket(); |
if ( mi[k] ) { |
if ( mi[k] ) { |
nmv = BDY(mjj); len = LEN(mjj); |
nmv = BDY(mjj); len = LEN(mjj); |
Line 4932 void nd_det(int mod,MAT f,P *rp) |
|
Line 5009 void nd_det(int mod,MAT f,P *rp) |
|
u = nd_quo(mod,bucket,d); |
u = nd_quo(mod,bucket,d); |
mi[k] = ndtondv(mod,u); |
mi[k] = ndtondv(mod,u); |
} |
} |
if ( DP_Print ) fprintf(stderr,"\n",k); |
/* if ( DP_Print ) fprintf(stderr,"\n",k); */ |
} |
} |
d = mjj; |
d = mjj; |
} |
} |
Line 4992 ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d) |
|
Line 5069 ND ndv_mul_nmv_trunc(int mod,NMV m0,NDV p,UINT *d) |
|
return r; |
return r; |
} |
} |
} |
} |
|
} |
|
|
|
void nd_det_reconstruct(NDV **dm,int n,int j,NDV d) |
|
{ |
|
int i,obpe,oadv,h,k,l; |
|
static NM prev_nm_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_det_reconstruct : exponent too large"); |
|
|
|
nd_setup_parameters(nd_nvar,0); |
|
prev_nm_free_list = _nm_free_list; |
|
_nm_free_list = 0; |
|
for ( k = j; k < n; k++ ) |
|
for (l = j; l < n; l++ ) |
|
ndv_realloc(dm[k][l],obpe,oadv,oepos); |
|
ndv_realloc(d,obpe,oadv,oepos); |
|
prev_nm_free_list = 0; |
|
#if 0 |
|
GC_gcollect(); |
|
#endif |
|
} |
|
|
|
UINT *nd_det_compute_bound(NDV **dm,int n,int j) |
|
{ |
|
UINT *d0,*d1,*d,*t,*r; |
|
int k,l; |
|
|
|
d0 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); |
|
d1 = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); |
|
for ( k = 0; k < nd_wpd; k++ ) d0[k] = 0; |
|
for ( k = j; k < n; k++ ) |
|
for ( l = j; l < n; l++ ) |
|
if ( dm[k][l] ) { |
|
d = ndv_compute_bound(dm[k][l]); |
|
ndl_lcm(d,d0,d1); |
|
t = d1; d1 = d0; d0 = t; |
|
} |
|
r = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); |
|
for ( k = 0; k < nd_wpd; k++ ) r[k] = d0[k]; |
|
return r; |
|
} |
|
|
|
DL nd_separate_d(UINT *d,UINT *trans) |
|
{ |
|
int n,ntrans,td,i,e; |
|
DL a; |
|
|
|
n = nd_nvar; ntrans = n-nd_nalg; |
|
ndl_zero(trans); |
|
td = 0; |
|
for ( i = 0; i < ntrans; i++ ) { |
|
e = GET_EXP(d,i); |
|
PUT_EXP(trans,i,e); |
|
td += MUL_WEIGHT(e,i); |
|
} |
|
TD(trans) = td; |
|
if ( nd_blockmask) ndl_weight_mask(trans); |
|
NEWDL(a,nd_nalg); |
|
td = 0; |
|
for ( ; i < n; i++ ) { |
|
e = GET_EXP(d,i); |
|
a->d[i-ntrans] = e; |
|
td += e; |
|
} |
|
a->td = td; |
|
return a; |
|
} |
|
|
|
NumberField get_numberfield(); |
|
|
|
int nd_monic(int mod,ND *p) |
|
{ |
|
UINT *trans,*t; |
|
DL alg; |
|
MP mp0,mp; |
|
NM m,m0,m1,ma0,ma,mb,mr0,mr; |
|
ND r; |
|
DL dl; |
|
DP nm; |
|
NDV ndv; |
|
DAlg inv,cd; |
|
ND s,c; |
|
Q l,mul; |
|
N ln; |
|
int n,ntrans,i,e,td,is_lc,len; |
|
NumberField nf; |
|
struct oEGT eg0,eg1; |
|
|
|
if ( !(nf = get_numberfield()) ) |
|
error("nd_monic : current_numberfield is not set"); |
|
|
|
n = nd_nvar; ntrans = n-nd_nalg; |
|
/* Q coef -> DAlg coef */ |
|
NEWNM(ma0); ma = ma0; |
|
m = BDY(*p); |
|
is_lc = 1; |
|
while ( 1 ) { |
|
NEWMP(mp0); mp = mp0; |
|
mp->c = (P)CQ(m); |
|
mp->dl = nd_separate_d(DL(m),DL(ma)); |
|
NEWNM(mb); |
|
for ( m = NEXT(m); m; m = NEXT(m) ) { |
|
alg = nd_separate_d(DL(m),DL(mb)); |
|
if ( !ndl_equal(DL(ma),DL(mb)) ) |
|
break; |
|
NEXTMP(mp0,mp); mp->c = (P)CQ(m); mp->dl = alg; |
|
} |
|
NEXT(mp) = 0; |
|
MKDP(nd_nalg,mp0,nm); |
|
MKDAlg(nm,ONE,cd); |
|
if ( is_lc == 1 ) { |
|
/* if the lc is a rational number, we have nothing to do */ |
|
if ( !mp0->dl->td ) |
|
return 1; |
|
|
|
get_eg(&eg0); |
|
invdalg(cd,&inv); |
|
get_eg(&eg1); add_eg(&eg_invdalg,&eg0,&eg1); |
|
/* check the validity of inv */ |
|
if ( mod && !rem(NM(inv->dn),mod) ) |
|
return 0; |
|
CA(ma) = nf->one; |
|
is_lc = 0; |
|
ln = ONEN; |
|
} else { |
|
muldalg(cd,inv,&CA(ma)); |
|
lcmn(ln,NM(CA(ma)->dn),&ln); |
|
} |
|
if ( m ) { |
|
NEXT(ma) = mb; ma = mb; |
|
} else { |
|
NEXT(ma) = 0; |
|
break; |
|
} |
|
} |
|
/* l = lcm(denoms) */ |
|
NTOQ(ln,1,l); |
|
for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) { |
|
divq(l,CA(m)->dn,&mul); |
|
for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) { |
|
NEXTNM(mr0,mr); |
|
mulq((Q)mp->c,mul,&CQ(mr)); |
|
dl = mp->dl; |
|
td = TD(DL(m)); |
|
ndl_copy(DL(m),DL(mr)); |
|
for ( i = ntrans; i < n; i++ ) { |
|
e = dl->d[i-ntrans]; |
|
PUT_EXP(DL(mr),i,e); |
|
td += MUL_WEIGHT(e,i); |
|
} |
|
TD(DL(mr)) = td; |
|
if ( nd_blockmask) ndl_weight_mask(DL(mr)); |
|
} |
|
} |
|
NEXT(mr) = 0; |
|
for ( len = 0, mr = mr0; mr; mr = NEXT(mr), len++ ); |
|
MKND(NV(*p),mr0,len,r); |
|
/* XXX */ |
|
SG(r) = SG(*p); |
|
nd_free(*p); |
|
*p = r; |
|
return 1; |
|
} |
|
|
|
void nd_set_nalg(int nalg) |
|
{ |
|
nd_nalg = nalg; |
} |
} |