Open chriselrod opened 7 years ago
The limitation here is that cdf
, like any function ForwardDiff
works on, must be able to accept any subtype of Real
as an argument. Both the Beta
and Gamma
examples you give use rmath
for the calculation, which only accepts Float64
.
This will eventually be resolved when we remove the dependency on rmath
, but in the meantime, you'll either need to implement the derivative function by hand or implement the cdf in pure Julia, which ForwardDiff
should be able to handle.
It is probably worth mentioning that the Gamma cdf is a slightly complicated function and the Beta cdf is an extremely complicated function which would require a lot of work and skills to reimplement in Julia.
A much simpler answer would then be to simply define appropriate diffrules: http://www.juliadiff.org/DiffBase.jl/latest/diffrule_api.html This sounds like the way to go if one wants to support ForwardDiff on CDFs. Even if one were to implement slightly (let alone extremely) complicated functions, I would guess the simplicity of the pdfs would make calling them directly would perform better.
The normal part is fixed by #875
Two comments:
cdf
that returns the pdf
SpecialFunctions
' beta_inc
and gamma_inc
which need DiffRules
definitions.2.
SpecialFunctions
'beta_inc
andgamma_inc
which needDiffRules
definitions.
The current design of DiffRules does not support defining rules for beta_inc
and gamma_inc
since they return tuples. Support for gamma_inc
was added to ForwardDiff directly in https://github.com/JuliaDiff/ForwardDiff.jl/pull/587 but currently only derivatives with respect to the second argument are implemented as derivatives with respect to the first argument would require (regularized) hypergeometric functions.
Is Hypergeometricfunctions.jl not mature enough to be a dependency for ForwardDiff.jl?
Otherwise the following does the job for derivatives of beta_inc
with respect to a
and b
and could be implemented in ForwardDiff
similarly to https://github.com/JuliaDiff/ForwardDiff.jl/pull/587?
using SpecialFunctions, HypergeometricFunctions
function beta_inc_deriv(a, b, z, wrt)
if wrt == :a
return (log(z) - polygamma(0, a) + polygamma(0, a + b))*beta_inc(a, b, z)[1] -
(gamma(a)*gamma(a+b)/gamma(b))*z^a*pFq((a, a, 1-b), (a+1, a+1), z)/(gamma(a+1)^2)
elseif wrt == :b
return (-log(1-z) + polygamma(0, b) - polygamma(0, a + b))*beta_inc(b, a, 1-z)[1] +
(gamma(b)*gamma(a+b)/gamma(a))*(1-z)^b*pFq((b, b, 1-a), (b+1, b+1), 1-z)/(gamma(b+1)^2)
else
error("wrt must be :a or :b")
end
end
While the normal distribution supports ForwardDiff (has cd
I take this as a sign that I should just work out the analytical derivatives in my application, but they are not always clear given more complicated functions of the cdf.
Status
gamma_inc
inSpecialFunctions
)beta_inc
inSpecialFunction
)