gonum.org/v1/gonum@v0.14.0/optimize/functions/vlse.go (about)

     1  // Copyright ©2017 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 functions
     6  
     7  import "math"
     8  
     9  // This file implements functions from the Virtual Library of Simulation Experiments.
    10  //  https://www.sfu.ca/~ssurjano/optimization.html
    11  // In many cases gradients and Hessians have been added. In some cases, these
    12  // are not defined at certain points or manifolds. The gradient in these locations
    13  // has been set to 0.
    14  
    15  // Ackley implements the Ackley function, a function of arbitrary dimension that
    16  // has many local minima. It has a single global minimum of 0 at 0. Its typical
    17  // domain is the hypercube of [-32.768, 32.768]^d.
    18  //
    19  //	f(x) = -20 * exp(-0.2 sqrt(1/d sum_i x_i^2)) - exp(1/d sum_i cos(2π x_i)) + 20 + exp(1)
    20  //
    21  // where d is the input dimension.
    22  //
    23  // Reference:
    24  //
    25  //	https://www.sfu.ca/~ssurjano/ackley.html (obtained June 2017)
    26  type Ackley struct{}
    27  
    28  func (Ackley) Func(x []float64) float64 {
    29  	var ss, sc float64
    30  	for _, v := range x {
    31  		ss += v * v
    32  		sc += math.Cos(2 * math.Pi * v)
    33  	}
    34  	id := 1 / float64(len(x))
    35  	return -20*math.Exp(-0.2*math.Sqrt(id*ss)) - math.Exp(id*sc) + 20 + math.E
    36  }
    37  
    38  // Bukin6 implements Bukin's 6th function. The function is two-dimensional, with
    39  // the typical domain as x_0 ∈ [-15, -5], x_1 ∈ [-3, 3]. The function has a unique
    40  // global minimum at [-10, 1], and many local minima.
    41  //
    42  //	f(x) = 100 * sqrt(|x_1 - 0.01*x_0^2|) + 0.01*|x_0+10|
    43  //
    44  // Reference:
    45  //
    46  //	https://www.sfu.ca/~ssurjano/bukin6.html (obtained June 2017)
    47  type Bukin6 struct{}
    48  
    49  func (Bukin6) Func(x []float64) float64 {
    50  	if len(x) != 2 {
    51  		panic(badInputDim)
    52  	}
    53  	return 100*math.Sqrt(math.Abs(x[1]-0.01*x[0]*x[0])) + 0.01*math.Abs(x[0]+10)
    54  }
    55  
    56  // CamelThree implements the three-hump camel function, a two-dimensional function
    57  // with three local minima, one of which is global.
    58  // The function is given by
    59  //
    60  //	f(x) = 2*x_0^2 - 1.05*x_0^4 + x_0^6/6 + x_0*x_1 + x_1^2
    61  //
    62  // with the global minimum at
    63  //
    64  //	x^* = (0, 0)
    65  //	f(x^*) = 0
    66  //
    67  // The typical domain is x_i ∈ [-5, 5] for all i.
    68  // Reference:
    69  //
    70  //	https://www.sfu.ca/~ssurjano/camel3.html (obtained December 2017)
    71  type CamelThree struct{}
    72  
    73  func (c CamelThree) Func(x []float64) float64 {
    74  	if len(x) != 2 {
    75  		panic("camelthree: dimension must be 2")
    76  	}
    77  	x0 := x[0]
    78  	x1 := x[1]
    79  	x02 := x0 * x0
    80  	x04 := x02 * x02
    81  	return 2*x02 - 1.05*x04 + x04*x02/6 + x0*x1 + x1*x1
    82  }
    83  
    84  // CamelSix implements the six-hump camel function, a two-dimensional function.
    85  // with six local minima, two of which are global.
    86  // The function is given by
    87  //
    88  //	f(x) = (4 - 2.1*x_0^2 + x_0^4/3)*x_0^2 + x_0*x_1 + (-4 + 4*x_1^2)*x_1^2
    89  //
    90  // with the global minima at
    91  //
    92  //	x^* = (0.0898, -0.7126), (-0.0898, 0.7126)
    93  //	f(x^*) = -1.0316
    94  //
    95  // The typical domain is x_0 ∈ [-3, 3], x_1 ∈ [-2, 2].
    96  // Reference:
    97  //
    98  //	https://www.sfu.ca/~ssurjano/camel6.html (obtained December 2017)
    99  type CamelSix struct{}
   100  
   101  func (c CamelSix) Func(x []float64) float64 {
   102  	if len(x) != 2 {
   103  		panic("camelsix: dimension must be 2")
   104  	}
   105  	x0 := x[0]
   106  	x1 := x[1]
   107  	x02 := x0 * x0
   108  	x12 := x1 * x1
   109  	return (4-2.1*x02+x02*x02/3)*x02 + x0*x1 + (-4+4*x12)*x12
   110  }
   111  
   112  // CrossInTray implements the cross-in-tray function. The cross-in-tray function
   113  // is a two-dimensional function with many local minima, and four global minima
   114  // at (±1.3491, ±1.3491). The function is typically evaluated in the square
   115  // [-10,10]^2.
   116  //
   117  //	f(x) = -0.001(|sin(x_0)sin(x_1)exp(|100-sqrt((x_0^2+x_1^2)/π)|)|+1)^0.1
   118  //
   119  // Reference:
   120  //
   121  //	https://www.sfu.ca/~ssurjano/crossit.html (obtained June 2017)
   122  type CrossInTray struct{}
   123  
   124  func (CrossInTray) Func(x []float64) float64 {
   125  	if len(x) != 2 {
   126  		panic(badInputDim)
   127  	}
   128  	x0 := x[0]
   129  	x1 := x[1]
   130  	exp := math.Abs(100 - math.Sqrt((x0*x0+x1*x1)/math.Pi))
   131  	return -0.0001 * math.Pow(math.Abs(math.Sin(x0)*math.Sin(x1)*math.Exp(exp))+1, 0.1)
   132  }
   133  
   134  // DixonPrice implements the DixonPrice function, a function of arbitrary dimension
   135  // Its typical domain is the hypercube of [-10, 10]^d.
   136  // The function is given by
   137  //
   138  //	f(x) = (x_0-1)^2 + \sum_{i=1}^{d-1} (i+1) * (2*x_i^2-x_{i-1})^2
   139  //
   140  // where d is the input dimension. There is a single global minimum, which has
   141  // a location and value of
   142  //
   143  //	x_i^* = 2^{-(2^{i+1}-2)/(2^{i+1})} for i = 0, ..., d-1.
   144  //	f(x^*) = 0
   145  //
   146  // Reference:
   147  //
   148  //	https://www.sfu.ca/~ssurjano/dixonpr.html (obtained June 2017)
   149  type DixonPrice struct{}
   150  
   151  func (DixonPrice) Func(x []float64) float64 {
   152  	xp := x[0]
   153  	v := (xp - 1) * (xp - 1)
   154  	for i := 1; i < len(x); i++ {
   155  		xn := x[i]
   156  		tmp := (2*xn*xn - xp)
   157  		v += float64(i+1) * tmp * tmp
   158  		xp = xn
   159  	}
   160  	return v
   161  }
   162  
   163  // DropWave implements the drop-wave function, a two-dimensional function with
   164  // many local minima and one global minimum at 0. The function is typically evaluated
   165  // in the square [-5.12, 5.12]^2.
   166  //
   167  //	f(x) = - (1+cos(12*sqrt(x0^2+x1^2))) / (0.5*(x0^2+x1^2)+2)
   168  //
   169  // Reference:
   170  //
   171  //	https://www.sfu.ca/~ssurjano/drop.html (obtained June 2017)
   172  type DropWave struct{}
   173  
   174  func (DropWave) Func(x []float64) float64 {
   175  	if len(x) != 2 {
   176  		panic(badInputDim)
   177  	}
   178  	x0 := x[0]
   179  	x1 := x[1]
   180  	num := 1 + math.Cos(12*math.Sqrt(x0*x0+x1*x1))
   181  	den := 0.5*(x0*x0+x1*x1) + 2
   182  	return -num / den
   183  }
   184  
   185  // Eggholder implements the Eggholder function, a two-dimensional function with
   186  // many local minima and one global minimum at [512, 404.2319]. The function
   187  // is typically evaluated in the square [-512, 512]^2.
   188  //
   189  //	f(x) = -(x_1+47)*sin(sqrt(|x_1+x_0/2+47|))-x_1*sin(sqrt(|x_0-(x_1+47)|))
   190  //
   191  // Reference:
   192  //
   193  //	https://www.sfu.ca/~ssurjano/egg.html (obtained June 2017)
   194  type Eggholder struct{}
   195  
   196  func (Eggholder) Func(x []float64) float64 {
   197  	if len(x) != 2 {
   198  		panic(badInputDim)
   199  	}
   200  	x0 := x[0]
   201  	x1 := x[1]
   202  	return -(x1+47)*math.Sin(math.Sqrt(math.Abs(x1+x0/2+47))) -
   203  		x0*math.Sin(math.Sqrt(math.Abs(x0-x1-47)))
   204  }
   205  
   206  // GramacyLee implements the Gramacy-Lee function, a one-dimensional function
   207  // with many local minima. The function is typically evaluated on the domain [0.5, 2.5].
   208  //
   209  //	f(x) = sin(10πx)/(2x) + (x-1)^4
   210  //
   211  // Reference:
   212  //
   213  //	https://www.sfu.ca/~ssurjano/grlee12.html (obtained June 2017)
   214  type GramacyLee struct{}
   215  
   216  func (GramacyLee) Func(x []float64) float64 {
   217  	if len(x) != 1 {
   218  		panic(badInputDim)
   219  	}
   220  	x0 := x[0]
   221  	return math.Sin(10*math.Pi*x0)/(2*x0) + math.Pow(x0-1, 4)
   222  }
   223  
   224  // Griewank implements the Griewank function, a function of arbitrary dimension that
   225  // has many local minima. It has a single global minimum of 0 at 0. Its typical
   226  // domain is the hypercube of [-600, 600]^d.
   227  //
   228  //	f(x) = \sum_i x_i^2/4000 - \prod_i cos(x_i/sqrt(i)) + 1
   229  //
   230  // where d is the input dimension.
   231  //
   232  // Reference:
   233  //
   234  //	https://www.sfu.ca/~ssurjano/griewank.html (obtained June 2017)
   235  type Griewank struct{}
   236  
   237  func (Griewank) Func(x []float64) float64 {
   238  	var ss float64
   239  	pc := 1.0
   240  	for i, v := range x {
   241  		ss += v * v
   242  		pc *= math.Cos(v / math.Sqrt(float64(i+1)))
   243  	}
   244  	return ss/4000 - pc + 1
   245  }
   246  
   247  // HolderTable implements the Holder table function. The Holder table function
   248  // is a two-dimensional function with many local minima, and four global minima
   249  // at (±8.05502, ±9.66459). The function is typically evaluated in the square [-10,10]^2.
   250  //
   251  //	f(x) = -|sin(x_0)cos(x1)exp(|1-sqrt(x_0^2+x1^2)/π|)|
   252  //
   253  // Reference:
   254  //
   255  //	https://www.sfu.ca/~ssurjano/holder.html (obtained June 2017)
   256  type HolderTable struct{}
   257  
   258  func (HolderTable) Func(x []float64) float64 {
   259  	if len(x) != 2 {
   260  		panic(badInputDim)
   261  	}
   262  	x0 := x[0]
   263  	x1 := x[1]
   264  	return -math.Abs(math.Sin(x0) * math.Cos(x1) * math.Exp(math.Abs(1-math.Sqrt(x0*x0+x1*x1)/math.Pi)))
   265  }
   266  
   267  // Langermann2 implements the two-dimensional version of the Langermann function.
   268  // The Langermann function has many local minima. The function is typically
   269  // evaluated in the square [0,10]^2.
   270  //
   271  //	f(x) = \sum_1^5 c_i exp(-(1/π)\sum_{j=1}^2(x_j-A_{ij})^2) * cos(π\sum_{j=1}^2 (x_j - A_{ij})^2)
   272  //	c = [5]float64{1,2,5,2,3}
   273  //	A = [5][2]float64{{3,5},{5,2},{2,1},{1,4},{7,9}}
   274  //
   275  // Reference:
   276  //
   277  //	https://www.sfu.ca/~ssurjano/langer.html (obtained June 2017)
   278  type Langermann2 struct{}
   279  
   280  func (Langermann2) Func(x []float64) float64 {
   281  	if len(x) != 2 {
   282  		panic(badInputDim)
   283  	}
   284  	var (
   285  		c = [5]float64{1, 2, 5, 2, 3}
   286  		A = [5][2]float64{{3, 5}, {5, 2}, {2, 1}, {1, 4}, {7, 9}}
   287  	)
   288  	var f float64
   289  	for i, cv := range c {
   290  		var ss float64
   291  		for j, av := range A[i] {
   292  			xja := x[j] - av
   293  			ss += xja * xja
   294  		}
   295  		f += cv * math.Exp(-(1/math.Pi)*ss) * math.Cos(math.Pi*ss)
   296  	}
   297  	return f
   298  }
   299  
   300  // Levy implements the Levy function, a function of arbitrary dimension that
   301  // has many local minima. It has a single global minimum of 0 at 1. Its typical
   302  // domain is the hypercube of [-10, 10]^d.
   303  //
   304  //	f(x) = sin^2(π*w_0) + \sum_{i=0}^{d-2}(w_i-1)^2*[1+10sin^2(π*w_i+1)] +
   305  //	          (w_{d-1}-1)^2*[1+sin^2(2π*w_{d-1})]
   306  //	 w_i = 1 + (x_i-1)/4
   307  //
   308  // where d is the input dimension.
   309  //
   310  // Reference:
   311  //
   312  //	https://www.sfu.ca/~ssurjano/levy.html (obtained June 2017)
   313  type Levy struct{}
   314  
   315  func (Levy) Func(x []float64) float64 {
   316  	w1 := 1 + (x[0]-1)/4
   317  	s1 := math.Sin(math.Pi * w1)
   318  	sum := s1 * s1
   319  	for i := 0; i < len(x)-1; i++ {
   320  		wi := 1 + (x[i]-1)/4
   321  		s := math.Sin(math.Pi*wi + 1)
   322  		sum += (wi - 1) * (wi - 1) * (1 + 10*s*s)
   323  	}
   324  	wd := 1 + (x[len(x)-1]-1)/4
   325  	sd := math.Sin(2 * math.Pi * wd)
   326  	return sum + (wd-1)*(wd-1)*(1+sd*sd)
   327  }
   328  
   329  // Levy13 implements the Levy-13 function, a two-dimensional function
   330  // with many local minima. It has a single global minimum of 0 at 1. Its typical
   331  // domain is the square [-10, 10]^2.
   332  //
   333  //	f(x) = sin^2(3π*x_0) + (x_0-1)^2*[1+sin^2(3π*x_1)] + (x_1-1)^2*[1+sin^2(2π*x_1)]
   334  //
   335  // Reference:
   336  //
   337  //	https://www.sfu.ca/~ssurjano/levy13.html (obtained June 2017)
   338  type Levy13 struct{}
   339  
   340  func (Levy13) Func(x []float64) float64 {
   341  	if len(x) != 2 {
   342  		panic(badInputDim)
   343  	}
   344  	x0 := x[0]
   345  	x1 := x[1]
   346  	s0 := math.Sin(3 * math.Pi * x0)
   347  	s1 := math.Sin(3 * math.Pi * x1)
   348  	s2 := math.Sin(2 * math.Pi * x1)
   349  	return s0*s0 + (x0-1)*(x0-1)*(1+s1*s1) + (x1-1)*(x1-1)*(1+s2*s2)
   350  }
   351  
   352  // Rastrigin implements the Rastrigen function, a function of arbitrary dimension
   353  // that has many local minima. It has a single global minimum of 0 at 0. Its typical
   354  // domain is the hypercube of [-5.12, 5.12]^d.
   355  //
   356  //	f(x) = 10d + \sum_i [x_i^2 - 10cos(2π*x_i)]
   357  //
   358  // where d is the input dimension.
   359  //
   360  // Reference:
   361  //
   362  //	https://www.sfu.ca/~ssurjano/rastr.html (obtained June 2017)
   363  type Rastrigin struct{}
   364  
   365  func (Rastrigin) Func(x []float64) float64 {
   366  	sum := 10 * float64(len(x))
   367  	for _, v := range x {
   368  		sum += v*v - 10*math.Cos(2*math.Pi*v)
   369  	}
   370  	return sum
   371  }
   372  
   373  // Schaffer2 implements the second Schaffer function, a two-dimensional function
   374  // with many local minima. It has a single global minimum of 0 at 0. Its typical
   375  // domain is the square [-100, 100]^2.
   376  //
   377  //	f(x) = 0.5 + (sin^2(x_0^2-x_1^2)-0.5) / (1+0.001*(x_0^2+x_1^2))^2
   378  //
   379  // Reference:
   380  //
   381  //	https://www.sfu.ca/~ssurjano/schaffer2.html (obtained June 2017)
   382  type Schaffer2 struct{}
   383  
   384  func (Schaffer2) Func(x []float64) float64 {
   385  	if len(x) != 2 {
   386  		panic(badInputDim)
   387  	}
   388  	x0 := x[0]
   389  	x1 := x[1]
   390  	s := math.Sin(x0*x0 - x1*x1)
   391  	den := 1 + 0.001*(x0*x0+x1*x1)
   392  	return 0.5 + (s*s-0.5)/(den*den)
   393  }
   394  
   395  // Schaffer4 implements the fourth Schaffer function, a two-dimensional function
   396  // with many local minima. Its typical domain is the square [-100, 100]^2.
   397  //
   398  //	f(x) = 0.5 + (cos(sin(|x_0^2-x_1^2|))-0.5) / (1+0.001*(x_0^2+x_1^2))^2
   399  //
   400  // Reference:
   401  //
   402  //	https://www.sfu.ca/~ssurjano/schaffer4.html (obtained June 2017)
   403  type Schaffer4 struct{}
   404  
   405  func (Schaffer4) Func(x []float64) float64 {
   406  	if len(x) != 2 {
   407  		panic(badInputDim)
   408  	}
   409  	x0 := x[0]
   410  	x1 := x[1]
   411  	den := 1 + 0.001*(x0*x0+x1*x1)
   412  	return 0.5 + (math.Cos(math.Sin(math.Abs(x0*x0-x1*x1)))-0.5)/(den*den)
   413  }
   414  
   415  // Schwefel implements the Schwefel function, a function of arbitrary dimension
   416  // that has many local minima. Its typical domain is the hypercube of [-500, 500]^d.
   417  //
   418  //	f(x) = 418.9829*d - \sum_i x_i*sin(sqrt(|x_i|))
   419  //
   420  // where d is the input dimension.
   421  //
   422  // Reference:
   423  //
   424  //	https://www.sfu.ca/~ssurjano/schwef.html (obtained June 2017)
   425  type Schwefel struct{}
   426  
   427  func (Schwefel) Func(x []float64) float64 {
   428  	var sum float64
   429  	for _, v := range x {
   430  		sum += v * math.Sin(math.Sqrt(math.Abs(v)))
   431  	}
   432  	return 418.9829*float64(len(x)) - sum
   433  }
   434  
   435  // Shubert implements the Shubert function, a two-dimensional function
   436  // with many local minima and many global minima. Its typical domain is the
   437  // square [-10, 10]^2.
   438  //
   439  //	f(x) = (sum_{i=1}^5 i cos((i+1)*x_0+i)) * (\sum_{i=1}^5 i cos((i+1)*x_1+i))
   440  //
   441  // Reference:
   442  //
   443  //	https://www.sfu.ca/~ssurjano/shubert.html (obtained June 2017)
   444  type Shubert struct{}
   445  
   446  func (Shubert) Func(x []float64) float64 {
   447  	if len(x) != 2 {
   448  		panic(badInputDim)
   449  	}
   450  	x0 := x[0]
   451  	x1 := x[1]
   452  	var s0, s1 float64
   453  	for i := 1.0; i <= 5.0; i++ {
   454  		s0 += i * math.Cos((i+1)*x0+i)
   455  		s1 += i * math.Cos((i+1)*x1+i)
   456  	}
   457  	return s0 * s1
   458  }