Hi
I like to create automatically functions that evaluates the total
derivative of a function with respect to time, eg.
given f(t, x1, x2) = t^2+x1*x2, I want to obtain
df/dt(t,x1,x2,dx1/dt,dx2/dt) = 2t+x1*dx2/dt+x2*dx1/dt,
d2f/dt2(t,x1,x2,dx1/dt,dx2/dt,d2x1/dt2,d2x2/dt) =
2+2dx1/dt*dx2/dt+x1*d2x2/dt2+x2*d2x1/dt2, and so on.
The initial function is specified as a string as are the arguments.
The following code using the Calculus package works nicely:
using Calculus
function total_derivatives_with_respect_to_time(f::AbstractString,
order::Int, names::AbstractString...)
derivs = Array(Function, order)
n = length(names)
args = AbstractString["t", names...]
derivs[1] = eval(parse("($(reduce((a,b)->"$a,$b",args)))->$f"))
if order > 1
fun = f
for o = 2:order
∇fun = differentiate(fun, args)
dfun = AbstractString["$(∇fun[1])"]
for i = 1:n
push!(args, "d$(o-1)_$(names[i])")
end
for j = 2:(o-1)*n+1
push!(dfun, "($(∇fun[j])) * $(args[j+n])")
end
fun = reduce((a,b)->"$a + $b", dfun)
derivs[o] = eval(parse("($(reduce((a,b)->"$a,$b",args)))->$fun"))
end
end
return derivs
end
derivs = total_derivatives_with_respect_to_time("t^2+x1*x2", 3, "x1", "x2")
println(derivs[1](1.0, 2.0, 3.0))
println(derivs[2](1.0, 2.0, 3.0, 4.0, 5.0))
println(derivs[3](1.0, 2.0, 3.0, 4.0, 5.0, -1.0, -2.0))
I have however the feeling that I am abusing the sequence of eval and parse
to automatically generate anonymous function. Is there a way to do this
more elegantly? Performance wise the code runs fine in Julia v0.5.
Ben