%mathpiper,def="Taylor"

/*COMMENT FROM AYAL: Jitse, I added some code to make Taylor2 work in the most general case too I believe.
  Could you check to see if you agree with my changes? If that is correct, perhaps we can start calling Taylor2
  by default in stead of Taylor1.
 */
Function("Taylor",{taylorvariable,taylorat,taylororder,taylorfunction})
  Taylor1(taylorvariable,taylorat,taylororder)(taylorfunction);

/*COMMENT FROM AYAL: this is the old slow but working version of Taylor series expansion. Jitse wrote a
 * faster version which resides in taylor.mpi, and uses lazy power series. This slow but correct version is still
 * useful for tests (the old and the new routine should yield identical results).
 */
Function("Taylor1",{taylorvariable,taylorat,taylororder,taylorfunction})
[
  Local(n,result,dif,polf);
  [
    MacroLocal(taylorvariable);
    [
      MacroLocal(taylorvariable);
      MacroBind(taylorvariable, taylorat);
      result:=Eval(taylorfunction);
    ];
    If(result=Undefined,
    [
      result:=Apply("Limit",{taylorvariable,taylorat,taylorfunction});
    ]);
/*
    MacroBind(taylorvariable,taylorat);
    result:=Eval(taylorfunction);
*/
  ];
  dif:=taylorfunction;
  polf:=(taylorvariable-taylorat);
  For(n:=1,result != Undefined And n<=taylororder,n++)
  [
    dif:= Deriv(taylorvariable) dif;
    Local(term);
    MacroLocal(taylorvariable);
    [
      MacroLocal(taylorvariable);
      MacroBind(taylorvariable, taylorat);
      term:=Eval(dif);
    ];
    If(term=Undefined,
    [
      term:=Apply("Limit",{taylorvariable,taylorat,dif});
    ]);

    result:=result+(term/(n!))*(polf^n);
/*    result:=result+Apply("Limit",{taylorvariable,taylorat,(dif/(n!))})*(polf^n); */
/*
    MacroBind(taylorvariable,taylorat);
    result:=result+(Eval(dif)/(n!))*(polf^n);
*/
  ];
  result;
];

%/mathpiper



%mathpiper_docs,name="Taylor",categories="User Functions;Series"
*CMD Taylor --- univariate Taylor series expansion
*STD
*CALL
	Taylor(var, at, order) expr

*PARMS

{var} -- variable

{at} -- point to get Taylor series around

{order} -- order of approximation

{expr} -- expression to get Taylor series for

*DESC

This function returns the Taylor series expansion of the expression
"expr" with respect to the variable "var" around "at" up to order
"order". This is a polynomial which agrees with "expr" at the
point "var = at", and furthermore the first "order" derivatives of
the polynomial at this point agree with "expr". Taylor expansions
around removable singularities are correctly handled by taking the
limit as "var" approaches "at".

*E.G.

In> PrettyForm(Taylor(x,0,9) Sin(x))
	
	     3    5      7       9
	    x    x      x       x
	x - -- + --- - ---- + ------
	    6    120   5040   362880
	
Result: True;

*SEE D, InverseTaylor, ReversePoly, BigOh
%/mathpiper_docs