eigenmath/taylor.cpp

170 lines
2.1 KiB
C++
Raw Permalink Normal View History

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 *));
}