diff --git a/ackwork/ackwork.go b/ackwork/ackwork.go
index 07ef3a52758695ee878a9ce1c96f6e06772ac99e..135bfd6ad5dca4b69d0d0e19bead09dfc145416d 100644
--- a/ackwork/ackwork.go
+++ b/ackwork/ackwork.go
@@ -20,7 +20,8 @@ type mcPrm struct {
nRun uint32 // number of separate runs
nOutput uint32 // write at least this many lines of output
fOutName string // where we write output to
- pOutName string // where we plot to
+ fPltName string // where we plot to (function values)
+ xPltName string // where we plot x trajectories to
verbose bool
dummy bool // for testing. If set, do not do a run
}
@@ -41,7 +42,7 @@ func realmain(fp io.Reader) error {
if err := rdPrm(fp, &mcPrm); err != nil {
return err
}
- if err := doRun(&mcPrm); err != nil {
+ if err := doRun(&mcPrm); err != nil {
return err
}
var x [1]float32
diff --git a/ackwork/ackwork_test.go b/ackwork/ackwork_test.go
index 55bd69d26d2e33e05e8ef85029df46336a60407b..b62c49474acd305c0d897232cf1273d35d557392 100644
--- a/ackwork/ackwork_test.go
+++ b/ackwork/ackwork_test.go
@@ -20,7 +20,7 @@ final_temp 0
x_ini 0.8,0.8,0.8
n_step = 100000
n_output = 5000
-f_outName testReal`
+fOutNamen testReal`
func TestTypo(t *testing.T) { // Make sure a typo in input does provoke an error
if err := realmain(strings.NewReader(sTypo)); err == nil {
@@ -34,7 +34,7 @@ final_temp 0.05
x_ini 15
n_step 10000
n_output 5000
-f_outName testanneal1d`
+fOutName testanneal1d`
var s3d = `
ini_temp 1
@@ -42,7 +42,7 @@ final_temp 0.05
x_ini 15,15,15
n_step 10000
n_output 500
-f_outName testanneal3d`
+fOutName testanneal3d`
// Five dimensions works easily. 10 is too hard.
var s5d = `
@@ -51,7 +51,7 @@ final_temp 0.02
x_ini 7,7,7,7,7
n_step 100000
n_output 10000
-f_outName testanneal5d`
+fOutName testanneal5d`
var s10d = `
ini_temp 0.1
@@ -60,7 +60,7 @@ x_ini 7,7,7,7,7,7,7,7,7,7
n_step 10000000
n_step 10
n_output 10000
-f_outName testanneal10d`
+fOutName testanneal10d`
var sCold = `
ini_temp 1e-10
@@ -68,7 +68,7 @@ final_temp 1e-12
x_ini 1,1,1
n_step 10000
n_output 500
-f_outName testcold`
+fOutName testcold`
var sHot = `
ini_temp 1
@@ -76,7 +76,7 @@ final_temp 1
x_ini 1,1,1
n_step 10000
n_output 500
-f_outName testhot`
+fOutName testhot`
var sRealAnneal = `
ini_temp 0.5
@@ -84,7 +84,7 @@ final_temp 0.05
x_ini 7,1,7
n_step 100000
n_output 5000
-f_outName testreal`
+fOutName testreal`
// These values seem to work well. There is something of a phase
// transition near temperature 0.09. Good values for an optimisation
@@ -104,7 +104,7 @@ final_temp 0.01
x_ini 7,1,7
n_step 100000
n_output 50000
-f_outName testphase`
+fOutName testphase`
var csv_test = []string{
s1d, s3d, sHot, sCold, sRealAnneal, sPhaseTrans, s5d, s10d}
@@ -123,8 +123,8 @@ final_temp 0.05
x_ini 15
n_step 10000
n_output 5000
-f_outName testanneal1d
-plot_outName testplot.svg`
+fOutName testanneal1d
+fPltName testplot.svg`
var plotTest = []string{
s1dplot,
diff --git a/ackwork/dorun.go b/ackwork/dorun.go
index ad2376724534af3066d86ef67fbdfb42d4103b77..260746514802ad742bc16cb20d819e1c0c7aaff4 100644
--- a/ackwork/dorun.go
+++ b/ackwork/dorun.go
@@ -26,18 +26,22 @@ func getSeed() int64 {
type cprm struct { // parameters calculated from input
rand *rand.Rand
- coolMult float64 // multiplier for temperature
- coolme bool // Are we cooling or just doing constant temperature ?
- plotme bool // Are we making output for plotting
- nEvery uint32 // Output every nEvery steps
- fOut io.WriteCloser
- plotOut io.WriteCloser
- plotx []float64 // Why float 64 ? Because the plotting libraries
- ploty []float64 // generally want this
+ coolMult float64 // multiplier for temperature
+ coolme bool // Are we cooling or just doing constant temperature ?
+ fplotme bool // Are we making output for plotting func values
+ xplotme bool // Are we plotting X trajectories
+ nEvery uint32 // Output every nEvery steps
+ fOut io.WriteCloser // csv file for plotting
+ fPlt io.WriteCloser // for function values
+ xPlt io.WriteCloser // for x trajectories
+ plotx []float64 // Why float 64 ? Because the plotting libraries
+ ploty []float64 // generally want this
+
}
// setupRun does things like get the cooling rate, seed the random numbers.
func setupRun(mcPrm *mcPrm, cprm *cprm) error {
+ const finalTempErr = "Final temp %g higher than initial temp %g"
var err error
if mcPrm.dummy == true {
return nil
@@ -48,7 +52,7 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
var coolrate float64
cprm.coolme = true
if mcPrm.fnlTmp > mcPrm.iniTmp {
- return fmt.Errorf("Final temp %g higher than initial temp %g", mcPrm.fnlTmp, mcPrm.iniTmp)
+ return fmt.Errorf(finalTempErr, mcPrm.fnlTmp, mcPrm.iniTmp)
}
nStep := float64(mcPrm.nStep)
fnlTmp, iniTmp := float64(mcPrm.fnlTmp), float64(mcPrm.iniTmp)
@@ -66,12 +70,12 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
if cprm.fOut, err = os.Create(ntmp); err != nil {
return err
}
- if mcPrm.pOutName != "" {
- mcPrm.pOutName = makepngName(mcPrm.pOutName)
- if cprm.plotOut, err = os.Create(mcPrm.pOutName); err != nil {
+ if mcPrm.fPltName != "" {
+ mcPrm.fPltName = makepngName(mcPrm.fPltName)
+ if cprm.fPlt, err = os.Create(mcPrm.fPltName); err != nil {
return err
}
- cprm.plotme = true
+ cprm.fplotme = true
n_alloc := mcPrm.nStep / 5 // About a fifth of the number of steps
cprm.plotx = make([]float64, 0, n_alloc)
cprm.ploty = make([]float64, 0, n_alloc)
@@ -111,8 +115,11 @@ func doRun(mcPrm *mcPrm) error {
if cprm.fOut != nil {
defer cprm.fOut.Close()
}
- if cprm.plotOut != nil {
- defer cprm.plotOut.Close()
+ if cprm.fPlt != nil {
+ defer cprm.fPlt.Close()
+ }
+ if cprm.xPlt != nil {
+ defer cprm.xPlt.Close()
}
const accRateIdeal = 0.05 // Arbitrary target of 5% acceptance
const nRunAccAdj = 200 // every n steps, check acceptance rate
@@ -128,7 +135,7 @@ func doRun(mcPrm *mcPrm) error {
nRunAcc := nRunAccAdj // Every nRunAccAdj, try adjusting the step size.
const runMult = 0.99
xDlta := mcPrm.xDlta // Adaptable step size
- plotPnt(0, fOld, &cprm.plotx, &cprm.ploty, cprm.plotme)
+ plotPnt(0, fOld, &cprm.plotx, &cprm.ploty, cprm.fplotme)
for n := uint32(0); n < mcPrm.nStep; n++ {
var acc bool
nout--
@@ -174,7 +181,7 @@ func doRun(mcPrm *mcPrm) error {
runAcc = runMult*runAcc + (1.0 - runMult)
copy(x, xT)
fOld = fTrial
- plotPnt(n+1, fTrial, &cprm.plotx, &cprm.ploty, cprm.plotme)
+ plotPnt(n+1, fTrial, &cprm.plotx, &cprm.ploty, cprm.fplotme)
} else { // update the running estimate of acceptance
runAcc = runMult * runAcc
}
@@ -182,7 +189,7 @@ func doRun(mcPrm *mcPrm) error {
tmprtr *= cprm.coolMult
}
}
- err := plotWrite(cprm.plotx, cprm.ploty, cprm.plotOut, cprm.plotme)
+ err := plotfWrt(cprm.plotx, cprm.ploty, cprm.fPlt, cprm.fplotme)
fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1)
return err
}
diff --git a/ackwork/plot.go b/ackwork/plot.go
index 369a135fccd8acf9a5c20a2297dbafccce9a2794..7382df5083c6c47feb4ed7d71c6742cbcf439ba1 100644
--- a/ackwork/plot.go
+++ b/ackwork/plot.go
@@ -51,9 +51,10 @@ func maketicks(axisDscrpt axticks.AxisDscrpt, prcsn int) []chart.Tick {
return t
}
-// plotWrt writes out a plot to the given io.writercloser and
-// closes the file when finished.
-func plotWrite(xdata, ydata []float64, plotOut io.WriteCloser, plotme bool) error {
+// plotfWrt writes out a plot of function values to the given
+// io.writer. We do not close the file. The caller opened it,
+// so he should close it.
+func plotfWrt(xdata, ydata []float64, plotOut io.Writer, plotme bool) error {
if !plotme {
return nil
}
@@ -115,6 +116,6 @@ func plotWrite(xdata, ydata []float64, plotOut io.WriteCloser, plotme bool) erro
if err := graph.Render(chart.PNG, plotOut); err != nil {
return fmt.Errorf("While plotting %w", err)
}
-
+
return nil
}
diff --git a/ackwork/rdprm.go b/ackwork/rdprm.go
index 6b951357a40f7f37c98d7092653c6700dd5c80d5..74dafbcd6a818ec624a2aad809fab72674409988 100644
--- a/ackwork/rdprm.go
+++ b/ackwork/rdprm.go
@@ -29,8 +29,9 @@ var cmdDflt = []struct {
{"x_ini", "3,4,5"},
{"x_delta", "0.5"},
{"seed", "1637"},
- {"f_outname", "mcrun"},
- {"plot_outname", ""}, // empty means no plots
+ {"foutname", "mcrun"},
+ {"fpltname", ""}, // empty means no plots of function
+ {"xpltname", ""},
{"verbose", ""},
{"dummy", ""},
}
@@ -81,8 +82,9 @@ func digest(prmMap map[string]string, mcPrm *mcPrm) error {
mcPrm.nRun = getu(prmMap["n_run"])
mcPrm.nOutput = getu(prmMap["n_output"])
mcPrm.xIni = getx(prmMap["x_ini"])
- mcPrm.fOutName = prmMap["f_outname"]
- mcPrm.pOutName = prmMap["plot_outname"]
+ mcPrm.fOutName = prmMap["fOutName"]
+ mcPrm.fPltName = prmMap["fPltName"]
+ mcPrm.xPltName = prmMap["xPltName"]
seed = int64(getu(prmMap["seed"]))
if err != nil { // Only returns the first error encountered
return err
@@ -127,7 +129,7 @@ func rdPrm(fp io.Reader, mcPrm *mcPrm) error {
}
key := ss[0]
if _, ok := prmMap[key]; !ok {
- return fmt.Errorf("unknown keyword %s\n%s", key, spew())
+ return fmt.Errorf("unknown keyword \"%s\"\n%s", key, spew())
} else {
prmMap[key] = ss[1]
}