go,tmpl: plot mean values
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
16cbf39a79
commit
3c8678a8d3
16
algo/algo.go
16
algo/algo.go
@ -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()
|
||||
|
45
algo/plot.go
45
algo/plot.go
@ -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}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user