#![cfg(feature = "test_functions")]
use std::{f64, i32};
pub fn ackley(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Ackley function takes an at least one dimensional vector as a parameter."
);
let mut temp1 = 0.0;
let mut temp2 = 0.0;
for x_curr in x {
temp1 += f64::powi(*x_curr, 2);
temp2 += f64::cos(2.0 * f64::consts::PI * *x_curr)
}
temp1 *= 1.0 / x.len() as f64;
temp2 *= 1.0 / x.len() as f64;
-20.0 * f64::exp(-0.2 * f64::sqrt(temp1)) - f64::exp(temp2) + 20.0 + f64::exp(1.0)
}
pub fn ackley2(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Ackley 2nd function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powf(-200_f64 * f64::consts::E, -0.02) * f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2))
}
pub fn ackley3(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Ackley 3rd function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
200_f64
* f64::powf(
f64::consts::E,
-0.02 * f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2)),
)
+ 5_f64 * f64::powf(f64::consts::E, f64::cos(3_f64 * x1) + f64::sin(3_f64 * x2))
}
pub fn adijman(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Adjiman function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::cos(x1) * f64::sin(x2) - (x1 / (f64::powi(x2, 2) + 1_f64))
}
pub fn alpine(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::abs(arg * f64::sin(*arg) + arg / 10_f64)
}
res
}
pub fn alpine2(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res *= f64::sqrt(*arg) * f64::sin(*arg)
}
res
}
pub fn brad(x: &Vec<f64>) -> f64 {
assert_eq!(
3,
x.len(),
"Brad function takes only a three dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let y = vec![
0.14, 0.18, 0.22, 0.25, 0.29, 0.32, 0.35, 0.39, 0.37, 0.58, 0.73, 0.96, 1.34, 2.10, 4.39,
];
let mut res = 0_f64;
for i in 0..15 {
res += f64::powi(
(y[0] - x1 - i as f64) / ((16 - i) as f64 * x2 + f64::min(i as f64, (16 - i) as f64) * x3),
2,
)
}
res
}
pub fn bartels_conn(x: &Vec<f64>) -> f64 {
assert_eq!(
3,
x.len(),
"Brad function takes only a three dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::abs(f64::powi(x1, 2) + f64::powi(x2, 2) + x1 * x2) + f64::abs(f64::sin(x1)) + f64::abs(f64::cos(x2))
}
pub fn beale(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Beale function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(1.5 - x1 + x1 * x2, 2)
+ f64::powi(2.25 - x1 + x1 * f64::powi(x2, 2), 2)
+ f64::powi(2.625 - x1 + x1 * f64::powi(x2, 3), 2)
}
pub fn biggs_exp2(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Biggs EXP2 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let mut res = 0_f64;
for i in 1..11 {
res += f64::powi(
f64::powf(f64::consts::E, -0.1 * i as f64 * x1)
- 5_f64 * f64::powf(f64::consts::E, -0.1 * i as f64 * x2)
- f64::powf(f64::consts::E, -0.1 * i as f64)
- 5_f64 * f64::powf(f64::consts::E, i as f64),
2,
)
}
res
}
pub fn biggs_exp3(x: &Vec<f64>) -> f64 {
assert_eq!(
3,
x.len(),
"Biggs EXP3 function takes only a three dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let mut res = 0_f64;
for i in 1..11 {
res += f64::powi(
f64::powf(f64::consts::E, -0.1 * i as f64 * x1)
- x3 * f64::powf(f64::consts::E, -0.1 * i as f64 * x2)
- f64::powf(f64::consts::E, -0.1 * i as f64)
- 5_f64 * f64::powf(f64::consts::E, i as f64),
2,
)
}
res
}
pub fn biggs_exp4(x: &Vec<f64>) -> f64 {
assert_eq!(
4,
x.len(),
"Biggs EXP4 function takes only a four dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
let mut res = 0_f64;
for i in 1..11 {
res += f64::powi(
x3 * f64::powf(f64::consts::E, -0.1 * i as f64 * x1)
- x4 * f64::powf(f64::consts::E, -0.1 * i as f64 * x2)
- f64::powf(f64::consts::E, -0.1 * i as f64)
- 5_f64 * f64::powf(f64::consts::E, i as f64),
2,
)
}
res
}
pub fn biggs_exp5(x: &Vec<f64>) -> f64 {
assert_eq!(
5,
x.len(),
"Biggs EXP5 function takes only a five dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
let x5 = x[4];
let mut res = 0_f64;
for i in 1..11 {
res += f64::powi(
x3 * f64::powf(f64::consts::E, -0.1 * i as f64 * x1)
- x4 * f64::powf(f64::consts::E, -0.1 * i as f64 * x2)
- f64::powf(f64::consts::E, -0.1 * i as f64)
- 5_f64
* f64::powf(
f64::consts::E,
i as f64 + 3_f64 * f64::powf(f64::consts::E, -0.1 * x5),
)
+ 3_f64 * f64::powf(f64::consts::E, -0.4 * i as f64),
2,
)
}
res
}
pub fn biggs_exp6(x: &Vec<f64>) -> f64 {
assert_eq!(
6,
x.len(),
"Biggs EXP6 function takes only a six dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
let x5 = x[4];
let x6 = x[5];
let mut res = 0_f64;
for i in 1..12 {
res += f64::powi(
x3 * f64::powf(f64::consts::E, -0.1 * i as f64 * x1)
- x4 * f64::powf(f64::consts::E, -0.1 * i as f64 * x2)
- f64::powf(f64::consts::E, -0.1 * i as f64)
- 5_f64
* f64::powf(
f64::consts::E,
i as f64 + x6 * f64::powf(f64::consts::E, -0.1 * x5),
)
+ 3_f64 * f64::powf(f64::consts::E, -0.4 * i as f64),
2,
)
}
res
}
pub fn bird(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Bird function takes only a two-dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::sin(x1) * f64::powf(f64::consts::E, f64::powi(1_f64 - f64::cos(x2), 2))
+ f64::cos(x2) * f64::powf(f64::consts::E, f64::powi(1_f64 - f64::sin(x1), 2))
+ f64::powi(x1 - x2, 2)
}
pub fn bohachevsky_n1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Bohhachevsky function N.1 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) + 2_f64 * f64::powi(x2, 2)
- 0.3 * f64::cos(3_f64 * f64::consts::PI * x1)
- 0.4 * f64::cos(4_f64 * f64::consts::PI * x2)
+ 0.7
}
pub fn bohachevsky_n2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Bohhachevsky function N.2 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) + 2_f64 * f64::powi(x2, 2)
- 0.3 * f64::cos(3_f64 * f64::consts::PI * x1) * f64::cos(4_f64 * f64::consts::PI * x2)
+ 0.3
}
pub fn bohachevsky_n3(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Bohhachevsky function N.3 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) + 2_f64 * f64::powi(x2, 2)
- 0.3 * f64::cos(3_f64 * f64::consts::PI * x1 + 4_f64 * f64::consts::PI * x2)
+ 0.3
}
pub fn booth(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Booth function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1 + 2.0 * x2 - 7.0, 2) + f64::powi(2.0 * x1 + x2 - 5.0, 2)
}
pub fn box_betts(x: &Vec<f64>) -> f64 {
assert_eq!(
3,
x.len(),
"Box-Betts function takes only a three-dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let mut res = 0_f64;
for i in 0..3 {
res += f64::powi(
f64::powf(f64::consts::E, -0.1 * (i + 1) as f64 * x1)
+ f64::powf(f64::consts::E, -0.1 * (i + 1) as f64 * x2)
+ f64::powf(
f64::consts::E,
x3 * (-0.1 * i as f64) - f64::powf(f64::consts::E, -1_f64 * (i + 1) as f64),
),
2,
)
}
res
}
pub fn branin(x: &Vec<f64>, a: &f64, b: &f64, c: &f64, r: &f64, s: &f64, t: &f64) -> f64 {
assert_eq!(
2,
x.len(),
"Branin function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
a * f64::powi(x2 - b * f64::powi(x1, 2) + c * x1 - r, 2) + s * (1_f64 - t) * f64::cos(x1) + s
}
pub fn branin_rcos(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Branin RCOS function takes only a two-dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(
x2 - 5.1 * f64::powi(x1, 2) / 4_f64 * f64::powi(f64::consts::PI, 2) + 5_f64 * x1 / f64::consts::PI
- 6_f64,
2,
) + 10_f64 * (1_f64 - 1_f64 / 8_f64 * f64::consts::PI) * f64::cos(x1)
+ 10_f64
}
pub fn branin_rcos2(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Branin RCOS function no2 takes only a two-dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(
x2 - 5.1 * f64::powi(x1, 2) / 4_f64 * f64::powi(f64::consts::PI, 2) + 5_f64 * x1 / f64::consts::PI
- 6_f64,
2,
) + 10_f64
* (1_f64 - 1_f64 / 8_f64 * f64::consts::PI)
* f64::cos(x1)
* f64::cos(x2)
* f64::ln(f64::powi(x1, 2) + f64::powi(x2, 2) + 1_f64)
+ 10_f64
}
pub fn branin_default(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Branin function takes only a two dimensional vector as a parameter."
);
let a = 1_f64;
let b = 5.1 / 4_f64 * f64::powi(f64::consts::PI, 2);
let c = 5_f64 / f64::consts::PI;
let r = 6_f64;
let s = 10_f64;
let t = 1_f64 / 8_f64 * f64::consts::PI;
let x1 = x[0];
let x2 = x[1];
a * f64::powi(x2 - b * f64::powi(x1, 2) + c * x1 - r, 2) + s * (1_f64 - t) * f64::cos(x1) + s
}
pub fn brent(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"Brent function takes only a two-dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1 + 10_f64, 2)
+ f64::powi(x2 + 10_f64, 2)
+ f64::powf(f64::consts::E, -1_f64 * f64::powi(x1, 2) - f64::powi(x2, 2))
}
pub fn brown(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for i in 0..x.len() - 1 {
res += f64::powf(f64::powi(x[i], 2), f64::powi(x[i + 1], 2) + 1_f64)
+ f64::powf(f64::powi(x[i + 1], 2), f64::powi(x[i], 2) + 1_f64)
}
res
}
pub fn bukin_2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Bukin function N.2 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100_f64 * (x2 - 0.01 * f64::powi(x1, 2) + 1_f64) + 0.01 * f64::powi(x1 + 10_f64, 2)
}
pub fn bukin_4(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Bukin function N.4 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100_f64 * f64::powi(x2, 2) + 0.01 * f64::abs(x1 + 10_f64)
}
pub fn bukin_n6(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Bukin function N.6 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100.0 * f64::sqrt(f64::abs(x2 - 0.01 * f64::powi(x1, 2))) + 0.01 * f64::abs(x1 + 10.0)
}
pub fn three_hump_camel(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Three-hump camel function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
2.0 * f64::powi(x1, 2) + -1.05 * f64::powi(x1, 4) + f64::powi(x1, 6) / 6.0 + x1 * x2 + f64::powi(x2, 2)
}
pub fn six_hump_camel(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Six-hump camel function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
(4_f64 - 2.1 * f64::powi(x1, 2) + f64::powi(x1, 3) / 3_f64) * f64::powi(x1, 2)
+ x1 * x2
+ (-4_f64 + 4_f64 * f64::powi(x2, 2)) * f64::powi(x2, 2)
}
pub fn chen_bird(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Chen Bird function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-0.001 / (0.001 * 0.001 + f64::powi(x1 - 0.4 * x2 + 0.1, 2))
- 0.001 / (0.001 * 0.001 + f64::powi(2_f64 * x1 + x2 - 1.5, 2))
}
pub fn chen_v(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Chen V function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-0.001 / (0.001 * 0.001 + f64::powi(f64::powi(x1, 2) + f64::powi(x2, 2) - 1_f64, 2))
- 0.001 / (0.001 * 0.001 + f64::powi(f64::powi(x1, 2) + f64::powi(x2, 2) - 0.5, 2))
- 0.001 / (0.001 * 0.001 + f64::powi(f64::powi(x1, 2) - f64::powi(x2, 2), 2))
}
pub fn chichinadze(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Chichinadze function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) - 12_f64 * x1
+ 11_f64
+ 10_f64 * f64::cos(f64::consts::PI * x1 / 2_f64)
+ 8_f64 * f64::sin(5_f64 * f64::consts::PI * x1 / 2_f64)
- f64::powf(0.2, 0.5) * f64::exp(-0.5 * f64::powi(x2 - 0.5, 2))
}
pub fn chung_reynolds(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(*arg, 2);
}
f64::powi(res, 2)
}
pub fn colville(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
4,
"Colville function takes only a four dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
100_f64 * f64::powi(f64::powi(x1, 2) - x2, 2)
+ f64::powi(x1 - 1_f64, 2)
+ f64::powi(x3 - 1_f64, 2)
+ 90_f64 * f64::powi(f64::powi(x3, 2) - x4, 2)
+ 10.1 * (f64::powi(x2 - 1_f64, 2) + f64::powi(x4 - 1_f64, 2))
+ 19.8 * (x2 - 1_f64) * (x4 - 1_f64)
}
pub fn cosine_mixture(x: &Vec<f64>) -> f64 {
let mut sum1 = 0_f64;
let mut sum2 = 0_f64;
for arg in x {
sum1 += f64::cos(5_f64 * f64::consts::PI * arg);
sum2 += f64::powi(*arg, 2)
}
-0.1 * sum1 - sum2
}
pub fn cross_in_tray(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Cross-in-tray function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-0.0001
* f64::powf(
f64::abs(
f64::sin(x1)
* f64::sin(x2)
* f64::exp(f64::abs(
100.0 - f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2)) / f64::consts::PI,
)),
) + 1.0,
0.1,
)
}
pub fn csendes(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(*arg, 6) * (2_f64 + f64::sin(1_f64 / arg))
}
res
}
pub fn cube(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Cube function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100_f64 * f64::powi(x2 - f64::powi(x1, 3), 2) + f64::powi(1_f64 - x1, 2)
}
pub fn damavandi(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Damavandi function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
(1_f64
- f64::powi(
f64::sin(f64::consts::PI * (x1 - 2_f64)) * f64::sin(f64::consts::PI * (x2 - 2_f64))
/ f64::powi(f64::consts::PI, 2)
* (x1 - 2_f64)
* (x2 - 2_f64),
5,
))
* (2_f64 + f64::powi(x1 - 7_f64, 2) + 2_f64 * f64::powi(x2 - 7_f64, 2))
}
pub fn deb1(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(f64::sin(5_f64 * f64::consts::PI * arg), 6)
}
-1_f64 / (x.len() - 1) as f64 * res
}
pub fn deb3(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(
f64::sin(5_f64 * f64::consts::PI * (f64::powf(*arg, 0.75) - 0.05)),
6,
)
}
-1_f64 / (x.len() - 1) as f64 * res
}
pub fn deckkers_aarts(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Deckkers-Aarts function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100000_f64 * f64::powi(x1, 2) + f64::powi(x2, 2) - f64::powi(f64::powi(x1, 2) + f64::powi(x2, 2), 2)
+ (1 / 100000) as f64 * f64::powi(f64::powi(x1, 2) + f64::powi(x2, 2), 4)
}
pub fn devilliers_glasser1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"deVilliers Glasser 1 function takes only a four dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
let mut res = 0_f64;
for i in 1..25 {
res += f64::powi(
x1 * f64::powf(x2, 0.1 * (i - 1) as f64) * f64::sin(x3 * 0.1 * (i - 1) as f64 + x4)
- 60.137
* f64::powf(
1.371,
0.1 * (i - 1) as f64 * f64::sin(3.112 * 0.1 * (i - 1) as f64 + 1.761),
),
2,
)
}
res
}
pub fn devilliers_glasser2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
5,
"deVilliers Glasser 2 function takes only a five dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
let x5 = x[4];
let mut res = 0_f64;
for i in 1..25 {
res += f64::powi(
x1 * f64::powf(x2, 0.1 * (i - 1) as f64)
* f64::tanh(x3 * 0.1 * (i - 1) as f64 + f64::sin(x4 * 0.1 * (i - 1) as f64))
* f64::cos(0.1 * (i - 1) as f64 * f64::powf(f64::consts::E, x5))
- 53.81
* f64::powf(1.27, 0.1 * (i - 1) as f64)
* f64::tanh(3.012 * 0.1 * (i - 1) as f64 + f64::sin(2.13 * 0.1 * (i - 1) as f64))
* f64::cos(f64::powf(f64::consts::E, 0.507) * 0.1 * (i - 1) as f64),
2,
)
}
res
}
pub fn dixon_price(x: &Vec<f64>) -> f64 {
assert!(
x.len() >= 2,
"Dixon-Price function takes an at least two dimensional vector as a parameter."
);
let mut result: f64 = f64::powi(x[0] - 1.0, 2);
for i in 1..x.len() {
result += (i as f64) * f64::powi(2.0 * f64::powi(x[i], 2) - x[i - 1], 2);
}
result
}
pub fn de_jong_n5(x: &Vec<f64>) -> f64 {
assert_eq!(
2,
x.len(),
"De Jong n.5 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let mut sum = 0_f64;
let mut a1 = vec![];
for _i in 1..6 {
a1.append(&mut vec![-32.0, -16.0, 16.0, 32.0]);
}
let mut b: Vec<f64> = vec![];
for i in (-32..33).step_by(16) {
b.append(&mut vec![i as f64; 5]);
}
let a = vec![a1, b];
for i in 1..26 {
sum += 1_f64 / i as f64 + f64::powi(x1 - a[1][i], 6) + f64::powi(x2 - a[2][i], 6);
}
f64::powf(0.002 + sum, -1_f64)
}
pub fn dolan(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
5,
"Dolan function takes only a five dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
let x5 = x[4];
(x1 + 1.7 * x2) * f64::sin(x1) - 1.5 * x3 - 0.1 * x4 * f64::cos(x4 + x5 - x1) + 0.2 * f64::powi(x5, 2)
- x2
- 1_f64
}
pub fn drop_wave(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Drop-wave function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1_f64 * (1_f64 + f64::cos(12_f64 * f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2))))
/ (0.5 * (f64::powi(x1, 2) + f64::powi(x2, 2)) + 2_f64)
}
pub fn easom(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Easom function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1.0 * f64::cos(x1)
* f64::cos(x2)
* f64::exp(-1.0 * (f64::powi(x1 - f64::consts::PI, 2) + f64::powi(x2 - f64::consts::PI, 2)))
}
pub fn eavd(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"El-Attar-Vidyasagar-Dutta function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::powi(x1, 2) + x2 - 10_f64, 2)
+ f64::powi(x1 + f64::powi(x2, 2) - 7_f64, 2)
+ f64::powi(f64::powi(x1, 2) + f64::powi(x2, 3) - 1_f64, 2)
}
pub fn egg_crate(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Egg crate function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) + f64::powi(x2, 2) + 25_f64 * (f64::powi(f64::sin(x1), 2) + f64::powi(f64::sin(x2), 2))
}
pub fn eggholder(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Eggholder function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1.0 * (x2 + 47.0) * f64::sin(f64::sqrt(f64::abs((x1 / 2.0) + x2 + 47.0)))
+ -1.0 * x1 * f64::sin(f64::sqrt(f64::abs(x1 - x2 - 47.0)))
}
pub fn exponential(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(*arg, 2)
}
-1_f64 * f64::exp(-0.5 * res)
}
pub fn exp2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Exp 2 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let mut res = 0_f64;
for i in 1..10 {
res += f64::powi(
f64::powf(f64::consts::E, -1_f64 * i as f64 * x1 / 10_f64)
- 5_f64 * f64::powf(f64::consts::E, -1_f64 * i as f64 * x2 / 10_f64)
- f64::powi(f64::consts::E, -i / 10)
+ 5_f64 * f64::powi(f64::consts::E, -i),
2,
)
}
res
}
pub fn forrester_et_al(x: &f64) -> f64 {
f64::powi(6_f64 * x - 2_f64, 2) * f64::sin(12_f64 * x - 4_f64)
}
pub fn freudenstein_roth(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Freudenstein Roth function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1 - 13_f64 + ((5_f64 - x2) * x2 - 2_f64) * x2, 2)
+ f64::powi(x1 - 29_f64 + ((x2 + 1_f64) * x2 - 14_f64) * x2, 2)
}
pub fn giunta(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Giunta function takes only a two dimensional vector as a parameter."
);
let mut res = 0_f64;
for arg in x {
res += f64::sin((16 / 15) as f64 * arg - 1_f64)
+ f64::powi((16 / 15) as f64 * arg - 1_f64, 2)
+ 0.02 * f64::sin(4_f64 * ((16 / 15) as f64 * arg - 1_f64))
}
res
}
pub fn goldstein_price(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Goldstein-Price function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
(1.0 + f64::powi(x1 + x2 + 1.0, 2)
* (19.0 - 14.0 * x1 + 3.0 * f64::powi(x1, 2) - 14.0 * x2 + 6.0 * x1 * x2 + 3.0 * f64::powi(x2, 2)))
* (30.0
+ f64::powi(2.0 * x1 - 3.0 * x2, 2)
* (18.0 - 32.0 * x1 + 12.0 * f64::powi(x1, 2) + 48.0 * x2 - 36.0 * x1 * x2
+ 27.0 * f64::powi(x2, 2)))
}
pub fn gramacy_lee(x: &f64) -> f64 {
f64::sin(10_f64 * f64::consts::PI * x) / 2_f64 * x + f64::powi(x - 1_f64, 4)
}
pub fn griewank(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Griewank function takes an at least one dimensional vector as a parameter."
);
let mut temp1 = 0.0;
let mut temp2 = 1.0;
for (index, x_curr) in x.iter().enumerate() {
temp1 += f64::powi(*x_curr, 2) / 4000.0;
temp2 *= f64::cos(*x_curr / f64::sqrt((index + 1) as f64));
}
temp1 - temp2 + 1.0
}
pub fn gulf_research(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
99,
"Gulf Research function takes only a 99-dimensional vector as a parameter."
);
let x3 = x[2];
let mut res = 0_f64;
for (i, _) in x.iter().enumerate() {
res += f64::powi(
f64::exp(
-1_f64
* f64::powf(
25_f64 + f64::powf(-50_f64 * f64::ln(0.01 * i as f64), 1_f64 / 1.5),
x3,
)
/ x[i],
),
2,
)
}
res
}
pub fn hartmann_3d(x: &Vec<f64>) -> f64 {
assert_eq!(
3,
x.len(),
"Hartmann 3-dimensional function takes only a three dimensional vector as a parameter."
);
let alfa = vec![1.0, 1.2, 3.0, 3.2];
let a = vec![
vec![3.0, 10.0, 30.0],
vec![0.1, 10.0, 35.0],
vec![3.0, 10.0, 30.0],
vec![0.1, 10.0, 35.0],
];
let p = vec![
vec![3.689, 1.17, 2.673],
vec![4.699, 4.387, 7.47],
vec![1.091, 8.732, 5.547],
vec![0.381, 5.743, 8.828],
];
let mut res = 0_f64;
for i in 1..5 {
let mut sum = 0_f64;
for (j, _) in x.iter().enumerate() {
sum += a[i][j] * f64::powi(x[j] - p[i][j], 2);
}
res -= alfa[i] * f64::exp(-1_f64 * sum);
}
res
}
pub fn hartmann_4d(x: &Vec<f64>) -> f64 {
assert_eq!(
4,
x.len(),
"Hartmann 4-dimensional function takes only a three dimensional vector as a parameter."
);
let alfa = vec![1.0, 1.2, 3.0, 3.2];
let a = vec![
vec![10.0, 3.0, 17.0, 3.5, 1.7, 8.0],
vec![0.05, 10.0, 17.0, 0.1, 8.0, 14.0],
vec![3.0, 3.5, 1.7, 10.0, 17.0, 8.0],
vec![17.0, 8.0, 0.05, 10.0, 0.1, 14.0],
];
let p = vec![
vec![1.312, 1.696, 5.569, 1.24, 8.283, 5.886],
vec![2.329, 4.135, 8.307, 3.736, 1.004, 9.991],
vec![2.348, 1.451, 3.522, 2.883, 3.047, 6.650],
vec![4.047, 8.828, 8.732, 5.743, 1.091, 3.81],
];
let mut sum = 0_f64;
for i in 1..5 {
let mut inner_sum = 0_f64;
for (j, _) in x.iter().enumerate() {
inner_sum += a[i][j] * f64::powi(x[j] - p[i][j], 2);
}
sum += alfa[i] * f64::exp(-inner_sum);
}
(1_f64 / 0.839) * (1.1 - sum)
}
pub fn hartmann_6d(x: &Vec<f64>) -> f64 {
assert_eq!(
6,
x.len(),
"Hartmann 6-dimensional function takes only a six dimensional vector as a parameter."
);
let alfa = vec![1.0, 1.2, 3.0, 3.2];
let a = vec![
vec![10.0, 3.0, 17.0, 3.5, 1.7, 8.0],
vec![0.05, 10.0, 17.0, 0.1, 8.0, 14.0],
vec![3.0, 3.5, 1.7, 10.0, 17.0, 8.0],
vec![17.0, 8.0, 0.05, 10.0, 0.1, 14.0],
];
let p = vec![
vec![1.312, 1.696, 5.569, 1.24, 8.283, 5.886],
vec![2.329, 4.135, 8.307, 3.736, 1.004, 9.991],
vec![2.348, 1.451, 0.522, 2.883, 3.047, 6.650],
vec![4.047, 8.828, 8.732, 5.743, 1.091, 3.81],
];
let mut sum = 0_f64;
for i in 1..5 {
let mut inner_sum = 0_f64;
for (j, _) in x.iter().enumerate() {
inner_sum += a[i][j] * f64::powi(x[j] - p[i][j], 2);
}
sum += alfa[i] * f64::exp(-1_f64 * inner_sum);
}
-1_f64 * sum
}
pub fn himmelblau(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Himmelblau's function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::powi(x1, 2) + x2 - 11.0, 2) + f64::powi(x1 + f64::powi(x2, 2) - 7.0, 2)
}
pub fn holder_table(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Holder table function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1.0 * f64::abs(
f64::sin(x1)
* f64::cos(x2)
* f64::exp(f64::abs(
1.0 - f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2)) / f64::consts::PI,
)),
)
}
pub fn holder_table2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Holder Table function 2 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1.0 * f64::abs(
f64::cos(x1)
* f64::cos(x2)
* f64::exp(f64::abs(
1.0 - f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2)) / f64::consts::PI,
)),
)
}
pub fn holder_table3(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Holder Table function 3 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1.0 * f64::abs(
f64::cos(x1)
* f64::cos(x2)
* f64::exp(f64::abs(f64::powi(
1.0 - f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2)) / f64::consts::PI,
2,
)))
/ 30_f64,
)
}
pub fn hosaki(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Hosaki function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
(1_f64 - 8_f64 * x1 + 7_f64 * f64::powi(x1, 2) - 7_f64 / 3_f64 * f64::powi(x1, 3)
+ 0.25 * f64::powi(x1, 4))
* f64::powi(x2, 2)
* f64::powf(f64::consts::E, -1_f64 * x2)
}
pub fn jennrich_sampson(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Jennrich-Sampson function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let mut res = 0_f64;
for i in 1..11 {
res += f64::powi(
2_f64 + 2_f64 * i as f64
- (f64::powf(f64::consts::E, i as f64 * x1) + f64::powf(f64::consts::E, i as f64 * x2)),
2,
)
}
res
}
pub fn langermann(x: &[f64], m: i32, c: &[f64], a: &[Vec<f64>]) -> f64 {
let mut res = 0_f64;
for i in 1..m + 1 {
let mut inner = 0_f64;
for (j, _) in x.iter().enumerate() {
inner += f64::powi(x[j] - a[i as usize][j], 2)
}
res += c[i as usize] * f64::exp(-1_f64 * f64::consts::PI / inner) * f64::cos(f64::consts::PI * inner)
}
res
}
pub fn levy(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Levy function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = f64::powi(f64::sin(f64::consts::PI * (1.0 + (x[0] - 1.0) / 4.0)), 2);
for x_i in x.iter().take(x.len() - 1) {
let temp: f64 = 1.0 + (x_i - 1.0) / 4.0;
result +=
f64::powi(temp - 1.0, 2) * (1.0 + 10.0 * f64::powi(f64::sin(f64::consts::PI * temp + 1.0), 2));
}
let temp: f64 = 1.0 + (x[x.len() - 1] - 1.0) / 4.0;
result += f64::powi(temp - 1.0, 2) * (1.0 + f64::powi(f64::sin(2.0 * f64::consts::PI * temp), 2));
result
}
pub fn levy_n13(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Levy function N.13 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::sin(3.0 * f64::consts::PI * x1), 2)
+ f64::powi(x1 - 1.0, 2) * (1.0 + f64::powi(f64::sin(3.0 * f64::consts::PI * x2), 2))
+ f64::powi(x2 - 1.0, 2) * (1.0 + f64::powi(f64::sin(2.0 * f64::consts::PI * x2), 2))
}
pub fn keane(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Keane function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::sin(x1 - x2), 2) * f64::powi(f64::sin(x1 + x2), 2)
/ f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2))
}
pub fn leon(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Leon function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100_f64 * f64::powi(x2 - f64::powi(x1, 2), 2) + f64::powi(1_f64 - x1, 2)
}
pub fn matyas(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Matyas function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
0.26 * (f64::powi(x1, 2) + f64::powi(x2, 2)) + -0.48 * x1 * x2
}
pub fn mcormick(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"McCormick table function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::sin(x1 + x2) + f64::powi(x1 - x2, 2) + -1.5 * x1 + 2.5 * x2 + 1.0
}
pub fn michalewicz(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Michalewicz function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for (index, x_curr) in x.iter().enumerate() {
result -= f64::sin(*x_curr)
* f64::powi(
f64::sin(((index + 1) as f64) * f64::powi(*x_curr, 2) / f64::consts::PI),
20,
);
}
result
}
pub fn miele_cantrell(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
4,
"Miele Cantrell function takes only a four dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
let x4 = x[3];
f64::powi(f64::powf(f64::consts::E, -1_f64 * x1) - x2, 4)
+ 100_f64 * f64::powi(x2 - x3, 6)
+ f64::powi(f64::tan(x3 - x4), 4)
+ f64::powi(x1, 8)
}
pub fn parsopoulos(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Parsopoulos function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::cos(x1), 2) + f64::powi(f64::sin(x2), 2)
}
pub fn pen_holder(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Pen Holder function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1_f64
* f64::exp(f64::powi(
f64::abs(
f64::cos(x1)
* f64::cos(x2)
* f64::powf(
f64::consts::E,
f64::abs(
1_f64 - f64::powf(f64::powi(x1, 2) + f64::powi(x2, 2), 0.5 / f64::consts::PI),
),
),
),
-1,
))
}
pub fn pathological(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for i in 1..x.len() - 2 {
res += 0.5
+ (f64::powi(
f64::sin(f64::sqrt(100_f64 * f64::powi(x[i], 2) + f64::powi(x[i + 1], 2))),
2,
) - 0.5)
/ (1_f64
+ 0.001
* f64::powi(
f64::powi(x[i], 2) - 2_f64 * x[i] * x[i + 1] + f64::powi(x[i + 1], 2),
2,
));
}
res
}
pub fn paviani(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
10,
"Paviani function takes only a ten dimensional vector as a parameter."
);
let mut res = 0_f64;
let mut sum = 0_f64;
for arg in x {
res += f64::powi(f64::ln(arg - 2_f64), 2) + f64::powi(f64::ln(10_f64 - arg), 2);
sum *= arg;
}
res - f64::powf(sum, 0.2)
}
pub fn pinter(x: &[f64]) -> f64 {
let mut res = 0_f64;
for (i, val) in x.iter().enumerate() {
res += i as f64 * f64::powi(*val, 2)
+ 20_f64 * i as f64 * f64::powi(f64::sin(x[i - 1] * f64::sin(*val) + f64::sin(x[i + 1])), 2)
+ i as f64
* f64::log(
1_f64
+ i as f64
* f64::powi(
f64::powi(x[i - 1], 2) - 2_f64 * val - 3_f64 * x[i - 1] - f64::cos(*val)
+ 1_f64,
2,
),
10_f64,
)
}
res
}
pub fn periodic(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Periodic function takes only a ten dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
1_f64 + f64::powi(f64::sin(x1), 2) + f64::powi(f64::sin(x2), 2)
- 0.1 * f64::powf(f64::consts::E, -1_f64 * (f64::powi(x1, 2) + f64::powi(x2, 2)))
}
pub fn perm_0_d_beta(x: &Vec<f64>, beta: &f64) -> f64 {
assert_eq!(
x.len(),
2,
"Perm 0, D, Beta function takes only a two dimensional vector as a parameter."
);
let d = x.len();
let mut res = 0_f64;
for i in 1..d + 1 {
let mut sum = 0_f64;
for (j, _) in x.iter().enumerate() {
sum += (j as f64 + beta) * f64::powi(x[j], i as i32) - 1_f64 / (f64::powi(j as f64, i as i32));
}
res += f64::powi(sum, 2);
}
res
}
pub fn perm_d_beta(x: &Vec<f64>, beta: &f64) -> f64 {
let d = x.len();
let mut res = 0_f64;
for i in 1..d + 1 {
let mut sum = 0_f64;
for (j, _) in x.iter().enumerate() {
sum += (f64::powi(j as f64, i as i32) + beta) * (f64::powi(x[j] / j as f64, i as i32) - 1_f64);
}
res += f64::powi(sum, 2);
}
res
}
pub fn powell(x: &Vec<f64>) -> f64 {
assert!(
x.len() > 3,
"Powell function takes at least a four dimensional vector as a parameter."
);
let d = f64::floor((x.len() / 4) as f64) as i32;
let mut res = 0_f64;
for i in 1_usize..(d + 1) as usize {
res += f64::powi(x[4 * i - 3] + 10_f64 * x[4 * i - 2], 2)
+ 5_f64 * f64::powi(x[4 * i - 1] - x[4 * i], 2)
+ f64::powi(x[4 * i - 2] - 2_f64 * x[4 * i - 1], 4)
+ 10_f64 * f64::powi(x[4 * i - 3] - x[4 * i], 4);
}
res
}
pub fn powell2(x: &Vec<f64>) -> f64 {
assert!(
x.len() > 3,
"Powell Singular 2 function takes at least a four dimensional vector as a parameter."
);
let mut res = 0_f64;
for i in 1..x.len() - 3 {
res += f64::powi(x[i - 1] + 10_f64 * x[i], 2)
+ 5_f64 * f64::powi(x[i + 1] - x[i + 2], 2)
+ f64::powi(x[i] - 2_f64 * x[i + 1], 4)
+ 1_f64 * f64::powi(x[i - 1] - x[i + 2], 4)
}
res
}
pub fn powell_sum(x: &[f64]) -> f64 {
let mut res = 0_f64;
for (dim, arg) in x.iter().enumerate() {
res += f64::powi(f64::abs(*arg), (dim + 1) as i32);
}
res
}
pub fn power_sum(x: &Vec<f64>, b: &Vec<f64>) -> f64 {
assert_eq!(
b.len(),
x.len(),
"Power sum function requires b to be equal in length to number of dimensions"
);
let mut res = 0_f64;
for (i, _) in b.iter().enumerate() {
let mut sum = 0_f64;
for j in x.iter() {
sum += f64::powi(*j, i as i32);
}
res += f64::powi(sum - b[i], 2);
}
res
}
pub fn price1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Price 1 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::abs(x1) - 5_f64, 2) + f64::powi(f64::abs(x2) - 5_f64, 2)
}
pub fn price2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Price 2 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
1_f64 + f64::powi(f64::sin(x1), 2) + f64::powi(f64::sin(x2), 2)
- 0.1 * f64::powf(f64::consts::E, -1_f64 * f64::powi(x1, 2) - f64::powi(x2, 2))
}
pub fn price3(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Price 3 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
100_f64 * f64::powi(x2 - f64::powi(x1, 2), 2)
+ 6_f64 * f64::powi(6.4 * f64::powi(x2 - 0.5, 2) - x1 - 0.6, 2)
}
pub fn price4(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Price 4 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(2_f64 * f64::powi(x1, 3) * x2 - f64::powi(x2, 3), 2)
+ f64::powi(6_f64 * x1 - f64::powi(x2, 2) + x2, 2)
}
pub fn qing(x: &Vec<f64>, i: &f64) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(f64::powi(*arg, 2) - i, 2)
}
res
}
pub fn quadratic(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Quadratic function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-3803.84 - 138.08 * x1 - 232.92 * x2
+ 128.08 * f64::powi(x1, 2)
+ 23.64 * f64::powi(x2, 2)
+ 182.25 * x1 * x2
}
pub fn quintic(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::abs(
f64::powi(*arg, 5) - 3_f64 * f64::powi(*arg, 4)
+ 4_f64 * f64::powi(*arg, 3)
+ 2_f64 * f64::powi(*arg, 2)
- 10_f64 * arg
- 4_f64,
)
}
res
}
pub fn rana(x: &[f64]) -> f64 {
let mut res = 0_f64;
for (dim, arg) in x.iter().enumerate() {
let t1 = f64::sqrt(f64::abs(x[dim + 1] + arg + 1_f64));
let t2 = f64::sqrt(f64::abs(x[dim + 1] - arg + 1_f64));
res += (x[dim + 1] + 1_f64) * f64::cos(t2) * f64::sin(t1) + arg * f64::cos(t1) * f64::sin(t2);
}
res
}
pub fn rastrigin(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Rastrigin function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for x_curr in x {
result += f64::powi(*x_curr, 2) - 10.0 * f64::cos(2.0 * f64::consts::PI * *x_curr);
}
result += 10.0 * x.len() as f64;
result
}
pub fn ripple1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ripple 1 function takes only a two dimensional vector as a parameter."
);
let mut res = 0_f64;
for arg in x {
res += -1_f64
* f64::powf(
f64::consts::E,
-2_f64 * f64::ln(2_f64 * f64::powi((arg - 1_f64) / 0.8, 2)),
)
* (f64::powi(f64::sin(5_f64 * f64::consts::PI * arg), 6)
+ 0.1 * f64::powi(f64::cos(500_f64 * f64::consts::PI * arg), 2))
}
res
}
pub fn ripple25(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ripple 25 function takes only a two dimensional vector as a parameter."
);
let mut res = 0_f64;
for arg in x {
res += -1_f64
* f64::powf(
f64::consts::E,
-2_f64 * f64::ln(2_f64 * f64::powi((arg - 1_f64) / 0.8, 2)),
)
* (f64::powi(f64::sin(5_f64 * f64::consts::PI * arg), 6))
}
res
}
pub fn rosenbrock(x: &Vec<f64>) -> f64 {
assert!(
x.len() >= 2,
"Rosenbrock function takes an at least two dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for i in 0..x.len() - 1 {
result += 100.0 * f64::powi(x[i + 1] - f64::powi(x[i], 2), 2) + f64::powi(1.0 - x[i], 2);
}
result
}
pub fn rosenbrock_modified(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ripple 25 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
74_f64 + 100_f64 * f64::powi(x2 - f64::powi(x1, 2), 2) + f64::powi(1_f64 - x2, 2)
- 400_f64
* f64::powf(
f64::consts::E,
-1_f64 * (f64::powi(x1 + 1_f64, 2)) + f64::powi(x2 + 1_f64, 2) / 0.1,
)
}
pub fn rotated_ellipse(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Rotated Ellipse function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
7_f64 * f64::powi(x1, 2) - 6_f64 * f64::sqrt(3_f64) * x1 * x2 + 13_f64 * f64::powi(x2, 2)
}
pub fn rotated_ellipse2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Rotated Ellipse 2 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) - x1 * x2 + f64::powi(x2, 2)
}
pub fn rotated_hyper_ellipsoid(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Rotated Hyper-Ellipsoid function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for i in 0..x.len() {
for x_j in x.iter().take(i + 1) {
result += f64::powi(*x_j, 2);
}
}
result
}
pub fn rump(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Rump function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
(333.75 - f64::powi(x1, 2)) * f64::powi(x2, 6)
+ f64::powi(x1, 2)
* (11_f64 * f64::powi(x1, 2) * f64::powi(x2, 2) - 121_f64 * f64::powi(x2, 4) - 2_f64)
+ 5.5 * f64::powi(x2, 8)
+ x1 / 2_f64 * x2
}
pub fn salomon(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for arg in x {
res += f64::powi(*arg, 2)
}
1_f64 - f64::cos(2_f64 * f64::consts::PI * res) + 0.1 * f64::sqrt(res)
}
pub fn sargan(x: &Vec<f64>) -> f64 {
let mut res = 0_f64;
for (dim, val) in x.iter().enumerate() {
let mut innersum = 0_f64;
for j in 0..x.len() {
if dim != j {
innersum += val * x[j]
}
res += x.len() as f64 * (f64::powi(*val, 2) + 0.4 * innersum)
}
}
res
}
pub fn schaffer_n1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Schaffer function N.1 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
0.5 + (f64::powi(f64::sin(f64::powi(x1, 2) + f64::powi(x2, 2)), 2) - 0.5)
/ (1_f64 + 0.001 * (f64::powi(x1, 2) + f64::powi(x2, 2)))
}
pub fn schaffer_n2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Schaffer function N.2 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
0.5 + (f64::powi(f64::sin(f64::powi(x1, 2) - f64::powi(x2, 2)), 2) - 0.5)
/ f64::powi(1.0 + 0.001 * (f64::powi(x1, 2) + f64::powi(x2, 2)), 2)
}
pub fn schaffer_n3(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Schaffer function N.3 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
0.5 + (f64::powi(
f64::sin(f64::cos(f64::abs(f64::powi(x1, 2) - f64::powi(x2, 2)))),
2,
) - 0.5)
/ (1_f64 + 0.001 * f64::powi(f64::powi(x1, 2) + f64::powi(x2, 2), 2))
}
pub fn schaffer_n4(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Schaffer function N.4 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
0.5 + (f64::powi(
f64::cos(f64::sin(f64::abs(f64::powi(x1, 2) - f64::powi(x2, 2)))),
2,
) - 0.5)
/ f64::powi(1.0 + 0.001 * (f64::powi(x1, 2) + f64::powi(x2, 2)), 2)
}
pub fn schmidt_vetters(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
3,
"Schmidt Vetters function takes only a three dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
1_f64 / (1_f64 + f64::powi(x1 - x2, 2))
+ f64::sin((f64::consts::PI * x2 + x3) / 2_f64)
+ f64::powf(f64::consts::E, f64::powi((x1 + x2) / 2_f64 - 2_f64, 2))
}
pub fn schumer_steiglitz(x: &[f64]) -> f64 {
let mut res = 0_f64;
for (_dim, arg) in x.iter().enumerate() {
res += f64::powi(*arg, 4)
}
res
}
pub fn schwefel(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Schwefel function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 418.9829 * (x.len() as f64);
for x_curr in x {
result -= *x_curr * f64::sin(f64::sqrt(f64::abs(*x_curr)));
}
result
}
pub fn shekel(x: &Vec<f64>, m: i32, beta: &Vec<f64>, c: &Vec<Vec<f64>>) -> f64 {
assert_eq!(
x.len(),
4,
"Shekel function takes only a four dimensional vector as a parameter."
);
assert_eq!(c[0].len(), 4, "C is a 4-by-m-dimensional matrix");
assert_eq!(c.len(), m as usize, "C is a 4-by-m-dimensional matrix");
assert_eq!(beta.len(), m as usize, "Beta is an -m-dimensional vector");
let mut res = 0_f64;
for i in 1..m + 1 {
let mut sum = 0_f64;
for j in 1..5 {
sum += f64::powi(x[j] - c[j][j], 2)
}
res += f64::powi(sum + beta[i as usize], -1)
}
res
}
pub fn shekel_default(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
4,
"Shekel function takes only a four dimensional vector as a parameter."
);
let mut res = 0.0;
let raw = vec![1.0, 2.0, 2.0, 4.0, 4.0, 6.0, 3.0, 7.0, 5.0, 5.0];
let beta = raw.into_iter().map(|x| 0.1 * x).collect::<Vec<_>>();
let c = vec![
vec![4.0, 1.0, 8.0, 6.0, 3.0, 2.0, 5.0, 8.0, 6.0, 7.0],
vec![4.0, 1.0, 8.0, 6.0, 7.0, 9.0, 3.0, 1.0, 2.0, 3.6],
vec![4.0, 1.0, 8.0, 6.0, 3.0, 2.0, 5.0, 8.0, 6.0, 7.0],
vec![4.0, 1.0, 8.0, 6.0, 7.0, 9.0, 3.0, 1.0, 2.0, 3.6],
];
for i in 1..11 {
let mut sum = 0_f64;
for j in 1..5 {
sum += f64::powi(x[j] - c[j][j], 2)
}
res += f64::powi(sum + beta[i as usize], -1)
}
res
}
pub fn shubert(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Shubert function N.3 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let mut y1 = 0_f64;
let mut y2 = 0_f64;
for i in 1..6 {
y1 += i as f64 * f64::cos((i + 1) as f64 * x1 + i as f64);
y2 += i as f64 * f64::cos((i + 1) as f64 * x2 + i as f64);
}
y1 * y2
}
pub fn sphere(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Sphere function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for x_curr in x {
result += f64::powi(*x_curr, 2)
}
result
}
pub fn styblinski_tang(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Styblinski-Tang function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for x_curr in x {
result += f64::powi(*x_curr, 4) - 16.0 * f64::powi(*x_curr, 2) + 5.0 * *x_curr;
}
result *= 0.5;
result
}
pub fn stretched_v_sine_wave(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Streched V Sine Wave function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for (index, x_curr) in x.iter().enumerate() {
result += f64::powf(f64::powi(x[index + 1], 2) + f64::powi(*x_curr, 2), 0.25)
* (f64::powi(
f64::sin(50_f64 * f64::powf(f64::powi(x[index + 1], 2) + f64::powi(*x_curr, 2), 0.1)),
2,
) + 0.1)
}
result
}
pub fn sum_of_powers(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Sum of Different Powers function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for (index, x_curr) in x.iter().enumerate() {
result += f64::powi(f64::abs(*x_curr), (index + 1) as i32);
}
result
}
pub fn sum_squares(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Sum Squares function takes an at least one dimensional vector as a parameter."
);
let mut result: f64 = 0.0;
for (index, x_curr) in x.iter().enumerate() {
result += ((index + 1) as f64) * f64::powi(*x_curr, 2);
}
result
}
pub fn testtube_holder(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Testtube Holder function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-4_f64
* f64::sin(x1)
* f64::cos(x2)
* f64::powf(
f64::consts::E,
f64::abs(f64::cos(f64::powi(x1, 2) + f64::powi(x2, 2)) / 200_f64),
)
}
pub fn trecanni(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Trecanni function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 4) - 4_f64 * f64::powi(x1, 3) + 4_f64 * x1 + f64::powi(x2, 2)
}
pub fn trid(x: &Vec<f64>) -> f64 {
assert!(
x.len() >= 2,
"Trid function takes an at least two dimensional vector as a parameter."
);
let mut result: f64 = f64::powi(x[0] - 1.0, 2);
for i in 1..x.len() {
result += f64::powi(x[i] - 1.0, 2) - x[i] * x[i - 1];
}
result
}
pub fn trid10(x: &Vec<f64>) -> f64 {
assert!(
x.len() >= 2,
"Trid 10 function takes an at least two dimensional vector as a parameter."
);
let mut temp1 = 0_f64;
let mut temp2 = 0_f64;
for (dim, val) in x.iter().enumerate() {
temp1 += f64::powi(val - 1_f64, 2);
temp2 += val * x[dim - 1]
}
temp1 - temp2
}
pub fn trigonometric1(x: &Vec<f64>) -> f64 {
assert!(
x.len() >= 2,
"Trigonometric 1 function takes an at least two dimensional vector as a parameter."
);
let mut res = 0_f64;
let mut sum = 0_f64;
for arg in x {
sum += f64::cos(*arg);
}
for (dim, arg) in x.iter().enumerate() {
res += f64::powi(
x.len() as f64 - sum + dim as f64 * (1_f64 - f64::cos(*arg) - f64::sin(*arg)),
2,
)
}
res
}
pub fn trigonometric2(x: &Vec<f64>) -> f64 {
assert!(
x.len() >= 2,
"Trigonometric 2 function takes an at least two dimensional vector as a parameter."
);
let mut sum = 0_f64;
for arg in x {
sum += f64::cos(*arg);
}
for (_dim, arg) in x.iter().enumerate() {
sum += 8_f64 * f64::powi(f64::sin(7_f64 * f64::powi(arg - 0.9, 2)), 2)
+ 6_f64 * f64::powi(f64::sin(14_f64 * f64::powi(x[0] - 0.9, 2)), 2)
+ f64::powi(arg - 0.9, 2)
}
1_f64 + sum
}
pub fn ursem1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ursem function N.1 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1_f64 * f64::sin(2_f64 * x1 - 0.5 * f64::consts::PI) - 3_f64 * f64::cos(x2) - 0.5 * x1
}
pub fn ursem3(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ursem function N.3 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-1_f64
* f64::sin(2.2 * f64::consts::PI * x1 + 0.5 * f64::consts::PI)
* (2_f64 - f64::abs(x1) / 2_f64)
* (3_f64 - f64::abs(x1) / 2_f64)
- 1_f64
* f64::sin(2.2 * f64::consts::PI * x2 + 0.5 * f64::consts::PI)
* (2_f64 - f64::abs(x2) / 2_f64)
* (3_f64 - f64::abs(x2) / 2_f64)
}
pub fn ursem4(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ursem function N.4 takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-3_f64
* f64::sin(0.5 * f64::consts::PI * x1 + f64::consts::PI * 0.5)
* (2_f64 - f64::sqrt(f64::powi(x1, 2) + f64::powi(x2, 2)))
/ 4_f64
}
pub fn ursem_waves(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Ursem Waves function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
-0.9 * f64::powi(x1, 2)
+ x1 * x2 * (f64::powi(x2, 2) - 4.5 * f64::powi(x2, 2))
+ 4.7 * f64::cos(3_f64 * x1 - f64::powi(x2, 2) * (2_f64 + x1)) * f64::sin(2.5 * f64::consts::PI)
}
pub fn trefethen(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Trefethen function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powf(f64::consts::E, f64::sin(50_f64 * x1))
+ f64::sin(60_f64 * f64::powf(f64::consts::E, x2))
+ f64::sin(70_f64 * f64::sin(x1))
+ f64::sin(f64::sin(80_f64 * x2))
- f64::sin(10_f64 * (x1 + x2))
+ 0.25 * (f64::powi(x1, 2) + f64::powi(x2, 2))
}
pub fn vss(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Venter Sobiesczanski-Sobieski function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(x1, 2) - 100_f64 * f64::powi(f64::cos(x1), 2) - 100_f64 * f64::cos(f64::powi(x1, 2) / 30_f64)
+ f64::powi(x2, 2)
- 100_f64
* f64::powf(
f64::cos(x2),
2_f64 - 100_f64 * f64::cos(f64::powi(x2, 2) / 30_f64),
)
}
pub fn wayburn_seader1(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Wayburn Seader 1 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::powi(x1, 6) + f64::powi(x2, 4) - 17_f64, 2) + f64::powi(2_f64 * x1 + x2 - 4_f64, 2)
}
pub fn wayburn_seader2(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Wayburn Seader 2 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(
1.613 - 4_f64 * f64::powi(x1 - 0.3125, 2) - 4_f64 * f64::powi(x2 - 1.625, 2),
2,
) + f64::powi(x1 - 2_f64, 2)
}
pub fn wayburn_seader3(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Wayburn Seader 3 function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
2_f64 * f64::powi(x1, 3) / 3_f64 - 8_f64 * f64::powi(x1, 2) + 33_f64 * x1 - x1 * x2
+ 5_f64
+ f64::powi(f64::powi(x1 - 4_f64, 2) + f64::powi(x2 - 5_f64, 2) - 4_f64, 2)
}
#[allow(clippy::ptr_arg)]
pub fn wordmax(chromosome: &Vec<bool>) -> f64 {
chromosome.iter().filter(|gene| **gene).count() as f64
}
pub fn wolfe(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
3,
"Wolfe function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
let x3 = x[2];
(4 / 3) as f64 * f64::powf(f64::powi(x1, 2) + f64::powi(x2, 2) - x1 * x2, 0.75) + x3
}
pub fn xin_she_yang_2(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Xin-She Yang function 2 takes an at least one dimensional vector as a parameter."
);
let mut temp1 = 0.0;
let mut temp2 = 0.0;
for (_index, x_curr) in x.iter().enumerate() {
temp1 += f64::abs(*x_curr);
temp2 += f64::sin(f64::powi(*x_curr, 2))
}
temp1 * f64::exp(-temp2)
}
pub fn zakharov(x: &Vec<f64>) -> f64 {
assert!(
!x.is_empty(),
"Zakharov function takes an at least one dimensional vector as a parameter."
);
let mut temp1 = 0.0;
let mut temp2 = 0.0;
for (index, x_curr) in x.iter().enumerate() {
temp1 += f64::powi(*x_curr, 2);
temp2 += 0.5 * ((index + 1) as f64) * *x_curr;
}
temp1 + f64::powi(temp2, 2) + f64::powi(temp2, 4)
}
pub fn zettl(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Zettl function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
f64::powi(f64::powi(x1, 2) + f64::powi(x2, 2) - 2_f64 * x1, 2) + 0.25 * x1
}
pub fn zirilli(x: &Vec<f64>) -> f64 {
assert_eq!(
x.len(),
2,
"Zirilli function takes only a two dimensional vector as a parameter."
);
let x1 = x[0];
let x2 = x[1];
0.25 * f64::powi(x1, 4) - 0.5 * f64::powi(x1, 2) + 0.1 * x1 + 0.5 * f64::powi(x2, 2)
}