simplify fermi.go again
This commit is contained in:
parent
2314bf5db2
commit
e93316446c
|
@ -193,11 +193,13 @@ Done:
|
||||||
- [x] Make -n flag work
|
- [x] Make -n flag work
|
||||||
- [x] Add flag to repeat input lines (useful when reading from files)
|
- [x] Add flag to repeat input lines (useful when reading from files)
|
||||||
- [x] Add percentages
|
- [x] Add percentages
|
||||||
|
- [x] Consider adding an understanding of percentages
|
||||||
|
|
||||||
To (possibly) do:
|
To (possibly) do:
|
||||||
|
|
||||||
|
- [ ] Consider implications of sampling strategy for operating variables in this case.
|
||||||
|
- [ ] Document mixture distributions
|
||||||
- [ ] Fix lognormal multiplication and division by 0 or < 0
|
- [ ] Fix lognormal multiplication and division by 0 or < 0
|
||||||
- [ ] Consider adding an understanding of percentages
|
|
||||||
- [ ] With the -f command line option, the program doesn't read from stdin after finishing reading the file
|
- [ ] With the -f command line option, the program doesn't read from stdin after finishing reading the file
|
||||||
- [ ] Add functions. Now easier to do with an explicit representation of the stakc
|
- [ ] Add functions. Now easier to do with an explicit representation of the stakc
|
||||||
- [ ] Think about how to draw a histogram from samples
|
- [ ] Think about how to draw a histogram from samples
|
||||||
|
|
35
fermi.go
35
fermi.go
|
@ -20,7 +20,6 @@ type Stack struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Dist interface {
|
type Dist interface {
|
||||||
Samples() []float64
|
|
||||||
Sampler(int, sample.State) float64
|
Sampler(int, sample.State) float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,44 +41,22 @@ type FilledSamples struct {
|
||||||
|
|
||||||
/* Dist interface functions */
|
/* Dist interface functions */
|
||||||
// https://go.dev/tour/methods/9
|
// https://go.dev/tour/methods/9
|
||||||
func (p Scalar) Samples() []float64 {
|
|
||||||
xs := make([]float64, N_SAMPLES)
|
|
||||||
for i := 0; i < N_SAMPLES; i++ {
|
|
||||||
xs[i] = float64(p)
|
|
||||||
}
|
|
||||||
return xs
|
|
||||||
}
|
|
||||||
func (p Scalar) Sampler(i int, r sample.State) float64 {
|
func (p Scalar) Sampler(i int, r sample.State) float64 {
|
||||||
return float64(p)
|
return float64(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ln Lognormal) Samples() []float64 {
|
|
||||||
sampler := func(r sample.State) float64 { return sample.Sample_to(ln.low, ln.high, r) }
|
|
||||||
// Can't do parallel because then I'd have to await throughout the code
|
|
||||||
return sample.Sample_serially(sampler, N_SAMPLES)
|
|
||||||
}
|
|
||||||
func (ln Lognormal) Sampler(i int, r sample.State) float64 {
|
func (ln Lognormal) Sampler(i int, r sample.State) float64 {
|
||||||
return sample.Sample_to(ln.low, ln.high, r)
|
return sample.Sample_to(ln.low, ln.high, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (beta Beta) Samples() []float64 {
|
|
||||||
sampler := func(r sample.State) float64 { return sample.Sample_beta(beta.a, beta.b, r) }
|
|
||||||
return sample.Sample_serially(sampler, N_SAMPLES)
|
|
||||||
}
|
|
||||||
func (beta Beta) Sampler(i int, r sample.State) float64 {
|
func (beta Beta) Sampler(i int, r sample.State) float64 {
|
||||||
return sample.Sample_beta(beta.a, beta.b, r)
|
return sample.Sample_beta(beta.a, beta.b, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs FilledSamples) Samples() []float64 {
|
|
||||||
return fs.xs
|
|
||||||
}
|
|
||||||
func (fs FilledSamples) Sampler(i int, r sample.State) float64 {
|
func (fs FilledSamples) Sampler(i int, r sample.State) float64 {
|
||||||
// This is a bit subtle, because sampling from FilledSamples randomly iteratively converges
|
// This is a bit subtle, because sampling from FilledSamples randomly iteratively converges
|
||||||
// to something different than the initial distribution
|
// to something different than the initial distribution
|
||||||
// So instead we have an i parameter.
|
// So instead we have an i parameter.
|
||||||
// Not sure how I feel about it
|
|
||||||
// n := len(fs.xs)
|
|
||||||
// i := sample.Sample_int(n, r)
|
|
||||||
return fs.xs[i]
|
return fs.xs[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +157,7 @@ func printAndReturnErr(err_msg string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func prettyPrintStats(dist Dist) {
|
func prettyPrintStats(dist Dist) {
|
||||||
xs := dist.Samples()
|
xs := sample.Sample_serially(dist.Sampler, N_SAMPLES)
|
||||||
n := len(xs)
|
n := len(xs)
|
||||||
|
|
||||||
mean := 0.0
|
mean := 0.0
|
||||||
|
@ -221,8 +198,8 @@ func prettyPrintStats(dist Dist) {
|
||||||
// Generic operations with samples
|
// Generic operations with samples
|
||||||
func operateDistsAsSamples(dist1 Dist, dist2 Dist, op string) (Dist, error) {
|
func operateDistsAsSamples(dist1 Dist, dist2 Dist, op string) (Dist, error) {
|
||||||
|
|
||||||
xs := dist1.Samples()
|
xs := sample.Sample_serially(dist1.Sampler, N_SAMPLES)
|
||||||
ys := dist2.Samples()
|
ys := sample.Sample_serially(dist2.Sampler, N_SAMPLES)
|
||||||
zs := make([]float64, N_SAMPLES)
|
zs := make([]float64, N_SAMPLES)
|
||||||
|
|
||||||
for i := 0; i < N_SAMPLES; i++ {
|
for i := 0; i < N_SAMPLES; i++ {
|
||||||
|
@ -379,9 +356,7 @@ func parseMixture(words []string, vars map[string]Dist) (Dist, error) {
|
||||||
return nil, printAndReturnErr("Not a mixture. \nMixture syntax: \nmx x 2.5 y 8 z 10\ni.e.: mx var weight var2 weight2 ... var_n weight_n")
|
return nil, printAndReturnErr("Not a mixture. \nMixture syntax: \nmx x 2.5 y 8 z 10\ni.e.: mx var weight var2 weight2 ... var_n weight_n")
|
||||||
}
|
}
|
||||||
|
|
||||||
var dists []Dist
|
|
||||||
var fs []func(int, sample.State) float64
|
var fs []func(int, sample.State) float64
|
||||||
// var ss [][]float64
|
|
||||||
var weights []float64
|
var weights []float64
|
||||||
|
|
||||||
for i, word := range words {
|
for i, word := range words {
|
||||||
|
@ -390,12 +365,8 @@ func parseMixture(words []string, vars map[string]Dist) (Dist, error) {
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, printAndReturnErr("Expected mixture variable but didn't get a variable. \nMixture syntax: \nmx x 2.5 y 8 z 10\ni.e.: mx var weight var2 weight2 ... var_n weight_n")
|
return nil, printAndReturnErr("Expected mixture variable but didn't get a variable. \nMixture syntax: \nmx x 2.5 y 8 z 10\ni.e.: mx var weight var2 weight2 ... var_n weight_n")
|
||||||
}
|
}
|
||||||
// samples := dist.Samples()
|
|
||||||
f := dist.Sampler
|
f := dist.Sampler
|
||||||
// Inefficient to draw N_SAMPLES for each of the distributions, but conceptually simpler.
|
|
||||||
dists = append(dists, dist)
|
|
||||||
fs = append(fs, f)
|
fs = append(fs, f)
|
||||||
// ss = append(ss, samples)
|
|
||||||
} else {
|
} else {
|
||||||
weight, err := pretty.ParseFloat(word)
|
weight, err := pretty.ParseFloat(word)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -149,11 +149,11 @@ func Sample_mixture_once(fs []func64, weights []float64, r State) float64 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Sample_serially(f func64, n_samples int) []float64 {
|
func Sample_serially(f func64i, n_samples int) []float64 {
|
||||||
xs := make([]float64, n_samples)
|
xs := make([]float64, n_samples)
|
||||||
// var global_state = rand.New(rand.NewPCG(uint64(1), uint64(2)))
|
// var global_state = rand.New(rand.NewPCG(uint64(1), uint64(2)))
|
||||||
for i := 0; i < n_samples; i++ {
|
for i := 0; i < n_samples; i++ {
|
||||||
xs[i] = f(global_state)
|
xs[i] = f(i, global_state)
|
||||||
}
|
}
|
||||||
return xs
|
return xs
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user