github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/neldermead/neldermead_test.go (about)

     1  package neldermead_test
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  
     7  	"github.com/influxdata/influxdb/v2/influxql/query/neldermead"
     8  )
     9  
    10  func round(num float64, precision float64) float64 {
    11  	rnum := num * math.Pow(10, precision)
    12  	var tnum float64
    13  	if rnum < 0 {
    14  		tnum = math.Floor(rnum - 0.5)
    15  	} else {
    16  		tnum = math.Floor(rnum + 0.5)
    17  	}
    18  	rnum = tnum / math.Pow(10, precision)
    19  	return rnum
    20  }
    21  
    22  func almostEqual(a, b, e float64) bool {
    23  	return math.Abs(a-b) < e
    24  }
    25  
    26  func Test_Optimize(t *testing.T) {
    27  
    28  	constraints := func(x []float64) {
    29  		for i := range x {
    30  			x[i] = round(x[i], 5)
    31  		}
    32  	}
    33  	// 100*(b-a^2)^2 + (1-a)^2
    34  	//
    35  	// Obvious global minimum at (a,b) = (1,1)
    36  	//
    37  	// Useful visualization:
    38  	// https://www.wolframalpha.com/input/?i=minimize(100*(b-a%5E2)%5E2+%2B+(1-a)%5E2)
    39  	f := func(x []float64) float64 {
    40  		constraints(x)
    41  		// a = x[0]
    42  		// b = x[1]
    43  		return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0]) + (1.0-x[0])*(1.0-x[0])
    44  	}
    45  
    46  	start := []float64{-1.2, 1.0}
    47  
    48  	opt := neldermead.New()
    49  	epsilon := 1e-5
    50  	min, parameters := opt.Optimize(f, start, epsilon, 1)
    51  
    52  	if !almostEqual(min, 0, epsilon) {
    53  		t.Errorf("unexpected min: got %f exp 0", min)
    54  	}
    55  
    56  	if !almostEqual(parameters[0], 1, 1e-2) {
    57  		t.Errorf("unexpected parameters[0]: got %f exp 1", parameters[0])
    58  	}
    59  
    60  	if !almostEqual(parameters[1], 1, 1e-2) {
    61  		t.Errorf("unexpected parameters[1]: got %f exp 1", parameters[1])
    62  	}
    63  
    64  }