JuliaDiff / FiniteDifferences.jl

High accuracy derivatives, estimated via numerical finite differences (formerly FDM.jl)
MIT License
296 stars 26 forks source link

Partial Derivatives #1

Open wesselb opened 6 years ago

wesselb commented 6 years ago

Add support for partial derivatives.

nickrobinson251 commented 5 years ago

Did you an API for this in mind?

Given we have grad(fdm, f, x::Vector) for scalar function f(x::Vector) https://github.com/JuliaDiff/FiniteDifferences.jl/blob/287a26186bc58cfba3f7d5a977bbb759b74cf871/src/grad.jl#L8 we could have

function grad(fdm, f, x::Vector{T}, i::Integer) where T<:Real
    v = zeros(T, size(x))
    v[i] = one(T)
    dx = fdm(ϵ -> f(x .+ ϵ .* v), zero(T))
    return dx
end

?

this is obviously better than computing all the partials then selecting the one you want... but maybe you had something nicer in mind?

julia> f(x) = x[1]^2 * x[2] + x[3];

julia> xs = randn(3);

julia> h = [1e-6, 0.0, 0.0];

julia> _fdm = central_fdm(3, 1);

julia> @btime ($f($xs + $h) - $f($xs - $h)) / (2 * $h[1])
  73.728 ns (2 allocations: 224 bytes)
-0.1254986907728295

julia> @btime grad($_fdm, $f, $xs)[1]
  12.084 μs (237 allocations: 7.41 KiB)
-0.12549869079279574

julia> @btime grad($_fdm, $f, $xs, 1)
  3.693 μs (87 allocations: 3.34 KiB)
-0.12549869079279574
wesselb commented 5 years ago

Your proposed interface looks good and like what I had in mind. We can allow multiple integers to specify mixed derivatives; e.g., grad(fdm, f, x, 1, 2) would estimate d^2 f / dx[1] dx[2]. The main challenge here is to generalise the algorithm that automatically determines the weights and step size for a given order, but I think we should be able to resolve that without too much trouble.

oxinabox commented 5 years ago

An alternative iterface would be to return a tuple of ChainRulesCore.Thunks. Nice thing is these are just anonfunctions so you call the one you want, which would do the work. and if there is common setup it can happen before them.

And ChainRules.extern (or just calling them) would evaluate them.