enumerable-stats 1.2.1 → 1.3.0
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 +46 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0131e566d1175fe367fb75c840914ae752eea76a1a194a8d35a02d24591d6ad
|
4
|
+
data.tar.gz: bb99194f3965132256bb9cdabed80bf58c5da172f7cd10e4f56277c0417fe7d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 022f98715f44e7788749adb509bbef27bf759d2d09c7d946ebbdf21e34ea6e8a7225e011be6ad39e3260cec3f7daad17c61ecefbd9a197457b0e75d9bd10889c
|
7
|
+
data.tar.gz: d1e0a0052b175fe9fc4175961d0b52248c8cc78c39258048fa7846d9e67c8bd2ff6fe6da365b41284b9b9e2d48c8a9c1fcc165d621a25d9227df88716849ae34
|
@@ -93,6 +93,9 @@ module EnumerableStats
|
|
93
93
|
# treatment = [15, 17, 16, 18, 14]
|
94
94
|
# t_stat = control.t_value(treatment) # => ~-4.2 (negative means treatment > control)
|
95
95
|
def t_value(other)
|
96
|
+
raise ArgumentError, "Cannot compare with an empty collection" if empty? || other.empty?
|
97
|
+
raise ArgumentError, "Parameter must be an Enumerable" unless other.respond_to?(:mean)
|
98
|
+
|
96
99
|
signal = (mean - other.mean)
|
97
100
|
noise = Math.sqrt(
|
98
101
|
((standard_deviation**2) / count) +
|
@@ -144,6 +147,16 @@ module EnumerableStats
|
|
144
147
|
t_stat > critical_value
|
145
148
|
end
|
146
149
|
|
150
|
+
# Alias for greater_than?
|
151
|
+
def >(other, alpha: 0.05)
|
152
|
+
greater_than?(other, alpha: alpha)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Alias for less_than?
|
156
|
+
def <(other, alpha: 0.05)
|
157
|
+
less_than?(other, alpha: alpha)
|
158
|
+
end
|
159
|
+
|
147
160
|
# Tests if this collection's mean is significantly less than another collection's mean
|
148
161
|
# using a one-tailed Student's t-test. Returns true if the test indicates statistical
|
149
162
|
# significance at the specified alpha level.
|
@@ -374,12 +387,28 @@ module EnumerableStats
|
|
374
387
|
# Cauchy distribution: exact inverse
|
375
388
|
return Math.tan(Math::PI * (0.5 - alpha))
|
376
389
|
elsif df == 2
|
377
|
-
# Exact
|
378
|
-
#
|
379
|
-
|
380
|
-
|
381
|
-
|
390
|
+
# Exact closed-form solution for df=2
|
391
|
+
# For df=2, CDF: F(t) = 1/2 * (1 + t/√(t² + 2))
|
392
|
+
# Quantile function: t = (2p - 1)/√(2p(1 - p)) where p = 1 - α
|
393
|
+
|
394
|
+
p = 1.0 - alpha
|
382
395
|
|
396
|
+
# Handle edge cases
|
397
|
+
return Float::INFINITY if p >= 1.0
|
398
|
+
return -Float::INFINITY if p <= 0.0
|
399
|
+
|
400
|
+
# For p very close to 0.5, use normal approximation to avoid numerical issues
|
401
|
+
return 0.0 if (p - 0.5).abs < 1e-10
|
402
|
+
|
403
|
+
# Apply exact formula: t = (2p - 1)/√(2p(1 - p))
|
404
|
+
numerator = (2.0 * p) - 1.0
|
405
|
+
denominator_sq = 2.0 * p * (1.0 - p)
|
406
|
+
|
407
|
+
# Ensure we don't have numerical issues with the square root
|
408
|
+
return numerator / Math.sqrt(denominator_sq) if denominator_sq.positive?
|
409
|
+
|
410
|
+
# Fallback to normal approximation for edge cases
|
411
|
+
return z
|
383
412
|
end
|
384
413
|
|
385
414
|
# Use Cornish-Fisher expansion for general case
|
@@ -388,29 +417,31 @@ module EnumerableStats
|
|
388
417
|
# Base normal quantile
|
389
418
|
t = z
|
390
419
|
|
391
|
-
# First-order correction
|
420
|
+
# First-order correction - Cornish-Fisher expansion
|
421
|
+
# Standard form: (z³ + z)/(4ν)
|
392
422
|
if df >= 4
|
393
|
-
c1 = z / 4.0
|
423
|
+
c1 = ((z**3) + z) / 4.0
|
394
424
|
t += c1 / df
|
395
425
|
end
|
396
426
|
|
397
|
-
# Second-order correction
|
427
|
+
# Second-order correction - Cornish-Fisher expansion
|
428
|
+
# Standard form: (5z⁵ + 16z³ + 3z)/(96ν²)
|
398
429
|
if df >= 6
|
399
|
-
c2 = ((5.0 * (z**
|
430
|
+
c2 = ((5.0 * (z**5)) + (16.0 * (z**3)) + (3.0 * z)) / 96.0
|
400
431
|
t += c2 / (df**2)
|
401
432
|
end
|
402
433
|
|
403
434
|
# Third-order correction for better accuracy
|
435
|
+
# Standard form: (3z⁷ + 19z⁵ + 17z³ - 15z)/(384ν³)
|
404
436
|
if df >= 8
|
405
|
-
c3 = ((3.0 * (z**
|
437
|
+
c3 = ((3.0 * (z**7)) + (19.0 * (z**5)) + (17.0 * (z**3)) - (15.0 * z)) / 384.0
|
406
438
|
t += c3 / (df**3)
|
407
439
|
end
|
408
440
|
|
409
|
-
# Fourth-order correction
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
441
|
+
# Fourth-order correction - using standard coefficients
|
442
|
+
# More conservative approach for high accuracy
|
443
|
+
if df >= 12
|
444
|
+
c4 = ((79.0 * (z**7)) + (776.0 * (z**5)) + (1482.0 * (z**3)) + (776.0 * z)) / CORNISH_FISHER_FOURTH_ORDER_DENOMINATOR
|
414
445
|
t += c4 / (df**4)
|
415
446
|
end
|
416
447
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumerable-stats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Daniel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
A Ruby gem that extends all Enumerable objects (Arrays, Ranges, Sets, etc.) with essential statistical methods.
|