diff --git a/go.mod b/go.mod
index 3925508..d04f3b2 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/illumos/go-kstat v0.0.0-20210513183136-173c9b0a9973
github.com/kubeservice-stack/common v1.9.1
- github.com/montanaflynn/stats v0.12.2
+ github.com/montanaflynn/stats v0.12.3
github.com/prometheus/client_golang v1.24.0
github.com/prometheus/common v0.70.0
github.com/prometheus/exporter-toolkit v0.17.1
diff --git a/go.sum b/go.sum
index ed49b98..1d4eafb 100644
--- a/go.sum
+++ b/go.sum
@@ -41,8 +41,8 @@ github.com/mdlayher/socket v0.6.0 h1:ScZPaAGyO1icQnbFrhPM8mnXyMu9qukC1K4ZoM2IQKU
github.com/mdlayher/socket v0.6.0/go.mod h1:q7vozUAnxSqnjHc12Fik5yUKIzfZ8ITCfMkhOtE9z18=
github.com/mdlayher/vsock v1.3.0 h1:bqQfZ1OznI03y6YiXp2sze05RVdzLn/zsfjnjd4+ivI=
github.com/mdlayher/vsock v1.3.0/go.mod h1:WsuksavOvwCnV5UqGHUkvAvCy+Dqy81y4goKQTzxxNY=
-github.com/montanaflynn/stats v0.12.2 h1:qHR+IveGjTbO+lnrz1nKR+xpIcOtovJ5Xu0cst99h80=
-github.com/montanaflynn/stats v0.12.2/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
+github.com/montanaflynn/stats v0.12.3 h1:6Wapv3TSE8rWROR0+nYl7Sy6C2jXlnZDcFCb0J554zk=
+github.com/montanaflynn/stats v0.12.3/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
diff --git a/vendor/github.com/montanaflynn/stats/CHANGELOG.md b/vendor/github.com/montanaflynn/stats/CHANGELOG.md
index ea3553a..1e407de 100644
--- a/vendor/github.com/montanaflynn/stats/CHANGELOG.md
+++ b/vendor/github.com/montanaflynn/stats/CHANGELOG.md
@@ -7,16 +7,19 @@
-
-## [v0.12.2] - 2026-07-17
+
+
+## [v0.12.3] - 2026-08-10
### Fix
-- Regression stability and invalid domains ([#124](https://github.com/montanaflynn/stats/issues/124))
+- ProbGeom off-by-one that drops the first interval term ([#127](https://github.com/montanaflynn/stats/issues/127))
+- NormIsf ignores loc, NormPpf uncorrected above the median ([#126](https://github.com/montanaflynn/stats/issues/126))
+- Normal tail collapses to 0/-Inf past ~8 sigma ([#125](https://github.com/montanaflynn/stats/issues/125))
-
-## [v0.12.1] - 2026-07-16
+
+## [v0.12.2] - 2026-07-17
### Fix
-- Stop Entropy from mutating its input slice ([#123](https://github.com/montanaflynn/stats/issues/123))
+- Regression stability and invalid domains ([#124](https://github.com/montanaflynn/stats/issues/124))
@@ -28,22 +31,6 @@
## [v0.12.0] - 2026-07-16
-
-## [v0.12.0] - 2026-07-16
-
-
-## [v0.11.0] - 2026-07-13
-### Add
-- Add Interp for piecewise-linear interpolation ([#121](https://github.com/montanaflynn/stats/issues/121))
-- Add Histogram with equal-width bins ([#120](https://github.com/montanaflynn/stats/issues/120))
-- Add KendallTau rank correlation coefficient ([#119](https://github.com/montanaflynn/stats/issues/119))
-- Add SEM, RMS, Product, and PercentileOfScore ([#118](https://github.com/montanaflynn/stats/issues/118))
-- Add MovingMedian, MovingMin, MovingMax, MovingSum, and EWMA ([#117](https://github.com/montanaflynn/stats/issues/117))
-- Add TrimmedMean and Winsorize robust statistics ([#116](https://github.com/montanaflynn/stats/issues/116))
-- Add Kurtosis, PopulationKurtosis, and SampleKurtosis ([#115](https://github.com/montanaflynn/stats/issues/115))
-- Add Clip and Rescale elementwise transforms ([#114](https://github.com/montanaflynn/stats/issues/114))
-
-
## [v0.11.0] - 2026-07-13
### Add
@@ -77,26 +64,6 @@
- Correct AutoCorrelation lag handling ([#83](https://github.com/montanaflynn/stats/issues/83)) ([#95](https://github.com/montanaflynn/stats/issues/95))
-
-## [v0.10.0] - 2026-07-10
-### Add
-- Add MovingAverage and MovingStdDev ([#112](https://github.com/montanaflynn/stats/issues/112))
-- Add ZScore and Rank functions ([#111](https://github.com/montanaflynn/stats/issues/111))
-- Add WeightedMean and CoefficientOfVariation ([#110](https://github.com/montanaflynn/stats/issues/110))
-- Add ArgMax, ArgMin and Range functions ([#109](https://github.com/montanaflynn/stats/issues/109))
-- Add CumulativeProduct, CumulativeMax and CumulativeMin ([#108](https://github.com/montanaflynn/stats/issues/108))
-- Add Diff and PercentChange functions ([#107](https://github.com/montanaflynn/stats/issues/107))
-- Add weighted percentile function ([#102](https://github.com/montanaflynn/stats/issues/102))
-- Add NormSample function for normal distribution sampling ([#100](https://github.com/montanaflynn/stats/issues/100))
-- Add Z-test and T-test functions ([#99](https://github.com/montanaflynn/stats/issues/99))
-- Add Spearman rank correlation function ([#98](https://github.com/montanaflynn/stats/issues/98))
-
-### Fix
-- Stabilize GeometricMean and add input validation
-- Use math.Round to avoid ARM64 FMA fusion miscompile ([#97](https://github.com/montanaflynn/stats/issues/97))
-- Correct AutoCorrelation lag handling ([#83](https://github.com/montanaflynn/stats/issues/83)) ([#95](https://github.com/montanaflynn/stats/issues/95))
-
-
## [v0.9.0] - 2026-03-24
### Add
@@ -638,16 +605,13 @@
- Merge pull request [#4](https://github.com/montanaflynn/stats/issues/4) from saromanov/sample
-[Unreleased]: https://github.com/montanaflynn/stats/compare/v0.12.2...HEAD
+[Unreleased]: https://github.com/montanaflynn/stats/compare/v0.12.3...HEAD
+[v0.12.3]: https://github.com/montanaflynn/stats/compare/v0.12.2...v0.12.3
[v0.12.2]: https://github.com/montanaflynn/stats/compare/v0.12.1...v0.12.2
[v0.12.1]: https://github.com/montanaflynn/stats/compare/v0.12.0...v0.12.1
-[v0.12.1]: https://github.com/montanaflynn/stats/compare/v0.12.0...v0.12.1
[v0.12.0]: https://github.com/montanaflynn/stats/compare/v0.11.0...v0.12.0
-[v0.12.0]: https://github.com/montanaflynn/stats/compare/v0.11.0...v0.12.0
-[v0.11.0]: https://github.com/montanaflynn/stats/compare/v0.10.0...v0.11.0
[v0.11.0]: https://github.com/montanaflynn/stats/compare/v0.10.0...v0.11.0
[v0.10.0]: https://github.com/montanaflynn/stats/compare/v0.9.0...v0.10.0
-[v0.10.0]: https://github.com/montanaflynn/stats/compare/v0.9.0...v0.10.0
[v0.9.0]: https://github.com/montanaflynn/stats/compare/v0.8.2...v0.9.0
[v0.8.2]: https://github.com/montanaflynn/stats/compare/v0.8.1...v0.8.2
[v0.8.1]: https://github.com/montanaflynn/stats/compare/v0.8.0...v0.8.1
diff --git a/vendor/github.com/montanaflynn/stats/geometric_distribution.go b/vendor/github.com/montanaflynn/stats/geometric_distribution.go
index db785dd..f1dfebe 100644
--- a/vendor/github.com/montanaflynn/stats/geometric_distribution.go
+++ b/vendor/github.com/montanaflynn/stats/geometric_distribution.go
@@ -12,14 +12,15 @@ func ProbGeom(a int, b int, p float64) (prob float64, err error) {
return math.NaN(), ErrBounds
}
- prob = 0
q := 1 - p // probability of failure
- for k := a + 1; k <= b; k++ {
- prob = prob + p*math.Pow(q, float64(k-1))
+ if a == b {
+ return p * math.Pow(q, float64(a-1)), nil
}
- return prob, nil
+ // closed form of the sum p*q^(k-1) over k = a..b; expm1/log1p keep
+ // 1-q^n accurate where direct subtraction would cancel
+ return math.Pow(q, float64(a-1)) * -math.Expm1(float64(b-a+1)*math.Log1p(-p)), nil
}
// ProbGeom generates the expectation or average number of trials
diff --git a/vendor/github.com/montanaflynn/stats/norm.go b/vendor/github.com/montanaflynn/stats/norm.go
index 620c5ac..0d0fd08 100644
--- a/vendor/github.com/montanaflynn/stats/norm.go
+++ b/vendor/github.com/montanaflynn/stats/norm.go
@@ -51,27 +51,53 @@ func NormPdf(x float64, loc float64, scale float64) float64 {
// NormLogPdf is the log of the probability density function.
func NormLogPdf(x float64, loc float64, scale float64) float64 {
- return math.Log((math.Pow(math.E, -(math.Pow(x-loc, 2))/(2*math.Pow(scale, 2)))) / (scale * math.Sqrt(2*math.Pi)))
+ z := (x - loc) / scale
+ return -0.5*z*z - math.Log(scale) - 0.5*math.Log(2*math.Pi)
}
// NormCdf is the cumulative distribution function.
func NormCdf(x float64, loc float64, scale float64) float64 {
- return 0.5 * (1 + math.Erf((x-loc)/(scale*math.Sqrt(2))))
+ return 0.5 * math.Erfc(-(x-loc)/(scale*math.Sqrt2))
}
// NormLogCdf is the log of the cumulative distribution function.
func NormLogCdf(x float64, loc float64, scale float64) float64 {
- return math.Log(0.5 * (1 + math.Erf((x-loc)/(scale*math.Sqrt(2)))))
+ z := (x - loc) / scale
+ if z > 0 {
+ return math.Log1p(-0.5 * math.Erfc(z/math.Sqrt2))
+ }
+ return normLogTail(-z)
}
// NormSf is the survival function (also defined as 1 - cdf, but sf is sometimes more accurate).
func NormSf(x float64, loc float64, scale float64) float64 {
- return 1 - 0.5*(1+math.Erf((x-loc)/(scale*math.Sqrt(2))))
+ return 0.5 * math.Erfc((x-loc)/(scale*math.Sqrt2))
}
// NormLogSf is the log of the survival function.
func NormLogSf(x float64, loc float64, scale float64) float64 {
- return math.Log(1 - 0.5*(1+math.Erf((x-loc)/(scale*math.Sqrt(2)))))
+ z := (x - loc) / scale
+ if z < 0 {
+ return math.Log1p(-0.5 * math.Erfc(-z/math.Sqrt2))
+ }
+ return normLogTail(z)
+}
+
+// normSmallestNormal is the smallest positive normal float64; below it math.Erfc
+// keeps only a handful of significant bits.
+const normSmallestNormal = 2.2250738585072014e-308
+
+// normLogTail returns log(sf(z)) for z >= 0.
+func normLogTail(z float64) float64 {
+ if q := 0.5 * math.Erfc(z/math.Sqrt2); q >= normSmallestNormal {
+ return math.Log(q)
+ }
+ // math.Erfc has decayed into the subnormals, so switch to the Mills ratio
+ // expansion sf(z) = pdf(z)/z * (1 - 1/z^2 + 3/z^4 - 15/z^6 + 105/z^8 - ...),
+ // whose first dropped term is below 1e-12 this far out.
+ r := 1 / (z * z)
+ return -0.5*z*z - math.Log(z) - 0.5*math.Log(2*math.Pi) +
+ math.Log1p(r*(-1+r*(3+r*(-15+r*105))))
}
// NormPpf is the point percentile function.
@@ -132,7 +158,15 @@ func NormPpf(p float64, loc float64, scale float64) (x float64) {
(((((b1*r+b2)*r+b3)*r+b4)*r+b5)*r + 1)
}
- e := 0.5*math.Erfc(-x/math.Sqrt2) - p
+ // Halley correction on cdf(x)-p. Above the median cdf(x) and p have both
+ // already rounded to 1, so the difference is taken between the survival
+ // functions instead; 1-p is exact for p >= 0.5.
+ var e float64
+ if p > 0.5 {
+ e = (1 - p) - 0.5*math.Erfc(x/math.Sqrt2)
+ } else {
+ e = 0.5*math.Erfc(-x/math.Sqrt2) - p
+ }
u := e * math.Sqrt(2*math.Pi) * math.Exp(x*x/2)
x = x - u/(1+x*u/2)
@@ -140,11 +174,10 @@ func NormPpf(p float64, loc float64, scale float64) (x float64) {
}
// NormIsf is the inverse survival function (inverse of sf).
-func NormIsf(p float64, loc float64, scale float64) (x float64) {
- if -NormPpf(p, loc, scale) == 0 {
- return 0
- }
- return -NormPpf(p, loc, scale)
+func NormIsf(p float64, loc float64, scale float64) float64 {
+ // isf(p) == ppf(1-p), reached by reflecting the standard normal so that
+ // loc stays out of the negation and 1-p is never formed.
+ return loc - scale*NormPpf(p, 0, 1)
}
// NormMoment approximates the non-central (raw) moment of order n.
@@ -225,11 +258,10 @@ func NormStd(loc float64, scale float64) float64 {
// NormInterval finds endpoints of the range that contains alpha percent of the distribution.
func NormInterval(alpha float64, loc float64, scale float64) [2]float64 {
- q1 := (1.0 - alpha) / 2
- q2 := (1.0 + alpha) / 2
- a := NormPpf(q1, loc, scale)
- b := NormPpf(q2, loc, scale)
- return [2]float64{a, b}
+ // Derive both endpoints from the lower tail: (1+alpha)/2 rounds to 1 once
+ // alpha is within an ulp of it, which sends the upper endpoint to +Inf.
+ z := NormPpf((1.0-alpha)/2, 0, 1)
+ return [2]float64{loc + scale*z, loc - scale*z}
}
// factorial is the naive factorial algorithm.
diff --git a/vendor/github.com/montanaflynn/stats/ttest.go b/vendor/github.com/montanaflynn/stats/ttest.go
index f36ea32..728014a 100644
--- a/vendor/github.com/montanaflynn/stats/ttest.go
+++ b/vendor/github.com/montanaflynn/stats/ttest.go
@@ -76,7 +76,7 @@ func regIncBeta(a, b, x float64) float64 {
}
lbeta := lgammaBeta(a, b)
- front := math.Exp(math.Log(x)*a + math.Log(1-x)*b - lbeta) / a
+ front := math.Exp(math.Log(x)*a+math.Log(1-x)*b-lbeta) / a
// Use Lentz's continued fraction algorithm
f := 1.0
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 8e72978..2651812 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -55,7 +55,7 @@ github.com/mdlayher/socket
# github.com/mdlayher/vsock v1.3.0
## explicit; go 1.25.0
github.com/mdlayher/vsock
-# github.com/montanaflynn/stats v0.12.2
+# github.com/montanaflynn/stats v0.12.3
## explicit; go 1.13
github.com/montanaflynn/stats
# github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822