diff --git a/go.mod b/go.mod index 08579caa1c60b51f490f9e31fd8283bc0ea255cc..d3a0ec07f49275e9ada2109ee10958d2f6e636e8 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module example.com/ackley_mc go 1.16 require ( + fyne.io/fyne v1.4.3 + fyne.io/fyne/v2 v2.1.2 github.com/wcharczuk/go-chart/v2 v2.1.0 gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20220120103412-d663ebb46145 ) diff --git a/go.sum b/go.sum index 55fb9bbcc10af31ba1006cf1898c339a52e88b43..95dec1be5bb6e11aba3379fbf019c64f7f486701 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,112 @@ +fyne.io/fyne v1.4.3 h1:356CnXCiYrrfaLGsB7qLK3c6ktzyh8WR05v/2RBu51I= +fyne.io/fyne v1.4.3/go.mod h1:8kiPBNSDmuplxs9WnKCkaWYqbcXFy0DeAzwa6PBO9Z8= +fyne.io/fyne/v2 v2.1.2 h1:avp9CvLAUdvE7fDMtH1tVKyjxEWHWcpow6aI6L7Kvvw= +fyne.io/fyne/v2 v2.1.2/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA= +github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fyne-io/mobile v0.1.2/go.mod h1:/kOrWrZB6sasLbEy2JIvr4arEzQTXBTZGb3Y96yWbHY= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f h1:s0O46d8fPwk9kU4k1jj76wBquMVETx7uveQD9MCIQoU= +github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200625191551-73d3c3675aa3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8= +github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc= +github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lucor/goinfo v0.0.0-20200401173949-526b5363a13a/go.mod h1:ORP3/rB5IsulLEBwQZCJyyV6niqmI7P4EWSmkug+1Ng= +github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 h1:HunZiaEKNGVdhTRQOVpMmj5MQnGnv+e8uZNu3xFLgyM= +github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4= +github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCEzJNy71UkeF4XIx2EVmL9KLwDQdmM= +github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I= github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E= +github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20220120103412-d663ebb46145 h1:02TpLZVj21Xg5OAKHE6vs+bJRlmyuQk4uphZXvDr/w0= gitlab.rrz.uni-hamburg.de/Bae5157/axticks v0.0.0-20220120103412-d663ebb46145/go.mod h1:5CNHyqeidRypmIVTnQksGqnmP56Oshw1Zv1nlUezrpQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200328031815-3db5fc6bac03/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/mc_work/dorun.go b/mc_work/dorun.go index 2f9442ab46d020f9cf09ecb7c1daecf515f8144d..d1f095bfbacdd47631a8da65d96d3c4a76741a59 100644 --- a/mc_work/dorun.go +++ b/mc_work/dorun.go @@ -3,6 +3,7 @@ package mc_work import ( "bufio" + "bytes" "fmt" "io" "math" @@ -31,24 +32,32 @@ func getSeed() int64 { return r } +type withCloser struct{ io.Writer } // We have to promote him to have a Close() +func (withCloser) Close() error { return nil } +func addClose(b io.Writer) withCloser { return withCloser{b} } + type cprm struct { // parameters calculated from input rand *rand.Rand coolMult float64 // multiplier for temperature - fOutRaw io.WriteCloser // the raw file for csv files + fOutRaw io.WriteCloser // the raw file handle for csv files fOut *bufio.Writer // buffered version of fOutRaw - plotnstp []float64 // Why float 64 ? Because the plotting libraries + doTxtFval bool // Are we writing text files (csv) ? + plotnstp []float64 // Number of steps. float64 for the plot library plotf []float64 // Function values for plotting plotTmprtr []float64 // Temperature values for plotting plotXtrj []float32 // for plotting trajectories - coolme bool // Are we cooling or just doing constant temperature ? - fplotme bool // Are we making output for plotting func values + coolme bool // Cooling ? or just constant temperature ? + fplotWrt io.WriteCloser // Where to write the plot of function values + fplotiobuf *bytes.Buffer // The buffer possibly behind fplotWrt xplotme bool // Are we plotting X trajectories } // isNotSane checks for obviously silly parameters func isNotSane(mcPrm *mcPrm) error { if mcPrm.fOutName == "" && mcPrm.fPltName == "" && mcPrm.xPltName == "" { - return fmt.Errorf("All output files are empty. You would not see anything") + if false { // if there are no graphics compiled in, .. + return fmt.Errorf("All output files are empty. You would not see anything") + } } if mcPrm.iniTmp < 0 { return fmt.Errorf("negative initial temperature %g", mcPrm.iniTmp) @@ -58,7 +67,6 @@ func isNotSane(mcPrm *mcPrm) error { // 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 { return nil @@ -69,65 +77,72 @@ func setupRun(mcPrm *mcPrm, cprm *cprm) error { var coolrate float64 cprm.coolme = true if mcPrm.fnlTmp > mcPrm.iniTmp { + const finalTempErr = "Final temp %g higher than initial temp %g" return fmt.Errorf(finalTempErr, mcPrm.fnlTmp, mcPrm.iniTmp) } nStep := float64(mcPrm.nStep) fnlTmp, iniTmp := float64(mcPrm.fnlTmp), float64(mcPrm.iniTmp) - if fnlTmp == 0 { + if fnlTmp == 0 { // avoid divide by zeroes fnlTmp = math.SmallestNonzeroFloat32 } coolrate = -1 / nStep coolrate *= math.Log(fnlTmp / iniTmp) cprm.coolMult = math.Exp(-coolrate) } - if mcPrm.fOutName != "" { + if mcPrm.fOutName != "" { // We are going to write to a file if mcPrm.fOutName, err = setSuffix(mcPrm.fOutName, ".csv"); err != nil { return err } if cprm.fOutRaw, err = os.Create(mcPrm.fOutName); err != nil { return err } + cprm.fOut = bufio.NewWriter(cprm.fOutRaw) + cprm.doTxtFval = true // other parts of code can see that we are writing to file } - cprm.fOut = bufio.NewWriter(cprm.fOutRaw) - if mcPrm.fPltName != "" { - var err error + + if mcPrm.fPltName != "" { // Then we are writing to a file if mcPrm.fPltName, err = setSuffix(mcPrm.fPltName, ".png"); err != nil { return fmt.Errorf("plot filename: %w", err) } - cprm.fplotme = true - n_alloc := mcPrm.nStep / 5 // About a fifth of the number of steps - cprm.plotnstp = make([]float64, 0, n_alloc) - cprm.plotf = make([]float64, 0, n_alloc) - if cprm.coolme { - cprm.plotTmprtr = make([]float64, 0, n_alloc) + if cprm.fplotWrt, err = os.Create(mcPrm.fPltName); err != nil { + return err } + } else { // Must be writing to a screen + var w bytes.Buffer // could be fancy, preallocate and use bytes.Newbuffer + cprm.fplotWrt = addClose(&w) // Fix this, effectively two copies + cprm.fplotiobuf = &w // of the pointer + } + n_alloc := mcPrm.nStep / 5 // About a fifth of the number of steps + cprm.plotnstp = make([]float64, 0, n_alloc) + cprm.plotf = make([]float64, 0, n_alloc) + if cprm.coolme { + cprm.plotTmprtr = make([]float64, 0, n_alloc) } + if mcPrm.xPltName != "" { - var err error if mcPrm.xPltName, err = setSuffix(mcPrm.xPltName, ".png"); err != nil { return fmt.Errorf("plot filename: %w", err) } cprm.xplotme = true - n_alloc := mcPrm.nStep / 5 n_dim := len(mcPrm.xIni) cprm.plotXtrj = make([]float32, 0, int(n_alloc)*n_dim) } - if err != isNotSane(mcPrm) { + if err = isNotSane(mcPrm); err != nil { return err } return nil } -// newx gets a candidate x slice. We have n dimensions, so a candidate -// move is a slice of length n. -/* -func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) { +// altnewx is not used at the moment, but I will build a switch for it. +// It is like newx, but moves all n dimensions a bit. +func alt_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 } -} */ +} + // newx will move just one coordinate at a time func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) { var iDim int @@ -139,7 +154,7 @@ func newx(xold []float32, xT []float32, rand *rand.Rand, xDlta float32) { xT[iDim] = xold[iDim] + t } -// printfVal is just 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. func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float64) { fmt.Fprintf(fOut, "%d,%.4g,%.5g", n, tmprtr, fOld) @@ -149,20 +164,20 @@ func printfVal(fOut io.Writer, x []float32, n uint32, tmprtr float64, fOld float fmt.Fprintln(fOut) } -// saveStep is called when we accept a change. It then writes or saves for +// saveStep is called when we accept a change. It writes or saves for // later plotting. func saveStep(cprm *cprm, n uint32, tmprtr float64, x []float32, fTrial float64) { - if cprm.fplotme || cprm.xplotme { + if cprm.fplotWrt != nil || cprm.xplotme { cprm.plotnstp = append(cprm.plotnstp, float64(n)) } - if cprm.fplotme { // Function values + if cprm.fplotWrt != nil { // 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...) } - if cprm.fOut != nil { + if cprm.doTxtFval { printfVal(cprm.fOut, x, n, tmprtr, fTrial) } } @@ -170,7 +185,6 @@ 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. func nRunAdj(mcPrm *mcPrm, nstep uint32, runAcc float64, xDlta float32) float32 { const step = "step" - if runAcc < accRateIdeal-0.01 { // acceptance rate too low xDlta *= 0.9 if mcPrm.verbose { @@ -184,6 +198,7 @@ func nRunAdj(mcPrm *mcPrm, nstep uint32, runAcc float64, xDlta float32) float32 } return xDlta } +func breaker() {} // doRun does a Monte Carlo run. Although single precision is fine for the // coordinates and function, we use double precision for the temperature. @@ -194,11 +209,15 @@ func doRun(mcPrm *mcPrm) error { if err := setupRun(mcPrm, &cprm); err != nil { return err } - if cprm.fOut != nil { // The text file documenting the run + if cprm.doTxtFval { // The text file documenting the run defer cprm.fOutRaw.Close() defer cprm.fOut.Flush() } + if cprm.fplotWrt != nil { + defer cprm.fplotWrt.Close() + } + var nAcc int // Counter, number of accepted moves x := make([]float32, len(mcPrm.xIni)) // current position xT := make([]float32, len(mcPrm.xIni)) // trial position @@ -244,14 +263,19 @@ func doRun(mcPrm *mcPrm) error { } } - // On plots, we want the last step, even if nothing changed. Print me. Fix. + // On plots, we want the last step, even if nothing changed. if fTrial != fOld { // last move was not accepted, so we have to add last step saveStep(&cprm, mcPrm.nStep, tmprtr, x, fOld) } defer fmt.Println("n accepted:", nAcc, "of", mcPrm.nStep+1) - if err := plotfWrt(&cprm, mcPrm.fPltName); err != nil { + if err := plotfWrt(&cprm); err != nil { return err } + + if cprm.fplotiobuf != nil { + fmt.Println("len", cprm.fplotiobuf.Len()) + scrnplt(cprm.fplotiobuf.Bytes()) + } if err := plotxWrt(&cprm, mcPrm.xPltName, len(mcPrm.xIni)); err != nil { return err } diff --git a/mc_work/mc_work_test.go b/mc_work/mc_work_test.go index 0cf25cf6649446f9630f864341ea870bc1f7cede..603329aad2b51e97e312a2e6cdee807185fceff3 100644 --- a/mc_work/mc_work_test.go +++ b/mc_work/mc_work_test.go @@ -87,6 +87,8 @@ func addOutNames(s gentest) string { ret += "\nfPltName" + " " + addTestPath(s.basename) + "_fval" return ret + "\n" } + + func Test1(t *testing.T) { for _, s := range set1 { instring := addOutNames(s) @@ -96,6 +98,15 @@ func Test1(t *testing.T) { } } +func Test2(t *testing.T) { + for _, s := range set1 { + if err := realmain(strings.NewReader(s.params)); err != nil { + t.Fatal("set1 test2 fail with \n", err, "\nInput:", s) + } + } +} + + func TestSetSuffix(t *testing.T) { var tdata = []struct { in, suffix, want string diff --git a/mc_work/plot.go b/mc_work/plot.go index 4dc9d3cc57f46103f71e09dbcb28a18e9019acdf..c3cb773b9124e2d7b27207b0ee479dc8a151ab4c 100644 --- a/mc_work/plot.go +++ b/mc_work/plot.go @@ -62,10 +62,9 @@ type range2 struct { chart.ContinuousRange } -// GetTicks is of the form wanted by go-chart to return ticks. It has to be -// a method on a range, but then you have to define your own kind of range. -// That is done by defining range2. We don't actually use any of the -// arguments that go-charts offers us. +// GetTicks is called by go-chart. It has to be a method that acts on a range. +// This means we define a range2 type and define this method on range2. We +// do not actually use the arguments that go-charts offers (style, formatter, ..) func (rng *range2) GetTicks(r chart.Renderer, cs chart.Style, vf chart.ValueFormatter) []chart.Tick { tmp := []float64{rng.Min, rng.Max} if a, err := axticks.Tickpos(tmp); err != nil { @@ -79,9 +78,9 @@ func (rng *range2) GetTicks(r chart.Renderer, cs chart.Style, vf chart.ValueForm } // plotfWrt writes out a plot of function values to the given -// filename -func plotfWrt(cprm *cprm, fname string) error { - if !cprm.fplotme { +// io.Writer. It used to ask for a string. +func plotfWrt(cprm *cprm) error { + if cprm.fplotWrt == nil { return nil } xdata := cprm.plotnstp // We just unpack for readability @@ -143,12 +142,8 @@ func plotfWrt(cprm *cprm, fname string) error { FillColor: drawing.ColorTransparent, }, } - fPlt, err := os.Create(fname) - if err != nil { - return err - } - defer fPlt.Close() - if err := graph.Render(chart.PNG, fPlt); err != nil { + + if err := graph.Render(chart.PNG, cprm.fplotWrt); err != nil { return fmt.Errorf("Render: %w", err) } diff --git a/mc_work/scrnplt.go b/mc_work/scrnplt.go new file mode 100644 index 0000000000000000000000000000000000000000..ca3f83323260260fe796c348e11f1bdf38b10b59 --- /dev/null +++ b/mc_work/scrnplt.go @@ -0,0 +1,14 @@ +// 25 Jan 2020 +// Given a buffer or two with a plot picture, send it to the screen + +// I think this might be better in its own package +package mc_work + +import ( + + "fmt" +) + +func scrnplt (b []byte) { + fmt.Println ("scrnplt says hello, buf size", len(b)) +}