Skip to content
Snippets Groups Projects
Commit f00519d5 authored by Andrew E. Torda's avatar Andrew E. Torda
Browse files

If we expand the range, as we do, we have to fix up the range

structure in GetTicks().
parent 5f72baab
Branches
No related tags found
No related merge requests found
...@@ -118,13 +118,14 @@ func TestCsv(t *testing.T) { ...@@ -118,13 +118,14 @@ func TestCsv(t *testing.T) {
} }
var s1dplot = ` var s1dplot = `
ini_temp 1 ini_temp 0.095
final_temp 0.05 final_temp 0.06
x_ini 15 x_ini 15,10,11,12,14,18,-12,-8,-9
n_step 10000 n_step 100000
n_output 5000 n_output 5000
fOutName testanneal1d fOutName test9d
fPltName testplot.svg` fPltName testplot.svg
xPltName testrajplt`
var plotTest = []string{ var plotTest = []string{
s1dplot, s1dplot,
......
...@@ -43,7 +43,7 @@ type cprm struct { // parameters calculated from input ...@@ -43,7 +43,7 @@ type cprm struct { // parameters calculated from input
plotx []float64 // Why float 64 ? Because the plotting libraries plotx []float64 // Why float 64 ? Because the plotting libraries
plotf []float64 // Function values for plotting plotf []float64 // Function values for plotting
plotTmprtr []float64 // Temperature values for plotting plotTmprtr []float64 // Temperature values for plotting
plotXtrj [][]float64 // for plotting trajectories plotXtrj []float32 // for plotting trajectories
} }
// setupRun does things like get the cooling rate, seed the random numbers. // setupRun does things like get the cooling rate, seed the random numbers.
...@@ -95,6 +95,20 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error { ...@@ -95,6 +95,20 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
cprm.plotTmprtr = make([]float64, 0, n_alloc) cprm.plotTmprtr = make([]float64, 0, n_alloc)
} }
} }
if mcPrm.xPltName != "" {
var err error
if mcPrm.xPltName, err = setSuffix(mcPrm.xPltName, ".png"); err != nil {
return fmt.Errorf("plot filename: %w", err)
}
if cprm.xPlt, err = os.Create(mcPrm.xPltName); err != nil {
return err
}
cprm.xplotme = true
n_alloc := mcPrm.nStep / 5
n_dim := len(mcPrm.xIni)
cprm.plotXtrj = make([]float32, 0, int(n_alloc) * n_dim)
// Should check that cprm.plotx is allocated for the step number
}
return nil return nil
} }
...@@ -107,7 +121,6 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) { ...@@ -107,7 +121,6 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) {
xT[i] = x + t xT[i] = x + t
} }
} }
func breaker() {}
// plotFval adds a point to the data to be plotted. At the start, we check // plotFval adds a point to the data to be plotted. At the start, we check
// if we have to plot at all. This is done here, to make the main loop // if we have to plot at all. This is done here, to make the main loop
...@@ -150,6 +163,13 @@ func printfVal (fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld floa ...@@ -150,6 +163,13 @@ func printfVal (fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld floa
fmt.Fprintln(fOut) fmt.Fprintln(fOut)
} }
// plotXtrj adds the next x coordinates to the pltXtrj for plotting at
// the end
func plotXtrj(n uint32, x []float32, pltXtrj *[]float32, xplotme bool) {
if ! xplotme { return }
*pltXtrj = append(*pltXtrj, x...)
}
// doRun does a Monte Carlo run. Although single precision is fine for the // doRun does a Monte Carlo run. Although single precision is fine for the
// coordinates and function, we use double precision for the temperature. // coordinates and function, we use double precision for the temperature.
func doRun(mcPrm *mcPrm) error { func doRun(mcPrm *mcPrm) error {
...@@ -177,7 +197,9 @@ func doRun(mcPrm *mcPrm) error { ...@@ -177,7 +197,9 @@ func doRun(mcPrm *mcPrm) error {
nRunAcc := nRunAccAdj // Every nRunAccAdj, try adjusting the step size. nRunAcc := nRunAccAdj // Every nRunAccAdj, try adjusting the step size.
const runMult = 0.99 const runMult = 0.99
xDlta := mcPrm.xDlta // Adaptable step size xDlta := mcPrm.xDlta // Adaptable step size
// if either plot is running, save the step.
plotFval(0, fOld, tmprtr, &cprm.plotx, &cprm.plotf, &cprm.plotTmprtr, cprm.fplotme) plotFval(0, fOld, tmprtr, &cprm.plotx, &cprm.plotf, &cprm.plotTmprtr, cprm.fplotme)
plotXtrj(0, x, &cprm.plotXtrj, cprm.xplotme)
for n := uint32(0); n < mcPrm.nStep; n++ { for n := uint32(0); n < mcPrm.nStep; n++ {
var acc bool var acc bool
nout-- nout--
...@@ -209,6 +231,7 @@ func doRun(mcPrm *mcPrm) error { ...@@ -209,6 +231,7 @@ func doRun(mcPrm *mcPrm) error {
copy(x, xT) copy(x, xT)
fOld = fTrial fOld = fTrial
plotFval(n+1, fTrial, tmprtr, &cprm.plotx, &cprm.plotf, &cprm.plotTmprtr, cprm.fplotme) plotFval(n+1, fTrial, tmprtr, &cprm.plotx, &cprm.plotf, &cprm.plotTmprtr, cprm.fplotme)
plotXtrj(n+1, x, &cprm.plotXtrj, cprm.xplotme)
} else { // update the running estimate of acceptance } else { // update the running estimate of acceptance
runAcc = runMult * runAcc runAcc = runMult * runAcc
} }
...@@ -217,6 +240,10 @@ func doRun(mcPrm *mcPrm) error { ...@@ -217,6 +240,10 @@ func doRun(mcPrm *mcPrm) error {
} }
} }
err := plotfWrt(cprm.plotx, cprm.plotf, cprm.plotTmprtr, cprm.fPlt, cprm.fplotme) err := plotfWrt(cprm.plotx, cprm.plotf, cprm.plotTmprtr, cprm.fPlt, cprm.fplotme)
if err != nil {
return err }
err = plotxWrt (&cprm, len(mcPrm.xIni))
fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1) fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1)
return err return err
} }
...@@ -13,48 +13,16 @@ ...@@ -13,48 +13,16 @@
package ackwork package ackwork
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"math" "math"
"os" "os"
"path/filepath"
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
"github.com/wcharczuk/go-chart/v2/drawing" "github.com/wcharczuk/go-chart/v2/drawing"
"gitlab.rrz.uni-hamburg.de/Bae5157/axticks" "gitlab.rrz.uni-hamburg.de/Bae5157/axticks"
) )
// setSuffix takes a name and makes sure the desired suffix is at the end
// of the filename.
func setSuffix(fname, suffix string) (string, error) {
if len(fname) == 0 {
return "", errors.New("setSuffix given empty fname")
}
if suffix == "" { // no suffix might not be an error. Just
if fname[len(fname)-1] == '.' { // remove any trailing dot
fname = fname[0 : len(fname)-1]
}
if len(fname) > 0 {
return fname, nil
}
return "", errors.New("setSuffix got empty filename")
}
if suffix[0] != '.' {
suffix = "." + suffix
}
oldExt := filepath.Ext(fname)
switch oldExt {
case suffix:
return fname, nil
case "":
return fname + suffix, nil
default:
return fname[0:len(fname)-len(oldExt)] + suffix, nil
}
}
// maketicks gives reasonable default tick locations // maketicks gives reasonable default tick locations
func maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick { func maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick {
xmin, delta, prcsn := axisDscrpt.Xmin, axisDscrpt.Delta, axisDscrpt.Prcsn xmin, delta, prcsn := axisDscrpt.Xmin, axisDscrpt.Delta, axisDscrpt.Prcsn
...@@ -85,6 +53,8 @@ func (rng *range2) GetTicks(r chart.Renderer, cs chart.Style, vf chart.ValueForm ...@@ -85,6 +53,8 @@ func (rng *range2) GetTicks(r chart.Renderer, cs chart.Style, vf chart.ValueForm
fmt.Fprintln(os.Stderr, "GetTicks error:", err) fmt.Fprintln(os.Stderr, "GetTicks error:", err)
return nil return nil
} else { } else {
rng.Min = a.Xmin
rng.Max = a.Xmax
return maketicks(a, a.Prcsn) return maketicks(a, a.Prcsn)
} }
} }
...@@ -112,7 +82,7 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64, ...@@ -112,7 +82,7 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64,
tmprtrAxis := chart.YAxis{ tmprtrAxis := chart.YAxis{
Name: "temperature", Name: "temperature",
NameStyle: chart.Style{TextRotationDegrees: math.SmallestNonzeroFloat64}, NameStyle: chart.Style{TextRotationDegrees: 360},
Range: &range2{}, Range: &range2{},
} }
...@@ -141,8 +111,8 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64, ...@@ -141,8 +111,8 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64,
Background: chart.Style{ Background: chart.Style{
Padding: chart.Box{ Padding: chart.Box{
Left: 75, Left: 50,
Right: 25, Right: 75,
}, },
FillColor: drawing.ColorTransparent, FillColor: drawing.ColorTransparent,
}, },
...@@ -153,3 +123,58 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64, ...@@ -153,3 +123,58 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64,
return nil return nil
} }
func breaker() {}
// plotxWrt
// For each dimension, allocate space. Copy elements over from the long array.
// Then call the plotter on each series in turn. I think I have to make a
// slice of continuous series and then add them into the chart structure.
func plotxWrt(cprm *cprm, ndim int) error {
if !cprm.xplotme {
return nil
}
type f64 []float64
len_used := len(cprm.plotx)
xdata := make([]f64, ndim)
fmt.Println("plotxWrt has", ndim, "dimensions and len_used is", len_used)
for i := 0; i < ndim; i++ {
xdata[i] = make([]float64, len_used)
}
breaker()
var n int
for i := 0; i < len_used; i++ {
for j := 0; j < ndim; j++ {
xdata[j][i] = float64(cprm.plotXtrj[n])
n++
}
}
series := make([]chart.Series, ndim)
for i := 0; i < ndim; i++ {
series[i] = chart.ContinuousSeries{
Name: fmt.Sprintf("dimension %d", i),
XValues: cprm.plotx,
YValues: xdata[i],
}
}
graph := chart.Chart{
Title: fmt.Sprintf("X trajectories %d dimension", ndim),
XAxis: chart.XAxis{Name: "step", Range: &range2{}},
YAxis: chart.YAxis{
Name: "x coord",
Range: &range2{},
AxisType: chart.YAxisSecondary,
NameStyle: chart.Style{TextRotationDegrees: 360},
},
Series: series,
Background: chart.Style{
Padding: chart.Box{
Left: 75,
},
},
}
if err := graph.Render(chart.PNG, cprm.xPlt); err != nil {
return fmt.Errorf("plotting X trajectories: %w", err)
}
return nil
}
// a utility
package ackwork
import (
"errors"
"path/filepath"
)
// setSuffix takes a name and makes sure the desired suffix is at the end
// of the filename.
func setSuffix(fname, suffix string) (string, error) {
if len(fname) == 0 {
return "", errors.New("setSuffix given empty fname")
}
if suffix == "" { // no suffix might not be an error. Just
if fname[len(fname)-1] == '.' { // remove any trailing dot
fname = fname[0 : len(fname)-1]
}
if len(fname) > 0 {
return fname, nil
}
return "", errors.New("setSuffix got empty filename")
}
if suffix[0] != '.' {
suffix = "." + suffix
}
oldExt := filepath.Ext(fname)
switch oldExt {
case suffix:
return fname, nil
case "":
return fname + suffix, nil
default:
return fname[0:len(fname)-len(oldExt)] + suffix, nil
}
}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// Ackley input_file // Ackley input_file
// where input_file is a set of name-value pairs. These are defined with defaults // where input_file is a set of name-value pairs. These are defined with defaults
// in rdprm.go. At the moment, we have // in rdprm.go. At the moment, we have
package main
/* /*
{"ini_temp", "20"}, {"ini_temp", "20"},
{"final_temp", "1"}, {"final_temp", "1"},
......
...@@ -6,3 +6,5 @@ require ( ...@@ -6,3 +6,5 @@ require (
github.com/wcharczuk/go-chart/v2 v2.1.0 github.com/wcharczuk/go-chart/v2 v2.1.0
gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20211227145643-dc5ef95d7dad gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20211227145643-dc5ef95d7dad
) )
replace gitlab.rrz.uni-hamburg.de/Bae5157/axticks => ../axticks
...@@ -2,8 +2,6 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0 ...@@ -2,8 +2,6 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I= github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA= github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20211227145643-dc5ef95d7dad h1:IBCLghidSwZff0/3RuvTLDnHgK9SaZHZ/cXWSjimEt0=
gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20211227145643-dc5ef95d7dad/go.mod h1:5CNHyqeidRypmIVTnQksGqnmP56Oshw1Zv1nlUezrpQ=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
...@@ -21,7 +21,7 @@ const ( ...@@ -21,7 +21,7 @@ const (
func main() { func main() {
if err := ackwork.MyMain (); err != nil { if err := ackwork.MyMain (); err != nil {
fmt.Println (os.Stderr, err) fmt.Fprintln (os.Stderr, err)
os.Exit (exitFailure) os.Exit (exitFailure)
} }
os.Exit (exitSuccess) os.Exit (exitSuccess)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment