Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality to allow users to pass parameters as f(x, args...) #182

Closed
wants to merge 3 commits into from

Conversation

huckl3b3rry87
Copy link

I added some additional functions that let the user pass parameters to the function of interest when taking it's derivative and it's gradient. All the tests are passing. I also created a folder with an IJulia example in it.

using IJulia
notebook(dir=Pkg.dir("ForwardDiff.jl/examples/temp/"))

Currently I am asking a question at the bottom of the script, which will make sense in the context. But, eventually I think that there should be a few examples to demonstrate the use of this code.

this was previously removed. I am just taking it away so that it matches the master more closely
@KristofferC
Copy link
Collaborator

KristofferC commented Dec 28, 2016

Passing functions that depends on parameters is in ForwardDiff (and other packages that tend to take function inputs, like equation-solver packages) performed using closures. This is simpler and will perform better than the Vararg you introduce here.

See previous discussion in #32 and #77.

A concrete example:

julia> f(x,a) = a * x
f (generic function with 1 method)

julia> const a = 5.0
5.0

julia> ForwardDiff.derivative(x -> f(x,a), 1.0)
5.0

@jrevels
Copy link
Member

jrevels commented Dec 28, 2016

Thanks for the contribution! However, @KristofferC is spot-on here - the closure method of passing parameters is well-established and performant. We really should have a set of examples that demonstrate this.

As for the question you posed in your notebook, there are two problems. The first is that you're using ForwardDiff.gradient to differentiate a function with an array input and an array output. ForwardDiff.gradient is for differentiating functions from arrays to scalars - what you want is ForwardDiff.jacobian. The second problem is the way you're defining your output array (L = zeros(eltype(x),Nc+1,ns)). The derivatives of this function at the given integer inputs are not themselves integers. In other words, your output array constructed via zeros(eltype(x), ...) won't be sufficiently typed to store the derivatives when eltype(x) === Int. This is why you're getting the InexactError - the function can't load a Dual{N,Float64} value into an array whose eltype is Dual{N,Int}.

You can easily work around this by just making sure the input array has an element type that is compatible with the type of the derivatives:

julia> ForwardDiff.jacobian(x -> lagrange_basis_poly(x, [1, 2, 3], 2), [1.0, 2.0])
6×2 Array{Float64,2}:
 -1.5  -0.0
  2.0   0.0
 -0.5   0.0
  0.0  -0.5
  0.0   0.0
  0.0   0.5

@huckl3b3rry87
Copy link
Author

@KristofferC and @jrevels I see! I did not know that I could pass arguments that way.

Thanks for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants