-
Notifications
You must be signed in to change notification settings - Fork 146
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
Is this code a supported use? (single-pass value and derivative) #610
Comments
I can't comment on official API and design questions here, at least not in an official way. However, a quick note on
DiffResults is a dependency of ForwardDiff, so it's a dependency anyway, regardless of whether you load it or not. You might even be able to load ForwardDiff.DiffResults or ForwardDiff.DiffResult directly. |
Thanks for the comment. That means that no extra packages are installed just for this simple use case (which is a good thing!). Unfortunately, it doesn't mean that one can avoid having to explicitly add Regarding that other point (i.e., the fact that, when using EDIT: By that I mean a adding a new method like this: import ForwardDiff
import DiffResults
@inline function ForwardDiff.derivative!(::Nothing, f, x::Real) # Or just value_and_derivative(f, x::Real)
T = typeof(ForwardDiff.Tag(f, typeof(x)))
ydual = f(ForwardDiff.Dual{T}(x, one(x)))
return DiffResults.DiffResult(ForwardDiff.value(T, ydual), ForwardDiff.extract_derivative(T, ydual))
end The
|
I've found a couple of implementations of the second method in SciML packages, so there's definitely demand for such a method, as well as some precedent of treating |
Small caveat is that SimpleNonLinearSolve was extracted and to a large extent copied from NonLinearSolve just some days ago, so the links are basically a single example of the second method. |
I am doing something similar in a private package. I don’t think it’s official API, so I just have a few tests that will be indicative when things break. I guess, whether you are fine with something like this depends on your risk persona and application area. |
@thomvet Well, I ended up doing the same. I still hope this type of usage can be included in the public API (or clarified as such if it's already meant to be API) so as to be able to avoid future breakage. |
Considering these two methods that compute the value and first derivative of a scalar function in a single pass:
The first method seems to be the officially recommended way to do this. However, (1) it introduces the
DiffResults
dependency just for this, and (2) it needlessly requires the caller to specifyf
's return type ahead of the call. Neither are dealbreakers, but IMO they add friction for something that looks like it shouldn't have it (intuition says that the value comes for free when computing a derivative withForwardDiff
)The second method uses the
Tag
andDual
types as well as theextract_derivative
function, which are not listed in the "Differentiation API" in the docs, so I'm not sure if they're considered part of the stable public APIBoth methods run equally fast (and significantly faster than a naive two-pass implementation), so my question is: does the second method constitute a supported use of
ForwardDiff
's public API?If such an use isn't supported (but maybe even if it is so—both method implementations appear too convoluted for a pretty common use case IMO), I'd like to suggest adding a
value_and_derivative
function with the second method to either this or one of the other packages inJuliaDiff
(I'm willing to write a PR).Related: #401, #391
EDITS:
y
->ydual
,ydual.value
->ForwardDiff.value(T, ydual)
, add another related issueThe text was updated successfully, but these errors were encountered: