math-optim/bench/cec2020/helperFunctions.go
leo e34922d6e5
All checks were successful
continuous-integration/drone/push Build is passing
cec2020: generalise Hybrid1 func's internals
2023-02-08 01:11:20 +01:00

194 lines
5.2 KiB
Go

// Copyright 2023 wanderer <a_mirre at utb dot cz>
// SPDX-License-Identifier: GPL-3.0-or-later
package cec2020
import (
"math"
"time"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/stat/distuv"
)
// void hf01 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 1
// void hf02 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 2
// void hf03 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 3
// void hf04 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 4
// void hf05 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 5
// void hf06 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 6
// void hf07 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 7
// void hf08 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 8
// void hf09 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 9
// void hf10 (double *, double *, int, double *,double *, int *,int, int); // Hybrid Function 10
//
// void cf01 (double *, double *, int , double *,double *, int); // Composition Function 1
// void cf02 (double *, double *, int , double *,double *, int); // Composition Function 2
// void cf03 (double *, double *, int , double *,double *, int); // Composition Function 3
// void cf04 (double *, double *, int , double *,double *, int); // Composition Function 4
// void cf05 (double *, double *, int , double *,double *, int); // Composition Function 5
// void cf06 (double *, double *, int , double *,double *, int); // Composition Function 6
// void cf07 (double *, double *, int , double *,double *, int); // Composition Function 7
// void cf08 (double *, double *, int , double *,double *, int); // Composition Function 8
// void cf09 (double *, double *, int , double *,double *, int *, int); // Composition Function 9/
// void cf10 (double *, double *, int , double *,double *, int *, int); // Composition Function 10
// void shiftfunc (double*,double*,int,double*);
// void rotatefunc (double*,double*,int, double*);
// void sr_func (double *, double *, int, double*, double*, double, int, int); // shift and rotate
// void asyfunc (double *, double *x, int, double);
// void oszfunc (double *, double *, int);
// void cf_cal(double *, double *, int, double *,double *,double *,double *,int);
// Shift shifts values of x based on values of os.
func Shift(x []float64, os []float64) {
if len(x) != len(os) {
cec2020Logger.Fatalln("slices are of different sizes, bailing...")
}
for i := range x {
x[i] -= os[i]
}
}
// Rotate rotates values of x based on values of mr.
func Rotate(x []float64, mr []float64) {
nx := len(x)
if int(math.Pow(float64(nx), 2)) > len(mr) {
cec2020Logger.Fatalf("either x is too big or mr is of insufficient size (%d:%d), bailing...\n", nx, len(mr))
}
xrot := make([]float64, nx)
for i := 0; i < nx; i++ {
for j := 0; j < nx; j++ {
x[j] += xrot[i] + (x[j] * mr[(i*nx)+j])
}
}
}
// ShiftRotate shifts and/or rotates the input x based on the request params
// shift and rotate (bool), using the values of os and/or mr.
func ShiftRotate(x []float64, os []float64, mr []float64, shiftRate float64, shift, rotate bool) {
switch {
case shift && rotate:
Shift(x, os)
// shrink to the original search range.
for i := range x {
x[i] *= shiftRate
}
Rotate(x, mr)
case shift && !rotate:
Shift(x, os)
// shrink to the original search range.
for i := range x {
x[i] *= shiftRate
}
case !shift && rotate:
// shrink to the original search range
for i := range x {
x[i] *= shiftRate
}
Rotate(x, mr)
case !shift && !rotate:
for i := range x {
x[i] *= shiftRate
}
}
}
// Asy is the asymptotic function.
func Asy(x []float64, beta float64) {
nx := len(x)
for i := range x {
if x[i] > 0 {
fi := float64(i)
fnx := float64(nx)
x[i] = math.Pow(x[i], 1+((beta*fi)/(fnx-1)*math.Pow(x[i], 0.5)))
}
}
}
func newXopt(n int, mu0 float64) []float64 {
gaussDist := &distuv.Normal{
Src: rand.NewSource(uint64(time.Now().UnixNano())),
}
tmpvec := make([]float64, n)
xopt := make([]float64, n)
for i := 0; i < n; i++ {
tmpvec = append(tmpvec, gaussDist.Rand())
xopt = append(xopt, 0.5*mu0)
if tmpvec[i] < 0 {
xopt[i] *= -1
}
}
return xopt
}
// newOpt returns a slice of optimal float64 values.
func newOpt(n int) []float64 {
uniformDist := &distuv.Uniform{
Src: rand.NewSource(uint64(time.Now().UnixNano())),
Min: SearchRange.Min(),
Max: SearchRange.Max(),
}
tmpvec := make([]float64, n)
xopt := make([]float64, n)
for i := 0; i < n; i++ {
tmpvec = append(tmpvec, uniformDist.Rand())
xopt = append(xopt, 0.5*uniformDist.Mean())
if tmpvec[i] < 0 {
xopt[i] *= -1
}
}
return xopt
}
// getGnx calculates G_nx.
func getGnx(p []float64, fnx float64) []float64 {
gnx := make([]float64, len(p))
gnxsum := 0.0
for i := 0; i < len(p)-1; i++ {
gnx[i] = math.Ceil(p[i] * fnx)
gnxsum += gnx[i]
}
gnx[len(p)] = fnx - gnxsum
return gnx
}
// getMz calculates Mz.
func getMz(x []float64, z []float64) []float64 {
nx := len(x)
mz := make([]float64, nx)
for i := range x {
mz = append(mz, x[i]*z[i])
}
return mz
}