Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,11 @@
/// <param name="p">The probability value in [0.0, 1.0].</param>
/// <returns>The quantile corresponding to the cumulative probability p.</returns>
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

/// <summary>Returns the support of the exponential distribution: [0, Positive Infinity).</summary>
Expand Down Expand Up @@ -199,7 +202,7 @@
/// </example>
static member Init dof =
{ new ContinuousDistribution<float,float> with
member d.Mean = ChiSquared.Mean dof

Check warning on line 205 in src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'float'.

Check warning on line 205 in src/FSharp.Stats/Distributions/Continuous/ChiSquared.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'float'.
member d.StandardDeviation = ChiSquared.StandardDeviation dof
member d.Variance = ChiSquared.Variance dof
member d.CDF x = ChiSquared.CDF dof x
Expand Down
59 changes: 59 additions & 0 deletions tests/FSharp.Stats.Tests/DistributionsContinuous.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading