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
No related branches found
No related tags found
No related merge requests found
......@@ -118,13 +118,14 @@ func TestCsv(t *testing.T) {
}
var s1dplot = `
ini_temp 1
final_temp 0.05
x_ini 15
n_step 10000
ini_temp 0.095
final_temp 0.06
x_ini 15,10,11,12,14,18,-12,-8,-9
n_step 100000
n_output 5000
fOutName testanneal1d
fPltName testplot.svg`
fOutName test9d
fPltName testplot.svg
xPltName testrajplt`
var plotTest = []string{
s1dplot,
......
......@@ -43,7 +43,7 @@ type cprm struct { // parameters calculated from input
plotx []float64 // Why float 64 ? Because the plotting libraries
plotf []float64 // Function 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.
......@@ -95,6 +95,20 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
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
}
......@@ -107,7 +121,6 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) {
xT[i] = x + t
}
}
func breaker() {}
// 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
......@@ -150,6 +163,13 @@ func printfVal (fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld floa
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
// coordinates and function, we use double precision for the temperature.
func doRun(mcPrm *mcPrm) error {
......@@ -177,7 +197,9 @@ func doRun(mcPrm *mcPrm) error {
nRunAcc := nRunAccAdj // Every nRunAccAdj, try adjusting the step size.
const runMult = 0.99
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)
plotXtrj(0, x, &cprm.plotXtrj, cprm.xplotme)
for n := uint32(0); n < mcPrm.nStep; n++ {
var acc bool
nout--
......@@ -209,6 +231,7 @@ func doRun(mcPrm *mcPrm) error {
copy(x, xT)
fOld = fTrial
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
runAcc = runMult * runAcc
}
......@@ -217,6 +240,10 @@ func doRun(mcPrm *mcPrm) error {
}
}
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)
return err
}
......@@ -13,48 +13,16 @@
package ackwork
import (
"errors"
"fmt"
"io"
"math"
"os"
"path/filepath"
"github.com/wcharczuk/go-chart/v2"
"github.com/wcharczuk/go-chart/v2/drawing"
"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
func maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick {
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
fmt.Fprintln(os.Stderr, "GetTicks error:", err)
return nil
} else {
rng.Min = a.Xmin
rng.Max = a.Xmax
return maketicks(a, a.Prcsn)
}
}
......@@ -112,7 +82,7 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64,
tmprtrAxis := chart.YAxis{
Name: "temperature",
NameStyle: chart.Style{TextRotationDegrees: math.SmallestNonzeroFloat64},
NameStyle: chart.Style{TextRotationDegrees: 360},
Range: &range2{},
}
......@@ -141,8 +111,8 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64,
Background: chart.Style{
Padding: chart.Box{
Left: 75,
Right: 25,
Left: 50,
Right: 75,
},
FillColor: drawing.ColorTransparent,
},
......@@ -153,3 +123,58 @@ func plotfWrt(xdata, ydata []float64, tmprtrData []float64,
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 @@
// Ackley input_file
// where input_file is a set of name-value pairs. These are defined with defaults
// in rdprm.go. At the moment, we have
package main
/*
{"ini_temp", "20"},
{"final_temp", "1"},
......
......@@ -6,3 +6,5 @@ require (
github.com/wcharczuk/go-chart/v2 v2.1.0
gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20211227145643-dc5ef95d7dad
)
replace gitlab.rrz.uni-hamburg.de/Bae5157/axticks => ../axticks
......@@ -21,7 +21,7 @@ const (
func main() {
if err := ackwork.MyMain (); err != nil {
fmt.Println (os.Stderr, err)
fmt.Fprintln (os.Stderr, err)
os.Exit (exitFailure)
}
os.Exit (exitSuccess)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment