eigenmath/laguerre.cpp

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

2008-06-20 04:24:35 +02:00
/* Laguerre function
Example
laguerre(x,3)
2008-06-20 04:24:35 +02:00
Result
2008-06-20 04:24:35 +02:00
1 3 3 2
- --- x + --- x - 3 x + 1
6 2
2008-06-21 02:53:04 +02:00
The computation uses the following recurrence relation.
2008-06-20 04:24:35 +02:00
L(x,0,k) = 1
L(x,1,k) = -x + k + 1
n*L(x,n,k) = (2*(n-1)+1-x+k)*L(x,n-1,k) - (n-1+k)*L(x,n-2,k)
In the "for" loop i = n-1 so the recurrence relation becomes
(i+1)*L(x,n,k) = (2*i+1-x+k)*L(x,n-1,k) - (i+k)*L(x,n-2,k)
*/
2004-03-03 21:24:06 +01:00
2005-10-27 19:39:15 +02:00
#include "stdafx.h"
2004-03-03 21:24:06 +01:00
#include "defs.h"
2008-06-20 04:24:35 +02:00
void
eval_laguerre(void)
{
// 1st arg
push(cadr(p1));
eval();
// 2nd arg
push(caddr(p1));
eval();
// 3rd arg
2008-06-20 04:35:03 +02:00
push(cadddr(p1));
eval();
p2 = pop();
if (p2 == symbol(NIL))
push_integer(0);
else
push(p2);
2008-06-20 04:24:35 +02:00
laguerre();
}
2004-03-03 21:24:06 +01:00
#define X p1
#define N p2
#define K p3
#define Y p4
#define Y0 p5
#define Y1 p6
void
laguerre(void)
{
int n;
2008-06-20 04:24:35 +02:00
save();
2004-03-03 21:24:06 +01:00
K = pop();
N = pop();
X = pop();
push(N);
n = pop_integer();
if (n < 0) {
push_symbol(LAGUERRE);
push(X);
push(N);
push(K);
list(4);
2008-06-20 04:24:35 +02:00
restore();
2004-03-03 21:24:06 +01:00
return;
}
if (issymbol(X))
2008-06-20 04:24:35 +02:00
laguerre2(n);
2004-03-03 21:24:06 +01:00
else {
Y = X; // do this when X is an expr
2006-01-17 01:52:35 +01:00
X = symbol(SECRETX);
2008-06-20 04:24:35 +02:00
laguerre2(n);
2004-03-03 21:24:06 +01:00
X = Y;
2006-01-17 01:52:35 +01:00
push(symbol(SECRETX));
2004-03-03 21:24:06 +01:00
push(X);
subst();
eval();
}
2008-06-20 04:24:35 +02:00
restore();
2004-03-03 21:24:06 +01:00
}
2005-10-27 19:39:15 +02:00
void
2008-06-20 04:24:35 +02:00
laguerre2(int n)
2004-03-03 21:24:06 +01:00
{
int i;
push_integer(1);
push_integer(0);
Y1 = pop();
for (i = 0; i < n; i++) {
Y0 = Y1;
Y1 = pop();
push_integer(2 * i + 1);
push(X);
subtract();
push(K);
add();
push(Y1);
multiply();
push_integer(i);
push(K);
add();
push(Y0);
multiply();
subtract();
push_integer(i + 1);
divide();
}
}
2007-05-08 16:57:30 +02:00
#if SELFTEST
2004-03-03 21:24:06 +01:00
static char *s[] = {
"laguerre(x,n)",
"laguerre(x,n,0)",
"laguerre(x,n,k)",
"laguerre(x,n,k)",
"laguerre(x,0)-1",
"0",
"laguerre(x,1)-(-x+1)",
"0",
"laguerre(x,2)-1/2*(x^2-4*x+2)",
"0",
"laguerre(x,3)-1/6*(-x^3+9*x^2-18*x+6)",
"0",
"laguerre(x,0,k)-1",
"0",
"laguerre(x,1,k)-(-x+k+1)",
"0",
"laguerre(x,2,k)-1/2*(x^2-2*(k+2)*x+(k+1)*(k+2))",
"0",
"laguerre(x,3,k)-1/6*(-x^3+3*(k+3)*x^2-3*(k+2)*(k+3)*x+(k+1)*(k+2)*(k+3))",
"0",
"laguerre(a-b,10)-eval(subst(a-b,x,laguerre(x,10)))",
"0",
};
void
test_laguerre(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}
2007-05-08 16:57:30 +02:00
#endif