go: implement RandomSearch (wip)
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
surtur 2022-06-17 01:54:30 +02:00
parent 3d00f09914
commit b3787da640
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D
6 changed files with 128 additions and 6 deletions

@ -5,7 +5,11 @@ package algo
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"git.dotya.ml/wanderer/math-optim/bench"
"gonum.org/v1/gonum/stat/distuv"
) )
func getRandomSearchLogPrefix() string { func getRandomSearchLogPrefix() string {
@ -21,3 +25,92 @@ func printRandomSearch(input string) error {
return err return err
} }
func genValsRandomSearch(dimens uint, vals []float64, uniform *distuv.Uniform) {
for i := uint(0); i < dimens; i++ {
// using Uniform.Rand from gonum's stat/distuv package.
// https://pkg.go.dev/gonum.org/v1/gonum/stat/distuv#Uniform.Rand
// boundaries are already set at this point.
vals[i] = uniform.Rand()
}
}
// singleRandomSearch performs a single iteration of the 'RandomSearch' algorithm.
// it takes a couple of arguments:
// * dimens uint: number of dimensions of the objective function
// * f string: name of the bench func to optimise (see bench/functions)
// * min/max float64: the upper/lower limit of the uniform distribution span,
// which is relevant to the objective function.
// nolint
func singleRandomSearch(dimens uint, f string, min, max float64) ([]float64, float64) {
var vals []float64
var res float64
// create a continuous uniform distribution representation within min/max bounds
uniformDist := distuv.Uniform{Min: min, Max: max}
genValsRandomSearch(dimens, vals, &uniformDist)
// result of the benchmarking function computation over vals
switch f {
// Schwefel
case bench.Functions[0]:
res = bench.Schwefel(vals)
// "DeJong1st"
case bench.Functions[1]:
res = bench.DeJong1st(vals)
// "DeJong2nd"
case bench.Functions[2]:
res = bench.DeJong2nd(vals)
}
return vals, res
}
func RandomSearch(fes uint) {
if fes == 0 {
log.Fatalln(" random search: fes set to 0, bailing")
}
var valsSchwefel []Values
var valsDeJong1st []Values
var valsDeJong2nd []Values
var resultsSchwefel Values
var resultsDeJong1st Values
var resultsDeJong2nd Values
// iterations needed to establish a minimal viable statistical baseline
minIters := 30
for _, dimens := range bench.Dimensions {
for j := 0; j < minIters; j++ {
// run Schwefel.
v, r := singleRandomSearch(dimens+1, "Schwefel", bench.SchwefelParams.Min(), bench.SchwefelParams.Max())
valsSchwefel = append(valsSchwefel, v)
resultsSchwefel = append(resultsSchwefel, r)
// run De Jong 1st.
vDJ1, rDJ1 := singleRandomSearch(dimens+1, "DeJong1st", bench.DeJong1Params.Min(), bench.DeJong1Params.Max())
valsDeJong1st = append(valsDeJong1st, vDJ1)
resultsDeJong1st = append(resultsDeJong1st, rDJ1)
// run De Jong 2nd.
vDJ2, rDJ2 := singleRandomSearch(dimens+1, "DeJong2nd", bench.DeJong2Params.Min(), bench.DeJong2Params.Max())
valsDeJong2nd = append(valsDeJong2nd, vDJ2)
resultsDeJong2nd = append(resultsDeJong2nd, rDJ2)
}
}
fmt.Fprintln(os.Stderr, "vals schw:", valsSchwefel)
fmt.Fprintln(os.Stderr, "vals dj1", valsDeJong1st)
fmt.Fprintln(os.Stderr, "vals dj2", valsDeJong2nd)
fmt.Fprintln(os.Stderr, "res schw:", resultsSchwefel)
fmt.Fprintln(os.Stderr, "res dj1", resultsDeJong1st)
fmt.Fprintln(os.Stderr, "res dj2", resultsDeJong2nd)
}

@ -16,7 +16,7 @@ const (
var ( var (
// Dimensions to compute for (spatial complexity..?). // Dimensions to compute for (spatial complexity..?).
Dimensions = []int{5, 10, 20} Dimensions = []uint{5, 10, 20}
SchwefelParams = funcParams{min: -500.0, max: 500.0} SchwefelParams = funcParams{min: -500.0, max: 500.0}
DeJong1Params = funcParams{min: -5.0, max: 5.0} DeJong1Params = funcParams{min: -5.0, max: 5.0}
@ -24,11 +24,11 @@ var (
) )
// Min returns the non-exported "min" field of a funcParams struct. // Min returns the non-exported "min" field of a funcParams struct.
func (*funcParams) Min(self *funcParams) float64 { func (f *funcParams) Min() float64 {
return self.max return f.min
} }
// Max returns the non-exported 'max' field of a funcParams struct. // Max returns the non-exported 'max' field of a funcParams struct.
func (*funcParams) Max(self *funcParams) float64 { func (f *funcParams) Max() float64 {
return self.max return f.max
} }

@ -5,6 +5,8 @@ package bench
import "math" import "math"
var Functions = []string{"Schwefel", "De Jong 1st", "De Jong 2nd"}
// Schwefel computes a value of the Schwefel function for x. // Schwefel computes a value of the Schwefel function for x.
func Schwefel(x []float64) float64 { func Schwefel(x []float64) float64 {
var res float64 var res float64

@ -80,7 +80,7 @@
modSha256 = lib.fakeSha256; modSha256 = lib.fakeSha256;
# dont't forget to update vendorSha256 whenever go.mod or go.sum change # dont't forget to update vendorSha256 whenever go.mod or go.sum change
vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo="; vendorSha256 = "sha256-NpZWn2yASg7HXr4sG849QSgUetouj8qjwS+p5jhlum0=";
# In 'nix develop', we don't need a copy of the source tree # In 'nix develop', we don't need a copy of the source tree
# in the Nix store. # in the Nix store.

4
go.mod

@ -1,3 +1,7 @@
module git.dotya.ml/wanderer/math-optim module git.dotya.ml/wanderer/math-optim
go 1.18 go 1.18
require gonum.org/v1/gonum v0.11.0
require golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 // indirect

23
go.sum

@ -0,0 +1,23 @@
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
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/sync v0.0.0-20190423024810-112230192c58/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E=
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=