#ifdef MODULAR
void addmp(VL vl,int mod,P p1,P p2,P *pr)
#else
void addp(VL vl,P p1,P p2,P *pr)
#endif
{
DCP dc1,dc2,dcr0,dcr;
V v1,v2;
P t;
if ( !p1 )
*pr = p2;
else if ( !p2 )
*pr = p1;
else if ( NUM(p1) )
if ( NUM(p2) )
ADDNUM(p1,p2,pr);
else
ADDPQ(p2,p1,pr);
else if ( NUM(p2) )
ADDPQ(p1,p2,pr);
else if ( ( v1 = VR(p1) ) == ( v2 = VR(p2) ) ) {
for ( dc1 = DC(p1), dc2 = DC(p2), dcr0 = 0; dc1 && dc2; )
switch ( cmpz(DEG(dc1),DEG(dc2)) ) {
case 0:
ADDP(vl,COEF(dc1),COEF(dc2),&t);
if ( t ) {
NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc1); COEF(dcr) = t;
}
dc1 = NEXT(dc1); dc2 = NEXT(dc2); break;
case 1:
NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc1); COEF(dcr) = COEF(dc1);
dc1 = NEXT(dc1); break;
case -1:
NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc2); COEF(dcr) = COEF(dc2);
dc2 = NEXT(dc2); break;
}
if ( !dcr0 )
if ( dc1 )
dcr0 = dc1;
else if ( dc2 )
dcr0 = dc2;
else {
*pr = 0;
return;
}
else
if ( dc1 )
NEXT(dcr) = dc1;
else if ( dc2 )
NEXT(dcr) = dc2;
else
NEXT(dcr) = 0;
MKP(v1,dcr0,*pr);
} else {
while ( v1 != VR(vl) && v2 != VR(vl) )
vl = NEXT(vl);
if ( v1 == VR(vl) )
ADDPTOC(vl,p1,p2,pr);
else
ADDPTOC(vl,p2,p1,pr);
}
}
#ifdef MODULAR
void addmpq(int mod,P p,P q,P *pr)
#else
void addpq(P p,P q,P *pr)
#endif
{
DCP dc,dcr,dcr0;
P t;
if ( NUM(p) )
ADDNUM(p,q,pr);
else {
dc = DC(p);
for ( dcr0 = 0; dc && cmpz(DEG(dc),0) > 0; dc = NEXT(dc) ) {
NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = COEF(dc);
}
if ( !dc ) {
NEXTDC(dcr0,dcr);
DEG(dcr) = 0; COEF(dcr) = q; NEXT(dcr) = 0;
} else if ( !DEG(dc) ) {
ADDPQ(COEF(dc),q,&t);
if ( t ) {
NEXTDC(dcr0,dcr);
DEG(dcr) = 0; COEF(dcr) = t;
}
NEXT(dcr) = NEXT(dc);
} else {
NEXTDC(dcr0,dcr);
DEG(dcr) = 0; COEF(dcr) = q; NEXT(dcr) = dc;
}
MKP(VR(p),dcr0,*pr);
}
}
#ifdef MODULAR
void addmptoc(VL vl,int mod,P p,P c,P *pr)
#else
void addptoc(VL vl,P p,P c,P *pr)
#endif
{
DCP dc,dcr,dcr0;
P t;
for ( dcr0 = 0, dc = DC(p); dc && cmpz(DEG(dc),0) > 0; dc = NEXT(dc) ) {
NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = COEF(dc);
}
if ( !dc ) {
NEXTDC(dcr0,dcr);
DEG(dcr) = 0; COEF(dcr) = c; NEXT(dcr) = 0;
} else if ( !DEG(dc) ) {
ADDP(vl,COEF(dc),c,&t);
if ( t ) {
NEXTDC(dcr0,dcr);
DEG(dcr) = 0; COEF(dcr) = t;
}
NEXT(dcr) = NEXT(dc);
} else {
NEXTDC(dcr0,dcr);
DEG(dcr) = 0; COEF(dcr) = c; NEXT(dcr) = dc;
}
MKP(VR(p),dcr0,*pr);
}
#ifdef MODULAR
void submp(VL vl,int mod,P p1,P p2,P *pr)
#else
void subp(VL vl,P p1,P p2,P *pr)
#endif
{
P t;
if ( !p2 )
*pr = p1;
else {
CHSGNP(p2,&t); ADDP(vl,p1,t,pr);
}
}
#ifdef MODULAR
void mulmp(VL vl,int mod,P p1,P p2,P *pr)
#else
void mulp(VL vl,P p1,P p2,P *pr)
#endif
{
DCP dc,dct,dcr,dcr0;
V v1,v2;
P t,s,u;
int n1,n2;
if ( !p1 || !p2 ) *pr = 0;
else if ( NUM(p1) )
MULPQ(p2,p1,pr);
else if ( NUM(p2) )
MULPQ(p1,p2,pr);
else if ( ( v1 = VR(p1) ) == ( v2 = VR(p2) ) ) {
for ( dc = DC(p1), n1 = 0; dc; dc = NEXT(dc), n1++ );
for ( dc = DC(p2), n2 = 0; dc; dc = NEXT(dc), n2++ );
if ( n1 > n2 )
for ( dc = DC(p2), s = 0; dc; dc = NEXT(dc) ) {
for ( dcr0 = 0, dct = DC(p1); dct; dct = NEXT(dct) ) {
NEXTDC(dcr0,dcr); MULP(vl,COEF(dct),COEF(dc),&COEF(dcr));
addz(DEG(dct),DEG(dc),&DEG(dcr));
}
NEXT(dcr) = 0; MKP(v1,dcr0,t);
ADDP(vl,s,t,&u); s = u; t = u = 0;
}
else
for ( dc = DC(p1), s = 0; dc; dc = NEXT(dc) ) {
for ( dcr0 = 0, dct = DC(p2); dct; dct = NEXT(dct) ) {
NEXTDC(dcr0,dcr); MULP(vl,COEF(dct),COEF(dc),&COEF(dcr));
addz(DEG(dct),DEG(dc),&DEG(dcr));
}
NEXT(dcr) = 0; MKP(v1,dcr0,t);
ADDP(vl,s,t,&u); s = u; t = u = 0;
}
*pr = s;
} else {
while ( v1 != VR(vl) && v2 != VR(vl) )
vl = NEXT(vl);
if ( v1 == VR(vl) )
MULPC(vl,p1,p2,pr);
else
MULPC(vl,p2,p1,pr);
}
}
#ifdef MODULAR
void mulmpq(int mod,P p,P q,P *pr)
#else
void mulpq(P p,P q,P *pr)
#endif
{
DCP dc,dcr,dcr0;
P t;
if (!p || !q)
*pr = 0;
else if ( Uniq(q) )
*pr = p;
else if ( NUM(p) )
MULNUM(p,q,pr);
else {
for ( dcr0 = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
MULPQ(COEF(dc),q,&t);
if ( t ) {
NEXTDC(dcr0,dcr); COEF(dcr) = t; DEG(dcr) = DEG(dc);
}
}
if ( dcr0 ) {
NEXT(dcr) = 0; MKP(VR(p),dcr0,*pr);
} else
*pr = 0;
}
}
#ifdef MODULAR
void mulmpc(VL vl,int mod,P p,P c,P *pr)
#else
void mulpc(VL vl,P p,P c,P *pr)
#endif
{
DCP dc,dcr,dcr0;
P t;
if ( NUM(c) )
MULPQ(p,c,pr);
else {
for ( dcr0 = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
MULP(vl,COEF(dc),c,&t);
if ( t ) {
NEXTDC(dcr0,dcr); COEF(dcr) = t; DEG(dcr) = DEG(dc);
}
}
if ( dcr0 ) {
NEXT(dcr) = 0; MKP(VR(p),dcr0,*pr);
} else
*pr = 0;
}
}
#ifdef MODULAR
void pwrmp(VL vl,int mod,P p,Z q,P *pr)
#else
void pwrp(VL vl,P p,Z q,P *pr)
#endif
{
DCP dc,dcr;
int n,i;
P *x,*y;
P t,s,u;
DCP dct;
P *pt;
if ( !q ) {
*pr = (P)One;
} else if ( !p )
*pr = 0;
else if ( UNIQ(q) )
*pr = p;
else if ( NUM(p) )
PWRNUM(p,(Q)q,pr);
else {
dc = DC(p);
if ( !NEXT(dc) ) {
NEWDC(dcr);
PWRP(vl,COEF(dc),q,&COEF(dcr)); mulz(DEG(dc),(Z)q,&DEG(dcr));
NEXT(dcr) = 0; MKP(VR(p),dcr,*pr);
} else if ( !INT(q) ) {
error("pwrp: can't calculate fractional power."); *pr = 0;
} else if ( smallz(q) ) {
n = ZTOS(q); x = (P *)ALLOCA((n+1)*sizeof(pointer));
NEWDC(dct); DEG(dct) = DEG(dc); COEF(dct) = COEF(dc);
NEXT(dct) = 0; MKP(VR(p),dct,t);
for ( i = 0, u = (P)One; i < n; i++ ) {
x[i] = u; MULP(vl,u,t,&s); u = s;
}
x[n] = u; y = (P *)ALLOCA((n+1)*sizeof(pointer));
MKP(VR(p),NEXT(dc),t);
for ( i = 0, u = (P)One; i < n; i++ ) {
y[i] = u; MULP(vl,u,t,&s); u = s;
}
y[n] = u;
pt = (P *)ALLOCA((n+1)*sizeof(pointer)); MKBC(n,pt);
for ( i = 0, u = 0; i <= n; i++ ) {
MULP(vl,x[i],y[n-i],&t); MULP(vl,t,pt[i],&s);
ADDP(vl,u,s,&t); u = t;
}
*pr = u;
} else {
error("exponent too big");
*pr = 0;
}
}
}
#ifdef MODULAR
void chsgnmp(int mod,P p,P *pr)
#else
void chsgnp(P p,P *pr)
#endif
{
register DCP dc,dcr,dcr0;
if ( !p )
*pr = NULL;
else if ( NUM(p) ) {
#if defined(_PA_RISC1_1) || defined(__alpha) || defined(mips) || defined(_IBMR2)
#ifdef FBASE
chsgnnum((Num)p,(Num *)pr);
#else
MQ mq;
NEWMQ(mq); CONT(mq)=mod-CONT((MQ)p); *pr = (P)mq;
#endif
#else
CHSGNNUM(p,*pr);
#endif
} else {
for ( dcr0 = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
NEXTDC(dcr0,dcr); CHSGNP(COEF(dc),&COEF(dcr)); DEG(dcr) = DEG(dc);
}
NEXT(dcr) = 0; MKP(VR(p),dcr0,*pr);
}
}