113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
// 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"
|
|
)
|
|
|
|
// statsRow represents the header in the table.
|
|
type statsHdr struct {
|
|
Algo string
|
|
BenchFuncName string
|
|
Dimens int
|
|
Generations int
|
|
Iterations int
|
|
}
|
|
|
|
// statsRow represents a single row in the table.
|
|
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 {
|
|
fmt.Fprintf(os.Stderr, "%+v\n", statsSingleFunc(singleFunc))
|
|
}
|
|
}
|
|
|
|
// statsSingleFunc computes statistics out of results of a single bench func
|
|
// and returns the statistic table as a []interface{} because it contains
|
|
// multiple table headers and rows. perhaps a table struct could be returned in
|
|
// the future.
|
|
func statsSingleFunc(singleFuncStats []Stats) []interface{} {
|
|
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
|
|
)
|
|
|
|
// out contains the constructed table and is returned at the end of
|
|
// this func.
|
|
out := make([]interface{}, 0)
|
|
|
|
for _, s := range singleFuncStats {
|
|
for _, dim := range s.BenchFuncStats {
|
|
hdr = makeTableHdr(
|
|
s.Algo,
|
|
s.BenchFuncStats[0].BenchName,
|
|
s.Dimens,
|
|
s.Generations,
|
|
s.Iterations,
|
|
)
|
|
out = append(out, "\n", hdr, "\n")
|
|
|
|
// 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)
|
|
|
|
out = append(out, row)
|
|
}
|
|
}
|
|
|
|
out = append(out, "\n")
|
|
|
|
return out
|
|
}
|
|
|
|
// makeTableHdr fills the table header with passed information.
|
|
// TODO(me): add checks to assert only valid inputs are passed in.
|
|
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
|
|
}
|
|
|
|
// newStatsHdr returns a pointer to a newly created statsHdr instance.
|
|
func newStatsHdr() *statsHdr {
|
|
return &statsHdr{}
|
|
}
|