scipy: `stats.norminvgauss` incorrect implementation?
Hi,
Mentioned in the latest release of TensorFlow Probability, it has been noted that scipy.stats.norminvgauss
has not been implemented in the same way as R or the original mathematical paper.
It seems the loc
and scale
parameters should actually be mu
and delta
. Is there a way to update this so that non-standard cases (other than loc=0, scale =1
) make mathematical sense?
Note that `scipy.stats.norminvgauss` implements the distribution as a
location-scale family. However, in the original paper, and other
implementations (such as R) do not implement it this way. Thus the
`scale` parameters here and scipy don't match unless `scale = 1`.
Warning: As mentioned above, this distribution is __not__ a location-scale
family.
Docs: https://www.tensorflow.org/probability/api_docs/python/tfp/distributions/NormalInverseGaussian
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 16 (9 by maintainers)
@mdhaber Thanks! That works really well!
Very close, but don’t use
norminvg
to calculate the PPF and ISF. The functions will only be evaluated atx = tol/10
, so you can code in correct values yourself. It is not very sensitive to these values being super accurate - e.g., for PPF, return any valuex
at whichnorminvg.cdf(x)
is very small (ideallytol/10
).Something like
This will make
NumericalInverseHermite
form an approximationH
of the inverse ofnorminvg.cdf
that is valid between -2 and 2. The round-trip tolerance (i.e.abs(x - norminvg.cdf(H(x)))
) will be controlled at mesh points and midpoints between mesh points totol=1e-6
.I can confirm the slow speed in the development version of SciPy:
But please consider upgrading; we can’t support such an old version.
If you upgrade to 1.7, you may find
NumericalInverseHermite
useful:In TF, if you use
loc = mu, tailweight = alpha, skewness = beta, scale = sigma
to evaluate the CDF, I think this corresponds tostats.norminvgauss(alpha*sigma, beta*sigma, loc=mu, scale=sigma).cdf(x)
in SciPy.