enumerable-stats 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/enumerable_stats/enumerable_ext.rb +33 -15
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67bc0d2458936c421a69879c70fa9eb553e48c7447012e87810ce3c4ab028d66
|
4
|
+
data.tar.gz: 819fcf5e9446b4f7e4a1d7e75aeb914d4ab6ca6a76e65065877d5c3d3bab3634
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5dfe0571aa591684f9ae8cf8e26a472695b6a26c424185878a6e7a9bfd2786ee20c205c2eca0be234a88fb25c895fc0d2cb25a599aabbc569375657b5ee1705
|
7
|
+
data.tar.gz: cd39ddb06cc2cbc1f204deaece6cce9fcf1835583510559a8dd7d24615df95aac16c9a2ff6bd0ba1678c1dce80c0e7636eae6c121e4b7fd31d418b619fed8604
|
@@ -374,12 +374,28 @@ module EnumerableStats
|
|
374
374
|
# Cauchy distribution: exact inverse
|
375
375
|
return Math.tan(Math::PI * (0.5 - alpha))
|
376
376
|
elsif df == 2
|
377
|
-
# Exact
|
378
|
-
#
|
379
|
-
|
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 - α
|
382
380
|
|
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
|
383
399
|
end
|
384
400
|
|
385
401
|
# Use Cornish-Fisher expansion for general case
|
@@ -388,29 +404,31 @@ module EnumerableStats
|
|
388
404
|
# Base normal quantile
|
389
405
|
t = z
|
390
406
|
|
391
|
-
# First-order correction
|
407
|
+
# First-order correction - Cornish-Fisher expansion
|
408
|
+
# Standard form: (z³ + z)/(4ν)
|
392
409
|
if df >= 4
|
393
|
-
c1 = z / 4.0
|
410
|
+
c1 = ((z**3) + z) / 4.0
|
394
411
|
t += c1 / df
|
395
412
|
end
|
396
413
|
|
397
|
-
# Second-order correction
|
414
|
+
# Second-order correction - Cornish-Fisher expansion
|
415
|
+
# Standard form: (5z⁵ + 16z³ + 3z)/(96ν²)
|
398
416
|
if df >= 6
|
399
|
-
c2 = ((5.0 * (z**
|
417
|
+
c2 = ((5.0 * (z**5)) + (16.0 * (z**3)) + (3.0 * z)) / 96.0
|
400
418
|
t += c2 / (df**2)
|
401
419
|
end
|
402
420
|
|
403
421
|
# Third-order correction for better accuracy
|
422
|
+
# Standard form: (3z⁷ + 19z⁵ + 17z³ - 15z)/(384ν³)
|
404
423
|
if df >= 8
|
405
|
-
c3 = ((3.0 * (z**
|
424
|
+
c3 = ((3.0 * (z**7)) + (19.0 * (z**5)) + (17.0 * (z**3)) - (15.0 * z)) / 384.0
|
406
425
|
t += c3 / (df**3)
|
407
426
|
end
|
408
427
|
|
409
|
-
# Fourth-order correction
|
410
|
-
|
411
|
-
|
412
|
-
|
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
|
414
432
|
t += c4 / (df**4)
|
415
433
|
end
|
416
434
|
|