Calculus.jl icon indicating copy to clipboard operation
Calculus.jl copied to clipboard

Evaluate symbolic derivatives at specific points

Open johnmyleswhite opened this issue 12 years ago • 10 comments

It would be useful to provide a tool like differentiate(:(exp(x)), :x)) that returns a compiled function that is immediately evaluable at specific values of x.

johnmyleswhite avatar May 26 '13 17:05 johnmyleswhite

So sorry, this is literally the first time I've ever used git or github, and I'm not too sure how pulls work (but I'll figure it out in a moment). Anyway this seems to work:

# differentiate a function f(x) at given x
function symbolic_difference(ex::Expr, wrt::SymbolicVariable, atx::Float64)
    ex = differentiate(ex)
    eval(:($wrt = $atx))
    return eval(ex)
end

The only problem I guess is that here you're messing around with global variables, but I'm still figuring out Julia.

julia> expression = differentiate(:(exp(x)), :x)
:(exp(x))

julia> symbolic_difference(expression, :x, 1.0)
2.7182818284590455

julia> symbolic_difference(expression, :x, 0.0)
1.0

Hmm, also, using eval like this seems dangerous.

jckt avatar May 26 '13 17:05 jckt

Yeah, using eval isn't ideal here. Let me ponder this for a bit.

johnmyleswhite avatar May 26 '13 20:05 johnmyleswhite

Hey there !

I'd really like to do something like this in my code. What is the advancement of this point ? There was a PR (#12) some time ago, is there anything I can do to help with this ?

I am very novice in metaprograming and symbolic computing, but I can try.

Luthaf avatar Nov 03 '14 23:11 Luthaf

I have a pretty clear sense how to implement this, but am very busy for the next few weeks. You might try working on it yourself for a while and submitting a PR, which I'll try to make time to review.

johnmyleswhite avatar Nov 04 '14 03:11 johnmyleswhite

Here's an overview:

(1) Understand the existing function that takes in a symbolic expression and produces its derivative.

(2) Write a macro that, given a symbolic expression, a) generates its derivative using (1), b) defines a function whose body is the derivative, and c) calls that function on the input.

Thus, you'd end up with a macro like the following:

@differentiate(5.0, sin(x) + cos(x))

johnmyleswhite avatar Nov 04 '14 03:11 johnmyleswhite

This is implemented efficiently in https://github.com/JuliaDiff/ReverseDiffSource.jl

mlubin avatar Nov 04 '14 03:11 mlubin

Well, it would be a good thing to have it in this package too : you can fall back to finite differences if there is no way to differentiate analytically the function.

Could the two packages being merged into one ? Or is it worth implementing the ReverseDiffSource method into this one ?

Luthaf avatar Nov 04 '14 09:11 Luthaf

The methods in ReverseDiffSource/ReverseDiffSparse are way too complex to be merged into the basic Calculus package. If you just need to compile derivatives of a simple symbolic expression, John's approach is pretty straightforward and would be a good addition to Calculus.jl.

mlubin avatar Nov 04 '14 15:11 mlubin

One thing that would be nice at some point is to try to unify interfaces between the packages so that it's easier to transition from Calculus to ReverseDiffSparse.

johnmyleswhite avatar Nov 04 '14 15:11 johnmyleswhite

One thing that would be nice at some point is to try to unify interfaces between the packages so that it's easier to transition from Calculus to ReverseDiffSparse.

Sure !

If you just need to compile derivatives of a simple symbolic expression, John's approach is pretty straightforward and would be a good addition to Calculus.jl.

I may try to do this if I find some time for hacking around. But I am pretty busy right now too ...

Luthaf avatar Nov 06 '14 17:11 Luthaf