math-optim/bench/cec2020/basicFunctions.go
leo e1fac11ec5
All checks were successful
continuous-integration/drone/push Build is passing
fix(cec2020): add Schwefel Modified's missing case
2023-02-22 12:52:14 +01:00

214 lines
4.7 KiB
Go

// Copyright 2023 wanderer <a_mirre at utb dot cz>
// SPDX-License-Identifier: GPL-3.0-or-later
package cec2020
import "math"
// Rastrigin calculates the value of the Rastrigin function for x.
func Rastrigin(x []float64) float64 {
var sum float64
for i := range x {
sum += math.Pow(x[i], 2) - (10 * math.Cos(2*math.Pi*x[i])) + 10
}
return sum
}
// HighConditionedElliptic is the "High Conditioned Elliptic Function" of
// CEC2020.
func HighConditionedElliptic(x []float64) float64 {
var sum float64
// float64 version of the length of x.
fnx := float64(len(x))
for i := range x {
sum += math.Pow(math.Pow(10, 6), float64(i-1)/(fnx-1)) * math.Pow(x[i], 2)
}
return sum
}
// HGBat is the "HGBat Function" of CEC2020.
func HGBat(x []float64) float64 {
var sum1 float64
var sum2 float64
for i := range x {
sum1 += math.Pow(x[i], 2)
sum2 += x[i]
}
// float64 version of the length of x.
fnx := float64(len(x))
return math.Pow(math.Abs(math.Pow(sum1, 2)-math.Pow(sum2, 2)), 0.5) + (((0.5 * sum1) + sum2) / (fnx + 0.5))
}
// Rosenbrock is the "Rosenbrock's Function" of CEC2020.
// ref: https://infinity77.net/global_optimization/test_functions_nd_R.html#go_benchmark.Rosenbrock
func Rosenbrock(x []float64) float64 {
var sum float64
for i := 0; i < len(x)-1; i++ {
sum += 100*(math.Pow(math.Pow(x[i], 2)-x[i+1], 2)) + math.Pow(x[i]-1, 2)
}
return sum
}
// Griewank is the "Griewank's Function" of CEC2020.
// ref: https://www.sfu.ca/~ssurjano/griewank.html
func Griewank(x []float64) float64 {
var sum float64
var prod float64
for i := range x {
sum += math.Pow(x[i], 2) / 4000
// use i+1 in sqrt so that we don't get Nan.
prod *= math.Cos(x[i] / math.Sqrt(float64(i+1)))
}
return sum - prod + 1
}
// Ackley is the "Ackley's Function" of CEC2020.
func Ackley(x []float64) float64 {
var sum1 float64
var sum2 float64
for i := range x {
sum1 += math.Pow(x[i], 2)
sum2 += math.Cos(2 * math.Pi * x[i])
}
// float64 version of the length of x.
fnx := float64(len(x))
return -20*math.Exp(-0.2*math.Sqrt((1/fnx)*sum1)) - math.Exp((1/fnx)*sum2) + 20 + math.E
}
// Happycat is the "Happycat Function" of CEC2020.
func Happycat(x []float64) float64 {
var sum1 float64
var sum2 float64
var sum3 float64
// float64 version of the length of x.
fnx := float64(len(x))
for i := range x {
xipow2 := math.Pow(x[i], 2)
sum1 += xipow2 - fnx
sum2 += xipow2
sum3 += x[i]
}
return math.Pow(math.Abs(sum1), 0.25) + (((0.5 * sum2) + sum3) / (fnx + 0.5))
}
// Discus is the "Discus Function" of CEC2020.
func Discus(x []float64) float64 {
var sum float64
nx := len(x)
for i := 1; i < nx; i++ {
sum += math.Pow(x[i], 2)
}
return sum + (1000000 * math.Pow(x[0], 2))
}
// SchwefelModified is the "Modified Schwefel's Function" of CEC2020 with summation
// of g(zi) where zi = xi + 4.209687462275036e+002 and
// g(zi) = zi * sin(|zi|^(1/2)) ... if |zi| <= 500,
// g(zi) = (500-mod(zi,500)) * sin(sqrt(|500-mod(zi,500)|)) - (zi-500^2)/10000D ... if zi > 500,
// g(zi) = (mod(|zi|,500)-500) * sin(sqrt(|mod(|zi|,500)-500|)) - (zi-500^2)/10000D ... if zi < -500.
func SchwefelModified(x []float64) float64 {
var sum float64
// float64 version of the length of x.
fnx := float64(len(x))
for i := range x {
zi := x[i] + 4.209687462275036e+002
switch {
case zi > 500:
// g(zi)
sum += (500-math.Mod(zi, 500))*math.Sin(math.Sqrt(math.Abs(500-math.Mod(zi, 500)))) - (math.Pow(zi-500.0, 2.0) - 10000*fnx)
case zi < -500:
// g(zi)
sum += (math.Mod(math.Abs(zi), 500)-500)*math.Sin(math.Sqrt(math.Abs(math.Mod(math.Abs(zi), 500)-500))) - (math.Pow(zi-500, 2) - 10000*fnx)
case math.Abs(zi) <= 500:
// g(zi)
sum += zi * math.Sin(math.Pow(math.Abs(zi), 0.5))
}
}
return 418.9829*fnx - sum
}
// Schaffer is the Schaffer's function.
func Schaffer(x, y float64) float64 {
return 0.5 + (math.Pow(math.Sin(math.Sqrt(math.Pow(x, 2)+math.Pow(y, 2))-0.5), 2) / (1 + 0.001*(math.Pow(x, 2)+math.Pow(y, 2))))
}
// SchafferExpanded is the "Expanded Schaffer's Function" of CEC2020.
func SchafferExpanded(x []float64) float64 {
var sum float64
nx := len(x)
for i := range x {
sum += Schaffer(x[i], x[i%nx])
}
return sum
}
// Weierstrass is the "Weierstrass Function" of CEC2020 with a=0.5, b=3 and
// kmax=20.
func Weierstrass(x []float64) float64 {
a := 0.5
b := 3.0
kmax := 20.0
// float64 version of the length of x.
fnx := float64(len(x))
var sum1 float64
var sum2 float64
for i := range x {
var ksum float64
for k := 0.0; k < kmax; k++ {
ksum += math.Pow(a, k) * math.Cos(2*math.Pi*math.Pow(b, k)*(x[i]+0.5))
}
sum1 += ksum
}
for k := 0.0; k < kmax; k++ {
sum2 += math.Pow(a, k) * math.Cos(2*math.Pi*math.Pow(b, k)*0.5)
}
return sum1 - (fnx * sum2)
}