Sindbad~EG File Manager
/* binomial series, for Mathpert, by M. Beeson
Original date 1.15.99
Last modified 1.15.99
6.3.15 modified binomialseries to accept a fraction
6.11.15 modified the convergence conditions for binomialseries and had it SETCONVERGENT
*/
#include <string.h>
#include <assert.h>
#include "globals.h"
#include "series.h"
#include "match.h"
#include "prover.h" /* getnewintvar1 */
#include "symbols.h"
#include "errbuf.h"
#include "psubst.h"
#include "pvalaux.h" /* twoparts */
#include "ssolve.h"
#include "islinear.h"
#include "cancel.h"
#include "pathtail.h"
#include "autosimp.h" /* SetShowStepOperation */
static int convergencetest(term x, term alpha)
/* return 1 for convergence, -1 for divergence, 0 for uncertain, 2 for isolated points possible */
/* Only good for real x */
{ int err;
err = infer(equation(x,zero));
if(!err)
return 2;
if(ONE(x))
{ err = check1(le(minusone,alpha));
return err ? -1 : 1;
}
if(equals(x,minusone))
{ err = check1(le(zero,alpha));
return err ? -1 : 1;
}
if(!check1(lessthan(abs1(x),one)))
return 1;
return 0;
}
/*_____________________________________________________________*/
int binomialseries(term t, term arg, term *next, char *reason)
/* (1+x)^alpha = sum(binomial(alpha,k)x^k,k,0,infinity) */
/* Also works on 1/(1+x)^alpha */
{ int sign =1;
term alpha,u,x;
term n;
int convergence = 0;
short savenextassumption = get_nextassumption();
if(FUNCTOR(t) == '/' && ONE(ARG(0,t)) && FUNCTOR(ARG(1,t)) == '^')
{ term s = make_power(ARG(0,ARG(1,t)),tnegate(ARG(1,ARG(1,t))));
return binomialseries(s,arg,next,reason);
}
if(FUNCTOR(t) != '^')
return 1;
alpha = ARG(1,t);
u = ARG(0,t);
if(FUNCTOR(u) != '+' || ARITY(u) != 2)
return 1;
if(ONE(ARG(0,u)))
x = ARG(1,u);
else if(ONE(ARG(1,u)))
x = ARG(0,u);
else
return 1;
if(NEGATIVE(x))
{ x = ARG(0,x);
sign = -1;
}
n = getnewindexvar(t,"knmjpqrs");
if(FUNCTOR(n) == ILLEGAL)
{ errbuf(0, english(1448));
/* Too many subscripted variables, can't make more. */
return 1;
}
/* Now for the convergence conditions */
convergence = convergencetest(x,alpha);
if(convergence == 2)
{ errbuf(0,english(2326)); /* The resulting series would converge only at isolated points */
set_nextassumption(savenextassumption);
}
if(convergence != 1)
{ errbuf(0,english(2325)); /* The resulting series would not be convergent */
set_nextassumption(savenextassumption);
return 1;
}
if(sign == 1)
*next = sigma(product(make_binomial(alpha,n),make_power(x,n)),n,zero,infinity);
else
*next = sigma(product3(make_power(minusone,n),make_binomial(alpha,n),make_power(x,n)),n,zero,infinity);
HIGHLIGHT(*next);
SETCONVERGENT(*next);
strcpy(reason,"$$(1+x)^alpha = sum(binomial(alpha,n)x^n,n,0,infinity)$$");
return 0;
}
/*__________________________________________________________________________*/
int binomialseries2(term t, term arg, term *next, char *reason)
{ term temp;
int err = binomialseries(t,arg,&temp,reason);
if(err)
return 1;
*next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),tnegate(three));
strcpy(reason,"$$(1+x)^alpha = sum(binomial(alpha,n)x^n,n,0,infinity,-3)$$");
return 0;
}
/*__________________________________________________________________________*/
int binomialseries3(term t, term arg, term *next, char *reason)
{ term temp;
int err = binomialseries(t,arg,&temp,reason);
if(err)
return 1;
*next = series(ARG(0,temp),ARG(1,temp),ARG(2,temp),ARG(3,temp),two);
strcpy(reason,"$$(1+x)^alpha = sum(binomial(alpha,n)x^n,n,0,infinity,2)$$");
return 0;
}
/*__________________________________________________________________________*/
int binomialseriesrev(term t, term arg, term *next, char *reason)
/* sum((binomial(alpha,k)/k!)x^k,k,0,infinity) = (1+x)^alpha */
{ term n,u,v,alpha,x;
int convergence;
int savenextassumption = get_nextassumption();
if(FUNCTOR(t) != SUM || !equals(ARG(3,t),infinity) || !ZERO(ARG(2,t)) )
return 1;
u = ARG(0,t);
n = ARG(1,t);
if(FUNCTOR(u) != '*' || ARITY(u) > 3)
return 1;
if(ARITY(u) == 3)
{ v = ARG(0,u);
if(FUNCTOR(v) != '^' || !equals(ARG(0,v),minusone) || !equals(ARG(1,v),n))
return 1;
if(FUNCTOR(ARG(1,u)) != BINOMIAL || FUNCTOR(ARG(2,u)) != '^')
return 1;
if(!equals(ARG(1,ARG(2,u)),n))
return 1;
x = ARG(0,ARG(2,u));
if(!equals(ARG(1,ARG(1,u)),n))
return 1;
alpha = ARG(0,ARG(1,u));
*next = make_power(sum(one,tnegate(x)),alpha);
}
else
{ if(FUNCTOR(ARG(0,u)) != BINOMIAL || FUNCTOR(ARG(1,u)) != '^')
return 1;
if(!equals(ARG(1,ARG(1,u)),n))
return 1;
x = ARG(0,ARG(1,u));
if(!equals(ARG(1,ARG(0,u)),n))
return 1;
alpha = ARG(0,ARG(0,u));
*next = make_power(sum(one,x),alpha);
}
convergence = convergencetest(x,alpha);
if(convergence == 2)
{ errbuf(0,english(2326)); /* The resulting series would converge only at isolated points */
set_nextassumption(savenextassumption);
}
if(convergence != 1)
{ errbuf(0,english(2325)); /* The resulting series would not be convergent */
set_nextassumption(savenextassumption);
return 1;
}
HIGHLIGHT(*next);
if(ARITY(t) == 4)
strcpy(reason,"$$sum(binomial(alpha,n)x^n,n,0,infinity) = (1+x)^alpha$$");
else if(NEGATIVE(ARG(4,t)))
strcpy(reason,"$$sum(binomial(alpha,n)x^n,n,0,infinity,-3) = (1+x)^alpha$$");
else
strcpy(reason,"$$sum(binomial(alpha,n)x^n,n,0,infinity,2) = (1+x)^alpha$$");
return 0;
}
/*__________________________________________________________________________*/
int binomialseries2rev(term t, term arg, term *next, char *reason)
{ return binomialseriesrev(t,arg,next,reason);
}
/*__________________________________________________________________________*/
int binomialseries3rev(term t, term arg, term *next, char *reason)
{ return binomialseriesrev(t,arg,next,reason);
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists