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

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

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

@ -8,16 +8,23 @@
% project homepage: https://git.dotya.ml/wanderer/math-optim/ % project homepage: https://git.dotya.ml/wanderer/math-optim/
\subsubsection{ {{- printf "%s - %s" .Algo .Bench -}} } \subsubsection{ {{- printf "%s - %s" .Algo .Bench -}} }
\begin{figure}[h!]
{{- range $i, $v := .Pics }}
\begin{figure}[!hbt]
\includesvg[width=0.30\textwidth]{ {{- printf "{%s}" $v.FilePath -}} }
\centering \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{figure}
{{- end }}
% vim: ft=gotexttmpl.tex ts=2 sts=2 sw=2 bs=2 expandtab % vim: ft=gotexttmpl.tex ts=2 sts=2 sw=2 bs=2 expandtab

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