algebrite
Version:
Computer Algebra System in Coffeescript
685 lines (578 loc) • 9.62 kB
text/coffeescript
# derivative
#define F p3
#define X p4
#define N p5
Eval_derivative = ->
# evaluate 1st arg to get function F
i = 0
p1 = cdr(p1)
push(car(p1))
Eval()
# evaluate 2nd arg and then...
# example result of 2nd arg what to do
#
# d(f) nil guess X, N = nil
# d(f,2) 2 guess X, N = 2
# d(f,x) x X = x, N = nil
# d(f,x,2) x X = x, N = 2
# d(f,x,y) x X = x, N = y
p1 = cdr(p1)
push(car(p1))
Eval()
p2 = pop()
if (p2 == symbol(NIL))
guess()
push(symbol(NIL))
else if (isnum(p2))
guess()
push(p2)
else
push(p2)
p1 = cdr(p1)
push(car(p1))
Eval()
p5 = pop(); # p5 is N
p4 = pop(); # p4 is X
p3 = pop(); # p3 is F
while (1)
# p5 (N) might be a symbol instead of a number
if (isnum(p5)) # p5 is N
push(p5); # p5 is N
n = pop_integer()
if (isNaN(n))
stop("nth derivative: check n")
else
n = 1
push(p3); # p3 is F
if (n >= 0)
for i in [0...n]
push(p4); # p4 is X
derivative()
else
n = -n
for i in [0...n]
push(p4); # p4 is X
integral()
p3 = pop(); # p3 is F
# if p5 (N) is nil then arglist is exhausted
if (p5 == symbol(NIL)) # p5 is N
break
# otherwise...
# N arg1 what to do
#
# number nil break
# number number N = arg1, continue
# number symbol X = arg1, N = arg2, continue
#
# symbol nil X = N, N = nil, continue
# symbol number X = N, N = arg1, continue
# symbol symbol X = N, N = arg1, continue
if (isnum(p5)) # p5 is N
p1 = cdr(p1)
push(car(p1))
Eval()
p5 = pop(); # p5 is N
if (p5 == symbol(NIL)) # p5 is N
break; # arglist exhausted
if (isnum(p5)) # p5 is N
doNothing = 1 # N = arg1
else
p4 = p5; # p5 is N # p4 is X # X = arg1
p1 = cdr(p1)
push(car(p1))
Eval()
p5 = pop(); # p5 is N # N = arg2
else
p4 = p5; # p5 is N # p4 is X # X = N
p1 = cdr(p1)
push(car(p1))
Eval()
p5 = pop(); # p5 is N # N = arg1
push(p3); # p3 is F # final result
derivative = ->
save()
p2 = pop()
p1 = pop()
if (isnum(p2))
stop("undefined function")
if (istensor(p1))
if (istensor(p2))
d_tensor_tensor()
else
d_tensor_scalar()
else
if (istensor(p2))
d_scalar_tensor()
else
d_scalar_scalar()
restore()
d_scalar_scalar = ->
if (issymbol(p2))
d_scalar_scalar_1()
else
# Example: d(sin(cos(x)),cos(x))
# Replace cos(x) <- X, find derivative, then do X <- cos(x)
push(p1); # sin(cos(x))
push(p2); # cos(x)
push(symbol(SECRETX)); # X
subst(); # sin(cos(x)) -> sin(X)
push(symbol(SECRETX)); # X
derivative()
push(symbol(SECRETX)); # X
push(p2); # cos(x)
subst(); # cos(X) -> cos(cos(x))
d_scalar_scalar_1 = ->
# d(x,x)?
if (equal(p1, p2))
push(one)
return
# d(a,x)?
if (!iscons(p1))
push(zero)
return
if (isadd(p1))
dsum()
return
if (car(p1) == symbol(MULTIPLY))
dproduct()
return
if (car(p1) == symbol(POWER))
dpower()
return
if (car(p1) == symbol(DERIVATIVE))
dd()
return
if (car(p1) == symbol(LOG))
dlog()
return
if (car(p1) == symbol(SIN))
dsin()
return
if (car(p1) == symbol(COS))
dcos()
return
if (car(p1) == symbol(TAN))
dtan()
return
if (car(p1) == symbol(ARCSIN))
darcsin()
return
if (car(p1) == symbol(ARCCOS))
darccos()
return
if (car(p1) == symbol(ARCTAN))
darctan()
return
if (car(p1) == symbol(SINH))
dsinh()
return
if (car(p1) == symbol(COSH))
dcosh()
return
if (car(p1) == symbol(TANH))
dtanh()
return
if (car(p1) == symbol(ARCSINH))
darcsinh()
return
if (car(p1) == symbol(ARCCOSH))
darccosh()
return
if (car(p1) == symbol(ARCTANH))
darctanh()
return
if (car(p1) == symbol(ABS))
dabs()
return
if (car(p1) == symbol(SGN))
dsgn()
return
if (car(p1) == symbol(HERMITE))
dhermite()
return
if (car(p1) == symbol(ERF))
derf()
return
if (car(p1) == symbol(ERFC))
derfc()
return
if (car(p1) == symbol(BESSELJ))
if (iszero(caddr(p1)))
dbesselj0()
else
dbesseljn()
return
if (car(p1) == symbol(BESSELY))
if (iszero(caddr(p1)))
dbessely0()
else
dbesselyn()
return
if (car(p1) == symbol(INTEGRAL) && caddr(p1) == p2)
derivative_of_integral()
return
dfunction()
dsum = ->
h = tos
p1 = cdr(p1)
while (iscons(p1))
push(car(p1))
push(p2)
derivative()
p1 = cdr(p1)
add_all(tos - h)
dproduct = ->
i = 0
j = 0
n = 0
n = length(p1) - 1
for i in [0...n]
p3 = cdr(p1)
for j in [0...n]
push(car(p3))
if (i == j)
push(p2)
derivative()
p3 = cdr(p3)
multiply_all(n)
add_all(n)
#-----------------------------------------------------------------------------
#
# v
# y = u
#
# log y = v log u
#
# 1 dy v du dv
# - -- = - -- + (log u) --
# y dx u dx dx
#
# dy v v du dv
# -- = u (- -- + (log u) --)
# dx u dx dx
#
#-----------------------------------------------------------------------------
dpower = ->
push(caddr(p1)); # v/u
push(cadr(p1))
divide()
push(cadr(p1)); # du/dx
push(p2)
derivative()
multiply()
push(cadr(p1)); # log u
logarithm()
push(caddr(p1)); # dv/dx
push(p2)
derivative()
multiply()
add()
push(p1); # u^v
multiply()
dlog = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
divide()
# derivative of derivative
#
# example: d(d(f(x,y),y),x)
#
# p1 = d(f(x,y),y)
#
# p2 = x
#
# cadr(p1) = f(x,y)
#
# caddr(p1) = y
dd = ->
# d(f(x,y),x)
push(cadr(p1))
push(p2)
derivative()
p3 = pop()
if (car(p3) == symbol(DERIVATIVE))
# sort dx terms
push_symbol(DERIVATIVE)
push_symbol(DERIVATIVE)
push(cadr(p3))
if (lessp(caddr(p3), caddr(p1)))
push(caddr(p3))
list(3)
push(caddr(p1))
else
push(caddr(p1))
list(3)
push(caddr(p3))
list(3)
else
push(p3)
push(caddr(p1))
derivative()
# derivative of a generic function
dfunction = ->
p3 = cdr(p1); # p3 is the argument list for the function
if (p3 == symbol(NIL) || Find(p3, p2))
push_symbol(DERIVATIVE)
push(p1)
push(p2)
list(3)
else
push(zero)
dsin = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
cosine()
multiply()
dcos = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
sine()
multiply()
negate()
dtan = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
cosine()
push_integer(-2)
power()
multiply()
darcsin = ->
push(cadr(p1))
push(p2)
derivative()
push_integer(1)
push(cadr(p1))
push_integer(2)
power()
subtract()
push_rational(-1, 2)
power()
multiply()
darccos = ->
push(cadr(p1))
push(p2)
derivative()
push_integer(1)
push(cadr(p1))
push_integer(2)
power()
subtract()
push_rational(-1, 2)
power()
multiply()
negate()
# Without simplify With simplify
#
# d(arctan(y/x),x) -y/(x^2*(y^2/x^2+1)) -y/(x^2+y^2)
#
# d(arctan(y/x),y) 1/(x*(y^2/x^2+1)) x/(x^2+y^2)
darctan = ->
push(cadr(p1))
push(p2)
derivative()
push_integer(1)
push(cadr(p1))
push_integer(2)
power()
add()
inverse()
multiply()
simplify()
dsinh = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
ycosh()
multiply()
dcosh = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
ysinh()
multiply()
dtanh = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
ycosh()
push_integer(-2)
power()
multiply()
darcsinh = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
push_integer(2)
power()
push_integer(1)
add()
push_rational(-1, 2)
power()
multiply()
darccosh = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
push_integer(2)
power()
push_integer(-1)
add()
push_rational(-1, 2)
power()
multiply()
darctanh = ->
push(cadr(p1))
push(p2)
derivative()
push_integer(1)
push(cadr(p1))
push_integer(2)
power()
subtract()
inverse()
multiply()
dabs = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
sgn()
multiply()
dsgn = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
dirac()
multiply()
push_integer(2)
multiply()
dhermite = ->
push(cadr(p1))
push(p2)
derivative()
push_integer(2)
push(caddr(p1))
multiply()
multiply()
push(cadr(p1))
push(caddr(p1))
push_integer(-1)
add()
hermite()
multiply()
derf = ->
push(cadr(p1))
push_integer(2)
power()
push_integer(-1)
multiply()
exponential()
if evaluatingAsFloats
push_double(Math.PI)
else
push_symbol(PI)
push_rational(-1,2)
power()
multiply()
push_integer(2)
multiply()
push(cadr(p1))
push(p2)
derivative()
multiply()
derfc = ->
push(cadr(p1))
push_integer(2)
power()
push_integer(-1)
multiply()
exponential()
if evaluatingAsFloats
push_double(Math.PI)
else
push_symbol(PI)
push_rational(-1,2)
power()
multiply()
push_integer(-2)
multiply()
push(cadr(p1))
push(p2)
derivative()
multiply()
dbesselj0 = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
push_integer(1)
besselj()
multiply()
push_integer(-1)
multiply()
dbesseljn = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
push(caddr(p1))
push_integer(-1)
add()
besselj()
push(caddr(p1))
push_integer(-1)
multiply()
push(cadr(p1))
divide()
push(cadr(p1))
push(caddr(p1))
besselj()
multiply()
add()
multiply()
dbessely0 = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
push_integer(1)
besselj()
multiply()
push_integer(-1)
multiply()
dbesselyn = ->
push(cadr(p1))
push(p2)
derivative()
push(cadr(p1))
push(caddr(p1))
push_integer(-1)
add()
bessely()
push(caddr(p1))
push_integer(-1)
multiply()
push(cadr(p1))
divide()
push(cadr(p1))
push(caddr(p1))
bessely()
multiply()
add()
multiply()
derivative_of_integral = ->
push(cadr(p1))