mirror of
				https://github.com/gonum/gonum.git
				synced 2025-11-01 02:52:49 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			82 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			1.9 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
 | |
| }
 | 
