From f168c80aaa441ef827b929c37300bec7cb7288f2 Mon Sep 17 00:00:00 2001
From: andrew-torda <55841222+andrew-torda@users.noreply.github.com>
Date: Sun, 22 Aug 2021 11:07:45 +0200
Subject: [PATCH] Mostly working. Need to check results of tests a bit more.

---
 {ackley => ackwork/ackley}/ackley.go      |   0
 {ackley => ackwork/ackley}/ackley_test.go |   0
 {ackley => ackwork/ackley}/notes          |   0
 ackwork/ackwork.go                        |  69 +++++++++++
 ackwork/ackwork_test.go                   |  58 ++++++++++
 ackwork/dorun.go                          | 127 ++++++++++++++++++++
 ackwork/prm_file.go                       | 134 ++++++++++++++++++++++
 function.docx                             | Bin 0 -> 16414 bytes
 go.mod                                    |   3 +
 9 files changed, 391 insertions(+)
 rename {ackley => ackwork/ackley}/ackley.go (100%)
 rename {ackley => ackwork/ackley}/ackley_test.go (100%)
 rename {ackley => ackwork/ackley}/notes (100%)
 create mode 100644 ackwork/ackwork.go
 create mode 100644 ackwork/ackwork_test.go
 create mode 100644 ackwork/dorun.go
 create mode 100644 ackwork/prm_file.go
 create mode 100644 function.docx
 create mode 100644 go.mod

diff --git a/ackley/ackley.go b/ackwork/ackley/ackley.go
similarity index 100%
rename from ackley/ackley.go
rename to ackwork/ackley/ackley.go
diff --git a/ackley/ackley_test.go b/ackwork/ackley/ackley_test.go
similarity index 100%
rename from ackley/ackley_test.go
rename to ackwork/ackley/ackley_test.go
diff --git a/ackley/notes b/ackwork/ackley/notes
similarity index 100%
rename from ackley/notes
rename to ackwork/ackley/notes
diff --git a/ackwork/ackwork.go b/ackwork/ackwork.go
new file mode 100644
index 0000000..ffc153e
--- /dev/null
+++ b/ackwork/ackwork.go
@@ -0,0 +1,69 @@
+// Aug 2021
+
+package ackwork
+
+import (
+	"ackley_mc/ackwork/ackley"
+	"flag"
+	"fmt"
+	"io"
+	"os"
+)
+
+const ndimDflt = 2
+
+type mcPrm struct {
+	iniTmp, fnlTmp float32   // Initial and final temperatures
+	xIni           []float32 // initial x slice
+	xDlta          float32   // change x by up to +- xDlta in trial moves
+	nStep          uint32    // number of steps
+	nRun           uint32    // number of separate runs
+	nOutput        uint32    // write at least this many lines of output
+	fOutName       string    // where we write output to
+	verbose        bool
+	dummy          bool // for testing. If set, do not do a run
+}
+
+var seed int64 // for random numbers, but each thread gets its own value
+
+// usage
+func usage() {
+	u := `[options] input_parameter_file`
+	fmt.Fprintf(flag.CommandLine.Output(), "usage of %s: %s\n", os.Args[0], u)
+}
+
+// realmain is the real main function. The program wants to read from a file,
+// but we can have it read from an io.Reader and then use the test functions
+// for playing with it.
+func realmain(fp io.Reader) error {
+	var mcPrm mcPrm
+	if err := rdPrm(fp, &mcPrm); err != nil {
+		return err
+	}
+ 	if err := doRun(&mcPrm); err != nil {
+		return err
+	}
+	var x [1]float32
+	ackley.Ackley(x[:])
+	return nil
+}
+
+// MyMain is called from the real main. It opens the input file, but passes a
+// reader to the function that does the work. This lets us call it from a test
+// function.
+func MyMain() error {
+	if len(os.Args) < 2 {
+		usage()
+		return fmt.Errorf("No input file given")
+	}
+	fname := os.Args[1]
+	if fp, err := os.Open(fname); err != nil {
+		return err
+	} else {
+		defer fp.Close()
+		if err := realmain(fp); err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/ackwork/ackwork_test.go b/ackwork/ackwork_test.go
new file mode 100644
index 0000000..35847b4
--- /dev/null
+++ b/ackwork/ackwork_test.go
@@ -0,0 +1,58 @@
+// Aug 2021
+
+package ackwork
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestErr(t *testing.T) {
+	rdrErr := strings.NewReader("\nrubbish")
+	if err := realmain(rdrErr); err == nil {
+		t.Fatal("line with rubbish should provoke error")
+	}
+}
+
+var s1d = `
+ini_temp 1
+final_temp 0.05
+x_ini 15
+n_step 10000
+n_output 5000
+f_outName testanneal1d`
+
+func TestAnneal1d(t *testing.T) {
+	if err := realmain(strings.NewReader(s1d)); err != nil {
+		t.Fatal("anneal run", err)
+	}
+
+}
+var s3d = `
+ini_temp 1
+final_temp 0.05
+x_ini 15,15,15
+n_step 10000
+n_output 500
+f_outName testanneal3d`
+
+func TestAnneal3d(t *testing.T) {
+	if err := realmain(strings.NewReader(s3d)); err != nil {
+		t.Fatal("anneal run", err)
+	}
+
+}
+
+var sCold = `
+ini_temp 1e-10
+final_temp 1e-12
+x_ini 1,1,1
+n_step 10000
+n_output 500
+f_outName testcold`
+
+func TestCold(t *testing.T) {
+	if err := realmain(strings.NewReader(sCold)); err != nil {
+		t.Fatal("anneal run", err)
+	}
+}
diff --git a/ackwork/dorun.go b/ackwork/dorun.go
new file mode 100644
index 0000000..7463c44
--- /dev/null
+++ b/ackwork/dorun.go
@@ -0,0 +1,127 @@
+// Aug 2021
+package ackwork
+
+import (
+	"fmt"
+	"math"
+	"math/rand"
+	"io"
+	"os"
+	"sync"
+
+	"ackley_mc/ackwork/ackley"
+)
+
+var seedLocker sync.Mutex
+
+// getSeed returns the random number seed, but we have to put a lock
+// around it so multiple runs get consistent successive seeds
+func getSeed() int64 {
+	seedLocker.Lock()
+	r := seed
+	seed++
+	seedLocker.Unlock()
+	return r
+}
+
+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 ?
+	nEvery   uint32  // Output every nEvery steps
+	fOut     io.WriteCloser
+}
+
+// setupRun does things like get the cooling rate
+func setupRun(mcPrm *mcPrm, cprm *cprm) error {
+	var err error
+	if mcPrm.dummy == true {
+		return nil
+	}
+	cprm.rand = rand.New(rand.NewSource(getSeed()))
+
+
+	if mcPrm.iniTmp != mcPrm.fnlTmp {
+		var coolrate float64
+		cprm.coolme = true
+		if mcPrm.fnlTmp > mcPrm.iniTmp {
+			// would you like to print out a warning ?
+		}
+		nStep := float64(mcPrm.nStep)
+		fnlTmp, iniTmp := float64(mcPrm.fnlTmp), float64(mcPrm.iniTmp)
+		coolrate = -1 / nStep
+		coolrate *= math.Log(fnlTmp / iniTmp)
+		cprm.coolMult = math.Exp(-coolrate)
+	}
+
+	cprm.nEvery = uint32(math.Ceil(float64(mcPrm.nStep) / float64(mcPrm.nOutput)))
+	// change the next line to handle the case of multiple runs
+	ntmp := mcPrm.fOutName + ".csv"
+	if cprm.fOut, err = os.Create (ntmp); err != nil {
+		return err
+	}
+		
+	return nil
+}
+
+// newx gets a candidate x slice
+func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) {
+	for i, x := range xold {
+		t := 2. * rand.Float32() - 1
+		t *= xDlta
+		xT[i] = x + t
+	}
+}
+
+func doRun(mcPrm *mcPrm) error {
+	var cprm cprm
+	if err := setupRun(mcPrm, &cprm); err != nil {
+		return err
+	}
+	if cprm.fOut != nil {
+		defer cprm.fOut.Close()
+	}
+	var nAcc int // number of accepted moves
+	x := make([]float32, len(mcPrm.xIni))
+	xT := make([]float32, len(mcPrm.xIni))
+	nout := uint32(1)
+
+	copy(x, mcPrm.xIni)
+	fOld := ackley.Ackley(x)
+	tmprtr := float64(mcPrm.iniTmp)
+	var n uint32
+	for ; n < mcPrm.nStep; n++ {
+		var acc bool
+		nout--
+		if nout == 0 {
+			fmt.Fprintf (cprm.fOut, "%d,%.4g,%.5g", n, tmprtr,fOld)
+			for _,xx := range x {
+				fmt.Fprintf(cprm.fOut, ",%.2g", xx)}
+			fmt.Fprintln(cprm.fOut)
+			nout = cprm.nEvery
+		}
+
+		newx(x, xT, cprm.rand, mcPrm.xDlta)
+		fTrial := ackley.Ackley(xT)
+
+		if fOld < fTrial {
+			r := cprm.rand.Float64()
+			delta := fTrial - fOld
+			t := math.Exp(-delta / tmprtr)
+			if r < t {
+				acc = true
+			}
+		} else {
+			acc = true
+		}
+		if acc == true {
+			nAcc++
+			copy(x, xT)
+			fOld = fTrial
+		}
+		if cprm.coolme {
+			tmprtr *= cprm.coolMult
+		}
+	}
+	return nil
+}
diff --git a/ackwork/prm_file.go b/ackwork/prm_file.go
new file mode 100644
index 0000000..0f26b1e
--- /dev/null
+++ b/ackwork/prm_file.go
@@ -0,0 +1,134 @@
+// Aug 2021
+// Read the parameters for a calculation
+// We have magic keywords like ini_temp.
+// These are stored in a map along with string values. These are then converted
+// to floats or ints and put into a structure or variable.
+
+package ackwork
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+
+	"strconv"
+	"strings"
+)
+
+var i int = 6
+var cmdDflt = []struct {
+	key string
+	v   string
+}{
+	{"ini_temp", "20"},
+	{"final_temp", "1"},
+	{"n_step", "1000"},
+	{"n_run", "1"},
+	{"n_output", "500"},
+	{"x_ini", "3,4,5"},
+	{"x_delta", "0.5"},
+	{"seed", "1637"},
+	{"f_outname", "mcrun"},
+	{"verbose", ""},
+	{"dummy", ""},
+}
+
+// digest digests the map, fills out our structure and sets the seed.
+func digest(prmMap map[string]string, mcPrm *mcPrm) 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)
+	}
+	getu := func(s string) uint32 {
+		if err != nil {
+			return 0
+		}
+		var u uint64
+		u, err = strconv.ParseUint(s, 10, 32)
+		return uint32(u)
+	}
+	getx := func(s string) []float32 {
+		y := strings.Split(s, ",")
+		if len(y) < 1 {
+			err = fmt.Errorf("broke trying to get initial x values")
+			return nil
+		}
+
+		x := make([]float32, len(y))
+		for i, s := range y {
+			r := 0.
+			if r, err = strconv.ParseFloat(s, 32); err != nil {
+				return nil
+			}
+			x[i] = float32(r)
+		}
+		return x
+	}
+	mcPrm.iniTmp = getf(prmMap["ini_temp"])
+	mcPrm.fnlTmp = getf(prmMap["final_temp"])
+	mcPrm.xDlta = getf(prmMap["x_delta"])
+	mcPrm.nStep = getu(prmMap["n_step"])
+	mcPrm.nRun = getu(prmMap["n_run"])
+	mcPrm.nOutput = getu(prmMap["n_output"])
+	mcPrm.xIni = getx(prmMap["x_ini"])
+	mcPrm.fOutName = prmMap["f_outname"]
+	seed = int64(getu(prmMap["seed"]))
+	if err != nil { // Only returns the first error encountered
+		return err
+	}
+	if prmMap["verbose"] != "" {
+		mcPrm.verbose = true
+	}
+	if prmMap["dummy"] != "" {
+		mcPrm.dummy = true
+	}
+	return nil
+}
+
+// spew spews out an error and known input parameters
+func spew() string {
+	s := `Input file should be of
+key value
+pairs. Values for x_ini are separated by commas without spaces.
+`
+	for _, ss := range cmdDflt {
+		s += fmt.Sprintf("%s %s\n", ss.key, ss.v)
+	}
+	return s
+}
+
+// rdPrmInner is in a function by itself, to make testing easier
+func rdPrm(fp io.Reader, mcPrm *mcPrm) error {
+	prmMap := make(map[string]string)
+	for _, s := range cmdDflt {
+		prmMap[s.key] = s.v // Put default values into map
+	}
+	scn := bufio.NewScanner(fp)
+	for scn.Scan() {
+		s := scn.Text()
+		if len(s) == 0 {
+			continue // blank lines
+		}
+		s = strings.ToLower(s)
+		ss := strings.Fields(s)
+		if len(ss) < 2 {
+			return fmt.Errorf("Only one field in line: %s\n%s", s, spew())
+		}
+		key := ss[0]
+		if _, ok := prmMap[key]; !ok {
+			return fmt.Errorf("unknown keyword %s\n%s", key, spew())
+		} else {
+			prmMap[key] = ss[1]
+		}
+	}
+	if err := scn.Err(); err != nil {
+		return errors.New(spew())
+	}
+	return digest(prmMap, mcPrm)
+}
diff --git a/function.docx b/function.docx
new file mode 100644
index 0000000000000000000000000000000000000000..068019791a47f07899e754c4cfb4861a951d6db4
GIT binary patch
literal 16414
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
I9Be>50ERnel>h($

literal 0
HcmV?d00001

diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..0e218ff
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module ackley_mc
+
+go 1.16
-- 
GitLab