Sindbad~EG File Manager
/* M. Beeson for series.dll
Select series operations for the Term Selection Menu
*/
/* Original date 2.28.00
Last modified 6.17.00
1.23.06 added sumtodifofsums and sumtodifofsums0
*/
#define SERIES_DLL
#include <math.h> /* abs */
#include <string.h> /* memset */
#include <assert.h>
#include "globals.h"
#include "graphstr.h"
#include "document.h"
#include "tdefn.h"
#include "trig.h"
#include "calc.h"
#include "display.h"
#include "display1.h" /* needed by lterm.h */
#include "bigrect.h"
#include "lterm.h"
#include "selectop.h"
#include "automode.h"
#include "cflags.h"
#include "probtype.h"
#include "calc.h"
#include "pvalaux.h" /* twoparts, iseven, isodd */
#include "prover.h" /* NOTDEFINED */
#include "docdata.h" /* history */
#include "select2.h"
#include "series.h" /* is_power_series */
#include "islinear.h" /* islinear */
#include "scontrol.h" /* used4 */
static int contains_power_of_minusone(term t);
/*_________________________________________________*/
static int contains_power_of_minusone(term t)
/* return 1 if t contains a power of minusone, 0 if not
*/
{ unsigned short i,n,f;
if(ATOMIC(t))
return 0;
f = FUNCTOR(t);
if(f == '^' && equals(ARG(0,t),minusone))
return 1;
n = ARITY(t);
for(i=0;i<n;i++)
{ if(contains_power_of_minusone(ARG(i,t)))
return 1;
}
return 0;
}
/*______________________________________________________________________________*/
static void expand_op(term t, actualop *o, int *nops)
/* t is an expression to be expanded in a series; suggest operations to try */
{ term u,v,x;
unsigned short g,h;
int i = 0;
int problemtype = get_problemtype();
x = get_eigenvariable();
if(FRACTION(t))
{ u = ARG(0,t);
v = ARG(1,t);
g = FUNCTOR(u);
h = FUNCTOR(v);
if(ONE(u) && h == '+' && ARITY(v) == 2)
{ if(ONE(ARG(0,v)) && NEGATIVE(ARG(1,v)))
{ o[i] = oneminusxseries; ++i;
o[i] = oneminusxseries2; ++i;
o[i] = oneminusxseries3; ++i;
}
else if(ONE(ARG(0,v)) || ONE(ARG(1,v)))
{ o[i] = oneplusxseries; ++i;
o[i] = oneplusxseries2; ++i;
o[i] = oneplusxseries3; ++i;
}
}
if(h == '+' && ARITY(v) == 2 && ONE(ARG(1,v)))
{ if(equals(u,ARG(0,v)))
{ o[i] = xoveroneplusxseries; ++i;
o[i] = xoveroneplusxseries2; ++i;
o[i] = xoveroneplusxseries3; ++i;
}
}
if(h == '+' && ARITY(v) == 2 && ONE(ARG(0,v)))
{ if(equals(u,ARG(1,v)))
{ o[i] = xoveroneplusxseries; ++i;
o[i] = xoveroneplusxseries2; ++i;
o[i] = xoveroneplusxseries3; ++i;
}
if(NEGATIVE(ARG(1,v)) && equals(ARG(0,ARG(1,v)),u))
{ o[i] = xoveroneminusxseries; ++i;
o[i] = xoveroneminusxseries2; ++i;
o[i] = xoveroneminusxseries3; ++i;
}
if(NEGATIVE(ARG(1,v)) &&
FUNCTOR(ARG(0,ARG(1,v))) == '^' &&
equals(ARG(0,ARG(0,ARG(1,v))),u)
)
{ o[i] = xmoveroneminusxkseries; ++i;
o[i] = xmoveroneminusxkseries2; ++i;
o[i] = xmoveroneminusxkseries3; ++i;
}
if(NEGATIVE(ARG(1,v)) &&
FUNCTOR(ARG(0,ARG(1,v))) == '^' &&
ONE(u)
)
{ o[i] = oneoveroneminusxkseries; ++i;
o[i] = oneoveroneminusxkseries2; ++i;
o[i] = oneoveroneminusxkseries3; ++i;
}
if(ONE(u) && FUNCTOR(ARG(1,v)) == '^')
{ o[i] = oneoveroneplusxkseries; ++i;
o[i] = oneoveroneplusxkseries2; ++i;
o[i] = oneoveroneplusxkseries3; ++i;
}
if(NEGATIVE(ARG(1,v)) && FUNCTOR(u) == '^' &&
equals(ARG(0,ARG(1,v)),ARG(0,u))
)
{ o[i] = geometricseriesfromk; ++i;
o[i] = geometricseriesfromk2; ++i;
o[i] = geometricseriesfromk3; ++i;
}
if(g == '^' && equals(ARG(1,v),ARG(0,u)))
{ o[i] = geometricseriesminusfromk; ++i;
o[i] = geometricseriesminusfromk2; ++i;
o[i] = geometricseriesminusfromk3; ++i;
}
if(FUNCTOR(u) == '^' && NEGATIVE(ARG(1,v)) &&
FUNCTOR(ARG(0,ARG(1,v))) == '^' &&
equals(ARG(0,u),ARG(0,ARG(0,ARG(1,v))))
)
{ o[i] = xmoveroneminusxkseries; ++i;
o[i] = xmoveroneminusxkseries2; ++i;
o[i] = xmoveroneminusxkseries3; ++i;
}
if(FUNCTOR(u) == '^' &&
FUNCTOR(ARG(1,v)) == '^' &&
equals(ARG(0,u),ARG(0,ARG(1,v)))
)
{ o[i] = xmoveroneplusxkseries; ++i;
o[i] = xmoveroneplusxkseries2; ++i;
o[i] = xmoveroneplusxkseries3; ++i;
}
}
}
* nops = i;
}
/*_________________________________________________________________________________________*/
MEXPORT_SERIES void select_series_op(term t, actualop *o, int *nops)
/* t is an infinite series, or an expression to be expanded in a series */
{ int i = 0;
term lo = ARG(2,t);
term u = ARG(0,t);
term indexvar = ARG(1,t);
term ldots = ARITY(t) == 4 ? zero : ARG(4,t);
term num,denom;
term a,b,c,s,w,temp;
char buffer[DIMREASONBUFFER];
unsigned short g = FUNCTOR(u);
int nfree;
if(FUNCTOR(t) != SUM)
{ expand_op(t,o,nops);
return;
}
if(ARITY(t) == 4)
{ o[i] = ldots0; ++i;
o[i] = ldots1; ++i;
o[i] = ldots2; ++i;
}
else
{ o[i] = ldotstosigma; ++i;
o[i] = showanotherterm; ++i;
o[i] = showmoreterms; ++i;
if(!EVALFACTORIAL(t))
{ o[i] = showevaluatedterms; ++i;
}
else
{ o[i] = showfactorialsinterms; ++i;
}
if(DEVALCOEF(t))
{ o[i] = showundevaluatedterms; ++i;
}
else
{ o[i] = showdevaluatedterms; ++i;
}
}
if(!contains(u,FUNCTOR(ARG(1,t))))
{ o[i] = sigmaconstant; ++i;
}
if(contains_power_of_minusone(u))
{ o[i] = seriesevenandodd; ++i;
}
nfree = numerical_sum(t);
// if(nfree == 2)
// { o[i] = evaluateinfiniteseries; ++i;
// }
if(nfree == 1)
{ o[i] = evalfirstterms; ++i;
}
if(ATOMIC(u))
{ *nops = i;
return;
}
if(!equals(lo,minusinfinity))
{ o[i] = seriesfirstterms; ++i;
o[i] = seriesmoreterms; ++i;
if(ARITY(t) == 4)
{ o[i] = seriesaddindex; ++i;
o[i] = seriessubindex; ++i;
}
o[i] = sumtodifofsums; ++i;
if(!ZERO(lo))
{ o[i] = sumtodifofsums0;++i;
}
}
if(get_problemtype() == TESTCONVERGENCE)
{ o[i] = divergencetest; ++i;
o[i] = integraltest; ++i;
o[i] = ratiotest; ++i;
o[i] = roottest; ++i;
o[i] = comparisontest1; ++i;
o[i] = comparisontest2; ++i;
o[i] = limitcomparisontest; ++i;
if(used4(comparisontest1))
{ o[i] = finishcomparisontest1; ++i;
}
if(used4(comparisontest2))
{ o[i] = finishcomparisontest2; ++i;
}
if(used4(finishcomparisontest1))
{ o[i] = statefinalbound1; ++i;
}
if(used4(finishcomparisontest2))
{ o[i] = statefinalbound2; ++i;
}
}
switch(g)
{ case '-':
o[i] = minusoutofsigma; ++i;
break;
case '/':
num = ARG(0,u);
denom = ARG(1,u);
if(ONE(num) && FUNCTOR(denom) == '^' &&
equals(ARG(1,denom),indexvar)
)
{ if(ONE(lo))
{ o[i] = xoveroneminusxseriesrev; ++i;
}
if(ZERO(lo))
{ o[i] = oneminusxseriesrev; ++i;
}
}
twoparts(u,indexvar,&c,&s);
if(!ONE(c))
{ o[i] = constantoutofsigma; ++i;
}
if(!harmonicseries(t,zero,&temp,buffer))
{ o[i] = harmonicseries; ++i;
}
if(!zeta2(t,zero,&temp,buffer))
{ o[i] = zeta2; ++i;
}
if(FUNCTOR(denom) == FACTORIAL && ZERO(lo) && equals(ARG(0,denom),indexvar))
/* recognize series for e^x, e^-x, sin x, and cos x */
{ if(!contains(u,'-'))
{ o[i] = ZERO(ldots) ? expseriesrev : NEGATIVE(ldots) ? expseries3rev : expseries3rev; ++i;
}
else if(FUNCTOR(num) == '*' && ARITY(num) == 2 &&
FUNCTOR(ARG(0,num)) == '^' && equals(ARG(0,ARG(0,num)),minusone) &&
equals(ARG(1,ARG(0,num)),indexvar) && FUNCTOR(ARG(1,num)) == '^'
)
{ if(equals(ARG(1,ARG(1,num)),indexvar))
{ o[i] = ZERO(ldots) ? negexpseriesrev: NEGATIVE(ldots) ? negexpseries2rev : negexpseries3rev; ++i;
}
else if(iseven(ARG(1,ARG(1,num))))
{ o[i] = ZERO(ldots) ? cosseriesrev : NEGATIVE(ldots) ? cosseries2rev : cosseries3rev; ++i;
}
else if(isodd(ARG(1,ARG(1,num))))
{ o[i] = ZERO(ldots) ? sinseriesrev : NEGATIVE(ldots) ? sinseries2rev : sinseries3rev; ++i;
}
}
}
break;
case '*':
twoparts(u,indexvar,&c,&s);
if(!ONE(c))
{ o[i] = constantoutofsigma; ++i;
}
if(ARITY(u) == 2 && FUNCTOR(ARG(0,u)) == '^' &&
equals(ARG(0,ARG(0,u)),minusone) &&
equals(ARG(1,ARG(0,u)),indexvar) &&
FUNCTOR(ARG(1,u)) == '^' &&
!contains(ARG(0,ARG(1,u)),FUNCTOR(indexvar))
)
{ /* (-1)^n x^? */
term w = ARG(0,ARG(1,u));
term power = ARG(1,ARG(1,u));
if(!contains(w,FUNCTOR(indexvar)))
{ if(equals(power,indexvar))
{ o[i] = ZERO(ldots) ? oneplusxseriesrev: NEGATIVE(ldots)? oneplusxseries2rev: oneplusxseries3rev; ++i;
}
else if(FUNCTOR(power) == '*' && !is_linear_in(power,indexvar))
{ o[i] = ZERO(ldots) ? oneoveroneplusxkseriesrev : NEGATIVE(ldots) ? oneoveroneplusxkseries2rev : oneoveroneplusxkseries3rev; ++i;
}
else if(FUNCTOR(power) == '+' && !is_linear_in(power,indexvar))
{ o[i] = ZERO(ldots) ? xmoveroneplusxkseriesrev : NEGATIVE(ldots) ? xmoveroneplusxkseries2rev : xmoveroneplusxkseries3rev; ++i;
}
}
}
if(FUNCTOR(s) == '^' && equals(indexvar,ARG(1,s)))
{ if(FUNCTOR(c) == BINOMIAL && equals(ARG(1,c),indexvar))
{ o[i] = ZERO(ldots) ? binomialseriesrev: NEGATIVE(ldots) ? binomialseries2rev : binomialseries3rev; ++i;
}
else if(FUNCTOR(c) == '*' && ARITY(c) == 2 &&
FUNCTOR(ARG(1,c)) == BINOMIAL &&
equals(ARG(1,ARG(1,c)),indexvar) &&
FUNCTOR(ARG(0,c)) == '^' &&
equals(ARG(0,ARG(0,c)),minusone) &&
equals(ARG(1,ARG(0,c)),indexvar)
)
{ o[i] = ZERO(ldots) ? binomialseriesrev: NEGATIVE(ldots) ? binomialseries2rev: binomialseries3rev; ++i;
}
}
if(ARITY(u) == 2 && FUNCTOR(ARG(1,u)) == '^' &&
islinear(ARG(1,ARG(1,u)),indexvar,&a,&b) &&
equals(a,two) &&
FRACTION(ARG(0,u)) &&
FUNCTOR(ARG(0,ARG(0,u))) == '^' &&
equals(ARG(0,ARG(0,ARG(0,u))),minusone) &&
FUNCTOR(ARG(1,ARG(0,u))) == FACTORIAL &&
equals(ARG(0,ARG(1,ARG(0,u))),ARG(1,ARG(1,u))) &&
equals(ARG(1,ARG(0,ARG(0,u))),indexvar)
)
{ if(ONE(b))
{ o[i] = sinseriesrev; ++i;
}
else
{ o[i] = cosseriesrev; ++i;
}
}
break;
case '+':
o[i] = seriessum; ++i;
if(ARITY(u) == 2 && !telescopingseries(t,zero,&w,buffer))
{ o[i] = telescopingseries; ++i;
}
break;
case '^':
if(equals(ARG(1,u),indexvar) && ZERO(lo) && !contains(ARG(0,u),FUNCTOR(indexvar)))
{ o[i] = ZERO(ldots) ? oneminusxseriesrev: NEGATIVE(ldots) ? oneminusxseries2rev : oneminusxseries3rev; ++i;
}
if(equals(ARG(1,u),indexvar) && ONE(lo) && !contains(ARG(0,u),FUNCTOR(indexvar)))
{ o[i] = ZERO(ldots) ? xoveroneminusxseriesrev : NEGATIVE(ldots) ? xoveroneminusxseries2rev : xoveroneminusxseries3rev; ++i;
}
if(FUNCTOR(ARG(1,u)) == '+' &&
!contains(ARG(0,u),FUNCTOR(indexvar)) &&
!is_linear_in(ARG(1,u),indexvar)
)
{ o[i] = ZERO(ldots) ? xmoveroneminusxkseriesrev : NEGATIVE(ldots) ? xmoveroneminusxkseries2rev : xmoveroneminusxkseries3rev; ++i;
}
if(FUNCTOR(ARG(1,u)) == '*'&&
!contains(ARG(0,u),FUNCTOR(indexvar)) &&
!is_linear_in(ARG(1,u),indexvar)
)
{ o[i] = ZERO(ldots) ? oneminusxseriesrev: NEGATIVE(ldots) ? oneminusxseries2rev : oneminusxseries3rev; ++i;
}
break;
case DIFF:
o[i] = reversedifseries; ++i;
break;
case INTEGRAL:
o[i] = reverseintseries; ++i;
break;
}
*nops = i;
return;
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists