From 7f689263aaca5983659dea08a8ad01a8b137e783 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 5 Apr 2026 12:15:25 +0000
Subject: [PATCH 1/2] Fix ChiSquared.InvCDF scale parameter bug; add InvCDF
tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ChiSquared.InvCDF delegates to Gamma.InvCDF, but was passing
beta = 1/2 (rate) while FSharp.Stats Gamma uses the *scale*
parameterisation (Mean = alpha * scale).
The correct scale for Chi-squared(dof) = Gamma(alpha=dof/2, scale=2)
is 2.0, not 0.5. The wrong value caused InvCDF to return quantiles
that were roughly 4× too small.
Also adds a testList "ChiSquared.InvCDF tests" with:
- boundary checks (p=0 → 0, p=1 → +∞)
- round-trip tests (CDF(InvCDF(p)) ≈ p) at p=0.5, 0.95, 0.01
- known-value tests derived from the existing CDF reference values
All 1201 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.../Distributions/Continuous/ChiSquared.fs | 5 +-
.../DistributionsContinuous.fs | 59 +++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs b/src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs
index 44aa14ac..5fdc11a8 100644
--- a/src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs
+++ b/src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs
@@ -140,8 +140,11 @@ type ChiSquared =
/// The probability value in [0.0, 1.0].
/// The quantile corresponding to the cumulative probability p.
static member InvCDF (dof: float) (p: float) : float =
+ // Chi-squared(dof) = Gamma(alpha=dof/2, scale=2).
+ // FSharp.Stats Gamma uses the scale parameterisation (Mean = alpha * scale),
+ // so the correct scale is 2.0, not 1/2.
let alpha = dof / 2.0
- let beta = 1. / 2.0
+ let beta = 2.0
Gamma.InvCDF alpha beta p
/// Returns the support of the exponential distribution: [0, Positive Infinity).
diff --git a/tests/FSharp.Stats.Tests/DistributionsContinuous.fs b/tests/FSharp.Stats.Tests/DistributionsContinuous.fs
index 6d13c751..c674cad2 100644
--- a/tests/FSharp.Stats.Tests/DistributionsContinuous.fs
+++ b/tests/FSharp.Stats.Tests/DistributionsContinuous.fs
@@ -618,6 +618,65 @@ let chiSquaredTests =
Expect.floatClose Accuracy.veryHigh (testCase.PDF -1.) 0. "Should be equal"
Expect.isTrue (Ops.isNan <| testCase.PDF nan) "Should be equal"
]
+
+ // Tests for ChiSquared.InvCDF (the percentile-point function).
+ // Reference values from standard chi-square tables (and CDF values already tested above).
+ testList "ChiSquared.InvCDF tests" [
+
+ test "ChiSquared.InvCDF returns 0.0 for p=0.0" {
+ let x = Continuous.ChiSquared.InvCDF 5. 0.
+ Expect.floatClose Accuracy.high x 0. "InvCDF(p=0) should be 0"
+ }
+
+ test "ChiSquared.InvCDF returns +∞ for p=1.0" {
+ let x = Continuous.ChiSquared.InvCDF 5. 1.
+ Expect.isTrue (x = infinity) "InvCDF(p=1) should be +infinity"
+ }
+
+ // Round-trip tests: CDF(InvCDF(p)) ≈ p
+ test "ChiSquared.InvCDF round-trip dof=5 p=0.5" {
+ let dof = 5.
+ let p = 0.5
+ let x = Continuous.ChiSquared.InvCDF dof p
+ let p2 = Continuous.ChiSquared.CDF dof x
+ Expect.floatClose Accuracy.high p p2 "CDF(InvCDF(0.5)) ≈ 0.5"
+ }
+
+ test "ChiSquared.InvCDF round-trip dof=1 p=0.95" {
+ let dof = 1.
+ let p = 0.95
+ let x = Continuous.ChiSquared.InvCDF dof p
+ let p2 = Continuous.ChiSquared.CDF dof x
+ Expect.floatClose Accuracy.high p p2 "CDF(InvCDF(0.95)) ≈ 0.95"
+ }
+
+ test "ChiSquared.InvCDF round-trip dof=10 p=0.01" {
+ let dof = 10.
+ let p = 0.01
+ let x = Continuous.ChiSquared.InvCDF dof p
+ let p2 = Continuous.ChiSquared.CDF dof x
+ Expect.floatClose Accuracy.high p p2 "CDF(InvCDF(0.01)) ≈ 0.01"
+ }
+
+ // Known-value tests derived from the CDF cases tested above
+ // (Williams 1984 table: CDF(20, 12.443) ≈ 0.1 → InvCDF(20, 0.1) ≈ 12.443)
+ test "ChiSquared.InvCDF known value dof=20 p=0.1" {
+ let x = Continuous.ChiSquared.InvCDF 20. 0.1
+ Expect.floatClose Accuracy.low x 12.443 "InvCDF(20, 0.1) should be ≈ 12.443"
+ }
+
+ // CDF(3, 1.424) ≈ 0.3 → InvCDF(3, 0.3) ≈ 1.424
+ test "ChiSquared.InvCDF known value dof=3 p=0.3" {
+ let x = Continuous.ChiSquared.InvCDF 3. 0.3
+ Expect.floatClose Accuracy.low x 1.424 "InvCDF(3, 0.3) should be ≈ 1.424"
+ }
+
+ // CDF(100, 129.561) ≈ 0.975 → InvCDF(100, 0.975) ≈ 129.561
+ test "ChiSquared.InvCDF known value dof=100 p=0.975" {
+ let x = Continuous.ChiSquared.InvCDF 100. 0.975
+ Expect.floatClose Accuracy.low x 129.561 "InvCDF(100, 0.975) should be ≈ 129.561"
+ }
+ ]
]
//Test ommitted due to long runtime of CodeCov
From 80f09b7699d29da44938ae24d25cba4b4c2a4c19 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sun, 5 Apr 2026 12:15:28 +0000
Subject: [PATCH 2/2] ci: trigger checks