@@ -374,12 +374,28 @@ def inverse_t_distribution(df, alpha)
374374 # Cauchy distribution: exact inverse
375375 return Math . tan ( Math ::PI * ( 0.5 - alpha ) )
376376 elsif df == 2
377- # Exact formula for df=2: t = z / sqrt(1 - z^2/(z^2 + 2))
378- # This is more numerically stable
379- z_sq = z **2
380- # Exact formula for df=2: t = z / sqrt(1 - z^2/(z^2 + 2))
381- return z / Math . sqrt ( 1.0 - ( z_sq / ( z_sq + 2.0 ) ) )
377+ # Exact closed-form solution for df=2
378+ # For df=2, CDF: F(t) = 1/2 * (1 + t/√(t² + 2))
379+ # Quantile function: t = (2p - 1)/√(2p(1 - p)) where p = 1 - α
382380
381+ p = 1.0 - alpha
382+
383+ # Handle edge cases
384+ return Float ::INFINITY if p >= 1.0
385+ return -Float ::INFINITY if p <= 0.0
386+
387+ # For p very close to 0.5, use normal approximation to avoid numerical issues
388+ return 0.0 if ( p - 0.5 ) . abs < 1e-10
389+
390+ # Apply exact formula: t = (2p - 1)/√(2p(1 - p))
391+ numerator = ( 2.0 * p ) - 1.0
392+ denominator_sq = 2.0 * p * ( 1.0 - p )
393+
394+ # Ensure we don't have numerical issues with the square root
395+ return numerator / Math . sqrt ( denominator_sq ) if denominator_sq . positive?
396+
397+ # Fallback to normal approximation for edge cases
398+ return z
383399 end
384400
385401 # Use Cornish-Fisher expansion for general case
@@ -388,29 +404,31 @@ def inverse_t_distribution(df, alpha)
388404 # Base normal quantile
389405 t = z
390406
391- # First-order correction
407+ # First-order correction - Cornish-Fisher expansion
408+ # Standard form: (z³ + z)/(4ν)
392409 if df >= 4
393- c1 = z / 4.0
410+ c1 = ( ( z ** 3 ) + z ) / 4.0
394411 t += c1 / df
395412 end
396413
397- # Second-order correction
414+ # Second-order correction - Cornish-Fisher expansion
415+ # Standard form: (5z⁵ + 16z³ + 3z)/(96ν²)
398416 if df >= 6
399- c2 = ( ( 5.0 * ( z **3 ) ) + ( 16.0 * z ) ) / 96.0
417+ c2 = ( ( 5.0 * ( z **5 ) ) + ( 16.0 * ( z ** 3 ) ) + ( 3 .0 * z ) ) / 96.0
400418 t += c2 / ( df **2 )
401419 end
402420
403421 # Third-order correction for better accuracy
422+ # Standard form: (3z⁷ + 19z⁵ + 17z³ - 15z)/(384ν³)
404423 if df >= 8
405- c3 = ( ( 3.0 * ( z **5 ) ) + ( 19.0 * ( z **3 ) ) + ( 17.0 * z ) ) / 384.0
424+ c3 = ( ( 3.0 * ( z **7 ) ) + ( 19.0 * ( z **5 ) ) + ( 17.0 * ( z ** 3 ) ) - ( 15 .0 * z ) ) / 384.0
406425 t += c3 / ( df **3 )
407426 end
408427
409- # Fourth-order correction for very high accuracy
410- if df >= 10
411- c4 = ( ( 79.0 * ( z **7 ) ) + ( 776.0 * ( z **5 ) ) +
412- ( 1482.0 * ( z **3 ) ) + ( 776.0 * z ) ) / CORNISH_FISHER_FOURTH_ORDER_DENOMINATOR
413-
428+ # Fourth-order correction - using standard coefficients
429+ # More conservative approach for high accuracy
430+ if df >= 12
431+ c4 = ( ( 79.0 * ( z **7 ) ) + ( 776.0 * ( z **5 ) ) + ( 1482.0 * ( z **3 ) ) + ( 776.0 * z ) ) / CORNISH_FISHER_FOURTH_ORDER_DENOMINATOR
414432 t += c4 / ( df **4 )
415433 end
416434
0 commit comments