mirror of
https://github.com/gonum/gonum.git
synced 2025-10-04 14:52:57 +08:00
61 lines
1.3 KiB
Go
61 lines
1.3 KiB
Go
// 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
|
|
}
|