stat/distuv: fix Beta.LogProb for alpha = 1, x = 0 and beta = 1, x = 1
MODIFY
stat/distuv/beta.go
stat/distuv/beta.go
@@ -71,7 +71,15 @@ func (b Beta) LogProb(x float64) float64 {
lab, _ := math.Lgamma(b.Alpha + b.Beta)
la, _ := math.Lgamma(b.Alpha)
lb, _ := math.Lgamma(b.Beta)
- return lab - la - lb + (b.Alpha-1)*math.Log(x) + (b.Beta-1)*math.Log(1-x)
+ var lx float64
+ if b.Alpha != 1 {
+ lx = (b.Alpha - 1) * math.Log(x)
+ }
+ var l1mx float64
+ if b.Beta != 1 {
+ l1mx = (b.Beta - 1) * math.Log(1-x)
+ }
+ return lab - la - lb + lx + l1mx
}
// Mean returns the mean of the probability distribution.

MODIFY
stat/distuv/beta_test.go
stat/distuv/beta_test.go
@@ -148,3 +148,27 @@ func TestBetaMode(t *testing.T) {
}
}
}
+
+// See https://github.com/gonum/gonum/issues/1377 for details.
+func TestBetaIssue1377(t *testing.T) {
+ t.Parallel()
+ b := Beta{Alpha: 1, Beta: 1}
+ p0 := b.Prob(0)
+ if p0 != 1 {
+ t.Errorf("Mismatch in PDF value at x == 0 for Alpha == 1 and Beta == 1: got %v, want 1", p0)
+ }
+ p1 := b.Prob(1)
+ if p1 != 1 {
+ t.Errorf("Mismatch in PDF value at x == 1 for Alpha == 1 and Beta == 1: got %v, want 1", p1)
+ }
+ b = Beta{Alpha: 1, Beta: 10}
+ p0 = b.Prob(0)
+ if math.IsNaN(p0) {
+ t.Errorf("NaN PDF at x == 0 for Alpha == 1 and Beta > 10")
+ }
+ b = Beta{Alpha: 10, Beta: 1}
+ p1 = b.Prob(1)
+ if math.IsNaN(p1) {
+ t.Errorf("NaN PDF at x == 1 for Alpha > 1 and Beta == 1")
+ }
+}

stat/distuv: fix Beta.LogProb for alpha = 1, x = 0 and beta = 1, x = 1