time-to-botec/go/squiggle.go

83 lines
1.9 KiB
Go
Raw Normal View History

2024-02-15 23:19:09 +00:00
package main
import "fmt"
2024-02-15 23:40:02 +00:00
import "math"
2024-02-15 23:19:09 +00:00
import rand "math/rand/v2"
2024-02-15 23:25:36 +00:00
var r = rand.New(rand.NewPCG(1, 2))
2024-02-15 23:57:22 +00:00
// https://pkg.go.dev/math/rand/v2
2024-02-15 23:40:02 +00:00
func sample_unit_uniform() float64 {
return r.Float64()
}
2024-02-15 23:25:36 +00:00
func sample_unit_normal() float64 {
2024-02-15 23:40:02 +00:00
return r.NormFloat64()
}
func sample_uniform(start float64, end float64) float64 {
return sample_unit_uniform()*(end-start) + start
}
func sample_normal(mean float64, sigma float64) float64 {
return mean + sample_unit_normal()*sigma
}
func sample_lognormal(logmean float64, logstd float64) float64 {
return (math.Exp(sample_normal(logmean, logstd)))
}
func sample_normal_from_90_ci(low float64, high float64) float64 {
var normal90 float64 = 1.6448536269514727
var mean float64 = (high + low) / 2.0
var std float64 = (high - low) / (2.0 * normal90)
return sample_normal(mean, std)
2024-02-15 23:25:36 +00:00
}
2024-02-15 23:42:39 +00:00
func sample_to(low float64, high float64) float64 {
// Given a (positive) 90% confidence interval,
// returns a sample from a lognorma with a matching 90% c.i.
// Key idea: If we want a lognormal with 90% confidence interval [a, b]
// we need but get a normal with 90% confidence interval [log(a), log(b)].
// Then see code for sample_normal_from_90_ci
var loglow float64 = math.Log(low)
var loghigh float64 = math.Log(high)
return math.Exp(sample_normal_from_90_ci(loglow, loghigh))
}
2024-02-16 09:10:16 +00:00
type func64 func() float64
2024-02-16 12:43:29 +00:00
func sample_mixture(fs []func64, weights []float64) float64 {
var sum_weights float64 = 0
2024-02-16 12:43:55 +00:00
for _, weight := range weights {
2024-02-16 12:43:29 +00:00
sum_weights += weight
}
return sum_weights
2024-02-16 09:10:16 +00:00
}
2024-02-15 23:19:09 +00:00
func main() {
2024-02-15 23:57:22 +00:00
var n_samples int = 1000000
// var array_samples [n_samples]float64
var avg float64 = 0
for i := 0; i < n_samples; i++ {
avg += sample_to(1, 10)
}
avg = avg / float64(n_samples)
fmt.Printf("%v\n", avg)
2024-02-16 09:10:16 +00:00
f1 := func() float64 {
return sample_to(1, 10)
}
2024-02-16 12:43:29 +00:00
f2 := func() float64 {
return sample_to(100, 1000)
}
fs := [2](func64){f1, f2}
ws := [2](float64){0.4, 0.1}
x := sample_mixture(fs[0:], ws[0:])
fmt.Printf("%v\n", x)
2024-02-15 23:19:09 +00:00
}