github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/optimize/termination.go (about)

     1  // Copyright ©2014 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package optimize
     6  
     7  import "errors"
     8  
     9  // Status represents the status of the optimization. Programs
    10  // should not rely on the underlying numeric value of the Status being constant.
    11  type Status int
    12  
    13  const (
    14  	NotTerminated Status = iota
    15  	Success
    16  	FunctionThreshold
    17  	FunctionConvergence
    18  	GradientThreshold
    19  	StepConvergence
    20  	FunctionNegativeInfinity
    21  	MethodConverge
    22  	Failure
    23  	IterationLimit
    24  	RuntimeLimit
    25  	FunctionEvaluationLimit
    26  	GradientEvaluationLimit
    27  	HessianEvaluationLimit
    28  )
    29  
    30  func (s Status) String() string {
    31  	return statuses[s].name
    32  }
    33  
    34  // Early returns true if the status indicates the optimization ended before a
    35  // minimum was found. As an example, if the maximum iterations was reached, a
    36  // minimum was not found, but if the gradient norm was reached then a minimum
    37  // was found.
    38  func (s Status) Early() bool {
    39  	return statuses[s].early
    40  }
    41  
    42  // Err returns the error associated with an early ending to the minimization. If
    43  // Early returns false, Err will return nil.
    44  func (s Status) Err() error {
    45  	return statuses[s].err
    46  }
    47  
    48  var statuses = []struct {
    49  	name  string
    50  	early bool
    51  	err   error
    52  }{
    53  	{
    54  		name: "NotTerminated",
    55  	},
    56  	{
    57  		name: "Success",
    58  	},
    59  	{
    60  		name: "FunctionThreshold",
    61  	},
    62  	{
    63  		name: "FunctionConvergence",
    64  	},
    65  	{
    66  		name: "GradientThreshold",
    67  	},
    68  	{
    69  		name: "StepConvergence",
    70  	},
    71  	{
    72  		name: "FunctionNegativeInfinity",
    73  	},
    74  	{
    75  		name: "MethodConverge",
    76  	},
    77  	{
    78  		name:  "Failure",
    79  		early: true,
    80  		err:   errors.New("optimize: termination ended in failure"),
    81  	},
    82  	{
    83  		name:  "IterationLimit",
    84  		early: true,
    85  		err:   errors.New("optimize: maximum number of major iterations reached"),
    86  	},
    87  	{
    88  		name:  "RuntimeLimit",
    89  		early: true,
    90  		err:   errors.New("optimize: maximum runtime reached"),
    91  	},
    92  	{
    93  		name:  "FunctionEvaluationLimit",
    94  		early: true,
    95  		err:   errors.New("optimize: maximum number of function evaluations reached"),
    96  	},
    97  	{
    98  		name:  "GradientEvaluationLimit",
    99  		early: true,
   100  		err:   errors.New("optimize: maximum number of gradient evaluations reached"),
   101  	},
   102  	{
   103  		name:  "HessianEvaluationLimit",
   104  		early: true,
   105  		err:   errors.New("optimize: maximum number of Hessian evaluations reached"),
   106  	},
   107  }
   108  
   109  // NewStatus returns a unique Status variable to represent a custom status.
   110  // NewStatus is intended to be called only during package initialization, and
   111  // calls to NewStatus are not thread safe.
   112  //
   113  // NewStatus takes in three arguments, the string that should be output from
   114  // Status.String, a boolean if the status indicates early optimization conclusion,
   115  // and the error to return from Err (if any).
   116  func NewStatus(name string, early bool, err error) Status {
   117  	statuses = append(statuses, struct {
   118  		name  string
   119  		early bool
   120  		err   error
   121  	}{name, early, err})
   122  	return Status(len(statuses) - 1)
   123  }