Non-Contradiction / autodiffr

Automatic Differentiation for R
https://non-contradiction.github.io/autodiffr/
Other
23 stars 2 forks source link

Progress of Wrapping APIs of ReverseDiff: Part 2 #17

Open Non-Contradiction opened 6 years ago

Non-Contradiction commented 6 years ago

This is a continuation of #3. Now the non-mutating APIs of ReverseDiff has all been implemented. And basic documentation and tests have been finished. Although some basic tests are still failed.....

Note that different from the original plan, APIs related to AbstractTape have been implemented. And multiple argument function is a challenge unexpected.

In sum, the result of wrapping of APIs of ReverseDiff is satisfactory, and can be considered finished basically, with potential further improvements:

nashjc commented 6 years ago

Is there an explanation of "mutating" or "non-mutating" somewhere? This may be important for maintenance of the code later.

Non-Contradiction commented 6 years ago

An easy but not very rigorous explanation will be

x <- something
f(x)
f non-mutating if x is still the same thing before executing f

Since most R functions are non-mutating (except the <- ones), then autodiffr assumes that the target function func in grad(func, x, ...), hessian(func, x, ...) to be non-mutating. so APIs related to mutating target function func of ForwardDiff and ReverseDiff are NOT wrapped in autodiffr (in Julia, functions with names ending in ! are supposed to "mutate" the arguments).

And ForwardDiff and ReverseDiff provide another sets of mutating APIs, which looks like:

result = DiffResults(...) # the object is to store the differentiation results.
result = ForwardDiff.gradient!(result, func, input, ...)
# then the things like gradient, the original function value will be stored in the result object

I'm wondering whether to wrap this set of APIs, and treat DiffResults just as a JuliaObject not normal R object. It has advantages in calculating the function value and gradient value and etc all in the same run. So it could improve performance if used appropriately. And I'm also wondering how to incorporate this into packages like optim and optimr.