forked from leesper/go_rng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
beta.go
40 lines (35 loc) · 1.18 KB
/
beta.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
package rng
import (
"fmt"
)
// BetaGenerator is a random number generator for beta distribution.
// The zero value is invalid, use NewBetaGenerator to create a generator
type BetaGenerator struct {
gamma1 *GammaGenerator
gamma2 *GammaGenerator
}
// NewBetaGenerator returns a beta distribution generator
// it is recommended using time.Now().UnixNano() as the seed, for example:
// brng := rng.NewBetaGenerator(time.Now().UnixNano())
func NewBetaGenerator(seed int64) *BetaGenerator {
grng1 := NewGammaGenerator(seed)
// according to "Numerical Recipes", all distinct
//gamma variates must have different random seeds
grng2 := NewGammaGenerator(2*seed + 1)
return &BetaGenerator{grng1, grng2}
}
// Beta returns a random number of beta distribution (alpha > 0.0 and beta > 0.0)
func (brng BetaGenerator) Beta(alpha, beta float64) float64 {
if !(alpha > 0.0) {
panic(fmt.Sprintf("Invalid parameter alpha: %.2f", alpha))
}
if !(beta > 0.0) {
panic(fmt.Sprintf("Invalid parameter beta: %.2f", beta))
}
return brng.beta(alpha, beta)
}
func (brng BetaGenerator) beta(alpha, beta float64) float64 {
X := brng.gamma1.Gamma(alpha, 1)
Y := brng.gamma2.Gamma(beta, 1)
return X / (X + Y)
}