2004-03-03 21:24:06 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Generate a Taylor expansion for expr.
|
|
|
|
//
|
2005-08-21 03:19:56 +02:00
|
|
|
// Input: tos-4 f(x)
|
2004-03-03 21:24:06 +01:00
|
|
|
//
|
2005-08-21 03:19:56 +02:00
|
|
|
// tos-3 x
|
2004-03-03 21:24:06 +01:00
|
|
|
//
|
|
|
|
// tos-2 number of terms
|
|
|
|
//
|
|
|
|
// tos-1 expansion point
|
|
|
|
//
|
|
|
|
// Output: Result on stack
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
//
|
|
|
|
// taylor(cos(x),x,8,a)
|
|
|
|
//
|
|
|
|
// tos-4 cos(x)
|
|
|
|
//
|
|
|
|
// tos-3 x
|
|
|
|
//
|
|
|
|
// tos-2 8
|
|
|
|
//
|
|
|
|
// tos-1 a
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2005-08-21 03:19:56 +02:00
|
|
|
#include "stdafx.h"
|
2004-03-03 21:24:06 +01:00
|
|
|
#include "defs.h"
|
2005-08-21 03:19:56 +02:00
|
|
|
static void ytaylor(void);
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2005-08-21 03:19:56 +02:00
|
|
|
void
|
|
|
|
eval_taylor(void)
|
|
|
|
{
|
|
|
|
// 1st arg
|
|
|
|
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
|
|
|
|
// 2nd arg
|
|
|
|
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p2 = pop();
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p2 == symbol(NIL))
|
2005-08-21 03:19:56 +02:00
|
|
|
guess(); // default x
|
|
|
|
else
|
|
|
|
push(p2);
|
|
|
|
|
|
|
|
// 3rd arg
|
|
|
|
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p2 = pop();
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p2 == symbol(NIL))
|
2005-08-21 03:19:56 +02:00
|
|
|
push_integer(24); // default number of terms
|
|
|
|
else
|
|
|
|
push(p2);
|
|
|
|
|
|
|
|
// 4th arg
|
|
|
|
|
|
|
|
p1 = cdr(p1);
|
|
|
|
push(car(p1));
|
|
|
|
eval();
|
|
|
|
p2 = pop();
|
2006-01-16 20:37:31 +01:00
|
|
|
if (p2 == symbol(NIL))
|
2005-08-21 03:19:56 +02:00
|
|
|
push_integer(0); // default expansion point
|
|
|
|
else
|
|
|
|
push(p2);
|
|
|
|
|
|
|
|
taylor();
|
|
|
|
}
|
2004-03-03 21:24:06 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
taylor(void)
|
|
|
|
{
|
|
|
|
save();
|
2005-08-21 03:19:56 +02:00
|
|
|
ytaylor();
|
2004-03-03 21:24:06 +01:00
|
|
|
restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
#define F p1
|
|
|
|
#define X p2
|
|
|
|
#define N p3
|
|
|
|
#define A p4
|
|
|
|
#define C p5
|
|
|
|
|
|
|
|
static void
|
2005-08-21 03:19:56 +02:00
|
|
|
ytaylor(void)
|
2004-03-03 21:24:06 +01:00
|
|
|
{
|
|
|
|
int i, k;
|
|
|
|
|
|
|
|
A = pop();
|
|
|
|
N = pop();
|
|
|
|
X = pop();
|
|
|
|
F = pop();
|
|
|
|
|
2005-08-06 22:57:37 +02:00
|
|
|
if (!issymbol(X))
|
2004-03-03 21:24:06 +01:00
|
|
|
stop("taylor: symbol expected, 2nd arg is not a symbol");
|
|
|
|
|
|
|
|
push(N);
|
|
|
|
k = pop_integer();
|
|
|
|
if (k == (int) 0x80000000) {
|
|
|
|
push_symbol(TAYLOR);
|
|
|
|
push(F);
|
|
|
|
push(X);
|
|
|
|
push(N);
|
|
|
|
push(A);
|
|
|
|
list(5);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
push(F); // f(a)
|
|
|
|
push(X);
|
|
|
|
push(A);
|
|
|
|
evalat();
|
|
|
|
|
2004-06-25 22:45:15 +02:00
|
|
|
C = one;
|
2004-03-03 21:24:06 +01:00
|
|
|
|
|
|
|
for (i = 1; i <= k; i++) {
|
|
|
|
|
|
|
|
push(F); // f = f'
|
|
|
|
push(X);
|
|
|
|
derivative();
|
|
|
|
F = pop();
|
|
|
|
|
|
|
|
if (iszero(F))
|
|
|
|
break;
|
|
|
|
|
|
|
|
push(C); // c = c * (x - a)
|
|
|
|
push(X);
|
|
|
|
push(A);
|
|
|
|
subtract();
|
|
|
|
multiply();
|
|
|
|
C = pop();
|
|
|
|
|
|
|
|
push(F); // f(a)
|
|
|
|
push(X);
|
|
|
|
push(A);
|
|
|
|
evalat();
|
|
|
|
|
|
|
|
push(C);
|
|
|
|
multiply();
|
|
|
|
push_integer(i);
|
|
|
|
factorial();
|
|
|
|
divide();
|
|
|
|
|
|
|
|
add();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *s[] = {
|
|
|
|
|
2006-02-10 17:21:52 +01:00
|
|
|
"taylor(1/(5+4*cos(x)),x,6,0)-(1/9+2/81*x^2+5/1458*x^4+49/131220*x^6)",
|
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
|
2006-02-10 17:21:52 +01:00
|
|
|
"taylor(1/(5+4*cos(x)),x,6)-(1/9+2/81*x^2+5/1458*x^4+49/131220*x^6)",
|
|
|
|
"0",
|
2004-03-03 21:24:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
test_taylor(void)
|
|
|
|
{
|
|
|
|
test(__FILE__, s, sizeof s / sizeof (char *));
|
|
|
|
}
|