Files
gonum/optimize/functionconvergence.go
Dan Kortschak 5f0141ca4c all: run gofmt and generate all packages
Changes made in dsp/fourier/internal/fftpack break the formatting used
there, so these are reverted. There will be complaints in CI.

[git-generate]
gofmt -w .
go generate gonum.org/v1/gonum/blas
go generate gonum.org/v1/gonum/blas/gonum
go generate gonum.org/v1/gonum/unit
go generate gonum.org/v1/gonum/unit/constant
go generate gonum.org/v1/gonum/graph/formats/dot
go generate gonum.org/v1/gonum/graph/formats/rdf
go generate gonum.org/v1/gonum/stat/card

git checkout -- dsp/fourier/internal/fftpack
2022-08-06 07:05:17 +09:30

86 lines
2.0 KiB
Go

// Copyright ©2015 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"
)
// Converger returns the convergence of the optimization based on
// locations found during optimization. Converger must not modify the value of
// the provided Location in any of the methods.
type Converger interface {
Init(dim int)
Converged(loc *Location) Status
}
var (
_ Converger = NeverTerminate{}
_ Converger = (*FunctionConverge)(nil)
)
// NeverTerminate implements Converger, always reporting NotTerminated.
type NeverTerminate struct{}
func (NeverTerminate) Init(dim int) {}
func (NeverTerminate) Converged(loc *Location) Status {
return NotTerminated
}
// FunctionConverge tests for insufficient improvement in the optimum value
// over the last iterations. A FunctionConvergence status is returned if
// there is no significant decrease for FunctionConverge.Iterations. A
// significant decrease is considered if
//
// f < f_best
//
// and
//
// f_best - f > FunctionConverge.Relative * maxabs(f, f_best) + FunctionConverge.Absolute
//
// If the decrease is significant, then the iteration counter is reset and
// f_best is updated.
//
// If FunctionConverge.Iterations == 0, it has no effect.
type FunctionConverge struct {
Absolute float64
Relative float64
Iterations int
first bool
best float64
iter int
}
func (fc *FunctionConverge) Init(dim int) {
fc.first = true
fc.best = 0
fc.iter = 0
}
func (fc *FunctionConverge) Converged(l *Location) Status {
f := l.F
if fc.first {
fc.best = f
fc.first = false
return NotTerminated
}
if fc.Iterations == 0 {
return NotTerminated
}
maxAbs := math.Max(math.Abs(f), math.Abs(fc.best))
if f < fc.best && fc.best-f > fc.Relative*maxAbs+fc.Absolute {
fc.best = f
fc.iter = 0
return NotTerminated
}
fc.iter++
if fc.iter < fc.Iterations {
return NotTerminated
}
return FunctionConvergence
}