1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use num::{Float, FromPrimitive};
use std::f64::consts::PI;
use std::iter::Sum;
pub fn levy<T: Float + FromPrimitive + Sum>(param: &[T]) -> T {
let plen = param.len();
assert!(plen >= 2);
let n1 = T::from_f64(1.0).unwrap();
let n2 = T::from_f64(2.0).unwrap();
let n4 = T::from_f64(4.0).unwrap();
let n10 = T::from_f64(10.0).unwrap();
let w = |x: T| n1 - (x - n1) / n4;
let pi = T::from_f64(PI).unwrap();
(pi * w(param[0])).sin().powi(2)
+ param[1..(plen - 1)]
.iter()
.map(|x| w(*x))
.map(|wi: T| (wi - n1).powi(2) * (n1 + n10 * (pi * wi + n1)))
.sum()
+ (w(param[plen - 1]) - n1).powi(2) * (n1 + (n2 * pi * w(param[plen - 1])).sin().powi(2))
}
pub fn levy_n13<T: Float + FromPrimitive + Sum>(param: &[T]) -> T {
let plen = param.len();
assert!(plen == 2);
let n1 = T::from_f64(1.0).unwrap();
let n2 = T::from_f64(2.0).unwrap();
let n3 = T::from_f64(3.0).unwrap();
let pi = T::from_f64(PI).unwrap();
let (x1, x2) = (param[0], param[1]);
(n3 * pi * x1).sin().powi(2)
+ (x1 - n1).powi(2) * (n1 + (n3 * pi * x2).sin().powi(2))
+ (x2 - n1).powi(2) * (n1 + (n2 * pi * x2).sin().powi(2))
}
mod tests {
#[test]
fn test_levy_optimum() {
assert!((::levy(&[1_f32, 1_f32, 1_f32])).abs() < ::std::f32::EPSILON);
assert!((::levy(&[1_f64, 1_f64, 1_f64])).abs() < ::std::f64::EPSILON);
}
#[test]
fn test_levy_n13_optimum() {
assert!((::levy_n13(&[1_f32, 1_f32])).abs() < ::std::f32::EPSILON);
assert!((::levy_n13(&[1_f64, 1_f64])).abs() < ::std::f64::EPSILON);
}
#[test]
#[should_panic]
fn test_levy_param_length() {
::levy(&[0.0_f32]);
}
#[test]
#[should_panic]
fn test_levy_n13_param_length() {
::levy_n13(&[0.0_f32, 0.0_f32, 0.0_f32]);
}
}