From 16cbf39a79d59b76ed37f23d63b323cc44b31b5f Mon Sep 17 00:00:00 2001 From: surtur Date: Mon, 18 Jul 2022 10:08:12 +0200 Subject: [PATCH] go(stats,algo): get,plot mean vals --- algo/plot.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-- stats/stats.go | 17 ++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/algo/plot.go b/algo/plot.go index 2832a37..0143c00 100644 --- a/algo/plot.go +++ b/algo/plot.go @@ -20,7 +20,60 @@ const preferredFontStyle = "Mono" -// edit: now not violating gocognit limit of 30, TODO(me): still split this up. +func plotMeanVals(vals []stats.BenchRound, fes int) *plot.Plot { + plotter.DefaultFont.Typeface = preferredFontStyle + plotter.DefaultLineStyle.Width = vg.Points(1.5) + + p := plot.New() + + p.Title.Text = "Mean" + + p.X.Label.Text = "Generations" + p.X.Label.TextStyle.Font.Variant = preferredFontStyle + p.X.Label.TextStyle.Font.Weight = 1 // Medium + p.X.Tick.Label.Font.Variant = preferredFontStyle + p.Y.Label.Text = "CF value" + p.Y.Label.TextStyle.Font.Variant = preferredFontStyle + p.Y.Label.TextStyle.Font.Weight = 1 // Medium + p.Y.Tick.Label.Font.Variant = preferredFontStyle + + p.Title.TextStyle.Font.Size = 11.5 + p.Title.TextStyle.Font.Variant = "Sans" + p.Title.TextStyle.Font.Weight = 2 // SemiBold + p.Title.Padding = 5 * vg.Millimeter + + // get mean vals. + meanVals := stats.GetMeanVals(vals, fes) + + // mark the end of the X axis with len(meanVals). + p.X.Max = float64(len(meanVals)) + p.Y.Min = floats.Min(meanVals) + p.Y.Max = floats.Max(meanVals) + + pts := make(plotter.XYs, len(meanVals)) + + // fill the plotter with datapoints. + for k, res := range meanVals { + pts[k].X = float64(k) + pts[k].Y = res + } + + lines := make([]interface{}, 0) + lines = append(lines, pts) + + err := plotutil.AddLines( + p, + lines..., + ) + if err != nil { + log.Panic(err) + } + + return p +} + +// violating gocognit 30, TODO(me): still split this up. +// nolint: gocognit func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.PicList) { start := time.Now() @@ -117,12 +170,21 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P fmt.Sprint(s.Dimens) + "D-" + fmt.Sprint(s.Generations) + "G-" + fmt.Sprint(len(dim.Solution)) + "I" + filenameMean := filename + util.SanitiseFName(" Mean") + + // NEVER EVER ATTEMPT TO INITIALISE THIS WITH `pic`! + picMean := report.NewPic() + picMean.Caption = "D:~" + fmt.Sprint(s.Dimens) + ", G:~" + + fmt.Sprint(s.Generations) + ", I:~" + fmt.Sprint(s.Iterations) // set pic file path (later used in tmpl generation) pic.FilePath = filename + picMean.FilePath = filenameMean + + pMean := plotMeanVals(dim.Solution, s.Generations) elapsed := time.Since(start) - info := "saving img to file: " + filename + fExt + + info := "saving img to file: " + filename + "(-Mean)" + fExt + " [generated in " + fmt.Sprint(elapsed) + "]" if s.Algo == "Random Search" { @@ -142,6 +204,15 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P // save pic. pics = append(pics, *pic) + + // save plot of pMean. + if err := pMean.Save( + pWidth, + pHeight, + filenameMean+fExt, + ); err != nil { + panic(err) + } } } diff --git a/stats/stats.go b/stats/stats.go index ce6d6cb..a641376 100644 --- a/stats/stats.go +++ b/stats/stats.go @@ -9,6 +9,7 @@ "log" "git.dotya.ml/wanderer/math-optim/util" + "gonum.org/v1/gonum/stat" ) // BenchRound holds the iteration couter value and Results of size 'maxFES'. @@ -70,3 +71,19 @@ func SaveStats(stats []Stats, fName string) { } } } + +func GetMeanVals(values []BenchRound, fes int) []float64 { + res := make([]float64, fes) + + for i := 0; i < fes; i++ { + iterVals := make([]float64, len(values)) + + for j, v := range values { + iterVals[j] = v.Results[i] + } + + res[i] = stat.Mean(iterVals, nil) + } + + return res +}