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

Cleaned up writing of values for plotting and printing. It is now all

in one function which is only called after a move is accepted.
parent f00519d5
No related branches found
No related tags found
No related merge requests found
In dorun.go
* remove the writeclosers from the cprm structure. Just open and close the file when we have to plot or write.
* make the csv files optional
* If the last step was not accepted, we do not write a value out.
* is there some way to clean up, using the go build tools ?
...@@ -18,6 +18,7 @@ var sTypo = ` ...@@ -18,6 +18,7 @@ var sTypo = `
ini_temp = 1 ini_temp = 1
final_temp 0 final_temp 0
x_ini 0.8,0.8,0.8 x_ini 0.8,0.8,0.8
x_delta, "0.4"
n_step = 100000 n_step = 100000
n_output = 5000 n_output = 5000
fOutNamen testReal` fOutNamen testReal`
...@@ -118,8 +119,8 @@ func TestCsv(t *testing.T) { ...@@ -118,8 +119,8 @@ func TestCsv(t *testing.T) {
} }
var s1dplot = ` var s1dplot = `
ini_temp 0.095 ini_temp 0.0925
final_temp 0.06 final_temp 0.09
x_ini 15,10,11,12,14,18,-12,-8,-9 x_ini 15,10,11,12,14,18,-12,-8,-9
n_step 100000 n_step 100000
n_output 5000 n_output 5000
......
...@@ -36,11 +36,10 @@ type cprm struct { // parameters calculated from input ...@@ -36,11 +36,10 @@ type cprm struct { // parameters calculated from input
coolme bool // Are we cooling or just doing constant temperature ? coolme bool // Are we cooling or just doing constant temperature ?
fplotme bool // Are we making output for plotting func values fplotme bool // Are we making output for plotting func values
xplotme bool // Are we plotting X trajectories xplotme bool // Are we plotting X trajectories
nEvery uint32 // Output every nEvery steps
fOut io.WriteCloser // csv file for plotting fOut io.WriteCloser // csv file for plotting
fPlt io.WriteCloser // for function values fPlt io.WriteCloser // for function values
xPlt io.WriteCloser // for x trajectories xPlt io.WriteCloser // for x trajectories
plotx []float64 // Why float 64 ? Because the plotting libraries plotnstp []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 []float32 // for plotting trajectories plotXtrj []float32 // for plotting trajectories
...@@ -71,8 +70,6 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error { ...@@ -71,8 +70,6 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
cprm.coolMult = math.Exp(-coolrate) cprm.coolMult = math.Exp(-coolrate)
} }
cprm.nEvery = uint32(math.Ceil(float64(mcPrm.nStep) / float64(mcPrm.nOutput)))
if mcPrm.fOutName, err = setSuffix(mcPrm.fOutName, ".csv"); err != nil { if mcPrm.fOutName, err = setSuffix(mcPrm.fOutName, ".csv"); err != nil {
return err return err
} }
...@@ -89,7 +86,7 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error { ...@@ -89,7 +86,7 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error {
} }
cprm.fplotme = true cprm.fplotme = true
n_alloc := mcPrm.nStep / 5 // About a fifth of the number of steps n_alloc := mcPrm.nStep / 5 // About a fifth of the number of steps
cprm.plotx = make([]float64, 0, n_alloc) cprm.plotnstp = make([]float64, 0, n_alloc)
cprm.plotf = make([]float64, 0, n_alloc) cprm.plotf = make([]float64, 0, n_alloc)
if cprm.coolme { if cprm.coolme {
cprm.plotTmprtr = make([]float64, 0, n_alloc) cprm.plotTmprtr = make([]float64, 0, n_alloc)
...@@ -122,17 +119,30 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) { ...@@ -122,17 +119,30 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) {
} }
} }
// plotFval adds a point to the data to be plotted. At the start, we check // printfVal is just the loop to print out the function value and coordinates
// if we have to plot at all. This is done here, to make the main loop // probably for later plotting.
// below a bit shorter. func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float64) {
func plotFval(n uint32, fTrial, tmprtr float64, fmt.Fprintf(fOut, "%d,%.4g,%.5g", n, tmprtr, fOld)
plotx, plotf, plotTmprtr *[]float64, plotme bool) { for _, xx := range x {
if !plotme { fmt.Fprintf(fOut, ",%.2g", xx)
return
} }
*plotx = append(*plotx, float64(n)) fmt.Fprintln(fOut)
*plotf = append(*plotf, float64(fTrial)) }
*plotTmprtr = append (*plotTmprtr, tmprtr)
// saveStep is called when we accept a change. It then writes or saves for
// later plotting.
func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64) {
if cprm.fplotme || cprm.xplotme {
cprm.plotnstp = append(cprm.plotnstp, float64(n))
}
if cprm.fplotme { // Function values
cprm.plotf = append(cprm.plotf, fTrial)
cprm.plotTmprtr = append(cprm.plotTmprtr, tmprtr)
}
if cprm.xplotme { // The trajectory
cprm.plotXtrj = append(cprm.plotXtrj, x...)
}
printfVal(cprm.fOut, x, n, tmprtr, fTrial)
} }
// nRunAdj will try to adjust the step size, given our history of accept/reject. // nRunAdj will try to adjust the step size, given our history of accept/reject.
...@@ -153,25 +163,10 @@ func nRunAdj(mcPrm *mcPrm, runAcc float64, xDlta float32) float32 { ...@@ -153,25 +163,10 @@ func nRunAdj(mcPrm *mcPrm, runAcc float64, xDlta float32) float32 {
return xDlta return xDlta
} }
// printfVal is just the loop to print out the function value and coordinates
// probably for later plotting.
func printfVal (fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float64) {
fmt.Fprintf(fOut, "%d,%.4g,%.5g", n, tmprtr, fOld)
for _, xx := range x {
fmt.Fprintf(fOut, ",%.2g", xx)
}
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.
// Unfortunately, the plotting functions want double precision, so we store
// an awful lot of stuff as float64.
func doRun(mcPrm *mcPrm) error { func doRun(mcPrm *mcPrm) error {
var cprm cprm var cprm cprm
if err := setupRun(mcPrm, &cprm); err != nil { if err := setupRun(mcPrm, &cprm); err != nil {
...@@ -189,7 +184,7 @@ func doRun(mcPrm *mcPrm) error { ...@@ -189,7 +184,7 @@ func doRun(mcPrm *mcPrm) error {
var nAcc int // Counter of number of accepted moves var nAcc int // Counter of number of accepted moves
x := make([]float32, len(mcPrm.xIni)) // current position x := make([]float32, len(mcPrm.xIni)) // current position
xT := make([]float32, len(mcPrm.xIni)) // trial position xT := make([]float32, len(mcPrm.xIni)) // trial position
nout := uint32(1) // counter for printing output // nout := uint32(1) // counter for printing output
runAcc := accRateIdeal // Running acceptance rate, exponentially weighted runAcc := accRateIdeal // Running acceptance rate, exponentially weighted
copy(x, mcPrm.xIni) copy(x, mcPrm.xIni)
fOld := ackley.Ackley(x) // Initial function value fOld := ackley.Ackley(x) // Initial function value
...@@ -197,16 +192,15 @@ func doRun(mcPrm *mcPrm) error { ...@@ -197,16 +192,15 @@ 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. saveStep(&cprm, 0, tmprtr, x, fOld)
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--
if nout == 0 { // Do we want to print out results on this step ? // if nout == 0 { // Do we want to print out results on this step ?
printfVal (cprm.fOut, x, n, tmprtr, fOld) // printfVal(cprm.fOut, x, n, tmprtr, fOld)
nout = cprm.nEvery // nout = cprm.nEvery
} // }
nRunAcc-- nRunAcc--
if nRunAcc == 0 { // Do we want to try adjusting the step size ? if nRunAcc == 0 { // Do we want to try adjusting the step size ?
xDlta = nRunAdj(mcPrm, runAcc, xDlta) xDlta = nRunAdj(mcPrm, runAcc, xDlta)
...@@ -230,8 +224,7 @@ func doRun(mcPrm *mcPrm) error { ...@@ -230,8 +224,7 @@ func doRun(mcPrm *mcPrm) error {
runAcc = runMult*runAcc + (1.0 - runMult) runAcc = runMult*runAcc + (1.0 - runMult)
copy(x, xT) copy(x, xT)
fOld = fTrial fOld = fTrial
plotFval(n+1, fTrial, tmprtr, &cprm.plotx, &cprm.plotf, &cprm.plotTmprtr, cprm.fplotme) saveStep(&cprm, n+1, tmprtr, x, fTrial)
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
} }
...@@ -239,9 +232,11 @@ func doRun(mcPrm *mcPrm) error { ...@@ -239,9 +232,11 @@ func doRun(mcPrm *mcPrm) error {
tmprtr *= cprm.coolMult tmprtr *= cprm.coolMult
} }
} }
err := plotfWrt(cprm.plotx, cprm.plotf, cprm.plotTmprtr, cprm.fPlt, cprm.fplotme) // On plots, we want the last step, even if nothing changed. Print me. Fix.
err := plotfWrt(cprm.plotnstp, cprm.plotf, cprm.plotTmprtr, cprm.fPlt, cprm.fplotme)
if err != nil { if err != nil {
return err } return err
}
err = plotxWrt(&cprm, len(mcPrm.xIni)) err = plotxWrt(&cprm, len(mcPrm.xIni))
fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1) fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1)
......
...@@ -135,7 +135,7 @@ func plotxWrt(cprm *cprm, ndim int) error { ...@@ -135,7 +135,7 @@ func plotxWrt(cprm *cprm, ndim int) error {
} }
type f64 []float64 type f64 []float64
len_used := len(cprm.plotx) len_used := len(cprm.plotnstp)
xdata := make([]f64, ndim) xdata := make([]f64, ndim)
fmt.Println("plotxWrt has", ndim, "dimensions and len_used is", len_used) fmt.Println("plotxWrt has", ndim, "dimensions and len_used is", len_used)
for i := 0; i < ndim; i++ { for i := 0; i < ndim; i++ {
...@@ -153,7 +153,7 @@ func plotxWrt(cprm *cprm, ndim int) error { ...@@ -153,7 +153,7 @@ func plotxWrt(cprm *cprm, ndim int) error {
for i := 0; i < ndim; i++ { for i := 0; i < ndim; i++ {
series[i] = chart.ContinuousSeries{ series[i] = chart.ContinuousSeries{
Name: fmt.Sprintf("dimension %d", i), Name: fmt.Sprintf("dimension %d", i),
XValues: cprm.plotx, XValues: cprm.plotnstp,
YValues: xdata[i], YValues: xdata[i],
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment