| version 1.3, 2000/08/22 05:04:04 |
version 1.7, 2018/03/29 01:32:51 |
|
|
| * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
| * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
| * |
* |
| * $OpenXM: OpenXM_contrib2/asir2000/engine/NEZ.c,v 1.2 2000/08/21 08:31:25 noro Exp $ |
* $OpenXM: OpenXM_contrib2/asir2000/engine/NEZ.c,v 1.6 2010/02/19 08:27:19 noro Exp $ |
| */ |
*/ |
| #include "ca.h" |
#include "ca.h" |
| |
|
|
|
| P *ps,*pr; |
P *ps,*pr; |
| int m; |
int m; |
| { |
{ |
| P t,s,mg; |
P t,s,mg; |
| VL tvl,svl,avl,nvl; |
VL tvl,svl,avl,nvl; |
| int i,j,k; |
int i,j,k; |
| N c; |
N c; |
| Q cq; |
Q cq; |
| P *pl,*pm; |
P *pl,*pm; |
| DCP *ml; |
DCP *ml; |
| Q *cl; |
Q *cl; |
| P **cp; |
P **cp; |
| int *cn; |
int *cn; |
| |
|
| pl = (P *)ALLOCA(m*sizeof(P)); |
if ( m == 1 ) { |
| ml = (DCP *)ALLOCA(m*sizeof(DCP)); |
*pr = ps[0]; return; |
| cl = (Q *)ALLOCA(m*sizeof(Q)); |
} |
| for ( i = 0; i < m; i++ ) |
pl = (P *)ALLOCA(m*sizeof(P)); |
| monomialfctr(vl,ps[i],&pl[i],&ml[i]); |
ml = (DCP *)ALLOCA(m*sizeof(DCP)); |
| gcdmonomial(vl,ml,m,&mg); |
cl = (Q *)ALLOCA(m*sizeof(Q)); |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) |
| ptozp(pl[i],1,&cl[i],&t); pl[i] = t; |
monomialfctr(vl,ps[i],&pl[i],&ml[i]); |
| } |
gcdmonomial(vl,ml,m,&mg); |
| for ( i = 1, cq = cl[0]; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| gcdn(NM(cl[i]),NM(cq),&c); NTOQ(c,1,cq); |
ptozp(pl[i],1,&cl[i],&t); pl[i] = t; |
| } |
} |
| for ( i = 0; i < m; i++ ) |
for ( i = 1, cq = cl[0]; i < m; i++ ) { |
| if ( NUM(pl[i]) ) { |
gcdn(NM(cl[i]),NM(cq),&c); NTOQ(c,1,cq); |
| mulp(vl,(P)cq,mg,pr); return; |
} |
| } |
for ( i = 0; i < m; i++ ) |
| for ( i = 0, nvl = vl, avl = 0; nvl && i < m; i++ ) { |
if ( NUM(pl[i]) ) { |
| clctv(vl,pl[i],&tvl); |
mulp(vl,(P)cq,mg,pr); return; |
| intersectv(nvl,tvl,&svl); nvl = svl; |
} |
| mergev(vl,avl,tvl,&svl); avl = svl; |
for ( i = 0, nvl = vl, avl = 0; nvl && i < m; i++ ) { |
| } |
clctv(vl,pl[i],&tvl); |
| if ( !nvl ) { |
intersectv(nvl,tvl,&svl); nvl = svl; |
| mulp(vl,(P)cq,mg,pr); return; |
mergev(vl,avl,tvl,&svl); avl = svl; |
| } |
} |
| if ( !NEXT(avl) ) { |
if ( !nvl ) { |
| nuezgcdnpzmain(vl,pl,m,&t); mulp(vl,t,(P)cq,&s); mulp(vl,s,mg,pr); |
mulp(vl,(P)cq,mg,pr); return; |
| return; |
} |
| } |
if ( !NEXT(avl) ) { |
| for ( tvl = nvl, i = 0; tvl; tvl = NEXT(tvl), i++ ); |
nuezgcdnpzmain(vl,pl,m,&t); mulp(vl,t,(P)cq,&s); mulp(vl,s,mg,pr); |
| for ( tvl = avl, j = 0; tvl; tvl = NEXT(tvl), j++ ); |
return; |
| if ( i == j ) { |
} |
| /* all the pl[i]'s have the same variables */ |
for ( tvl = nvl, i = 0; tvl; tvl = NEXT(tvl), i++ ); |
| sortplistbyhomdeg(pl,m); nezgcdnpzmain(nvl,pl,m,&t); |
for ( tvl = avl, j = 0; tvl; tvl = NEXT(tvl), j++ ); |
| |
if ( i == j ) { |
| |
/* all the pl[i]'s have the same variables */ |
| |
sortplistbyhomdeg(pl,m); nezgcdnpzmain(nvl,pl,m,&t); |
| #if 0 |
#if 0 |
| /* search the minimal degree poly */ |
/* search the minimal degree poly */ |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| for ( tvl = nvl; tvl; tvl = NEXT(tvl) ) { |
for ( tvl = nvl; tvl; tvl = NEXT(tvl) ) { |
| dt = getdeg(tvl->v,pl[i]); |
dt = getdeg(tvl->v,pl[i]); |
| if ( tvl == nvl || dt < d1 ) { |
if ( tvl == nvl || dt < d1 ) { |
| v1 = tvl->v; d1 = dt; |
v1 = tvl->v; d1 = dt; |
| } |
} |
| } |
} |
| if ( i == 0 || d1 < d ) { |
if ( i == 0 || d1 < d ) { |
| v = v1; d = d1; j = i; |
v = v1; d = d1; j = i; |
| } |
} |
| } |
} |
| t = pl[0]; pl[0] = pl[j]; pl[j] = t; |
t = pl[0]; pl[0] = pl[j]; pl[j] = t; |
| if ( v != nvl->v ) { |
if ( v != nvl->v ) { |
| reordvar(nvl,v,&mvl); |
reordvar(nvl,v,&mvl); |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| reorderp(mvl,nvl,pl[i],&t); pl[i] = t; |
reorderp(mvl,nvl,pl[i],&t); pl[i] = t; |
| } |
} |
| nezgcdnpzmain(mvl,pl,m,&s); reorderp(nvl,mvl,s,&t); |
nezgcdnpzmain(mvl,pl,m,&s); reorderp(nvl,mvl,s,&t); |
| } else |
} else |
| nezgcdnpzmain(nvl,pl,m,&t); |
nezgcdnpzmain(nvl,pl,m,&t); |
| #endif |
#endif |
| } else { |
} else { |
| cp = (P **)ALLOCA(m*sizeof(P *)); |
cp = (P **)ALLOCA(m*sizeof(P *)); |
| cn = (int *)ALLOCA(m*sizeof(int)); |
cn = (int *)ALLOCA(m*sizeof(int)); |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| cp[i] = (P *)ALLOCA(lengthp(pl[i])*sizeof(P)); |
cp[i] = (P *)ALLOCA(lengthp(pl[i])*sizeof(P)); |
| cn[i] = pcoef(vl,nvl,pl[i],cp[i]); |
cn[i] = pcoef(vl,nvl,pl[i],cp[i]); |
| } |
} |
| for ( i = j = 0; i < m; i++ ) |
for ( i = j = 0; i < m; i++ ) |
| j += cn[i]; |
j += cn[i]; |
| pm = (P *)ALLOCA(j*sizeof(P)); |
pm = (P *)ALLOCA(j*sizeof(P)); |
| for ( i = k = 0; i < m; i++ ) |
for ( i = k = 0; i < m; i++ ) |
| for ( j = 0; j < cn[i]; j++ ) |
for ( j = 0; j < cn[i]; j++ ) |
| pm[k++] = cp[i][j]; |
pm[k++] = cp[i][j]; |
| nezgcdnpz(vl,pm,k,&t); |
nezgcdnpz(vl,pm,k,&t); |
| } |
} |
| mulp(vl,t,(P)cq,&s); mulp(vl,s,mg,pr); |
mulp(vl,t,(P)cq,&s); mulp(vl,s,mg,pr); |
| } |
} |
| |
|
| void sortplistbyhomdeg(p,n) |
void sortplistbyhomdeg(p,n) |
| P *p; |
P *p; |
| int n; |
int n; |
| { |
{ |
| int i,j,k; |
int i,j,k; |
| int *l; |
int *l; |
| P t; |
P t; |
| |
|
| l = (int *)ALLOCA(n*sizeof(int)); |
l = (int *)ALLOCA(n*sizeof(int)); |
| for ( i = 0; i < n; i++ ) |
for ( i = 0; i < n; i++ ) |
| l[i] = homdeg(p[i]); |
l[i] = homdeg(p[i]); |
| for ( i = 0; i < n; i++ ) |
for ( i = 0; i < n; i++ ) |
| for ( j = i + 1; j < n; j++ ) |
for ( j = i + 1; j < n; j++ ) |
| if ( l[j] < l[i] ) { |
if ( l[j] < l[i] ) { |
| t = p[i]; p[i] = p[j]; p[j] = t; |
t = p[i]; p[i] = p[j]; p[j] = t; |
| k = l[i]; l[i] = l[j]; l[j] = k; |
k = l[i]; l[i] = l[j]; l[j] = k; |
| } |
} |
| } |
} |
| |
|
| void nuezgcdnpzmain(vl,ps,m,r) |
void nuezgcdnpzmain(vl,ps,m,r) |
|
|
| int m; |
int m; |
| P *r; |
P *r; |
| { |
{ |
| P *tps; |
P *tps; |
| P f,t; |
P f,t; |
| int i; |
int i; |
| |
|
| for ( i = 0; i < m; i++ ) |
for ( i = 0; i < m; i++ ) |
| if ( NUM(ps[i]) ) { |
if ( NUM(ps[i]) ) { |
| *r = (P)ONE; return; |
*r = (P)ONE; return; |
| } |
} |
| tps = (P *) ALLOCA(m*sizeof(P)); |
tps = (P *) ALLOCA(m*sizeof(P)); |
| for ( i = 0; i < m; i++ ) |
for ( i = 0; i < m; i++ ) |
| tps[i] = ps[i]; |
tps[i] = ps[i]; |
| sortplist(tps,m); |
sortplist(tps,m); |
| for ( i = 1, f = tps[0]; i < m && !NUM(f); i++ ) { |
for ( i = 1, f = tps[0]; i < m && !NUM(f); i++ ) { |
| uezgcdpz(vl,f,tps[i],&t); f = t; |
uezgcdpz(vl,f,tps[i],&t); f = t; |
| } |
} |
| *r = f; |
*r = f; |
| } |
} |
| |
|
| void gcdmonomial(vl,dcl,m,r) |
void gcdmonomial(vl,dcl,m,r) |
|
|
| int m; |
int m; |
| P *r; |
P *r; |
| { |
{ |
| int i,j,n; |
int i,j,n; |
| P g,x,s,t; |
P g,x,s,t; |
| Q d; |
Q d; |
| DCP dc; |
DCP dc; |
| VN vn; |
VN vn; |
| |
|
| for ( i = 0; i < m; i++ ) |
for ( i = 0; i < m; i++ ) |
| if ( !dcl[i] ) { |
if ( !dcl[i] ) { |
| *r = (P)ONE; return; |
*r = (P)ONE; return; |
| } |
} |
| for ( n = 0, dc = dcl[0]; dc; dc = NEXT(dc), n++ ); |
for ( n = 0, dc = dcl[0]; dc; dc = NEXT(dc), n++ ); |
| vn = (VN)ALLOCA(n*sizeof(struct oVN)); |
vn = (VN)ALLOCA(n*sizeof(struct oVN)); |
| for ( i = 0, dc = dcl[0]; i < n; dc = NEXT(dc), i++ ) { |
for ( i = 0, dc = dcl[0]; i < n; dc = NEXT(dc), i++ ) { |
| vn[i].v = VR(COEF(dc)); vn[i].n = QTOS(DEG(dc)); |
vn[i].v = VR(COEF(dc)); vn[i].n = QTOS(DEG(dc)); |
| } |
} |
| for ( i = 1; i < m; i++ ) { |
for ( i = 1; i < m; i++ ) { |
| for ( j = 0; j < n; j++ ) { |
for ( j = 0; j < n; j++ ) { |
| for ( dc = dcl[i]; dc; dc = NEXT(dc) ) |
for ( dc = dcl[i]; dc; dc = NEXT(dc) ) |
| if ( VR(COEF(dc)) == vn[j].v ) { |
if ( VR(COEF(dc)) == vn[j].v ) { |
| vn[j].n = MIN(vn[j].n,QTOS(DEG(dc))); break; |
vn[j].n = MIN(vn[j].n,QTOS(DEG(dc))); break; |
| } |
} |
| if ( !dc ) |
if ( !dc ) |
| vn[j].n = 0; |
vn[j].n = 0; |
| } |
} |
| for ( j = n-1; j >= 0 && !vn[j].n; j-- ); |
for ( j = n-1; j >= 0 && !vn[j].n; j-- ); |
| if ( j < 0 ) { |
if ( j < 0 ) { |
| *r = (P)ONE; return; |
*r = (P)ONE; return; |
| } else |
} else |
| n = j+1; |
n = j+1; |
| } |
} |
| for ( j = 0, g = (P)ONE; j < n; j++ ) |
for ( j = 0, g = (P)ONE; j < n; j++ ) |
| if ( vn[j].n ) { |
if ( vn[j].n ) { |
| MKV(vn[j].v,x); STOQ(vn[j].n,d); |
MKV(vn[j].v,x); STOQ(vn[j].n,d); |
| pwrp(vl,x,d,&t); mulp(vl,t,g,&s); g = s; |
pwrp(vl,x,d,&t); mulp(vl,t,g,&s); g = s; |
| } |
} |
| *r = g; |
*r = g; |
| } |
} |
| |
|
| void nezgcdnpzmain(vl,pl,m,pr) |
void nezgcdnpzmain(vl,pl,m,pr) |
|
|
| P *pl,*pr; |
P *pl,*pr; |
| int m; |
int m; |
| { |
{ |
| P *ppl,*pcl; |
P *ppl,*pcl; |
| int i; |
int i; |
| P cont,gcd,t,s; |
P cont,gcd,t,s; |
| DCP dc; |
DCP dc; |
| |
|
| ppl = (P *)ALLOCA(m*sizeof(P)); |
ppl = (P *)ALLOCA(m*sizeof(P)); |
| pcl = (P *)ALLOCA(m*sizeof(P)); |
pcl = (P *)ALLOCA(m*sizeof(P)); |
| for ( i = 0; i < m; i++ ) |
for ( i = 0; i < m; i++ ) |
| pcp(vl,pl[i],&ppl[i],&pcl[i]); |
pcp(vl,pl[i],&ppl[i],&pcl[i]); |
| nezgcdnpz(vl,pcl,m,&cont); |
nezgcdnpz(vl,pcl,m,&cont); |
| sqfrp(vl,ppl[0],&dc); |
sqfrp(vl,ppl[0],&dc); |
| for ( dc = NEXT(dc), gcd = (P)ONE; dc; dc = NEXT(dc) ) { |
for ( dc = NEXT(dc), gcd = (P)ONE; dc; dc = NEXT(dc) ) { |
| if ( NUM(COEF(dc)) ) |
if ( NUM(COEF(dc)) ) |
| continue; |
continue; |
| nezgcdnpp(vl,dc,ppl+1,m-1,&t); |
nezgcdnpp(vl,dc,ppl+1,m-1,&t); |
| if ( NUM(t) ) |
if ( NUM(t) ) |
| continue; |
continue; |
| mulp(vl,gcd,t,&s); gcd = s; |
mulp(vl,gcd,t,&s); gcd = s; |
| } |
} |
| mulp(vl,gcd,cont,pr); |
mulp(vl,gcd,cont,pr); |
| } |
} |
| |
|
| void nezgcdnpp(vl,dc,pl,m,r) |
void nezgcdnpp(vl,dc,pl,m,r) |
|
|
| int m; |
int m; |
| P *r; |
P *r; |
| { |
{ |
| int i,k; |
int i,k; |
| P g,t,s,gcd; |
P g,t,s,gcd; |
| P *pm; |
P *pm; |
| |
|
| nezgcdnp_sqfr_primitive(vl,COEF(dc),pl,m,&gcd); |
nezgcdnp_sqfr_primitive(vl,COEF(dc),pl,m,&gcd); |
| if ( NUM(gcd) ) { |
if ( NUM(gcd) ) { |
| *r = (P)ONE; return; |
*r = (P)ONE; return; |
| } |
} |
| pm = (P *) ALLOCA(m*sizeof(P)); |
pm = (P *) ALLOCA(m*sizeof(P)); |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| divsp(vl,pl[i],gcd,&pm[i]); |
divsp(vl,pl[i],gcd,&pm[i]); |
| if ( NUM(pm[i]) ) { |
if ( NUM(pm[i]) ) { |
| *r = gcd; return; |
*r = gcd; return; |
| } |
} |
| } |
} |
| for ( g = gcd, k = QTOS(DEG(dc))-1; k > 0; k-- ) { |
for ( g = gcd, k = QTOS(DEG(dc))-1; k > 0; k-- ) { |
| nezgcdnp_sqfr_primitive(vl,g,pm,m,&t); |
nezgcdnp_sqfr_primitive(vl,g,pm,m,&t); |
| if ( NUM(t) ) |
if ( NUM(t) ) |
| break; |
break; |
| mulp(vl,gcd,t,&s); gcd = s; |
mulp(vl,gcd,t,&s); gcd = s; |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| divsp(vl,pm[i],t,&s); |
divsp(vl,pm[i],t,&s); |
| if ( NUM(s) ) { |
if ( NUM(s) ) { |
| *r = gcd; return; |
*r = gcd; return; |
| } |
} |
| pm[i] = s; |
pm[i] = s; |
| } |
} |
| } |
} |
| *r = gcd; |
*r = gcd; |
| } |
} |
| |
|
| /* |
/* |
|
|
| int m; |
int m; |
| P p0,*ps,*pr; |
P p0,*ps,*pr; |
| { |
{ |
| /* variables */ |
/* variables */ |
| P p00,g,h,g0,h0,a0,b0; |
P p00,g,h,g0,h0,a0,b0; |
| P lp0,lgp0,lp00,lg,lg0,cbd,tq,t; |
P lp0,lgp0,lp00,lg,lg0,cbd,tq,t; |
| P *lc; |
P *lc; |
| P *tps; |
P *tps; |
| VL nvl1,nvl2,nvl,tvl; |
VL nvl1,nvl2,nvl,tvl; |
| V v; |
V v; |
| int i,j,k,d0,dg,dg0,dmin; |
int i,j,k,d0,dg,dg0,dmin,z; |
| VN vn0,vn1,vnt; |
VN vn1; |
| int nv,flag; |
int nv,flag,max; |
| |
|
| /* set-up */ |
/* set-up */ |
| if ( NUM(p0) ) { |
if ( NUM(p0) ) { |
| *pr = (P) ONE; return; |
*pr = (P) ONE; return; |
| } |
} |
| for ( v = VR(p0), i = 0; i < m; i++ ) |
for ( v = VR(p0), i = 0; i < m; i++ ) |
| if ( NUM(ps[i]) || (v != VR(ps[i])) ) { |
if ( NUM(ps[i]) || (v != VR(ps[i])) ) { |
| *pr = (P)ONE; return; |
*pr = (P)ONE; return; |
| } |
} |
| tps = (P *) ALLOCA(m*sizeof(P)); |
tps = (P *) ALLOCA(m*sizeof(P)); |
| for ( i = 0; i < m; i++ ) |
for ( i = 0; i < m; i++ ) |
| tps[i] = ps[i]; |
tps[i] = ps[i]; |
| sortplist(tps,m); |
sortplist(tps,m); |
| /* deg(tps[0]) <= deg(tps[1]) <= ... */ |
/* deg(tps[0]) <= deg(tps[1]) <= ... */ |
| |
|
| if ( !cmpq(DEG(DC(p0)),ONE) ) { |
if ( !cmpq(DEG(DC(p0)),ONE) ) { |
| if ( divcheck(vl,tps,m,(P)ONE,p0) ) |
if ( divcheck(vl,tps,m,(P)ONE,p0) ) |
| *pr = p0; |
*pr = p0; |
| else |
else |
| *pr = (P)ONE; |
*pr = (P)ONE; |
| return; |
return; |
| } |
} |
| |
|
| lp0 = LC(p0); dmin = d0 = deg(v,p0); lc = (P *)ALLOCA((m+1)*sizeof(P)); |
lp0 = LC(p0); dmin = d0 = deg(v,p0); lc = (P *)ALLOCA((m+1)*sizeof(P)); |
| for ( lc[0] = lp0, i = 0; i < m; i++ ) |
for ( lc[0] = lp0, i = 0; i < m; i++ ) |
| lc[i+1] = LC(tps[i]); |
lc[i+1] = LC(tps[i]); |
| clctv(vl,p0,&nvl); |
clctv(vl,p0,&nvl); |
| for ( i = 0; i < m; i++ ) { |
for ( i = 0; i < m; i++ ) { |
| clctv(vl,tps[i],&nvl1); mergev(vl,nvl,nvl1,&nvl2); nvl = nvl2; |
clctv(vl,tps[i],&nvl1); mergev(vl,nvl,nvl1,&nvl2); nvl = nvl2; |
| } |
} |
| nezgcdnpz(nvl,lc,m+1,&lg); |
nezgcdnpz(nvl,lc,m+1,&lg); |
| |
|
| mulp(nvl,p0,lg,&lgp0); k = dbound(v,lgp0)+1; cbound(nvl,lgp0,(Q *)&cbd); |
mulp(nvl,p0,lg,&lgp0); k = dbound(v,lgp0)+1; cbound(nvl,lgp0,(Q *)&cbd); |
| for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++ ); |
for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++ ); |
| W_CALLOC(nv,struct oVN,vn0); W_CALLOC(nv,struct oVN,vnt); |
W_CALLOC(nv,struct oVN,vn1); |
| W_CALLOC(nv,struct oVN,vn1); |
for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ ) |
| for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ ) |
vn1[i].v = tvl->v; |
| vn1[i].v = vn0[i].v = tvl->v; |
|
| |
|
| /* main loop */ |
/* main loop */ |
| for ( dg = deg(v,tps[0]) + 1; ; next(vn0) ) |
/* finally, 'max' random evaluations will be generated */ |
| do { |
for ( max = 1, dg = deg(v,tps[0]) + 1; ; max = 2*max ) |
| for ( i = 0, j = 0; vn0[i].v; i++ ) |
for ( z = 0; z < max; z++ ) { |
| if ( vn0[i].n ) vnt[j++].v = (V)i; |
for ( i = 0; vn1[i].v; i++ ) |
| vnt[j].n = 0; |
vn1[i].n = mt_genrand()%max; |
| |
|
| /* find b s.t. LC(p0)(b), LC(tps[i])(b) != 0 */ |
/* find b s.t. LC(p0)(b), LC(tps[i])(b) != 0 */ |
| mulsgn(vn0,vnt,j,vn1); substvp(nvl,p0,vn1,&p00); |
|
| flag = (!zerovpchk(nvl,lp0,vn1) && sqfrchk(p00)); |
substvp(nvl,p0,vn1,&p00); |
| for ( i = 0; flag && (i < m); i++ ) |
flag = (!zerovpchk(nvl,lp0,vn1) && sqfrchk(p00)); |
| flag &= (!zerovpchk(nvl,LC(tps[i]),vn1)); |
for ( i = 0; flag && (i < m); i++ ) |
| if ( !flag ) |
flag &= (!zerovpchk(nvl,LC(tps[i]),vn1)); |
| continue; |
if ( !flag ) |
| |
continue; |
| |
|
| /* substitute y -> b */ |
/* substitute y -> b */ |
| substvp(nvl,lg,vn1,&lg0); lp00 = LC(p00); |
substvp(nvl,lg,vn1,&lg0); lp00 = LC(p00); |
| /* extended-gcd in 1-variable */ |
/* extended-gcd in 1-variable */ |
| uexgcdnp(nvl,p00,tps,m,vn1,(Q)cbd,&g0,&h0,&a0,&b0,(Q *)&tq); |
uexgcdnp(nvl,p00,tps,m,vn1,(Q)cbd,&g0,&h0,&a0,&b0,(Q *)&tq); |
| if ( NUM(g0) ) { |
if ( NUM(g0) ) { |
| *pr = (P)ONE; return; |
*pr = (P)ONE; return; |
| } else if ( dg > ( dg0 = deg(v,g0) ) ) { |
} else if ( dg > ( dg0 = deg(v,g0) ) ) { |
| dg = dg0; |
dg = dg0; |
| if ( dg == d0 ) { |
if ( dg == d0 ) { |
| if ( divcheck(nvl,tps,m,lp0,p0) ) { |
if ( divcheck(nvl,tps,m,lp0,p0) ) { |
| *pr = p0; return; |
*pr = p0; return; |
| } |
} |
| } else if ( dg == deg(v,tps[0]) ) { |
} else if ( dg == deg(v,tps[0]) ) { |
| if ( divtpz(nvl,p0,tps[0],&t) && |
if ( divtpz(nvl,p0,tps[0],&t) && |
| divcheck(nvl,tps+1,m-1,LC(tps[0]),tps[0]) ) { |
divcheck(nvl,tps+1,m-1,LC(tps[0]),tps[0]) ) { |
| *pr = tps[0]; return; |
*pr = tps[0]; return; |
| } else |
} else |
| break; |
break; |
| } else { |
} else { |
| henmv(nvl,vn1,lgp0,g0,h0,a0,b0,lg,lp0,lg0,lp00,(Q)tq,k,&g,&h); |
henmv(nvl,vn1,lgp0,g0,h0,a0,b0,lg,lp0,lg0,lp00,(Q)tq,k,&g,&h); |
| if ( divtpz(nvl,lgp0,g,&t) && |
if ( divtpz(nvl,lgp0,g,&t) && |
| divcheck(nvl,tps,m,lg,g) ) { |
divcheck(nvl,tps,m,lg,g) ) { |
| pcp(nvl,g,pr,&t); return; |
pcp(nvl,g,pr,&t); return; |
| } |
} |
| } |
} |
| } |
} |
| } while ( !nextbin(vnt,j) ); |
} |
| } |
} |
| |
|
| void intersectv(vl1,vl2,vlp) |
void intersectv(vl1,vl2,vlp) |
| VL vl1,vl2,*vlp; |
VL vl1,vl2,*vlp; |
| { |
{ |
| int i,n; |
int i,n; |
| VL tvl; |
VL tvl; |
| VN tvn; |
VN tvn; |
| |
|
| if ( !vl1 || !vl2 ) { |
if ( !vl1 || !vl2 ) { |
| *vlp = 0; return; |
*vlp = 0; return; |
| } |
} |
| for ( n = 0, tvl = vl1; tvl; tvl = NEXT(tvl), n++ ); |
for ( n = 0, tvl = vl1; tvl; tvl = NEXT(tvl), n++ ); |
| tvn = (VN) ALLOCA(n*sizeof(struct oVN)); |
tvn = (VN) ALLOCA(n*sizeof(struct oVN)); |
| for ( i = 0, tvl = vl1; i < n; tvl = NEXT(tvl), i++ ) { |
for ( i = 0, tvl = vl1; i < n; tvl = NEXT(tvl), i++ ) { |
| tvn[i].v = tvl->v; tvn[i].n = 0; |
tvn[i].v = tvl->v; tvn[i].n = 0; |
| } |
} |
| for ( tvl = vl2; tvl; tvl = NEXT(tvl) ) |
for ( tvl = vl2; tvl; tvl = NEXT(tvl) ) |
| for ( i = 0; i < n; i++ ) |
for ( i = 0; i < n; i++ ) |
| if ( tvn[i].v == tvl->v ) { |
if ( tvn[i].v == tvl->v ) { |
| tvn[i].n = 1; break; |
tvn[i].n = 1; break; |
| } |
} |
| vntovl(tvn,n,vlp); |
vntovl(tvn,n,vlp); |
| } |
} |
| |
|
| int pcoef(vl,ivl,p,cp) |
int pcoef(vl,ivl,p,cp) |
|
|
| P p; |
P p; |
| P *cp; |
P *cp; |
| { |
{ |
| VL nvl,tvl,svl,mvl,mvl0; |
VL nvl,tvl,svl,mvl,mvl0; |
| P t; |
P t; |
| |
|
| if ( NUM(p) ) { |
if ( NUM(p) ) { |
| cp[0] = p; return 1; |
cp[0] = p; return 1; |
| } else { |
} else { |
| clctv(vl,p,&nvl); |
clctv(vl,p,&nvl); |
| for ( tvl = nvl, mvl0 = 0; tvl; tvl = NEXT(tvl) ) { |
for ( tvl = nvl, mvl0 = 0; tvl; tvl = NEXT(tvl) ) { |
| for ( svl = ivl; svl; svl = NEXT(svl) ) |
for ( svl = ivl; svl; svl = NEXT(svl) ) |
| if ( tvl->v == svl->v ) |
if ( tvl->v == svl->v ) |
| break; |
break; |
| if ( !svl ) { |
if ( !svl ) { |
| if ( !mvl0 ) { |
if ( !mvl0 ) { |
| NEWVL(mvl0); mvl = mvl0; |
NEWVL(mvl0); mvl = mvl0; |
| } else { |
} else { |
| NEWVL(NEXT(mvl)); mvl = NEXT(mvl); |
NEWVL(NEXT(mvl)); mvl = NEXT(mvl); |
| } |
} |
| mvl->v = tvl->v; |
mvl->v = tvl->v; |
| } |
} |
| } |
} |
| if ( mvl0 ) |
if ( mvl0 ) |
| NEXT(mvl) = ivl; |
NEXT(mvl) = ivl; |
| else |
else |
| mvl0 = ivl; |
mvl0 = ivl; |
| reorderp(mvl0,nvl,p,&t); |
reorderp(mvl0,nvl,p,&t); |
| return pcoef0(mvl0,ivl,t,cp); |
return pcoef0(mvl0,ivl,t,cp); |
| } |
} |
| } |
} |
| |
|
| int pcoef0(vl,ivl,p,cp) |
int pcoef0(vl,ivl,p,cp) |
|
|
| P p; |
P p; |
| P *cp; |
P *cp; |
| { |
{ |
| int cn,n; |
int cn,n; |
| DCP dc; |
DCP dc; |
| V v; |
V v; |
| VL tvl; |
VL tvl; |
| |
|
| if ( NUM(p) ) { |
if ( NUM(p) ) { |
| cp[0] = p; return 1; |
cp[0] = p; return 1; |
| } else { |
} else { |
| for ( v = VR(p), tvl = ivl; tvl; tvl = NEXT(tvl) ) |
for ( v = VR(p), tvl = ivl; tvl; tvl = NEXT(tvl) ) |
| if ( v == tvl->v ) |
if ( v == tvl->v ) |
| break; |
break; |
| if ( tvl ) { |
if ( tvl ) { |
| cp[0] = p; return 1; |
cp[0] = p; return 1; |
| } else { |
} else { |
| for ( dc = DC(p), n = 0; dc; dc = NEXT(dc) ) { |
for ( dc = DC(p), n = 0; dc; dc = NEXT(dc) ) { |
| cn = pcoef0(vl,ivl,COEF(dc),cp); cp += cn; n += cn; |
cn = pcoef0(vl,ivl,COEF(dc),cp); cp += cn; n += cn; |
| } |
} |
| return n; |
return n; |
| } |
} |
| } |
} |
| } |
} |
| |
|
| int lengthp(p) |
int lengthp(p) |
| P p; |
P p; |
| { |
{ |
| int n; |
int n; |
| DCP dc; |
DCP dc; |
| |
|
| if ( NUM(p) ) |
if ( NUM(p) ) |
| return 1; |
return 1; |
| else { |
else { |
| for ( dc = DC(p), n = 0; dc; dc = NEXT(dc) ) |
for ( dc = DC(p), n = 0; dc; dc = NEXT(dc) ) |
| n += lengthp(COEF(dc)); |
n += lengthp(COEF(dc)); |
| return n; |
return n; |
| } |
} |
| |
} |
| |
|
| |
int nonzero_const_term(P p) |
| |
{ |
| |
DCP dc; |
| |
|
| |
if ( !p ) |
| |
return 0; |
| |
else if ( NUM(p) ) |
| |
return 1; |
| |
else { |
| |
dc = DC(p); |
| |
for ( ; NEXT(dc); dc = NEXT(dc) ); |
| |
if ( DEG(dc) ) |
| |
return 0; |
| |
else |
| |
return nonzero_const_term(COEF(dc)); |
| |
} |
| } |
} |