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

Reply via email to