version 1.117, 2004/12/03 08:57:30 |
version 1.119, 2004/12/06 09:29:34 |
|
|
/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.116 2004/12/01 12:36:17 noro Exp $ */ |
/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.118 2004/12/04 09:39:27 noro Exp $ */ |
|
|
#include "nd.h" |
#include "nd.h" |
|
|
Line 42 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; |
|
|
|
NumberField get_numberfield(); |
UINT *nd_det_compute_bound(NDV **dm,int n,int j); |
UINT *nd_det_compute_bound(NDV **dm,int n,int j); |
void nd_det_reconstruct(NDV **dm,int n,int j,NDV d); |
void nd_det_reconstruct(NDV **dm,int n,int j,NDV d); |
ND nd_pseudo_monic(int m,ND p); |
int nd_monic(int m,ND *p); |
|
|
void nd_free_private_storage() |
void nd_free_private_storage() |
{ |
{ |
|
|
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 ( nd_nalg ) { |
if ( !m && nd_nalg ) { |
nf1 = nd_pseudo_monic(m,nf); nd_free(nf); |
nd_monic(0,&nf); |
stat = nd_nf(m,nf1,nd_ps,1,0,&nf); |
nd_removecont(m,nf); |
if ( stat ) { |
|
NEXT(l) = d; d = l; |
|
d = nd_reconstruct(0,d); |
|
goto again; |
|
} |
|
} |
} |
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); |
Line 1696 void do_diagonalize_trace(int sugar,int m) |
|
Line 1692 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 1706 NODE nd_gb_trace(int m,int ishomo) |
|
Line 1705 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 2194 void ndv_setup(int mod,int trace,NODE f) |
|
Line 2211 void ndv_setup(int mod,int trace,NODE f) |
|
} |
} |
} |
} |
|
|
|
struct order_spec *append_block(struct order_spec *spec, |
|
int nv,int nalg,int ord); |
|
|
void nd_gr(LIST f,LIST v,int m,int f4,struct order_spec *ord,LIST *rp) |
void nd_gr(LIST f,LIST v,int m,int f4,struct order_spec *ord,LIST *rp) |
{ |
{ |
VL tv,fv,vv,vc; |
VL tv,fv,vv,vc,av; |
NODE fd,fd0,r,r0,t,x,s,xx; |
NODE fd,fd0,r,r0,t,x,s,xx,alist; |
int e,max,nvar; |
int e,max,nvar,i; |
NDV b; |
NDV b; |
int ishomo; |
int ishomo,nalg; |
|
Alg alpha,dp; |
|
P p; |
|
LIST f1,f2; |
|
Obj obj; |
|
NumberField nf; |
|
|
if ( !m && Demand ) nd_demand = 1; |
if ( !m && Demand ) nd_demand = 1; |
else nd_demand = 0; |
else nd_demand = 0; |
Line 2218 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
Line 2243 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
default: |
default: |
break; |
break; |
} |
} |
|
nd_nalg = 0; |
|
if ( !m ) { |
|
get_algtree((Obj)f,&av); |
|
for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ ); |
|
nd_nalg = nalg; |
|
/* #i -> t#i */ |
|
if ( nalg ) { |
|
for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) { |
|
NEXTNODE(alist,t); MKV(tv->v,p); |
|
MKAlg(p,alpha); BDY(t) = (pointer)alpha; |
|
tv->v = tv->v->priv; |
|
} |
|
NEXT(t) = 0; |
|
for ( tv = vv; NEXT(tv); tv = NEXT(tv) ); |
|
NEXT(tv) = av; |
|
ord = append_block(ord,nvar,nalg,2); |
|
nvar += nalg; |
|
setfield_dalg(alist); |
|
nf = get_numberfield(); |
|
for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) { |
|
MKAlg(nf->defpoly[i],dp); |
|
MKNODE(s,dp,t); t = s; |
|
} |
|
MKLIST(f1,t); |
|
algobjtorat(f1,&f2); f = f2; |
|
} |
|
} |
nd_init_ord(ord); |
nd_init_ord(ord); |
for ( t = BDY(f), max = 0; t; t = NEXT(t) ) |
for ( t = BDY(f), max = 0; t; t = NEXT(t) ) |
for ( tv = vv; tv; tv = NEXT(tv) ) { |
for ( tv = vv; tv; tv = NEXT(tv) ) { |
Line 2242 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
Line 2294 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
for ( r0 = 0, t = x; t; t = NEXT(t) ) { |
for ( r0 = 0, t = x; t; t = NEXT(t) ) { |
NEXTNODE(r0,r); |
NEXTNODE(r0,r); |
BDY(r) = ndvtop(m,CO,vv,BDY(t)); |
BDY(r) = ndvtop(m,CO,vv,BDY(t)); |
|
if ( nalg ) { |
|
p = BDY(r); |
|
for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) { |
|
substr(CO,0,(Obj)p,tv->v,(Obj)BDY(s),&obj); p = (P)obj; |
|
} |
|
BDY(r) = p; |
|
} |
} |
} |
if ( r0 ) NEXT(r) = 0; |
if ( r0 ) NEXT(r) = 0; |
MKLIST(*rp,r0); |
MKLIST(*rp,r0); |
Line 2253 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
Line 2312 void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe |
|
void nd_gr_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp) |
void nd_gr_trace(LIST f,LIST v,int trace,int homo,struct order_spec *ord,LIST *rp) |
{ |
{ |
struct order_spec *ord1; |
struct order_spec *ord1; |
VL tv,fv,vv,vc; |
VL tv,fv,vv,vc,av; |
NODE fd,fd0,in0,in,r,r0,t,s,cand; |
NODE fd,fd0,in0,in,r,r0,t,s,cand,alist; |
int m,nocheck,nvar,mindex,e,max; |
int m,nocheck,nvar,mindex,e,max; |
NDV c; |
NDV c; |
NMV a; |
NMV a; |
P p; |
P p; |
EPOS oepos; |
EPOS oepos; |
int obpe,oadv,wmax,i,len,cbpe,ishomo; |
int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg; |
|
Alg alpha,dp; |
|
P poly; |
|
LIST f1,f2; |
|
Obj obj; |
|
NumberField nf; |
|
|
get_vars((Obj)f,&fv); pltovl(v,&vv); |
get_vars((Obj)f,&fv); pltovl(v,&vv); |
for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); |
for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); |
Line 2272 void nd_gr_trace(LIST f,LIST v,int trace,int homo,stru |
|
Line 2336 void nd_gr_trace(LIST f,LIST v,int trace,int homo,stru |
|
default: |
default: |
break; |
break; |
} |
} |
|
|
|
get_algtree((Obj)f,&av); |
|
for ( nalg = 0, tv = av; tv; tv = NEXT(tv), nalg++ ); |
|
nd_nalg = nalg; |
|
/* #i -> t#i */ |
|
if ( nalg ) { |
|
for ( alist = 0, tv = av; tv; tv = NEXT(tv) ) { |
|
NEXTNODE(alist,t); MKV(tv->v,poly); |
|
MKAlg(poly,alpha); BDY(t) = (pointer)alpha; |
|
tv->v = tv->v->priv; |
|
} |
|
NEXT(t) = 0; |
|
for ( tv = vv; NEXT(tv); tv = NEXT(tv) ); |
|
NEXT(tv) = av; |
|
ord = append_block(ord,nvar,nalg,2); |
|
nvar += nalg; |
|
setfield_dalg(alist); |
|
nf = get_numberfield(); |
|
for ( i = nalg-1, t = BDY(f); i >= 0; i-- ) { |
|
MKAlg(nf->defpoly[i],dp); |
|
MKNODE(s,dp,t); t = s; |
|
} |
|
MKLIST(f1,t); |
|
algobjtorat(f1,&f2); f = f2; |
|
} |
|
|
nocheck = 0; |
nocheck = 0; |
mindex = 0; |
mindex = 0; |
|
|
Line 2361 void nd_gr_trace(LIST f,LIST v,int trace,int homo,stru |
|
Line 2451 void nd_gr_trace(LIST f,LIST v,int trace,int homo,stru |
|
/* dp->p */ |
/* dp->p */ |
nd_bpe = cbpe; |
nd_bpe = cbpe; |
nd_setup_parameters(nd_nvar,0); |
nd_setup_parameters(nd_nvar,0); |
for ( r = cand; r; r = NEXT(r) ) BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r)); |
for ( r = cand; r; r = NEXT(r) ) { |
|
BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r)); |
|
if ( nalg ) { |
|
poly = BDY(r); |
|
for ( tv = av, s = alist; tv; tv = NEXT(tv), s = NEXT(s) ) { |
|
substr(CO,0,(Obj)poly,tv->v,(Obj)BDY(s),&obj); poly = (P)obj; |
|
} |
|
BDY(r) = poly; |
|
} |
|
} |
MKLIST(*rp,cand); |
MKLIST(*rp,cand); |
} |
} |
|
|
Line 5134 DL nd_separate_d(UINT *d,UINT *trans) |
|
Line 5233 DL nd_separate_d(UINT *d,UINT *trans) |
|
return a; |
return a; |
} |
} |
|
|
ND nd_pseudo_monic(int mod,ND p) |
int nd_monic(int mod,ND *p) |
{ |
{ |
UINT *trans,*t; |
UINT *trans,*t; |
DL alg; |
DL alg; |
MP mp0,mp; |
MP mp0,mp; |
NM m,m0,m1; |
NM m,m0,m1,ma0,ma,mb,mr0,mr; |
|
ND r; |
DL dl; |
DL dl; |
DP nm; |
DP nm; |
NDV ndv; |
NDV ndv; |
DAlg lc,inv; |
DAlg inv,cd; |
ND s,c; |
ND s,c; |
int n,ntrans,i,e,td; |
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; |
n = nd_nvar; ntrans = n-nd_nalg; |
NEWNM(m0); |
/* Q coef -> DAlg coef */ |
NEWNM(m1); |
NEWNM(ma0); ma = ma0; |
alg = nd_separate_d(HDL(p),DL(m0)); |
m = BDY(*p); |
mp0 = 0; NEXTMP(mp0,mp); mp->c = (P)HCQ(p); mp->dl = alg; |
is_lc = 1; |
if ( !mp->dl->td ) |
while ( 1 ) { |
return p; |
NEWMP(mp0); mp = mp0; |
for ( m = NEXT(BDY(p)); m; m = NEXT(m) ) { |
mp->c = (P)CQ(m); |
alg = nd_separate_d(DL(m),DL(m1)); |
mp->dl = nd_separate_d(DL(m),DL(ma)); |
if ( !ndl_equal(DL(m0),DL(m1)) ) |
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; |
break; |
NEXTMP(mp0,mp); mp->c = (P)CQ(m); mp->dl = alg; |
} |
} |
} |
NEXT(mp) = 0; |
/* l = lcm(denoms) */ |
MKDP(nd_nalg,mp0,nm); |
NTOQ(ln,1,l); |
MKDAlg(nm,ONE,lc); |
for ( mr0 = 0, m = ma0; m; m = NEXT(m) ) { |
invdalg(lc,&inv); |
divq(l,CA(m)->dn,&mul); |
ndv = ndtondv(0,p); |
for ( mp = BDY(CA(m)->nm); mp; mp = NEXT(mp) ) { |
for ( s = 0, mp = BDY(inv->nm); mp; mp = NEXT(mp) ) { |
NEXTNM(mr0,mr); |
CQ(m0) = (Q)mp->c; |
mulq((Q)mp->c,mul,&CQ(mr)); |
dl = mp->dl; |
dl = mp->dl; |
for ( td = 0, i = ntrans; i < n; i++ ) { |
td = TD(DL(m)); |
e = dl->d[i-ntrans]; |
ndl_copy(DL(m),DL(mr)); |
ndl_zero(DL(m0)); |
for ( i = ntrans; i < n; i++ ) { |
PUT_EXP(DL(m0),i,e); |
e = dl->d[i-ntrans]; |
td += MUL_WEIGHT(e,i); |
PUT_EXP(DL(mr),i,e); |
|
td += MUL_WEIGHT(e,i); |
|
} |
|
TD(DL(mr)) = td; |
|
if ( nd_blockmask) ndl_weight_mask(DL(mr)); |
} |
} |
TD(DL(m0)) = td; |
|
if ( nd_blockmask) ndl_weight_mask(trans); |
|
s = nd_add(0,s,ndv_mul_nm(0,m0,ndv)); |
|
} |
} |
ndv_free(ndv); |
NEXT(mr) = 0; |
return s; |
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; |
} |
} |