# Problem with the Inverse CDF of Non-central F Ratio Distribution

In:= n = 5; n1 = 4; n2 = 6; γ = 0.05; α = 1/370;
InverseCDF[NoncentralFRatioDistribution[1, n1 - 1, n1/γ^2],
1 - α - (n - n1)/n2]


During evaluation of In:= FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances. >>

Out= 3.24659


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 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 *)

• See edit for "corrected" function. – Bob Hanlon Jan 16 '19 at 15:52
• Thanks a lot for your effort. The problem is you have fixed the starting value at 50 in the findroot function, which will not be the good choice in general. The starting value maybe 0.5. It means, every time we need to put the correct starting value. The built-in inverseCDF function, however, doesn't require any starting value. The problem is thus still there!! – Abdul Haq Jan 17 '19 at 20:19
• The starting value is not fixed at 50 it defaults to 50. You can specify any starting value that you want. The default used by InverseCDF` isn't working so I gave you the ability to specify one. – Bob Hanlon Jan 17 '19 at 20:23