That's quite a strong statement to say never use parse. Could you explain? 
I think manipulating strings is typically much easier than Expr objects.

On Thursday, April 28, 2016 at 8:38:27 AM UTC-4, Yichao Yu wrote:
>
>
> On Apr 28, 2016 7:15 AM, "Ben Lauwens" <[email protected] <javascript:>> 
> wrote:
> >
> > 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))
>
> For calculating derivatives there may be better ways (forwarddiff and 
> other packages). In general, generating functions with eval is fine as long 
> as you dont do that in the performance critical part. However, you should 
> never use parse and should construct the AST directly.
>
> > 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