-
Notifications
You must be signed in to change notification settings - Fork 12
/
multinomial.go
57 lines (55 loc) · 1.09 KB
/
multinomial.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package stat
import (
. "github.com/ematvey/go-fn/fn"
)
func Multinomial_PMF(θ []float64, n int64) func(x []int64) float64 {
return func(x []int64) float64 {
if len(x) != len(θ) {
return 0
}
l := fOne
totalx := iZero
for i := 0; i < len(x); i++ {
l *= pow(θ[i], float64(x[i]))
l /= Γ(float64(x[i] + 1))
totalx += x[i]
}
if totalx != n {
return 0
}
l *= Γ(float64(totalx + 1))
return l
}
}
func Multinomial_LnPMF(θ []float64, n int64) func(x []int64) float64 {
return func(x []int64) float64 {
if len(x) != len(θ) {
return negInf
}
l := fZero
totalx := iZero
for i := 0; i < len(x); i++ {
l += log(θ[i]) * float64(x[i])
l -= LnΓ(float64(x[i] + 1))
totalx += x[i]
}
if totalx != n {
return negInf
}
l += LnΓ(float64(totalx + 1))
return l
}
}
func NextMultinomial(θ []float64, n int64) []int64 {
x := make([]int64, len(θ))
chooser := Choice(θ)
for i := iZero; i < n; i++ {
x[chooser()]++
}
return x
}
func Multinomial(θ []float64, n int64) func() []int64 {
return func() []int64 {
return NextMultinomial(θ, n)
}
}