go: add a way to print statistic table
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
surtur 2022-06-24 00:45:43 +02:00
parent 7ada3dac80
commit 63da28a8f0
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D
2 changed files with 113 additions and 7 deletions

@ -5,6 +5,9 @@ package algo
import ( import (
"sync" "sync"
"git.dotya.ml/wanderer/math-optim/bench"
"git.dotya.ml/wanderer/math-optim/stats"
) )
// Values type is just a fancy named []float64 that will allow us to define // Values type is just a fancy named []float64 that will allow us to define
@ -19,14 +22,21 @@ func DoRandomSearch(wg *sync.WaitGroup) {
printRandomSearch("starting...") printRandomSearch("starting...")
// ng y'all. // funcCount is the number of bench functions available.
schw := RandomSearchNG(10000, 30, []int{5, 10, 20}, "Schwefel") funcCount := len(bench.Functions)
djg1 := RandomSearchNG(10000, 30, []int{5, 10, 20}, "De Jong 1st") // stats for the current algo (RandomSearch).
djg2 := RandomSearchNG(10000, 30, []int{5, 10, 20}, "De Jong 2nd") algoStats := make([][]stats.Stats, funcCount)
plotAllDims(schw, "plot", ".svg") // ng y'all.
plotAllDims(djg1, "plot", ".svg") algoStats[0] = RandomSearchNG(10000, 30, []int{5, 10, 20}, "Schwefel")
plotAllDims(djg2, "plot", ".svg") algoStats[1] = RandomSearchNG(10000, 30, []int{5, 10, 20}, "De Jong 1st")
algoStats[2] = RandomSearchNG(10000, 30, []int{5, 10, 20}, "De Jong 2nd")
for i := range algoStats {
plotAllDims(algoStats[i], "plot", ".svg")
}
stats.PrintStatisticTable(algoStats)
} }
// DoStochasticHillClimbing performs a search using the 'Stochastic Hill // DoStochasticHillClimbing performs a search using the 'Stochastic Hill

96
stats/table.go Normal file

@ -0,0 +1,96 @@
// Copyright 2022 wanderer <a_mirre at utb dot cz>
// SPDX-License-Identifier: GPL-3.0-or-later
package stats
import (
"fmt"
"os"
"gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/stat"
)
type statsHdr struct {
Algo string
BenchFuncName string
Dimens int
Generations int
Iterations int
}
type statsRow struct {
Min float64
Max float64
Mean float64
Median float64
StdDev float64
}
// PrintStatisticTable prints to console computed statistics for current algo.
func PrintStatisticTable(algoStats [][]Stats) {
fmt.Fprintln(os.Stderr, "printing statistic table data (min, max, mean, median, stddev)")
for _, singleFunc := range algoStats {
statsSingleFunc(singleFunc)
}
}
// statsSingleFunc computes statistics out of results of a single bench func.
func statsSingleFunc(singleFuncStats []Stats) {
var (
// hdr is the table header as determined based on the data being dealt with.
hdr statsHdr
// row contains the data of the statistic properties being tracked.
row statsRow
)
for _, s := range singleFuncStats {
for _, dim := range s.BenchFuncStats {
hdr = makeTableHdr(
s.Algo,
s.BenchFuncStats[0].BenchName,
s.Dimens,
s.Generations,
s.Iterations,
)
fmt.Fprintln(os.Stderr, hdr)
// collect the best.
var best []float64
for _, iter := range dim.Solution {
last := s.Generations - 1
best = append(best, iter.Results[last])
}
row.Min = floats.Min(best)
row.Max = floats.Max(best)
row.Mean = stat.Mean(best, nil)
row.Median = stat.Mean(best, nil)
row.StdDev = stat.StdDev(best, nil)
fmt.Fprintln(os.Stderr, row)
}
}
}
func makeTableHdr(
algo, benchFuncName string,
dimens, generations, iterations int,
) statsHdr {
hdr := newStatsHdr()
hdr.Algo = algo
hdr.BenchFuncName = benchFuncName
hdr.Dimens = dimens
hdr.Generations = generations
hdr.Iterations = iterations
return *hdr
}
func newStatsHdr() *statsHdr {
return &statsHdr{}
}