algebrite
Version:
Computer Algebra System in Coffeescript
180 lines (129 loc) • 2.2 kB
text/coffeescript
###
Legendre function
Example
legendre(x,3,0)
Result
5 3 3
--- x - --- x
2 2
The computation uses the following recurrence relation.
P(x,0) = 1
P(x,1) = x
n*P(x,n) = (2*(n-1)+1)*x*P(x,n-1) - (n-1)*P(x,n-2)
In the "for" loop we have i = n-1 so the recurrence relation becomes
(i+1)*P(x,n) = (2*i+1)*x*P(x,n-1) - i*P(x,n-2)
For m > 0
P(x,n,m) = (-1)^m * (1-x^2)^(m/2) * d^m/dx^m P(x,n)
###
Eval_legendre = ->
# 1st arg
push(cadr(p1))
Eval()
# 2nd arg
push(caddr(p1))
Eval()
# 3rd arg (optional)
push(cadddr(p1))
Eval()
p2 = pop()
if (p2 == symbol(NIL))
push_integer(0)
else
push(p2)
legendre()
#define X p1
#define N p2
#define M p3
#define Y p4
#define Y0 p5
#define Y1 p6
legendre = ->
save()
__legendre()
restore()
__legendre = ->
m = 0
n = 0
p3 = pop()
p2 = pop()
p1 = pop()
push(p2)
n = pop_integer()
push(p3)
m = pop_integer()
if (n < 0 || n == 0x80000000 || m < 0 || m == 0x80000000)
push_symbol(LEGENDRE)
push(p1)
push(p2)
push(p3)
list(4)
return
if (issymbol(p1))
__legendre2(n, m)
else
p4 = p1; # do this when X is an expr
p1 = symbol(SECRETX)
__legendre2(n, m)
p1 = p4
push(symbol(SECRETX))
push(p1)
subst()
Eval()
__legendre3(m)
__legendre2 = (n, m) ->
i = 0
push_integer(1)
push_integer(0)
p6 = pop()
# i=1 p5 = 0
# p6 = 1
# ((2*i+1)*x*p6 - i*p5) / i = x
#
# i=2 p5 = 1
# p6 = x
# ((2*i+1)*x*p6 - i*p5) / i = -1/2 + 3/2*x^2
#
# i=3 p5 = x
# p6 = -1/2 + 3/2*x^2
# ((2*i+1)*x*p6 - i*p5) / i = -3/2*x + 5/2*x^3
for i in [0...n]
p5 = p6
p6 = pop()
push_integer(2 * i + 1)
push(p1)
multiply()
push(p6)
multiply()
push_integer(i)
push(p5)
multiply()
subtract()
push_integer(i + 1)
divide()
for i in [0...m]
push(p1)
derivative()
# tos = tos * (-1)^m * (1-x^2)^(m/2)
__legendre3 = (m) ->
if (m == 0)
return
if (car(p1) == symbol(COS))
push(cadr(p1))
sine()
square()
else if (car(p1) == symbol(SIN))
push(cadr(p1))
cosine()
square()
else
push_integer(1)
push(p1)
square()
subtract()
push_integer(m)
push_rational(1, 2)
multiply()
power()
multiply()
if (m % 2)
negate()