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

Boring changes to make data types simple int's and float64's so that I can use...

Boring changes to make data types simple int's and float64's so that I can use the binding function in fyne. It is otherwise too painful to have to do lots of casts.
parent 42e6e853
No related branches found
No related tags found
No related merge requests found
...@@ -159,7 +159,7 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float64) { ...@@ -159,7 +159,7 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float64) {
// printfVal is the loop to print out the function value and coordinates // printfVal is the loop to print out the function value and coordinates
// probably for later plotting. // probably for later plotting.
func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float64) { func printfVal(fOut io.Writer, x []float32, n int, tmprtr float64, fOld float64) {
fmt.Fprintf(fOut, "%d,%.4g,%.5g", n, tmprtr, fOld) fmt.Fprintf(fOut, "%d,%.4g,%.5g", n, tmprtr, fOld)
for _, xx := range x { for _, xx := range x {
fmt.Fprintf(fOut, ",%.2g", xx) fmt.Fprintf(fOut, ",%.2g", xx)
...@@ -169,7 +169,7 @@ func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float ...@@ -169,7 +169,7 @@ func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float
// saveStep is called when we accept a change. It writes or saves for // saveStep is called when we accept a change. It writes or saves for
// later plotting. // later plotting.
func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64) { func saveStep(cprm *cprm, n int, tmprtr float64, x []float32, fTrial float64) {
cprm.plotnstp = append(cprm.plotnstp, float64(n)) // num steps cprm.plotnstp = append(cprm.plotnstp, float64(n)) // num steps
if cprm.fplotWrt != nil { // Function values // function values if cprm.fplotWrt != nil { // Function values // function values
cprm.plotf = append(cprm.plotf, fTrial) cprm.plotf = append(cprm.plotf, fTrial)
...@@ -184,7 +184,7 @@ func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64) ...@@ -184,7 +184,7 @@ func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64)
} }
// 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.
func nRunAdj(mcPrm *McPrm, nstep uint32, runAcc float64, xDlta float64) float64 { func nRunAdj(mcPrm *McPrm, nstep int, runAcc float64, xDlta float64) float64 {
const step = "step" const step = "step"
if runAcc < accRateIdeal-0.01 { // acceptance rate too low if runAcc < accRateIdeal-0.01 { // acceptance rate too low
xDlta *= 0.9 xDlta *= 0.9
...@@ -236,7 +236,7 @@ func DoRun(mcPrm *McPrm) ([]byte, []byte, error) { ...@@ -236,7 +236,7 @@ func DoRun(mcPrm *McPrm) ([]byte, []byte, error) {
xDlta := mcPrm.XDlta // Adaptable step size xDlta := mcPrm.XDlta // Adaptable step size
saveStep(&cprm, 0, tmprtr, x, fOld) saveStep(&cprm, 0, tmprtr, x, fOld)
for n := uint32(0); n < mcPrm.NStep; n++ { for n := 0; n < mcPrm.NStep; n++ {
var accept bool var accept bool
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 ?
......
...@@ -13,8 +13,8 @@ type McPrm struct { ...@@ -13,8 +13,8 @@ type McPrm struct {
IniTmp, FnlTmp float64 // Initial and final temperatures IniTmp, FnlTmp float64 // Initial and final temperatures
XIni []float32 // initial x slice XIni []float32 // initial x slice
XDlta float64 // change x by up to +- xDlta in trial moves XDlta float64 // change x by up to +- xDlta in trial moves
NStep uint32 // number of steps NStep int // number of steps
NRun uint32 // number of separate runs NRun int // number of separate runs
fOutName string // where we write output to fOutName string // where we write output to
fPltName string // where we plot to (function values) fPltName string // where we plot to (function values)
xPltName string // where we plot x trajectories to xPltName string // where we plot x trajectories to
......
...@@ -36,14 +36,6 @@ var cmdDflt = []struct { ...@@ -36,14 +36,6 @@ var cmdDflt = []struct {
// digest digests the map, fills out our structure and sets the seed. // digest digests the map, fills out our structure and sets the seed.
func digest(prmMap map[string]string, mcPrm *McPrm) error { func digest(prmMap map[string]string, mcPrm *McPrm) error {
var err error var err error
/* getf := func(s string) float32 {
if err != nil {
return 0.0
}
var r float64
r, err = strconv.ParseFloat(s, 32)
return float32(r)
} */
getf64 := func(s string) float64 { getf64 := func(s string) float64 {
if err != nil { if err != nil {
return 0.0 return 0.0
...@@ -52,13 +44,13 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error { ...@@ -52,13 +44,13 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error {
r, err = strconv.ParseFloat(s, 64) r, err = strconv.ParseFloat(s, 64)
return r return r
} }
getu := func(s string) uint32 { geti := func(s string) int {
if err != nil { if err != nil {
return 0 return 0
} }
var u uint64 var u int64
u, err = strconv.ParseUint(s, 10, 32) u, err = strconv.ParseInt(s, 10, 32)
return uint32(u) return int(u)
} }
getx := func(s string) []float32 { getx := func(s string) []float32 {
if err != nil { if err != nil {
...@@ -83,13 +75,13 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error { ...@@ -83,13 +75,13 @@ func digest(prmMap map[string]string, mcPrm *McPrm) error {
mcPrm.IniTmp = getf64(prmMap["ini_temp"]) mcPrm.IniTmp = getf64(prmMap["ini_temp"])
mcPrm.FnlTmp = getf64(prmMap["final_temp"]) mcPrm.FnlTmp = getf64(prmMap["final_temp"])
mcPrm.XDlta = getf64(prmMap["x_delta"]) mcPrm.XDlta = getf64(prmMap["x_delta"])
mcPrm.NStep = getu(prmMap["n_step"]) mcPrm.NStep = geti(prmMap["n_step"])
mcPrm.NRun = getu(prmMap["n_run"]) mcPrm.NRun = geti(prmMap["n_run"])
mcPrm.XIni = getx(prmMap["x_ini"]) mcPrm.XIni = getx(prmMap["x_ini"])
mcPrm.fOutName = prmMap["foutname"] mcPrm.fOutName = prmMap["foutname"]
mcPrm.fPltName = prmMap["fpltname"] mcPrm.fPltName = prmMap["fpltname"]
mcPrm.xPltName = prmMap["xpltname"] mcPrm.xPltName = prmMap["xpltname"]
seed = int64(getu(prmMap["seed"])) seed = int64(geti(prmMap["seed"]))
if err != nil { // Only returns the first error encountered if err != nil { // Only returns the first error encountered
return err return err
} }
......
...@@ -20,7 +20,7 @@ func realmain(fp io.Reader) error { ...@@ -20,7 +20,7 @@ func realmain(fp io.Reader) error {
if err := RdPrm(fp, &mcPrm); err != nil { if err := RdPrm(fp, &mcPrm); err != nil {
return err return err
} }
if _, _, err := doRun(&mcPrm); err != nil { if _, _, err := DoRun(&mcPrm); err != nil {
return err return err
} }
......
...@@ -30,35 +30,44 @@ type workstatus struct { ...@@ -30,35 +30,44 @@ type workstatus struct {
status status status status
} }
// showIniTab is just a card to be shown before we have any calculations
// done.
func showIniTab(cntr *fyne.Container) { func showIniTab(cntr *fyne.Container) {
cntr.Add(widget.NewCard("No results yet", "go back to the input", nil)) cntr.Add(widget.NewCard("No results yet", "go back to the input", nil))
} }
func showCalcTab(cntr *fyne.Container) { // emptyContainer gets rid of any old contents
for _, c := range cntr.Objects { func emptyContainer (cntr *fyne.Container) {
cntr.Remove(c) for _, o := range cntr.Objects {
cntr.Remove(o)
}
} }
// showCalcTab is shown while calculating. Have to check if the refresh()
// is actually necessary.
func showCalcTab(cntr *fyne.Container) {
emptyContainer (cntr)
cntr.Add(widget.NewCard("calculating", "busy", nil)) cntr.Add(widget.NewCard("calculating", "busy", nil))
cntr.Refresh() cntr.Refresh()
} }
// showResultsTab show the two plots // showResultsTab show the two plots
func showResultsTab(cntr *fyne.Container, fdata, xdata []byte) { func showResultsTab(cntr *fyne.Container, fdata, xdata []byte) {
for _, c := range cntr.Objects { emptyContainer (cntr)
cntr.Remove(c) pictureSize := fyne.Size{Width: 500, Height: 250}
}
fImage := canvas.NewImageFromReader(bytes.NewReader(fdata), "func.png") fImage := canvas.NewImageFromReader(bytes.NewReader(fdata), "func.png")
fImage.FillMode = canvas.ImageFillContain fImage.FillMode = canvas.ImageFillContain
fImage.SetMinSize( fyne.Size{500, 300}) fImage.SetMinSize( pictureSize)
xImage := canvas.NewImageFromReader(bytes.NewReader(xdata), "xdata.png") xImage := canvas.NewImageFromReader(bytes.NewReader(xdata), "xdata.png")
xImage.FillMode = canvas.ImageFillContain xImage.FillMode = canvas.ImageFillContain
xImage.SetMinSize( fyne.Size{500, 300}) xImage.SetMinSize( pictureSize)
content := container.NewGridWithRows(2, fImage, xImage) content := container.NewGridWithRows(2, fImage, xImage)
cntr.Add(content) cntr.Add(content)
} }
// outputTab is run as a background process. After showing the initial
// screen, it sits and waits on notifications. When it gets one,
// it redraws its tab.
func outputTab(chn chan workstatus, cntr *fyne.Container) { func outputTab(chn chan workstatus, cntr *fyne.Container) {
showIniTab(cntr) showIniTab(cntr)
for s := range chn { for s := range chn {
......
...@@ -50,17 +50,19 @@ func s2f32(s string) ([]float32, error) { ...@@ -50,17 +50,19 @@ func s2f32(s string) ([]float32, error) {
return x, nil return x, nil
} }
// validateXini checks if we can convert a string to a slice of float32's.
// Unfortunately, fyne calls this function every time the cursor is moved
// in the field. I think this is a little bug on their part.
func validateXini(s string) error { func validateXini(s string) error {
fmt.Println("validation called")
_, err := s2f32(s) _, err := s2f32(s)
return err return err
} }
// paramScreen sets up a screen full of parameters we can adjust. It returns a the screen // paramScreen sets up a screen full of parameters we can adjust.
// and a function to be called to refresh it if parameters are changed elsewhere, like // It returns the screen and a function to be called to refresh it.
// reading from a file. // This is necessary, since there is a button to read parameters from
// a file, which means all the values should be updated.
func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) { func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) {
iniTmp := binding.BindFloat(&mcPrm.IniTmp) iniTmp := binding.BindFloat(&mcPrm.IniTmp)
iniTmpEntry := widget.NewEntryWithData(binding.FloatToString(iniTmp)) iniTmpEntry := widget.NewEntryWithData(binding.FloatToString(iniTmp))
iniTmpLabel := widget.NewLabel("initial temp") iniTmpLabel := widget.NewLabel("initial temp")
...@@ -87,21 +89,30 @@ func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) { ...@@ -87,21 +89,30 @@ func paramScreen(mcPrm *mcwork.McPrm) (*fyne.Container, func()) {
xIniEntry.Validator = validateXini xIniEntry.Validator = validateXini
xIniLabel := widget.NewLabel("X ini") xIniLabel := widget.NewLabel("X ini")
nStepBnd := binding.BindInt(&mcPrm.NStep)
nStepEntry := widget.NewEntryWithData(binding.IntToString(nStepBnd))
nStepLabel := widget.NewLabel("num steps")
r := container.NewGridWithColumns(2, r := container.NewGridWithColumns(2,
iniTmpLabel, iniTmpEntry, iniTmpLabel, iniTmpEntry,
fnlTmpLabel, fnlTmpEntry, fnlTmpLabel, fnlTmpEntry,
xDltaLabel, xDltaEntry, xDltaLabel, xDltaEntry,
xIniLabel, xIniEntry) xIniLabel, xIniEntry,
nStepEntry, nStepLabel)
refreshPScreen := func() { refreshPScreen := func() {
iniTmp.Reload() iniTmp.Reload()
fnlTmp.Reload() fnlTmp.Reload()
xDlta.Reload() xDlta.Reload()
xIniEntry.SetText(fslicestrng(mcPrm.XIni)) xIniEntry.SetText(fslicestrng(mcPrm.XIni))
nStepBnd.Reload()
} }
return r, refreshPScreen return r, refreshPScreen
} }
func checkok(c *fyne.Container, parent fyne.Window) error {
// checkOk does a last pass over all fields and calls any validators
// it can find. A run can only be started if everything seems to be OK.
func checkOk(c *fyne.Container, parent fyne.Window) error {
for _, obj := range c.Objects { for _, obj := range c.Objects {
if ent, ok := obj.(*widget.Entry); ok { if ent, ok := obj.(*widget.Entry); ok {
if err := ent.Validate(); err != nil { if err := ent.Validate(); err != nil {
...@@ -133,7 +144,7 @@ func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, refreshme func()) error { ...@@ -133,7 +144,7 @@ func rdwork(mcPrm *mcwork.McPrm, parent fyne.Window, refreshme func()) error {
} else { } else {
fmt.Println("I think mcprm is", mcPrm) fmt.Println("I think mcprm is", mcPrm)
refreshme() refreshme()
dialog.NewInformation("OK confirmed", "read file, no errors", parent).Show() dialog.NewInformation("OK", "read file, no errors", parent).Show()
return return
} }
} }
...@@ -160,11 +171,10 @@ func inputTab(mcPrm *mcwork.McPrm, parent fyne.Window, chn chan workstatus) (*fy ...@@ -160,11 +171,10 @@ func inputTab(mcPrm *mcwork.McPrm, parent fyne.Window, chn chan workstatus) (*fy
} }
} }
startrun := func() { startrun := func() {
if err := checkok(paramBinding, parent); err != nil { if err := checkOk(paramBinding, parent); err != nil {
dialog.NewError(err, parent).Show() dialog.NewError(err, parent).Show()
return return
} }
fmt.Println("I want to run with paremeters", mcPrm)
chn <- workstatus{status: calculating} chn <- workstatus{status: calculating}
if fdata, xdata, err := mcwork.DoRun(mcPrm); err != nil { if fdata, xdata, err := mcwork.DoRun(mcPrm); err != nil {
dialog.NewError(err, parent).Show() dialog.NewError(err, parent).Show()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment