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

Added a switch to turn off adaptive move size.

parent 976e47c5
No related branches found
No related tags found
No related merge requests found
- in main MC, add a boolean to make move size adjustment optional. Otherwise the method works too well for an Uebung.
- Add radio button to input tab for adaptive move sizes
- Change the adaptive scheme so it looks more like weak coupling. Scale the adjustment by current rate / desired rate
- add testing to the ui directory
- Save the best found configuration, print out at end
\ No newline at end of file
......@@ -7,6 +7,7 @@
// 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
// BUGS
// A chart in png format from go-chart is no problem, but a file in svg format causes a parse error in fyne.
/*
......
......@@ -189,10 +189,11 @@ func nRunAdj(mcPrm *McPrm, nstep int, runAcc float64, xDlta float64) float64 {
return xDlta
}
// doRun does a Monte Carlo run. Although single precision is fine for the
// 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.
// doRun does a Monte Carlo run.
// We only need single precision for most things, except for function
// values, but the interface to the plot and interface packages mostly
// want double precision, so we have a lot of float64 that shoudl be
// float32.
func DoRun(mcPrm *McPrm) (MCresult, error) {
var cprm cprm
broken := MCresult{}
......@@ -204,8 +205,11 @@ func DoRun(mcPrm *McPrm) (MCresult, error) {
defer cprm.fOut.Flush()
}
if c, ok := cprm.fplotWrt.(io.Closer); ok { // will also have to do for X values
defer c.Close()
if c, ok := cprm.fplotWrt.(io.Closer); ok {
defer c.Close() // file handle for function values
}
if c, ok := cprm.xplotWrt.(io.Closer); ok {
defer c.Close() // file handle for X trajectories
}
var nAcc int // Counter, number of accepted moves
......@@ -213,32 +217,33 @@ func DoRun(mcPrm *McPrm) (MCresult, error) {
xT := make([]float32, len(mcPrm.XIni)) // trial position
runAcc := accRateIdeal // Running acceptance rate, exponentially weighted
for i := range mcPrm.XIni {
x[i] = float32(mcPrm.XIni[i])
for i := range mcPrm.XIni { // Initial coordinates from
x[i] = float32(mcPrm.XIni[i]) // the control structure
}
// copy(x, mcPrm.XIni) I had to replace this with the loop above
fOld := ackley.Ackley(x) // Initial function value
fTrial := fOld
tmprtr := float64(mcPrm.IniTmp)
nRunAcc := nRunAccAdj // Every nRunAccAdj, try adjusting the step size.
const runMult = 0.99
xDlta := mcPrm.XDlta // Adaptable step size
xDlta := mcPrm.XDlta // Step size which might be adjusted on the fly
saveStep(&cprm, 0, tmprtr, x, fOld)
for n := 0; n < mcPrm.NStep; n++ {
var accept bool
if mcPrm.AdaptStep {
nRunAcc--
if nRunAcc == 0 { // Do we want to try adjusting the step size ?
xDlta = nRunAdj(mcPrm, n, runAcc, xDlta)
nRunAcc = nRunAccAdj // Reset the counter
}
}
newx(x, xT, cprm.rand, xDlta)
fTrial = ackley.Ackley(xT)
if fTrial <= fOld {
accept = true
} else {
delta := fTrial - fOld // Make the decision as to whether to
delta := fTrial - fOld // Decision as to whether to
t := math.Exp(-delta / tmprtr) // accept or reject the trial
if cprm.rand.Float64() < t {
accept = true
......@@ -246,12 +251,16 @@ func DoRun(mcPrm *McPrm) (MCresult, error) {
}
if accept {
nAcc++
runAcc = runMult*runAcc + (1.0 - runMult)
copy(x, xT)
fOld = fTrial
saveStep(&cprm, n+1, tmprtr, x, fTrial)
} else { // update the running estimate of acceptance
runAcc = runMult * runAcc
if mcPrm.AdaptStep {
runAcc = runMult*runAcc + (1.0 - runMult)
}
} else { // else don't really have to do anything, but update statistics
if mcPrm.AdaptStep {
runAcc = runMult * runAcc // update the running estimate of acceptance
}
}
if cprm.coolme {
tmprtr *= cprm.coolMult
......
......@@ -15,6 +15,7 @@ type McPrm struct {
fOutName string // where we write output to
fPltName string // where we plot to (function values)
xPltName string // where we plot x trajectories to
AdaptStep bool // Adaptive step sizes
verbose bool
dummy bool // for testing. If set, do not do a run
}
......
......@@ -29,6 +29,7 @@ var cmdDflt = []struct {
{"foutname", ""},
{"fpltname", ""}, // empty means no plots of function
{"xpltname", ""},
{"adaptstep", ""},
{"verbose", ""},
{"dummy", ""},
}
......@@ -88,6 +89,9 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error {
if prmMap["verbose"] != "" {
mcPrm.verbose = true
}
if prmMap["adaptstep"] != "" {
mcPrm.AdaptStep = true
}
if prmMap["dummy"] != "" {
mcPrm.dummy = true
}
......
......@@ -86,6 +86,7 @@ func intItem(xAddr *int, label string, htext string) (*widget.FormItem, func())
}
var xCoordHint = "The starting point. A comma-separated list of floats. It is used to set the dimensionality"
// paramBox sets up a screen full of parameters we can adjust.
// It returns the screen and a function to be called to refresh it.
// This is necessary, since there is a button to read parameters from
......@@ -115,6 +116,11 @@ func paramForm(genParams genParams) *widget.Form {
nStepItem, nStepReload := intItem(&mcPrm.NStep, "N steps", "number of steps in calculation")
seedItem, seedReload := intItem(&mcwork.Seed, "seed random numbers", "seed for random number generator")
adaptbind := binding.BindBool(&mcPrm.AdaptStep)
adaptEntry := widget.NewCheckWithData("adaptive step size", adaptbind)
adaptItem := widget.NewFormItem("fI string", adaptEntry)
adaptItem.HintText = "Turn on adaptive moves to try to keep acceptance near 5%"
adaptReload := func() { _ = adaptbind.Reload() }
reloadPTab := func() {
iniTmpReload()
fnlTmpReload()
......@@ -122,6 +128,7 @@ func paramForm(genParams genParams) *widget.Form {
xIniEntry.SetText(fslicestrng(mcPrm.XIni))
nStepReload()
seedReload()
adaptReload()
}
rdfile := func() { rdwork(genParams, reloadPTab) }
......@@ -130,7 +137,7 @@ func paramForm(genParams genParams) *widget.Form {
r := widget.NewForm( // Lays out the items in the form
iniTmpItem, fnlTmpItem, xDltaItem, xIniItem,
nStepItem, seedItem, rdFileItem)
nStepItem, seedItem, adaptItem, rdFileItem)
r.SubmitText = "start calculation"
r.OnSubmit = func() { startrun(genParams, r, mcPrm) }
reloadPTab() // does this help ? sometimes the form pops up with entries not ready
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment