simplify fermi.go again
This commit is contained in:
parent
2314bf5db2
commit
e93316446c
|
@ -193,11 +193,13 @@ Done:
|
|||
- [x] Make -n flag work
|
||||
- [x] Add flag to repeat input lines (useful when reading from files)
|
||||
- [x] Add percentages
|
||||
- [x] Consider adding an understanding of percentages
|
||||
|
||||
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
|
||||
- [ ] Consider adding an understanding of percentages
|
||||
- [ ] 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
|
||||
- [ ] 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 {
|
||||
Samples() []float64
|
||||
Sampler(int, sample.State) float64
|
||||
}
|
||||
|
||||
|
@ -42,44 +41,22 @@ type FilledSamples struct {
|
|||
|
||||
/* Dist interface functions */
|
||||
// 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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
// This is a bit subtle, because sampling from FilledSamples randomly iteratively converges
|
||||
// to something different than the initial distribution
|
||||
// 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]
|
||||
}
|
||||
|
||||
|
@ -180,7 +157,7 @@ func printAndReturnErr(err_msg string) error {
|
|||
}
|
||||
|
||||
func prettyPrintStats(dist Dist) {
|
||||
xs := dist.Samples()
|
||||
xs := sample.Sample_serially(dist.Sampler, N_SAMPLES)
|
||||
n := len(xs)
|
||||
|
||||
mean := 0.0
|
||||
|
@ -221,8 +198,8 @@ func prettyPrintStats(dist Dist) {
|
|||
// Generic operations with samples
|
||||
func operateDistsAsSamples(dist1 Dist, dist2 Dist, op string) (Dist, error) {
|
||||
|
||||
xs := dist1.Samples()
|
||||
ys := dist2.Samples()
|
||||
xs := sample.Sample_serially(dist1.Sampler, N_SAMPLES)
|
||||
ys := sample.Sample_serially(dist2.Sampler, N_SAMPLES)
|
||||
zs := make([]float64, N_SAMPLES)
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
var dists []Dist
|
||||
var fs []func(int, sample.State) float64
|
||||
// var ss [][]float64
|
||||
var weights []float64
|
||||
|
||||
for i, word := range words {
|
||||
|
@ -390,12 +365,8 @@ func parseMixture(words []string, vars map[string]Dist) (Dist, error) {
|
|||
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")
|
||||
}
|
||||
// samples := dist.Samples()
|
||||
f := dist.Sampler
|
||||
// Inefficient to draw N_SAMPLES for each of the distributions, but conceptually simpler.
|
||||
dists = append(dists, dist)
|
||||
fs = append(fs, f)
|
||||
// ss = append(ss, samples)
|
||||
} else {
|
||||
weight, err := pretty.ParseFloat(word)
|
||||
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)
|
||||
// var global_state = rand.New(rand.NewPCG(uint64(1), uint64(2)))
|
||||
for i := 0; i < n_samples; i++ {
|
||||
xs[i] = f(global_state)
|
||||
xs[i] = f(i, global_state)
|
||||
}
|
||||
return xs
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user