go(algo): add PrepComparisonOfMeans
All checks were successful
continuous-integration/drone/push Build is passing

...also another one: getComparisonOfMeansPics, that is used in the
former func internally.
This commit is contained in:
surtur 2022-08-03 21:28:43 +02:00
parent b4c9ebcf5a
commit 9618f958a8
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D

@ -4,6 +4,8 @@
package algo
import (
"fmt"
"log"
"sort"
"sync"
@ -22,6 +24,17 @@ var meanStats = &stats.MeanStats{}
var comparisonOfMeansPicList = &report.PicList{Algo: "Comparison of Means"}
// getComparisonOfMeansPics returns a sorted slice of pics field from the
// package global 'algoMeanPics'.
func getComparisonOfMeansPics() []report.Pic {
// note: sorting by filename (dimens value being 0-padded at generation
// time), relying on this as a hack so that we didn't have to implement our
// own natural-order sorter.
sort.Sort(comparisonOfMeansPicList.Pics)
return comparisonOfMeansPicList.Pics
}
// GetMeanStats returns a pointer of type stats.MeanStats to a sorted package
// global 'meanStats'.
func GetMeanStats() *stats.MeanStats {
@ -30,6 +43,93 @@ func GetMeanStats() *stats.MeanStats {
return meanStats
}
func PrepComparisonOfMeans(wg *sync.WaitGroup) (*report.PicList, int) {
pL := report.NewPicList()
meanStats := GetMeanStats()
algos := make([]string, 0)
// learn how many algos were processed based on the data.
for _, v := range meanStats.AlgoMeans {
// if algos is empty just add the value directly, else determine if
// it's already been added or not.
if len(algos) > 0 {
alreadyadded := false
for _, algoName := range algos {
if algoName == v.Algo {
// early bail if already added.
alreadyadded = true
break
}
}
if !alreadyadded {
algos = append(algos, v.Algo)
}
} else {
algos = append(algos, v.Algo)
}
}
// construct title consisting of names of all involved algorithms.
for _, v := range algos {
switch pL.Algo {
case "":
pL.Algo = v
default:
pL.Algo += " vs " + v
}
}
log.Println(`generating "Comparison of Means" plots`)
algoCount := len(algos)
dimLen := len(bench.Dimensions)
benchCount := len(bench.Functions)
// note: this is a wee bit ugly.
for d := 0; d < dimLen; d++ {
for i := 0; i < benchCount; i++ {
dimXAlgoMeanVals := make([]stats.AlgoMeanVals, 0, algoCount)
for j := 0; j < algoCount*benchCount; j += benchCount {
neighbInfo := ""
// only add info about neighbours if it was changed (from
// the default of -1).
if n := meanStats.AlgoMeans[d+j].BenchMeans[i].Neighbours; n != -1 {
neighbInfo = fmt.Sprintf(" (N: %d)", n)
}
ms := &stats.AlgoMeanVals{
Title: meanStats.AlgoMeans[d+j].Algo + neighbInfo,
MeanVals: meanStats.AlgoMeans[d+j].BenchMeans[i].MeanVals,
}
dimXAlgoMeanVals = append(dimXAlgoMeanVals, *ms)
}
dimens := meanStats.AlgoMeans[d].BenchMeans[i].Dimens
iterations := meanStats.AlgoMeans[d].BenchMeans[i].Iterations
bench := meanStats.AlgoMeans[d].BenchMeans[i].Bench
wg.Add(1)
// construct plots concurrently.
go PlotMeanValsMulti(
wg, dimens, iterations, bench, "plot-", ".svg",
dimXAlgoMeanVals...,
)
}
}
// wait for all the plotting to conclude.
wg.Wait()
pL.Pics = getComparisonOfMeansPics()
return pL, benchCount
}
// DoRandomSearch executes a search using the 'Random search' method.
func DoRandomSearch(wg *sync.WaitGroup, m *sync.Mutex) {
defer wg.Done()