This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-statistics.git
The following commit(s) were added to refs/heads/master by this push:
new 976c3cc1 STATISTICS-95: Validate mean is finite and variance is
positive finite
976c3cc1 is described below
commit 976c3cc1ee318199bc1d6687a86943c1e7f079c0
Author: Alex Herbert <[email protected]>
AuthorDate: Thu Aug 27 09:17:14 2026 +0100
STATISTICS-95: Validate mean is finite and variance is positive finite
---
.../statistics/interval/NormalConfidenceInterval.java | 10 +++++++++-
.../interval/NormalConfidenceIntervalTest.java | 18 ++++++++++++++++++
src/changes/changes.xml | 3 +++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git
a/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
b/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
index 79f4f0bb..ee5b12f9 100644
---
a/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
+++
b/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
@@ -72,13 +72,21 @@ public enum NormalConfidenceInterval {
* @param alpha Desired error rate that the true value falls
* <em>outside</em> the returned interval.
* @return Confidence interval containing the target with error rate
{@code alpha}
- * @throws IllegalArgumentException if {@code n <= 1}, or if {@code alpha}
is not in
+ * @throws IllegalArgumentException if {@code n <= 1}; if {@code mean} is
not finite;
+ * if {@code variance} is not positive and finite; or if {@code alpha} is
not in
* the open interval {@code (0, 1)}.
*/
public Interval fromErrorRate(double mean, double variance, long n, double
alpha) {
if (n <= 1) {
throw new IllegalArgumentException("Sample size is not above one:
" + n);
}
+ if (!Double.isFinite(mean)) {
+ throw new IllegalArgumentException("Mean is not finite: " + mean);
+ }
+ if (!(variance >= 0 && variance < Double.POSITIVE_INFINITY)) {
+ // negative, infinite or nan
+ throw new IllegalArgumentException("Variance is not positive and
finite: " + variance);
+ }
ArgumentUtils.checkErrorRate(alpha);
return create(mean, variance, n, alpha);
}
diff --git
a/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
b/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
index eece3f9a..539d8315 100644
---
a/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
+++
b/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
@@ -49,6 +49,21 @@ class NormalConfidenceIntervalTest {
Assertions.assertThrows(IllegalArgumentException.class, () ->
method.fromErrorRate(mean, variance, n, -0.01));
Assertions.assertThrows(IllegalArgumentException.class, () ->
method.fromErrorRate(mean, variance, n, 1.01));
Assertions.assertThrows(IllegalArgumentException.class, () ->
method.fromErrorRate(mean, variance, n, Double.NaN));
+ // mean must be finite
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> method.fromErrorRate(Double.NaN, variance, n, alpha));
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> method.fromErrorRate(Double.POSITIVE_INFINITY, variance, n,
alpha));
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> method.fromErrorRate(Double.NEGATIVE_INFINITY, variance, n,
alpha));
+ // variance must be positive and finite
+ Assertions.assertDoesNotThrow(() -> method.fromErrorRate(mean, 0.0, n,
alpha));
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> method.fromErrorRate(mean, Double.NaN, n, alpha));
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> method.fromErrorRate(mean, Double.POSITIVE_INFINITY, n,
alpha));
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> method.fromErrorRate(mean, -1.0, n, alpha));
}
@ParameterizedTest
@@ -87,6 +102,9 @@ class NormalConfidenceIntervalTest {
add(builder, method, 2.9535381946732131, 5.2628380291790835, 50, 0.1,
3.887312567406342, 7.6002576083181186,
1e-14);
+ // Edge cases of zero variance: the interval should be [0, 0]
+ add(builder, method, 1.23, 0.0, 100, 0.05, 0.0, 0.0, 0.0);
+
// Approximate formula for asymptotic distributions at large n uses z
critical value
// from a normal distribution, here z_{0.025} = 1.96
final double z = 1.96;
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bf52d353..c393e874 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -53,6 +53,9 @@ If the output is not quite correct, check for invisible
trailing spaces!
</properties>
<body>
<release version="1.4" date="TBD" description="Adds new features (requires
Java 8).">
+ <action dev="aherbert" type="fix" due-to="Security scan, Aex Herbert"
issue="STATISTICS-95">
+ "NormalConfidenceInterval": Validate mean is finite and variance is
positive finite.
+ </action>
</release>
<release version="1.3" date="2026-05-01" description="Adds new features
(requires Java 8).">