Skip to content

Instantly share code, notes, and snippets.

@mauro3
Created June 30, 2016 20:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mauro3/d8a127ab798d8655c3151f3a21a6fa85 to your computer and use it in GitHub Desktop.
Save mauro3/d8a127ab798d8655c3151f3a21a6fa85 to your computer and use it in GitHub Desktop.
forwarddiff with in-place functions
using ForwardDiff
const T = Float64 # the datatype used, probably Float64
const dof = 4
fn!(;T_::Type=T, dof_=dof) = zeros(T_,dof_)
function fn!(res, y)#, dydt)
@show typeof(res), typeof(y)
for i=1:dof
res[i] = 3*y[i]#+dydt[i]
end
nothing
end
const res = fn!()
function fn_ex(y)
fn!(res, y)
return res
end
ad_jacobian(F) = (t,y)->ForwardDiff.jacobian(F,y)
const out = fn!()
ad_jacobian2(F!) = (t,y)->ForwardDiff.jacobian(F!,out,y)
ad_jacobian2!(F!) = (outJ,t,y)->ForwardDiff.jacobian!(outJ,F!,out,y)
J = ad_jacobian(fn_ex)
J! = ad_jacobian2(fn!)
J!! = ad_jacobian2!(fn!)
ic = zeros(T,dof)
typeof(J(0.0,ic))
typeof(J!(0.0,ic))
const outJ = similar(out, length(out), length(out))
J!!(outJ,0,ic)
typeof(outJ)
@mauro3
Copy link
Author

mauro3 commented Jun 30, 2016

J(0.0,ic) errors because it tries to fill res with dual numbers. J! and J!! work.

@pwl
Copy link

pwl commented Jul 1, 2016

This looks like a bad style to me. fn_ex should become fn_ex! and accept res as an argument, then you actually can't use line 23 as the implementation of a Jacobian. Lines 25 and 26 work perfectly well.

@pwl
Copy link

pwl commented Jul 1, 2016

You are passing a function with side effects to jacobian, while it probably expects that each evaluation is independent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment