Use FindRoot
directly with arbitrary-precision
n = 5; n1 = 4; n2 = 6; γ = 1/20; α = 1/370;
icdf = x /.
FindRoot[CDF[NoncentralFRatioDistribution[1, n1 - 1, n1/γ^2], x] ==
1 - α - (n - n1)/n2, {x, 500},
WorkingPrecision -> $MachinePrecision]
(* 5468.146403807255 *)
Verifying,
(CDF[NoncentralFRatioDistribution[1, n1 - 1, n1/γ^2], icdf] //
RootApproximant) === 1 - α - (n - n1)/n2
(* True *)
Note that while the starting value used in FindRoot
needs to be large, it does not have to be particularly close to the actual value.
EDIT: To "correct" the InverseCDF
define your own function
Clear["Global`*"]
n = 5; n1 = 4; n2 = 6; γ = 1/20; α = 1/370;
invCDF[dist_, q_, start_: 50, wkprec_: $MachinePrecision] :=
Module[
{x, distr = Rationalize[dist], qr = Rationalize[q]},
Check[InverseCDF[dist, q],
x /. FindRoot[CDF[distr, x] == qr, {x, start},
WorkingPrecision -> wkprec]]]
dist = NoncentralFRatioDistribution[1, n1 - 1, n1/γ^2];
Exact input to invCDF
will output exact output (i.e., unevaluated for your example distribution). Since InverseCDF
does not throw an error message, switching to FindRoot
does not occur.
invCDF[dist, 1 - α - (n - n1)/n2]
(* InverseCDF[NoncentralFRatioDistribution[1, 3, 1600], 461/555] *)
This is desired for less complicated distributions for which the InverseCDF
is known, e.g.,
invCDF[NormalDistribution[], 3/4]
(* Sqrt[2] InverseErfc[1/2] *)
Converting the argument for your distribution to a numeric approximation will result in evaluation and the desired switching to FindRoot
.
invCDF[dist, 1 - α - (n - n1)/n2 // N] // Quiet
(* 5468.146403807255 *)