@@ -42,10 +42,95 @@ where
42
42
. sum ( )
43
43
}
44
44
45
+ /// Derivative of Styblinski-Tang test function
46
+ pub fn styblinski_tang_derivative < T > ( param : & [ T ] ) -> Vec < T >
47
+ where
48
+ T : Float + FromPrimitive + Sum ,
49
+ {
50
+ let n2 = T :: from_f64 ( 2.0 ) . unwrap ( ) ;
51
+ let n2_5 = T :: from_f64 ( 2.5 ) . unwrap ( ) ;
52
+ let n16 = T :: from_f64 ( 16.0 ) . unwrap ( ) ;
53
+
54
+ param
55
+ . iter ( )
56
+ . map ( |x| n2 * x. powi ( 3 ) - n16 * * x + n2_5)
57
+ . collect ( )
58
+ }
59
+
60
+ /// Derivative of Styblinski-Tang test function
61
+ ///
62
+ /// This is the const generics version, which requires the number of parameters to be known
63
+ /// at compile time.
64
+ pub fn styblinski_tang_derivative_const < const N : usize , T > ( param : & [ T ; N ] ) -> [ T ; N ]
65
+ where
66
+ T : Float + FromPrimitive + Sum ,
67
+ {
68
+ let n0 = T :: from_f64 ( 0.0 ) . unwrap ( ) ;
69
+ let n2 = T :: from_f64 ( 2.0 ) . unwrap ( ) ;
70
+ let n2_5 = T :: from_f64 ( 2.5 ) . unwrap ( ) ;
71
+ let n16 = T :: from_f64 ( 16.0 ) . unwrap ( ) ;
72
+
73
+ let mut out = [ n0; N ] ;
74
+
75
+ param
76
+ . iter ( )
77
+ . zip ( out. iter_mut ( ) )
78
+ . map ( |( x, o) | * o = n2 * x. powi ( 3 ) - n16 * * x + n2_5)
79
+ . count ( ) ;
80
+
81
+ out
82
+ }
83
+
84
+ /// Hessian of Styblinski-Tang test function
85
+ pub fn styblinski_tang_hessian < T > ( param : & [ T ] ) -> Vec < Vec < T > >
86
+ where
87
+ T : Float + FromPrimitive + Sum ,
88
+ {
89
+ let n0 = T :: from_f64 ( 0.0 ) . unwrap ( ) ;
90
+ let n6 = T :: from_f64 ( 6.0 ) . unwrap ( ) ;
91
+ let n16 = T :: from_f64 ( 16.0 ) . unwrap ( ) ;
92
+
93
+ let n = param. len ( ) ;
94
+ let mut out = vec ! [ vec![ n0; n] ; n] ;
95
+
96
+ param
97
+ . iter ( )
98
+ . enumerate ( )
99
+ . map ( |( i, x) | out[ i] [ i] = n6 * x. powi ( 2 ) - n16)
100
+ . count ( ) ;
101
+
102
+ out
103
+ }
104
+
105
+ /// Hessian of Styblinski-Tang test function
106
+ ///
107
+ /// This is the const generics version, which requires the number of parameters to be known
108
+ /// at compile time.
109
+ pub fn styblinski_tang_hessian_const < const N : usize , T > ( param : & [ T ; N ] ) -> [ [ T ; N ] ; N ]
110
+ where
111
+ T : Float + FromPrimitive + Sum ,
112
+ {
113
+ let n0 = T :: from_f64 ( 0.0 ) . unwrap ( ) ;
114
+ let n6 = T :: from_f64 ( 6.0 ) . unwrap ( ) ;
115
+ let n16 = T :: from_f64 ( 16.0 ) . unwrap ( ) ;
116
+
117
+ let mut out = [ [ n0; N ] ; N ] ;
118
+
119
+ param
120
+ . iter ( )
121
+ . enumerate ( )
122
+ . map ( |( i, x) | out[ i] [ i] = n6 * x. powi ( 2 ) - n16)
123
+ . count ( ) ;
124
+
125
+ out
126
+ }
127
+
45
128
#[ cfg( test) ]
46
129
mod tests {
47
130
use super :: * ;
48
131
use approx:: assert_relative_eq;
132
+ use finitediff:: FiniteDiff ;
133
+ use proptest:: prelude:: * ;
49
134
use std:: f32;
50
135
51
136
#[ test]
@@ -60,5 +145,110 @@ mod tests {
60
145
-117.4984971113142 ,
61
146
epsilon = f64 :: EPSILON
62
147
) ;
148
+
149
+ let deriv = styblinski_tang_derivative ( & [ -2.903534_f64 , -2.903534_f64 , -2.903534_f64 ] ) ;
150
+ for i in 0 ..3 {
151
+ assert_relative_eq ! ( deriv[ i] , 0.0 , epsilon = 1e-5 , max_relative = 1e-5 ) ;
152
+ }
153
+ }
154
+
155
+ proptest ! {
156
+ #[ test]
157
+ fn test_styblinski_tang_derivative_finitediff( a in -5.0 ..5.0 ,
158
+ b in -5.0 ..5.0 ,
159
+ c in -5.0 ..5.0 ,
160
+ d in -5.0 ..5.0 ,
161
+ e in -5.0 ..5.0 ,
162
+ f in -5.0 ..5.0 ,
163
+ g in -5.0 ..5.0 ,
164
+ h in -5.0 ..5.0 ) {
165
+ let param = [ a, b, c, d, e, f, g, h] ;
166
+ let derivative = styblinski_tang_derivative( & param) ;
167
+ let derivative_fd = Vec :: from( param) . central_diff( & |x| styblinski_tang( & x) ) ;
168
+ for i in 0 ..derivative. len( ) {
169
+ assert_relative_eq!(
170
+ derivative[ i] ,
171
+ derivative_fd[ i] ,
172
+ epsilon = std:: f64 :: EPSILON ,
173
+ max_relative = 1e-3
174
+ ) ;
175
+ }
176
+ }
177
+ }
178
+
179
+ proptest ! {
180
+ #[ test]
181
+ fn test_styblinski_tang_derivative_const_finitediff( a in -5.0 ..5.0 ,
182
+ b in -5.0 ..5.0 ,
183
+ c in -5.0 ..5.0 ,
184
+ d in -5.0 ..5.0 ,
185
+ e in -5.0 ..5.0 ,
186
+ f in -5.0 ..5.0 ,
187
+ g in -5.0 ..5.0 ,
188
+ h in -5.0 ..5.0 ) {
189
+ let param = [ a, b, c, d, e, f, g, h] ;
190
+ let derivative = styblinski_tang_derivative_const( & param) ;
191
+ let derivative_fd = Vec :: from( param) . central_diff( & |x| styblinski_tang( & x) ) ;
192
+ for i in 0 ..derivative. len( ) {
193
+ assert_relative_eq!(
194
+ derivative[ i] ,
195
+ derivative_fd[ i] ,
196
+ epsilon = std:: f64 :: EPSILON ,
197
+ max_relative = 1e-3
198
+ ) ;
199
+ }
200
+ }
201
+ }
202
+
203
+ proptest ! {
204
+ #[ test]
205
+ fn test_styblinski_tang_hessian_finitediff( a in -5.0 ..5.0 ,
206
+ b in -5.0 ..5.0 ,
207
+ c in -5.0 ..5.0 ,
208
+ d in -5.0 ..5.0 ,
209
+ e in -5.0 ..5.0 ,
210
+ f in -5.0 ..5.0 ,
211
+ g in -5.0 ..5.0 ,
212
+ h in -5.0 ..5.0 ) {
213
+ let param = [ a, b, c, d, e, f, g, h] ;
214
+ let derivative = styblinski_tang_hessian( & param) ;
215
+ let derivative_fd = Vec :: from( param) . central_hessian( & |x| styblinski_tang_derivative( & x) ) ;
216
+ for i in 0 ..derivative. len( ) {
217
+ for j in 0 ..derivative[ i] . len( ) {
218
+ assert_relative_eq!(
219
+ derivative[ i] [ j] ,
220
+ derivative_fd[ i] [ j] ,
221
+ epsilon = std:: f64 :: EPSILON ,
222
+ max_relative = 1e-3
223
+ ) ;
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ proptest ! {
230
+ #[ test]
231
+ fn test_styblinski_tang_hessian_const_finitediff( a in -5.0 ..5.0 ,
232
+ b in -5.0 ..5.0 ,
233
+ c in -5.0 ..5.0 ,
234
+ d in -5.0 ..5.0 ,
235
+ e in -5.0 ..5.0 ,
236
+ f in -5.0 ..5.0 ,
237
+ g in -5.0 ..5.0 ,
238
+ h in -5.0 ..5.0 ) {
239
+ let param = [ a, b, c, d, e, f, g, h] ;
240
+ let derivative = styblinski_tang_hessian_const( & param) ;
241
+ let derivative_fd = Vec :: from( param) . central_hessian( & |x| styblinski_tang_derivative( & x) ) ;
242
+ for i in 0 ..derivative. len( ) {
243
+ for j in 0 ..derivative[ i] . len( ) {
244
+ assert_relative_eq!(
245
+ derivative[ i] [ j] ,
246
+ derivative_fd[ i] [ j] ,
247
+ epsilon = std:: f64 :: EPSILON ,
248
+ max_relative = 1e-3
249
+ ) ;
250
+ }
251
+ }
252
+ }
63
253
}
64
254
}
0 commit comments