go,tmpl: plot mean values
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
surtur 2022-07-18 22:36:47 +02:00
parent 16cbf39a79
commit 3c8678a8d3
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D
5 changed files with 65 additions and 33 deletions

@ -41,24 +41,28 @@ func DoRandomSearch(wg *sync.WaitGroup, m *sync.Mutex) {
}
pCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
pMeanCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
for i := range algoStats {
go plotAllDims(algoStats[i], "plot", ".svg", pCh)
go plotAllDims(algoStats[i], "plot", ".svg", pCh, pMeanCh)
}
pLs := []report.PicList{}
pLsMean := []report.PicList{}
for range algoStats {
pL := <-pCh
pLMean := <-pMeanCh
pLs = append(pLs, pL)
pLsMean = append(pLsMean, pLMean)
}
algoName := "Random Search"
// protect access to shared data.
m.Lock()
report.SavePicsToFile(pLs, algoName)
report.SavePicsToFile(pLs, pLsMean, algoName)
stats.SaveTable(algoName, algoStats)
m.Unlock()
@ -90,24 +94,28 @@ func DoStochasticHillClimbing(wg *sync.WaitGroup, m *sync.Mutex) {
}
pCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
pMeanCh := make(chan report.PicList, funcCount*len(bench.Dimensions))
for _, algoStat := range algoStats {
go plotAllDims(algoStat, "plot", ".svg", pCh)
go plotAllDims(algoStat, "plot", ".svg", pCh, pMeanCh)
}
pLs := []report.PicList{}
pLsMean := []report.PicList{}
for range algoStats {
pL := <-pCh
pLMean := <-pMeanCh
pLs = append(pLs, pL)
pLsMean = append(pLsMean, pLMean)
}
algoName := "Stochastic Hill Climbing"
// protect access to shared data.
m.Lock()
report.SavePicsToFile(pLs, algoName)
report.SavePicsToFile(pLs, pLsMean, algoName)
stats.SaveTable(algoName, algoStats)
m.Unlock()

@ -20,13 +20,13 @@ import (
const preferredFontStyle = "Mono"
func plotMeanVals(vals []stats.BenchRound, fes int) *plot.Plot {
func plotMeanVals(vals []stats.BenchRound, title string, fes int) *plot.Plot {
plotter.DefaultFont.Typeface = preferredFontStyle
plotter.DefaultLineStyle.Width = vg.Points(1.5)
plotter.DefaultLineStyle.Width = vg.Points(2.0)
p := plot.New()
p.Title.Text = "Mean"
p.Title.Text = "Mean - " + title
p.X.Label.Text = "Generations"
p.X.Label.TextStyle.Font.Variant = preferredFontStyle
@ -37,10 +37,10 @@ func plotMeanVals(vals []stats.BenchRound, fes int) *plot.Plot {
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.Size = 14.5
p.Title.TextStyle.Font.Variant = "Sans"
p.Title.TextStyle.Font.Weight = 2 // SemiBold
p.Title.Padding = 5 * vg.Millimeter
p.Title.Padding = 3 * vg.Millimeter
// get mean vals.
meanVals := stats.GetMeanVals(vals, fes)
@ -74,7 +74,7 @@ func plotMeanVals(vals []stats.BenchRound, fes int) *plot.Plot {
// violating gocognit 30, TODO(me): still split this up.
// nolint: gocognit
func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.PicList) {
func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.PicList, chMean chan report.PicList) {
start := time.Now()
picsDir := report.GetPicsDir()
@ -87,10 +87,13 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
pL := report.NewPicList()
pics := make([]report.Pic, 0)
pLMean := report.NewPicList()
picsMean := make([]report.Pic, 0)
// since the algoStats only contains results of a single algo, it's safe to
// set the value like this.
pL.Algo = algoStats[0].Algo
pLMean.Algo = algoStats[0].Algo
pWidth := 13 * vg.Centimeter
pHeight := 13 * vg.Centimeter
@ -102,15 +105,16 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
p := plot.New()
pic := report.NewPic()
p.Title.Text = s.Algo + ", D=" + fmt.Sprint(s.Dimens) +
", func=" + s.BenchFuncStats[0].BenchName +
", G=" + fmt.Sprint(s.Generations) +
", I=" + fmt.Sprint(s.Iterations)
p.Title.Text = "D: " + fmt.Sprint(s.Dimens) +
", G: " + fmt.Sprint(s.Generations) +
", I: " + fmt.Sprint(s.Iterations)
// pic.Caption = p.Title.Text
pic.Caption = ""
pic.Caption = p.Title.Text
// since a single stat slice of algoStats only contains results of a
// single bench func, it's safe to set the value like this.
pL.Bench = s.BenchFuncStats[0].BenchName
pLMean.Bench = s.BenchFuncStats[0].BenchName
p.X.Label.Text = "Generations"
p.X.Label.TextStyle.Font.Variant = preferredFontStyle
@ -121,10 +125,10 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
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.Size = 14.5
p.Title.TextStyle.Font.Variant = "Sans"
p.Title.TextStyle.Font.Weight = 2 // SemiBold
p.Title.Padding = 5 * vg.Millimeter
p.Title.Padding = 3 * vg.Millimeter
for _, dim := range s.BenchFuncStats {
// infinite thanks to this SO comment for the interface "hack":
@ -174,14 +178,18 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
// 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)
meanTitle := "D: " + fmt.Sprint(s.Dimens) + ", G: " +
fmt.Sprint(s.Generations) + ", I: " + fmt.Sprint(s.Iterations)
// picMean.Caption = "D:~" + fmt.Sprint(s.Dimens) + ", G:~" +
// fmt.Sprint(s.Generations) + ", I:~" + fmt.Sprint(s.Iterations)
picMean.Caption = ""
// set pic file path (later used in tmpl generation)
pic.FilePath = filename
picMean.FilePath = filenameMean
pMean := plotMeanVals(dim.Solution, s.Generations)
// get the *mean* plot.
pMean := plotMeanVals(dim.Solution, meanTitle, s.Generations)
elapsed := time.Since(start)
info := "saving img to file: " + filename + "(-Mean)" + fExt +
@ -213,10 +221,15 @@ func plotAllDims(algoStats []stats.Stats, fPrefix, fExt string, ch chan report.P
); err != nil {
panic(err)
}
// save mean pic.
picsMean = append(picsMean, *picMean)
}
}
pL.Pics = pics
pLMean.Pics = picsMean
ch <- *pL
chMean <- *pLMean
}

@ -42,12 +42,12 @@ func NewPicList() *PicList {
// SavePicsToFile saves each pic list for all bench funcs of a specified algo
// to a file.
func SavePicsToFile(pls []PicList, algoName string) {
func SavePicsToFile(pls, plsMean []PicList, algoName string) {
var paths []string
ptf := picTexFiles{Algo: algoName}
for _, p := range pls {
for i, p := range pls {
safeName := util.SanitiseFName(p.Algo + "-" + p.Bench)
texPicsFile := GetTexDir() + "pics-" + safeName + ".tex"
tmplPics := template.New("pics")
@ -73,11 +73,13 @@ func SavePicsToFile(pls []PicList, algoName string) {
Algo string
Bench string
Pics []Pic
PicsMean []Pic
Timestamp time.Time
}{
Algo: p.Algo,
Bench: p.Bench,
Pics: p.Pics,
PicsMean: plsMean[i].Pics,
Timestamp: time.Now(),
})

@ -8,16 +8,23 @@
% project homepage: https://git.dotya.ml/wanderer/math-optim/
\subsubsection{ {{- printf "%s - %s" .Algo .Bench -}} }
{{- range $i, $v := .Pics }}
\begin{figure}[!hbt]
\includesvg[width=0.30\textwidth]{ {{- printf "{%s}" $v.FilePath -}} }
\begin{figure}[h!]
\centering
\caption{ {{- $v.Caption -}} }
{{- range $i, $v := .Pics }}
\begin{subfigure}{0.30\textwidth}
% note: this accomodates 3 plots a row comfortably..should the requirements
% change, this would have to be reworked.
{\includesvg[scale=0.45]{ {{- printf "%s" $v.FilePath -}} }}
\end{subfigure}
\hfill
{{- end -}}
{{ range $k, $w := .PicsMean }}
\begin{subfigure}{0.30\textwidth}
\vspace{2em}
{\includesvg[scale=0.45]{ {{- printf "%s" $w.FilePath -}} }}
\end{subfigure}
\hfill
{{- end }}
\end{figure}
{{- end }}
% vim: ft=gotexttmpl.tex ts=2 sts=2 sw=2 bs=2 expandtab

@ -16,9 +16,11 @@
\usepackage{graphicx}
\usepackage{textcomp}
\usepackage{hyperref}
\usepackage{etoolbox}
\usepackage{longtable}
\usepackage{subcaption} % for subcaption
\usepackage{sansmath}
\sansmath
\usepackage{svg}
\svgsetup{inkscapelatex=false} % this is important to not have jumbled plot labels
\usepackage{meta}
\usepackage[affil-it]{authblk}