blob: e08fc4c6524a5ec2ebead557ae975013ff36bd8e [file] [log] [blame] [edit]
// Copyright ©2016 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package optimize
import (
"math"
"sync"
"gonum.org/v1/gonum/stat/distmv"
)
// GuessAndCheck is a global optimizer that evaluates the function at random
// locations. Not a good optimizer, but useful for comparison and debugging.
type GuessAndCheck struct {
Rander distmv.Rander
eval []bool
mux *sync.Mutex
bestF float64
bestX []float64
}
func (g *GuessAndCheck) Needs() struct{ Gradient, Hessian bool } {
return struct{ Gradient, Hessian bool }{false, false}
}
func (g *GuessAndCheck) Done() {
// No cleanup needed
}
func (g *GuessAndCheck) InitGlobal(dim, tasks int) int {
g.eval = make([]bool, tasks)
g.bestF = math.Inf(1)
g.bestX = resize(g.bestX, dim)
g.mux = &sync.Mutex{}
return tasks
}
func (g *GuessAndCheck) IterateGlobal(task int, loc *Location) (Operation, error) {
// Task is true if it contains a new function evaluation.
if g.eval[task] {
g.eval[task] = false
g.mux.Lock()
if loc.F < g.bestF {
g.bestF = loc.F
copy(g.bestX, loc.X)
} else {
loc.F = g.bestF
copy(loc.X, g.bestX)
}
g.mux.Unlock()
return MajorIteration, nil
}
g.eval[task] = true
g.Rander.Rand(loc.X)
return FuncEvaluation, nil
}