diff --git a/f.go b/f.go index 600ab17..c58369c 100644 --- a/f.go +++ b/f.go @@ -7,12 +7,14 @@ import ( "git.nunosempere.com/NunoSempere/fermi/sample" "math" "os" + "sort" "strconv" "strings" ) const NORMAL90CONFIDENCE = 1.6448536269514727 const GENERAL_ERR_MSG = "Valid inputs: 2 || * 2 || / 2 || 2 20 || * 2 20 || / 2 20 || clean || =: var || op var || clean || help || debug || exit" +const N_SAMPLES = 10 // 1_000_000 // Distribution interface // https://go.dev/tour/methods/9 @@ -21,21 +23,18 @@ type Dist interface { Samples() []float64 } -// Point implementing distribution - type Scalar struct { p float64 } func (p Scalar) Samples() []float64 { - xs := make([]float64, 1_000_000) - for i := 0; i < 1_000_000; i++ { + xs := make([]float64, N_SAMPLES) + for i := 0; i < N_SAMPLES; i++ { xs[i] = p.p } return xs } -// Lognormal implementing Distribution type Lognormal struct { low float64 high float64 @@ -43,13 +42,9 @@ type Lognormal struct { func (ln Lognormal) Samples() []float64 { sampler := func(r sample.Src) float64 { return sample.Sample_to(ln.low, ln.high, r) } - return sample.Sample_parallel(sampler, 1_000_000) -} -func (ln Lognormal) Type() string { - return "Lognormal" + return sample.Sample_parallel(sampler, N_SAMPLES) } -// Beta implementing Distribution type Beta struct { a float64 b float64 @@ -57,13 +52,9 @@ type Beta struct { func (beta Beta) Samples() []float64 { sampler := func(r sample.Src) float64 { return sample.Sample_beta(beta.a, beta.b, r) } - return sample.Sample_parallel(sampler, 1_000_000) -} -func (beta Beta) Type() string { - return "Beta" + return sample.Sample_parallel(sampler, N_SAMPLES) } -// FilledSamples implementing Distribution type FilledSamples struct { xs []float64 } @@ -71,9 +62,6 @@ type FilledSamples struct { func (fs FilledSamples) Samples() []float64 { return fs.xs } -func (beta FilledSamples) Type() string { - return "FilledSamples" -} // Parse line into Distribution func parseLineErr(err_msg string) (string, Dist, error) { @@ -124,8 +112,19 @@ func parseLine(line string, vars map[string]Dist) (string, Dist, error) { return parseLineErr("Trying to operate by a distribution, but distribution is not specified as two floats") } dist = Lognormal{low: new_low, high: new_high} + case 3: + if words[0] == "beta" || words[0] == "b" { + a, err1 := strconv.ParseFloat(words[1], 64) + b, err2 := strconv.ParseFloat(words[2], 64) + if err1 != nil || err2 != nil { + return parseLineErr("Trying to specify a beta distribution? Try beta 1 2") + } + dist = Beta{a: a, b: b} + } else { + return parseLineErr("Input not understood or not implemented yet") + } default: - return parseLineErr("Other input methods not implemented yet") + return parseLineErr("Input not understood or not implemented yet") } return op, dist, nil @@ -156,14 +155,21 @@ func multiplyBetaDists(beta1 Beta, beta2 Beta) Beta { } func multiplyAsSamples(dist1 Dist, dist2 Dist) Dist { + // dist2 = Beta{a: 1, b: 2} + fmt.Printf("dist1: %v\n", dist1) + fmt.Printf("dist2: %v\n", dist2) xs := dist1.Samples() ys := dist2.Samples() - zs := make([]float64, 1_000_000) - for i, x := range xs { - zs[i] = x * ys[i] + fmt.Printf("xs: %v\n", xs) + fmt.Printf("ys: %v\n", ys) + zs := make([]float64, N_SAMPLES) + + for i := 0; i < N_SAMPLES; i++ { + zs[i] = xs[i] * ys[i] } - return FilledSamples{xs: xs} + fmt.Printf("%v\n", zs) + return FilledSamples{xs: zs} } func multiplyDists(old_dist Dist, new_dist Dist) (Dist, error) { @@ -219,7 +225,7 @@ func joinDists(old_dist Dist, new_dist Dist, op string) (Dist, error) { } /* Pretty print distributions */ -func prettyPrintLognormal(low float64, high float64) { +func prettyPrint90CI(low float64, high float64) { // fmt.Printf("=> %.1f %.1f\n", low, high) fmt.Printf("=> ") switch { @@ -258,7 +264,18 @@ func prettyPrintLognormal(low float64, high float64) { func prettyPrintDist(dist Dist) { switch v := dist.(type) { case Lognormal: - prettyPrintLognormal(v.low, v.high) + prettyPrint90CI(v.low, v.high) + case FilledSamples: + tmp_xs := make([]float64, N_SAMPLES) + copy(tmp_xs, v.xs) + sort.Slice(tmp_xs, func(i, j int) bool { + return tmp_xs[i] < tmp_xs[j] + }) + low_int := N_SAMPLES / 20 + low := tmp_xs[low_int] + high_int := N_SAMPLES * 19 / 20 + high := tmp_xs[high_int] + prettyPrint90CI(low, high) default: fmt.Printf("%v", v) } @@ -267,13 +284,9 @@ func prettyPrintDist(dist Dist) { /* Main event loop */ func main() { - sample_0 := func(r sample.Src) float64 { return 0 } - x := sample.Sample_parallel(sample_0, 10) - fmt.Printf("%v\n", x) - reader := bufio.NewReader(os.Stdin) var init_dist Dist - init_dist = Lognormal{low: 1, high: 1} + init_dist = Scalar{p: 1} // Lognormal{low: 1, high: 1} old_dist := init_dist vars := make(map[string]Dist) // Could eventually be a more complex struct with: