1#![doc = include_str!("../README.md")]
2#![doc = include_str!("../REFERENCES.md")]
3#![allow(unused)]
4
5use ndarray::{Array1, Array2};
6use std::collections::HashMap;
7
8pub mod functions;
10pub use functions::*;
11
12#[derive(Debug, Clone)]
14pub struct FunctionMetadata {
15 pub name: String,
17 pub bounds: Vec<(f64, f64)>,
19 pub global_minima: Vec<(Vec<f64>, f64)>,
21 pub inequality_constraints: Vec<fn(&Array1<f64>) -> f64>,
23 pub equality_constraints: Vec<fn(&Array1<f64>) -> f64>,
25 pub description: String,
27 pub multimodal: bool,
29 pub dimensions: Vec<usize>,
31}
32
33pub fn create_bounds(n: usize, lower: f64, upper: f64) -> Array2<f64> {
36 Array2::from_shape_fn((2, n), |(i, _)| if i == 0 { lower } else { upper })
37}
38
39pub fn get_function_metadata() -> HashMap<String, FunctionMetadata> {
41 let mut metadata = HashMap::new();
42
43 metadata.insert(
46 "ackley".to_string(),
47 FunctionMetadata {
48 name: "ackley".to_string(),
49 bounds: vec![(-32.768, 32.768); 2],
50 global_minima: vec![(vec![0.0, 0.0], 0.0)],
51 inequality_constraints: vec![],
52 equality_constraints: vec![],
53 description: "Multimodal Ackley function with many local minima".to_string(),
54 multimodal: true,
55 dimensions: vec![2],
56 },
57 );
58
59 metadata.insert(
60 "ackley_n2".to_string(),
61 FunctionMetadata {
62 name: "ackley_n2".to_string(),
63 bounds: vec![(-32.768, 32.768); 2],
64 global_minima: vec![(vec![-1.0, -1.0], -200.0)],
65 inequality_constraints: vec![],
66 equality_constraints: vec![],
67 description: "Modified Ackley N.2 function".to_string(),
68 multimodal: true,
69 dimensions: vec![2],
70 },
71 );
72
73 metadata.insert(
74 "ackley_n3".to_string(),
75 FunctionMetadata {
76 name: "ackley_n3".to_string(),
77 bounds: vec![(-32.768, 32.768); 2],
78 global_minima: vec![(vec![0.682584, -0.36075], -195.629)],
79 inequality_constraints: vec![],
80 equality_constraints: vec![],
81 description: "Modified Ackley N.3 function".to_string(),
82 multimodal: true,
83 dimensions: vec![2],
84 },
85 );
86
87 metadata.insert(
88 "alpine_n1".to_string(),
89 FunctionMetadata {
90 name: "alpine_n1".to_string(),
91 bounds: vec![(-10.0, 10.0); 2],
92 global_minima: vec![(vec![0.0, 0.0], 0.0)],
93 inequality_constraints: vec![],
94 equality_constraints: vec![],
95 description: "Alpine N.1 function".to_string(),
96 multimodal: true,
97 dimensions: vec![2],
98 },
99 );
100
101 metadata.insert(
102 "alpine_n2".to_string(),
103 FunctionMetadata {
104 name: "alpine_n2".to_string(),
105 bounds: vec![(0.0, 10.0); 2],
106 global_minima: vec![(vec![7.917, 7.917], -12.259)],
107 inequality_constraints: vec![],
108 equality_constraints: vec![],
109 description: "Alpine N.2 function".to_string(),
110 multimodal: true,
111 dimensions: vec![2],
112 },
113 );
114
115 metadata.insert(
116 "beale".to_string(),
117 FunctionMetadata {
118 name: "beale".to_string(),
119 bounds: vec![(-10.0, 10.0); 2],
120 global_minima: vec![(vec![3.0, 0.5], 0.0)],
121 inequality_constraints: vec![],
122 equality_constraints: vec![],
123 description: "Beale function".to_string(),
124 multimodal: false,
125 dimensions: vec![2],
126 },
127 );
128
129 metadata.insert(
130 "bent_cigar".to_string(),
131 FunctionMetadata {
132 name: "bent_cigar".to_string(),
133 bounds: vec![(-100.0, 100.0); 2],
134 global_minima: vec![(vec![0.0, 0.0], 0.0)],
135 inequality_constraints: vec![],
136 equality_constraints: vec![],
137 description: "Bent Cigar function".to_string(),
138 multimodal: false,
139 dimensions: vec![2],
140 },
141 );
142
143 metadata.insert(
144 "bent_cigar_alt".to_string(),
145 FunctionMetadata {
146 name: "bent_cigar_alt".to_string(),
147 bounds: vec![(-100.0, 100.0); 2],
148 global_minima: vec![(vec![0.0, 0.0], 0.0)],
149 inequality_constraints: vec![],
150 equality_constraints: vec![],
151 description: "Alternative Bent Cigar function".to_string(),
152 multimodal: false,
153 dimensions: vec![2],
154 },
155 );
156
157 metadata.insert(
158 "binh_korn_constraint1".to_string(),
159 FunctionMetadata {
160 name: "binh_korn_constraint1".to_string(),
161 bounds: vec![(0.0, 5.0), (0.0, 3.0)],
162 global_minima: vec![(vec![0.0, 0.0], 0.0)],
163 inequality_constraints: vec![binh_korn_constraint1, binh_korn_constraint2],
164 equality_constraints: vec![],
165 description: "Binh-Korn constraints: x1^2 + x2^2 <= 25 and (x1-8)^2 + (x2+3)^2 >= 7.7"
166 .to_string(),
167 multimodal: false,
168 dimensions: vec![2],
169 },
170 );
171
172 metadata.insert(
173 "binh_korn_constraint2".to_string(),
174 FunctionMetadata {
175 name: "binh_korn_constraint2".to_string(),
176 bounds: vec![(0.0, 5.0), (0.0, 3.0)],
177 global_minima: vec![],
178 inequality_constraints: vec![],
179 equality_constraints: vec![],
180 description: "Binh-Korn constraint 2 function".to_string(),
181 multimodal: false,
182 dimensions: vec![2],
183 },
184 );
185
186 metadata.insert(
187 "binh_korn_weighted".to_string(),
188 FunctionMetadata {
189 name: "binh_korn_weighted".to_string(),
190 bounds: vec![(0.0, 5.0), (0.0, 3.0)],
191 global_minima: vec![],
192 inequality_constraints: vec![],
193 equality_constraints: vec![],
194 description: "Binh-Korn weighted function".to_string(),
195 multimodal: false,
196 dimensions: vec![2],
197 },
198 );
199
200 metadata.insert(
201 "bird".to_string(),
202 FunctionMetadata {
203 name: "bird".to_string(),
204 bounds: vec![(-2.0 * std::f64::consts::PI, 2.0 * std::f64::consts::PI); 2],
205 global_minima: vec![
206 (vec![4.70104, 3.15294], -106.764537),
207 (vec![-1.58214, -3.13024], -106.764537),
208 ],
209 inequality_constraints: vec![],
210 equality_constraints: vec![],
211 description: "Bird function".to_string(),
212 multimodal: true,
213 dimensions: vec![2],
214 },
215 );
216
217 metadata.insert(
218 "bohachevsky1".to_string(),
219 FunctionMetadata {
220 name: "bohachevsky1".to_string(),
221 bounds: vec![(-15.0, 15.0); 2],
222 global_minima: vec![(vec![0.0, 0.0], 0.0)],
223 inequality_constraints: vec![],
224 equality_constraints: vec![],
225 description: "Bohachevsky N.1 function".to_string(),
226 multimodal: false,
227 dimensions: vec![2],
228 },
229 );
230
231 metadata.insert(
232 "bohachevsky2".to_string(),
233 FunctionMetadata {
234 name: "bohachevsky2".to_string(),
235 bounds: vec![(-15.0, 15.0); 2],
236 global_minima: vec![(vec![0.0, 0.0], 0.0)],
237 inequality_constraints: vec![],
238 equality_constraints: vec![],
239 description: "Bohachevsky N.2 function".to_string(),
240 multimodal: false,
241 dimensions: vec![2],
242 },
243 );
244
245 metadata.insert(
246 "bohachevsky3".to_string(),
247 FunctionMetadata {
248 name: "bohachevsky3".to_string(),
249 bounds: vec![(-15.0, 15.0); 2],
250 global_minima: vec![(vec![0.0, 0.0], 0.0)],
251 inequality_constraints: vec![],
252 equality_constraints: vec![],
253 description: "Bohachevsky N.3 function".to_string(),
254 multimodal: false,
255 dimensions: vec![2],
256 },
257 );
258
259 metadata.insert(
260 "booth".to_string(),
261 FunctionMetadata {
262 name: "booth".to_string(),
263 bounds: vec![(-10.0, 10.0); 2],
264 global_minima: vec![(vec![1.0, 3.0], 0.0)],
265 inequality_constraints: vec![],
266 equality_constraints: vec![],
267 description: "Booth function".to_string(),
268 multimodal: false,
269 dimensions: vec![2],
270 },
271 );
272
273 metadata.insert(
274 "branin".to_string(),
275 FunctionMetadata {
276 name: "branin".to_string(),
277 bounds: vec![(-5.0, 10.0), (0.0, 15.0)],
278 global_minima: vec![
279 (vec![-std::f64::consts::PI, 12.275], 0.397887),
280 (vec![std::f64::consts::PI, 2.275], 0.397887),
281 (vec![9.42478, 2.475], 0.397887),
282 ],
283 inequality_constraints: vec![],
284 equality_constraints: vec![],
285 description: "Branin function".to_string(),
286 multimodal: true,
287 dimensions: vec![2],
288 },
289 );
290
291 metadata.insert(
292 "brown".to_string(),
293 FunctionMetadata {
294 name: "brown".to_string(),
295 bounds: vec![(-1.0, 4.0); 2],
296 global_minima: vec![(vec![0.0, 0.0], 0.0)],
297 inequality_constraints: vec![],
298 equality_constraints: vec![],
299 description: "Brown function".to_string(),
300 multimodal: false,
301 dimensions: vec![2],
302 },
303 );
304
305 metadata.insert(
306 "bukin_n6".to_string(),
307 FunctionMetadata {
308 name: "bukin_n6".to_string(),
309 bounds: vec![(-15.0, -5.0), (-3.0, 3.0)],
310 global_minima: vec![(vec![-10.0, 1.0], 0.0)],
311 inequality_constraints: vec![],
312 equality_constraints: vec![],
313 description: "Bukin N.6 function".to_string(),
314 multimodal: true,
315 dimensions: vec![2],
316 },
317 );
318
319 metadata.insert(
320 "chung_reynolds".to_string(),
321 FunctionMetadata {
322 name: "chung_reynolds".to_string(),
323 bounds: vec![(-100.0, 100.0); 2],
324 global_minima: vec![(vec![0.0, 0.0], 0.0)],
325 inequality_constraints: vec![],
326 equality_constraints: vec![],
327 description: "Chung Reynolds function".to_string(),
328 multimodal: false,
329 dimensions: vec![2],
330 },
331 );
332
333 metadata.insert(
334 "cigar".to_string(),
335 FunctionMetadata {
336 name: "cigar".to_string(),
337 bounds: vec![(-100.0, 100.0); 2],
338 global_minima: vec![(vec![0.0, 0.0], 0.0)],
339 inequality_constraints: vec![],
340 equality_constraints: vec![],
341 description: "Cigar function".to_string(),
342 multimodal: false,
343 dimensions: vec![2],
344 },
345 );
346
347 metadata.insert(
348 "colville".to_string(),
349 FunctionMetadata {
350 name: "colville".to_string(),
351 bounds: vec![(-10.0, 10.0); 4],
352 global_minima: vec![(vec![1.0, 1.0, 1.0, 1.0], 0.0)],
353 inequality_constraints: vec![],
354 equality_constraints: vec![],
355 description: "Colville function (4D)".to_string(),
356 multimodal: false,
357 dimensions: vec![4],
358 },
359 );
360
361 metadata.insert(
362 "cosine_mixture".to_string(),
363 FunctionMetadata {
364 name: "cosine_mixture".to_string(),
365 bounds: vec![(-1.0, 1.0); 2],
366 global_minima: vec![(vec![0.0, 0.0], -0.2)],
367 inequality_constraints: vec![],
368 equality_constraints: vec![],
369 description: "Cosine Mixture function".to_string(),
370 multimodal: true,
371 dimensions: vec![2],
372 },
373 );
374
375 metadata.insert(
376 "cross_in_tray".to_string(),
377 FunctionMetadata {
378 name: "cross_in_tray".to_string(),
379 bounds: vec![(-15.0, 15.0); 2],
380 global_minima: vec![
381 (vec![1.3491, -1.3491], -2.06261),
382 (vec![1.3491, 1.3491], -2.06261),
383 (vec![-1.3491, 1.3491], -2.06261),
384 (vec![-1.3491, -1.3491], -2.06261),
385 ],
386 inequality_constraints: vec![],
387 equality_constraints: vec![],
388 description: "Cross-in-Tray function".to_string(),
389 multimodal: true,
390 dimensions: vec![2],
391 },
392 );
393
394 metadata.insert(
395 "de_jong_step2".to_string(),
396 FunctionMetadata {
397 name: "de_jong_step2".to_string(),
398 bounds: vec![(-100.0, 100.0); 2],
399 global_minima: vec![(vec![0.0, 0.0], 0.0)],
400 inequality_constraints: vec![],
401 equality_constraints: vec![],
402 description: "De Jong Step 2 function".to_string(),
403 multimodal: false,
404 dimensions: vec![2],
405 },
406 );
407
408 metadata.insert(
409 "dejong_f5_foxholes".to_string(),
410 FunctionMetadata {
411 name: "dejong_f5_foxholes".to_string(),
412 bounds: vec![(-65.536, 65.536); 2],
413 global_minima: vec![(vec![-32.0, -32.0], 0.998003838)],
414 inequality_constraints: vec![],
415 equality_constraints: vec![],
416 description: "De Jong F5 (Foxholes) function".to_string(),
417 multimodal: true,
418 dimensions: vec![2],
419 },
420 );
421
422 metadata.insert(
423 "different_powers".to_string(),
424 FunctionMetadata {
425 name: "different_powers".to_string(),
426 bounds: vec![(-1.0, 1.0); 2],
427 global_minima: vec![(vec![0.0, 0.0], 0.0)],
428 inequality_constraints: vec![],
429 equality_constraints: vec![],
430 description: "Different Powers function".to_string(),
431 multimodal: false,
432 dimensions: vec![2],
433 },
434 );
435
436 metadata.insert(
437 "discus".to_string(),
438 FunctionMetadata {
439 name: "discus".to_string(),
440 bounds: vec![(-100.0, 100.0); 2],
441 global_minima: vec![(vec![0.0, 0.0], 0.0)],
442 inequality_constraints: vec![],
443 equality_constraints: vec![],
444 description: "Discus function".to_string(),
445 multimodal: false,
446 dimensions: vec![2],
447 },
448 );
449
450 metadata.insert(
451 "dixons_price".to_string(),
452 FunctionMetadata {
453 name: "dixons_price".to_string(),
454 bounds: vec![(-10.0, 10.0); 2],
455 global_minima: vec![(vec![1.0, 0.5], 0.0)],
456 inequality_constraints: vec![],
457 equality_constraints: vec![],
458 description: "Dixon's Price function".to_string(),
459 multimodal: false,
460 dimensions: vec![2],
461 },
462 );
463
464 metadata.insert(
465 "drop_wave".to_string(),
466 FunctionMetadata {
467 name: "drop_wave".to_string(),
468 bounds: vec![(-5.12, 5.12); 2],
469 global_minima: vec![(vec![0.0, 0.0], -1.0)],
470 inequality_constraints: vec![],
471 equality_constraints: vec![],
472 description: "Drop-Wave function".to_string(),
473 multimodal: true,
474 dimensions: vec![2],
475 },
476 );
477
478 metadata.insert(
479 "easom".to_string(),
480 FunctionMetadata {
481 name: "easom".to_string(),
482 bounds: vec![(-100.0, 100.0); 2],
483 global_minima: vec![(vec![std::f64::consts::PI, std::f64::consts::PI], -1.0)],
484 inequality_constraints: vec![],
485 equality_constraints: vec![],
486 description: "Easom function".to_string(),
487 multimodal: false,
488 dimensions: vec![2],
489 },
490 );
491
492 metadata.insert(
493 "eggholder".to_string(),
494 FunctionMetadata {
495 name: "eggholder".to_string(),
496 bounds: vec![(-512.0, 512.0); 2],
497 global_minima: vec![(vec![512.0, 404.2319], -959.6407)],
498 inequality_constraints: vec![],
499 equality_constraints: vec![],
500 description: "Eggholder function".to_string(),
501 multimodal: true,
502 dimensions: vec![2],
503 },
504 );
505
506 metadata.insert(
507 "elliptic".to_string(),
508 FunctionMetadata {
509 name: "elliptic".to_string(),
510 bounds: vec![(-100.0, 100.0); 2],
511 global_minima: vec![(vec![0.0, 0.0], 0.0)],
512 inequality_constraints: vec![],
513 equality_constraints: vec![],
514 description: "Elliptic function".to_string(),
515 multimodal: false,
516 dimensions: vec![2],
517 },
518 );
519
520 metadata.insert(
521 "epistatic_michalewicz".to_string(),
522 FunctionMetadata {
523 name: "epistatic_michalewicz".to_string(),
524 bounds: vec![(0.0, std::f64::consts::PI); 2],
525 global_minima: vec![],
526 inequality_constraints: vec![],
527 equality_constraints: vec![],
528 description: "Epistatic Michalewicz function".to_string(),
529 multimodal: true,
530 dimensions: vec![2],
531 },
532 );
533
534 metadata.insert(
535 "expanded_griewank_rosenbrock".to_string(),
536 FunctionMetadata {
537 name: "expanded_griewank_rosenbrock".to_string(),
538 bounds: vec![(-100.0, 100.0); 2],
539 global_minima: vec![(vec![1.0, 1.0], 0.0)],
540 inequality_constraints: vec![],
541 equality_constraints: vec![],
542 description: "Expanded Griewank + Rosenbrock function".to_string(),
543 multimodal: true,
544 dimensions: vec![2],
545 },
546 );
547
548 metadata.insert(
549 "exponential".to_string(),
550 FunctionMetadata {
551 name: "exponential".to_string(),
552 bounds: vec![(-1.0, 1.0); 2],
553 global_minima: vec![(vec![0.0, 0.0], -1.0)],
554 inequality_constraints: vec![],
555 equality_constraints: vec![],
556 description: "Exponential function".to_string(),
557 multimodal: false,
558 dimensions: vec![2],
559 },
560 );
561
562 metadata.insert(
563 "forrester_2008".to_string(),
564 FunctionMetadata {
565 name: "forrester_2008".to_string(),
566 bounds: vec![(0.0, 1.0)],
567 global_minima: vec![(vec![0.757249], -6.02074)],
568 inequality_constraints: vec![],
569 equality_constraints: vec![],
570 description: "Forrester et al. (2008) function (1D)".to_string(),
571 multimodal: true,
572 dimensions: vec![1],
573 },
574 );
575
576 metadata.insert(
577 "freudenstein_roth".to_string(),
578 FunctionMetadata {
579 name: "freudenstein_roth".to_string(),
580 bounds: vec![(-10.0, 10.0); 2],
581 global_minima: vec![(vec![5.0, 4.0], 0.0), (vec![11.41, -0.8968], 48.9842)],
582 inequality_constraints: vec![],
583 equality_constraints: vec![],
584 description: "Freudenstein and Roth function".to_string(),
585 multimodal: true,
586 dimensions: vec![2],
587 },
588 );
589
590 metadata.insert(
591 "goldstein_price".to_string(),
592 FunctionMetadata {
593 name: "goldstein_price".to_string(),
594 bounds: vec![(-2.0, 2.0); 2],
595 global_minima: vec![(vec![0.0, -1.0], 3.0)],
596 inequality_constraints: vec![],
597 equality_constraints: vec![],
598 description: "Goldstein-Price function".to_string(),
599 multimodal: true,
600 dimensions: vec![2],
601 },
602 );
603
604 metadata.insert(
605 "gramacy_lee_2012".to_string(),
606 FunctionMetadata {
607 name: "gramacy_lee_2012".to_string(),
608 bounds: vec![(0.5, 2.5)],
609 global_minima: vec![(vec![0.548563], -0.869011)],
610 inequality_constraints: vec![],
611 equality_constraints: vec![],
612 description: "Gramacy & Lee (2012) function (1D)".to_string(),
613 multimodal: false,
614 dimensions: vec![1],
615 },
616 );
617
618 metadata.insert(
619 "gramacy_lee_function".to_string(),
620 FunctionMetadata {
621 name: "gramacy_lee_function".to_string(),
622 bounds: vec![(0.0, 6.0)],
623 global_minima: vec![],
624 inequality_constraints: vec![],
625 equality_constraints: vec![],
626 description: "Gramacy & Lee function (1D)".to_string(),
627 multimodal: true,
628 dimensions: vec![1],
629 },
630 );
631
632 metadata.insert(
633 "griewank".to_string(),
634 FunctionMetadata {
635 name: "griewank".to_string(),
636 bounds: vec![(-600.0, 600.0); 2],
637 global_minima: vec![(vec![0.0, 0.0], 0.0)],
638 inequality_constraints: vec![],
639 equality_constraints: vec![],
640 description: "Griewank function".to_string(),
641 multimodal: true,
642 dimensions: vec![2],
643 },
644 );
645
646 metadata.insert(
647 "griewank2".to_string(),
648 FunctionMetadata {
649 name: "griewank2".to_string(),
650 bounds: vec![(-600.0, 600.0); 2],
651 global_minima: vec![(vec![0.0, 0.0], 0.0)],
652 inequality_constraints: vec![],
653 equality_constraints: vec![],
654 description: "Griewank function variant 2".to_string(),
655 multimodal: true,
656 dimensions: vec![2],
657 },
658 );
659
660 metadata.insert(
661 "happy_cat".to_string(),
662 FunctionMetadata {
663 name: "happy_cat".to_string(),
664 bounds: vec![(-2.0, 2.0); 2],
665 global_minima: vec![(vec![-1.0, -1.0], 0.0)],
666 inequality_constraints: vec![],
667 equality_constraints: vec![],
668 description: "Happy Cat function".to_string(),
669 multimodal: false,
670 dimensions: vec![2],
671 },
672 );
673
674 metadata.insert(
675 "happycat".to_string(),
676 FunctionMetadata {
677 name: "happycat".to_string(),
678 bounds: vec![(-2.0, 2.0); 2],
679 global_minima: vec![(vec![-1.0, -1.0], 0.0)],
680 inequality_constraints: vec![],
681 equality_constraints: vec![],
682 description: "HappyCat function".to_string(),
683 multimodal: false,
684 dimensions: vec![2],
685 },
686 );
687
688 metadata.insert(
689 "hartman_3d".to_string(),
690 FunctionMetadata {
691 name: "hartman_3d".to_string(),
692 bounds: vec![(0.0, 1.0); 3],
693 global_minima: vec![(vec![0.114614, 0.555649, 0.852547], -3.86278)],
694 inequality_constraints: vec![],
695 equality_constraints: vec![],
696 description: "Hartmann 3D function".to_string(),
697 multimodal: true,
698 dimensions: vec![3],
699 },
700 );
701
702 metadata.insert(
703 "hartman_4d".to_string(),
704 FunctionMetadata {
705 name: "hartman_4d".to_string(),
706 bounds: vec![(0.0, 1.0); 4],
707 global_minima: vec![(vec![0.1873, 0.1936, 0.5576, 0.2647], -3.72983)],
708 inequality_constraints: vec![],
709 equality_constraints: vec![],
710 description: "Hartmann 4D function".to_string(),
711 multimodal: true,
712 dimensions: vec![4],
713 },
714 );
715
716 metadata.insert(
717 "hartman_6d".to_string(),
718 FunctionMetadata {
719 name: "hartman_6d".to_string(),
720 bounds: vec![(0.0, 1.0); 6],
721 global_minima: vec![(
722 vec![0.20169, 0.150011, 0.476874, 0.275332, 0.311652, 0.6573],
723 -3.32237,
724 )],
725 inequality_constraints: vec![],
726 equality_constraints: vec![],
727 description: "Hartmann 6D function".to_string(),
728 multimodal: true,
729 dimensions: vec![6],
730 },
731 );
732
733 metadata.insert(
734 "himmelblau".to_string(),
735 FunctionMetadata {
736 name: "himmelblau".to_string(),
737 bounds: vec![(-6.0, 6.0); 2],
738 global_minima: vec![
739 (vec![3.0, 2.0], 0.0),
740 (vec![-2.805118, 3.131312], 0.0),
741 (vec![-3.779310, -3.283186], 0.0),
742 (vec![3.584428, -1.848126], 0.0),
743 ],
744 inequality_constraints: vec![],
745 equality_constraints: vec![],
746 description: "Himmelblau's function".to_string(),
747 multimodal: true,
748 dimensions: vec![2],
749 },
750 );
751
752 metadata.insert(
753 "holder_table".to_string(),
754 FunctionMetadata {
755 name: "holder_table".to_string(),
756 bounds: vec![(-10.0, 10.0); 2],
757 global_minima: vec![
758 (vec![8.05502, 9.66459], -19.2085),
759 (vec![-8.05502, 9.66459], -19.2085),
760 (vec![8.05502, -9.66459], -19.2085),
761 (vec![-8.05502, -9.66459], -19.2085),
762 ],
763 inequality_constraints: vec![],
764 equality_constraints: vec![],
765 description: "Holder Table function".to_string(),
766 multimodal: true,
767 dimensions: vec![2],
768 },
769 );
770
771 metadata.insert(
772 "katsuura".to_string(),
773 FunctionMetadata {
774 name: "katsuura".to_string(),
775 bounds: vec![(0.0, 100.0); 2],
776 global_minima: vec![(vec![0.0, 0.0], 0.0)],
777 inequality_constraints: vec![],
778 equality_constraints: vec![],
779 description: "Katsuura function".to_string(),
780 multimodal: true,
781 dimensions: vec![2],
782 },
783 );
784
785 metadata.insert(
786 "keanes_bump_constraint1".to_string(),
787 FunctionMetadata {
788 name: "keanes_bump_constraint1".to_string(),
789 bounds: vec![(0.0, 10.0); 2],
790 global_minima: vec![],
791 inequality_constraints: vec![],
792 equality_constraints: vec![],
793 description: "Keane's Bump constraint 1 function".to_string(),
794 multimodal: false,
795 dimensions: vec![2],
796 },
797 );
798
799 metadata.insert(
800 "keanes_bump_constraint2".to_string(),
801 FunctionMetadata {
802 name: "keanes_bump_constraint2".to_string(),
803 bounds: vec![(0.0, 10.0); 2],
804 global_minima: vec![],
805 inequality_constraints: vec![],
806 equality_constraints: vec![],
807 description: "Keane's Bump constraint 2 function".to_string(),
808 multimodal: false,
809 dimensions: vec![2],
810 },
811 );
812
813 metadata.insert(
814 "keanes_bump_objective".to_string(),
815 FunctionMetadata {
816 name: "keanes_bump_objective".to_string(),
817 bounds: vec![(0.0, 10.0); 2],
818 global_minima: vec![(vec![1.393249, 0.0], 0.673668)],
819 inequality_constraints: vec![],
820 equality_constraints: vec![],
821 description: "Keane's Bump objective function".to_string(),
822 multimodal: true,
823 dimensions: vec![2],
824 },
825 );
826
827 metadata.insert(
828 "lampinen_simplified".to_string(),
829 FunctionMetadata {
830 name: "lampinen_simplified".to_string(),
831 bounds: vec![(0.0, 6.0); 2],
832 global_minima: vec![],
833 inequality_constraints: vec![],
834 equality_constraints: vec![],
835 description: "Lampinen simplified function".to_string(),
836 multimodal: false,
837 dimensions: vec![2],
838 },
839 );
840
841 metadata.insert(
842 "langermann".to_string(),
843 FunctionMetadata {
844 name: "langermann".to_string(),
845 bounds: vec![(0.0, 10.0); 2],
846 global_minima: vec![(vec![2.00299219, 1.006096], -5.1621259)],
847 inequality_constraints: vec![],
848 equality_constraints: vec![],
849 description: "Langermann function".to_string(),
850 multimodal: true,
851 dimensions: vec![2],
852 },
853 );
854
855 metadata.insert(
856 "levi13".to_string(),
857 FunctionMetadata {
858 name: "levi13".to_string(),
859 bounds: vec![(-10.0, 10.0); 2],
860 global_minima: vec![(vec![1.0, 1.0], 0.0)],
861 inequality_constraints: vec![],
862 equality_constraints: vec![],
863 description: "LƩvi N.13 function".to_string(),
864 multimodal: true,
865 dimensions: vec![2],
866 },
867 );
868
869 metadata.insert(
870 "levy".to_string(),
871 FunctionMetadata {
872 name: "levy".to_string(),
873 bounds: vec![(-10.0, 10.0); 2],
874 global_minima: vec![(vec![1.0, 1.0], 0.0)],
875 inequality_constraints: vec![],
876 equality_constraints: vec![],
877 description: "LƩvy function".to_string(),
878 multimodal: true,
879 dimensions: vec![2],
880 },
881 );
882
883 metadata.insert(
884 "levy_n13".to_string(),
885 FunctionMetadata {
886 name: "levy_n13".to_string(),
887 bounds: vec![(-10.0, 10.0); 2],
888 global_minima: vec![(vec![1.0, 1.0], 0.0)],
889 inequality_constraints: vec![],
890 equality_constraints: vec![],
891 description: "LƩvy N.13 function".to_string(),
892 multimodal: true,
893 dimensions: vec![2],
894 },
895 );
896
897 metadata.insert(
898 "matyas".to_string(),
899 FunctionMetadata {
900 name: "matyas".to_string(),
901 bounds: vec![(-10.0, 10.0); 2],
902 global_minima: vec![(vec![0.0, 0.0], 0.0)],
903 inequality_constraints: vec![],
904 equality_constraints: vec![],
905 description: "Matyas function".to_string(),
906 multimodal: false,
907 dimensions: vec![2],
908 },
909 );
910
911 metadata.insert(
912 "mccormick".to_string(),
913 FunctionMetadata {
914 name: "mccormick".to_string(),
915 bounds: vec![(-1.5, 4.0), (-3.0, 4.0)],
916 global_minima: vec![(vec![-0.54719, -1.54719], -1.9133)],
917 inequality_constraints: vec![],
918 equality_constraints: vec![],
919 description: "McCormick function".to_string(),
920 multimodal: true,
921 dimensions: vec![2],
922 },
923 );
924
925 metadata.insert(
926 "michalewicz".to_string(),
927 FunctionMetadata {
928 name: "michalewicz".to_string(),
929 bounds: vec![(0.0, std::f64::consts::PI); 2],
930 global_minima: vec![(vec![2.20, 1.57], -1.8013)],
931 inequality_constraints: vec![],
932 equality_constraints: vec![],
933 description: "Michalewicz function".to_string(),
934 multimodal: true,
935 dimensions: vec![2],
936 },
937 );
938
939 metadata.insert(
940 "mishras_bird_constraint".to_string(),
941 FunctionMetadata {
942 name: "mishras_bird_constraint".to_string(),
943 bounds: vec![(-10.0, 0.0); 2],
944 global_minima: vec![],
945 inequality_constraints: vec![],
946 equality_constraints: vec![],
947 description: "Mishra's Bird constraint function".to_string(),
948 multimodal: false,
949 dimensions: vec![2],
950 },
951 );
952
953 metadata.insert(
954 "mishras_bird_objective".to_string(),
955 FunctionMetadata {
956 name: "mishras_bird_objective".to_string(),
957 bounds: vec![(-10.0, 0.0); 2],
958 global_minima: vec![(vec![-3.1302468, -1.5821422], -106.7645367)],
959 inequality_constraints: vec![],
960 equality_constraints: vec![],
961 description: "Mishra's Bird objective function".to_string(),
962 multimodal: true,
963 dimensions: vec![2],
964 },
965 );
966
967 metadata.insert(
968 "periodic".to_string(),
969 FunctionMetadata {
970 name: "periodic".to_string(),
971 bounds: vec![(-10.0, 10.0); 2],
972 global_minima: vec![(vec![0.0, 0.0], 0.9)],
973 inequality_constraints: vec![],
974 equality_constraints: vec![],
975 description: "Periodic function".to_string(),
976 multimodal: true,
977 dimensions: vec![2],
978 },
979 );
980
981 metadata.insert(
982 "perm_0_d_beta".to_string(),
983 FunctionMetadata {
984 name: "perm_0_d_beta".to_string(),
985 bounds: vec![(-2.0, 2.0); 2],
986 global_minima: vec![(vec![1.0, 0.5], 0.0)],
987 inequality_constraints: vec![],
988 equality_constraints: vec![],
989 description: "Perm 0,d,β function".to_string(),
990 multimodal: false,
991 dimensions: vec![2],
992 },
993 );
994
995 metadata.insert(
996 "perm_d_beta".to_string(),
997 FunctionMetadata {
998 name: "perm_d_beta".to_string(),
999 bounds: vec![(-2.0, 2.0); 2],
1000 global_minima: vec![(vec![1.0, 0.5], 0.0)],
1001 inequality_constraints: vec![],
1002 equality_constraints: vec![],
1003 description: "Perm d,β function".to_string(),
1004 multimodal: false,
1005 dimensions: vec![2],
1006 },
1007 );
1008
1009 metadata.insert(
1010 "pinter".to_string(),
1011 FunctionMetadata {
1012 name: "pinter".to_string(),
1013 bounds: vec![(-10.0, 10.0); 2],
1014 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1015 inequality_constraints: vec![],
1016 equality_constraints: vec![],
1017 description: "Pinter function".to_string(),
1018 multimodal: false,
1019 dimensions: vec![2],
1020 },
1021 );
1022
1023 metadata.insert(
1024 "powell".to_string(),
1025 FunctionMetadata {
1026 name: "powell".to_string(),
1027 bounds: vec![(-4.0, 5.0); 4],
1028 global_minima: vec![(vec![0.0, 0.0, 0.0, 0.0], 0.0)],
1029 inequality_constraints: vec![],
1030 equality_constraints: vec![],
1031 description: "Powell function (4D)".to_string(),
1032 multimodal: false,
1033 dimensions: vec![4],
1034 },
1035 );
1036
1037 metadata.insert(
1038 "power_sum".to_string(),
1039 FunctionMetadata {
1040 name: "power_sum".to_string(),
1041 bounds: vec![(0.0, 4.0); 4],
1042 global_minima: vec![(vec![1.0, 2.0, 2.0, 3.0], 0.0)],
1043 inequality_constraints: vec![],
1044 equality_constraints: vec![],
1045 description: "Power Sum function (4D)".to_string(),
1046 multimodal: false,
1047 dimensions: vec![4],
1048 },
1049 );
1050
1051 metadata.insert(
1052 "qing".to_string(),
1053 FunctionMetadata {
1054 name: "qing".to_string(),
1055 bounds: vec![(-500.0, 500.0); 2],
1056 global_minima: vec![(vec![std::f64::consts::SQRT_2, 2.0], 0.0)],
1057 inequality_constraints: vec![],
1058 equality_constraints: vec![],
1059 description: "Qing function".to_string(),
1060 multimodal: false,
1061 dimensions: vec![2],
1062 },
1063 );
1064
1065 metadata.insert(
1066 "quadratic".to_string(),
1067 FunctionMetadata {
1068 name: "quadratic".to_string(),
1069 bounds: vec![(-10.0, 10.0); 2],
1070 global_minima: vec![(vec![0.19388, 0.48513], -3873.7243)],
1071 inequality_constraints: vec![],
1072 equality_constraints: vec![],
1073 description: "Quadratic function".to_string(),
1074 multimodal: false,
1075 dimensions: vec![2],
1076 },
1077 );
1078
1079 metadata.insert(
1080 "quartic".to_string(),
1081 FunctionMetadata {
1082 name: "quartic".to_string(),
1083 bounds: vec![(-1.28, 1.28); 2],
1084 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1085 inequality_constraints: vec![],
1086 equality_constraints: vec![],
1087 description: "Quartic function with noise".to_string(),
1088 multimodal: false,
1089 dimensions: vec![2],
1090 },
1091 );
1092
1093 metadata.insert(
1094 "rastrigin".to_string(),
1095 FunctionMetadata {
1096 name: "rastrigin".to_string(),
1097 bounds: vec![(-5.12, 5.12); 2],
1098 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1099 inequality_constraints: vec![],
1100 equality_constraints: vec![],
1101 description: "Highly multimodal Rastrigin function".to_string(),
1102 multimodal: true,
1103 dimensions: vec![2],
1104 },
1105 );
1106
1107 metadata.insert(
1108 "ridge".to_string(),
1109 FunctionMetadata {
1110 name: "ridge".to_string(),
1111 bounds: vec![(-5.0, 5.0); 2],
1112 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1113 inequality_constraints: vec![],
1114 equality_constraints: vec![],
1115 description: "Ridge function".to_string(),
1116 multimodal: false,
1117 dimensions: vec![2],
1118 },
1119 );
1120
1121 metadata.insert(
1122 "rosenbrock".to_string(),
1123 FunctionMetadata {
1124 name: "rosenbrock".to_string(),
1125 bounds: vec![(-2.048, 2.048); 2],
1126 global_minima: vec![(vec![1.0, 1.0], 0.0)],
1127 inequality_constraints: vec![],
1128 equality_constraints: vec![],
1129 description: "Classic Rosenbrock banana function".to_string(),
1130 multimodal: false,
1131 dimensions: vec![2],
1132 },
1133 );
1134
1135 metadata.insert(
1136 "rosenbrock_disk_constraint".to_string(),
1137 FunctionMetadata {
1138 name: "rosenbrock_disk_constraint".to_string(),
1139 bounds: vec![(-1.5, 1.5); 2],
1140 global_minima: vec![(vec![1.0, 1.0], 0.0)],
1141 inequality_constraints: vec![rosenbrock_disk_constraint],
1142 equality_constraints: vec![],
1143 description: "Disk constraint: x^2 + y^2 <= 2".to_string(),
1144 multimodal: false,
1145 dimensions: vec![2],
1146 },
1147 );
1148
1149 metadata.insert(
1150 "rosenbrock_objective".to_string(),
1151 FunctionMetadata {
1152 name: "rosenbrock_objective".to_string(),
1153 bounds: vec![(-2.048, 2.048); 2],
1154 global_minima: vec![(vec![1.0, 1.0], 0.0)],
1155 inequality_constraints: vec![],
1156 equality_constraints: vec![],
1157 description: "Rosenbrock objective function".to_string(),
1158 multimodal: false,
1159 dimensions: vec![2],
1160 },
1161 );
1162
1163 metadata.insert(
1164 "rotated_hyper_ellipsoid".to_string(),
1165 FunctionMetadata {
1166 name: "rotated_hyper_ellipsoid".to_string(),
1167 bounds: vec![(-65.536, 65.536); 2],
1168 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1169 inequality_constraints: vec![],
1170 equality_constraints: vec![],
1171 description: "Rotated Hyper-ellipsoid function".to_string(),
1172 multimodal: false,
1173 dimensions: vec![2],
1174 },
1175 );
1176
1177 metadata.insert(
1178 "salomon".to_string(),
1179 FunctionMetadata {
1180 name: "salomon".to_string(),
1181 bounds: vec![(-100.0, 100.0); 2],
1182 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1183 inequality_constraints: vec![],
1184 equality_constraints: vec![],
1185 description: "Salomon function".to_string(),
1186 multimodal: true,
1187 dimensions: vec![2],
1188 },
1189 );
1190
1191 metadata.insert(
1192 "salomon_corrected".to_string(),
1193 FunctionMetadata {
1194 name: "salomon_corrected".to_string(),
1195 bounds: vec![(-100.0, 100.0); 2],
1196 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1197 inequality_constraints: vec![],
1198 equality_constraints: vec![],
1199 description: "Salomon corrected function".to_string(),
1200 multimodal: true,
1201 dimensions: vec![2],
1202 },
1203 );
1204
1205 metadata.insert(
1206 "schaffer_n2".to_string(),
1207 FunctionMetadata {
1208 name: "schaffer_n2".to_string(),
1209 bounds: vec![(-100.0, 100.0); 2],
1210 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1211 inequality_constraints: vec![],
1212 equality_constraints: vec![],
1213 description: "Schaffer N.2 function".to_string(),
1214 multimodal: true,
1215 dimensions: vec![2],
1216 },
1217 );
1218
1219 metadata.insert(
1220 "schaffer_n4".to_string(),
1221 FunctionMetadata {
1222 name: "schaffer_n4".to_string(),
1223 bounds: vec![(-100.0, 100.0); 2],
1224 global_minima: vec![
1225 (vec![0.0, 1.25313], 0.292579),
1226 (vec![0.0, -1.25313], 0.292579),
1227 ],
1228 inequality_constraints: vec![],
1229 equality_constraints: vec![],
1230 description: "Schaffer N.4 function".to_string(),
1231 multimodal: true,
1232 dimensions: vec![2],
1233 },
1234 );
1235
1236 metadata.insert(
1237 "schwefel".to_string(),
1238 FunctionMetadata {
1239 name: "schwefel".to_string(),
1240 bounds: vec![(-500.0, 500.0); 2],
1241 global_minima: vec![(vec![420.9687, 420.9687], 0.0)],
1242 inequality_constraints: vec![],
1243 equality_constraints: vec![],
1244 description: "Schwefel function".to_string(),
1245 multimodal: true,
1246 dimensions: vec![2],
1247 },
1248 );
1249
1250 metadata.insert(
1251 "schwefel2".to_string(),
1252 FunctionMetadata {
1253 name: "schwefel2".to_string(),
1254 bounds: vec![(-100.0, 100.0); 2],
1255 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1256 inequality_constraints: vec![],
1257 equality_constraints: vec![],
1258 description: "Schwefel 2 function".to_string(),
1259 multimodal: false,
1260 dimensions: vec![2],
1261 },
1262 );
1263
1264 metadata.insert(
1265 "sharp_ridge".to_string(),
1266 FunctionMetadata {
1267 name: "sharp_ridge".to_string(),
1268 bounds: vec![(-5.0, 5.0); 2],
1269 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1270 inequality_constraints: vec![],
1271 equality_constraints: vec![],
1272 description: "Sharp Ridge function".to_string(),
1273 multimodal: false,
1274 dimensions: vec![2],
1275 },
1276 );
1277
1278 metadata.insert(
1279 "shekel".to_string(),
1280 FunctionMetadata {
1281 name: "shekel".to_string(),
1282 bounds: vec![(0.0, 10.0); 4],
1283 global_minima: vec![(vec![4.0, 4.0, 4.0, 4.0], -10.5364)],
1284 inequality_constraints: vec![],
1285 equality_constraints: vec![],
1286 description: "Shekel function (4D)".to_string(),
1287 multimodal: true,
1288 dimensions: vec![4],
1289 },
1290 );
1291
1292 metadata.insert(
1293 "shubert".to_string(),
1294 FunctionMetadata {
1295 name: "shubert".to_string(),
1296 bounds: vec![(-10.0, 10.0); 2],
1297 global_minima: vec![(vec![-7.0835, 4.8580], -186.7309)],
1298 inequality_constraints: vec![],
1299 equality_constraints: vec![],
1300 description: "Shubert function".to_string(),
1301 multimodal: true,
1302 dimensions: vec![2],
1303 },
1304 );
1305
1306 metadata.insert(
1307 "six_hump_camel".to_string(),
1308 FunctionMetadata {
1309 name: "six_hump_camel".to_string(),
1310 bounds: vec![(-3.0, 3.0), (-2.0, 2.0)],
1311 global_minima: vec![
1312 (vec![0.0898, -0.7126], -1.0316),
1313 (vec![-0.0898, 0.7126], -1.0316),
1314 ],
1315 inequality_constraints: vec![],
1316 equality_constraints: vec![],
1317 description: "Six-hump Camel function".to_string(),
1318 multimodal: true,
1319 dimensions: vec![2],
1320 },
1321 );
1322
1323 metadata.insert(
1324 "sphere".to_string(),
1325 FunctionMetadata {
1326 name: "sphere".to_string(),
1327 bounds: vec![(-5.0, 5.0); 2],
1328 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1329 inequality_constraints: vec![],
1330 equality_constraints: vec![],
1331 description: "Simple quadratic sphere function".to_string(),
1332 multimodal: false,
1333 dimensions: vec![2],
1334 },
1335 );
1336
1337 metadata.insert(
1338 "step".to_string(),
1339 FunctionMetadata {
1340 name: "step".to_string(),
1341 bounds: vec![(-100.0, 100.0); 2],
1342 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1343 inequality_constraints: vec![],
1344 equality_constraints: vec![],
1345 description: "Step function".to_string(),
1346 multimodal: false,
1347 dimensions: vec![2],
1348 },
1349 );
1350
1351 metadata.insert(
1352 "styblinski_tang2".to_string(),
1353 FunctionMetadata {
1354 name: "styblinski_tang2".to_string(),
1355 bounds: vec![(-5.0, 5.0); 2],
1356 global_minima: vec![(vec![-2.903534, -2.903534], -78.332)],
1357 inequality_constraints: vec![],
1358 equality_constraints: vec![],
1359 description: "Styblinski-Tang function (2D)".to_string(),
1360 multimodal: true,
1361 dimensions: vec![2],
1362 },
1363 );
1364
1365 metadata.insert(
1366 "sum_of_different_powers".to_string(),
1367 FunctionMetadata {
1368 name: "sum_of_different_powers".to_string(),
1369 bounds: vec![(-1.0, 1.0); 2],
1370 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1371 inequality_constraints: vec![],
1372 equality_constraints: vec![],
1373 description: "Sum of Different Powers function".to_string(),
1374 multimodal: false,
1375 dimensions: vec![2],
1376 },
1377 );
1378
1379 metadata.insert(
1380 "sum_squares".to_string(),
1381 FunctionMetadata {
1382 name: "sum_squares".to_string(),
1383 bounds: vec![(-10.0, 10.0); 2],
1384 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1385 inequality_constraints: vec![],
1386 equality_constraints: vec![],
1387 description: "Sum Squares function".to_string(),
1388 multimodal: false,
1389 dimensions: vec![2],
1390 },
1391 );
1392
1393 metadata.insert(
1394 "tablet".to_string(),
1395 FunctionMetadata {
1396 name: "tablet".to_string(),
1397 bounds: vec![(-100.0, 100.0); 2],
1398 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1399 inequality_constraints: vec![],
1400 equality_constraints: vec![],
1401 description: "Tablet function".to_string(),
1402 multimodal: false,
1403 dimensions: vec![2],
1404 },
1405 );
1406
1407 metadata.insert(
1408 "three_hump_camel".to_string(),
1409 FunctionMetadata {
1410 name: "three_hump_camel".to_string(),
1411 bounds: vec![(-5.0, 5.0); 2],
1412 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1413 inequality_constraints: vec![],
1414 equality_constraints: vec![],
1415 description: "Three-hump Camel function".to_string(),
1416 multimodal: true,
1417 dimensions: vec![2],
1418 },
1419 );
1420
1421 metadata.insert(
1422 "trid".to_string(),
1423 FunctionMetadata {
1424 name: "trid".to_string(),
1425 bounds: vec![(-4.0, 4.0); 2],
1426 global_minima: vec![(vec![1.0, 2.0], -2.0)],
1427 inequality_constraints: vec![],
1428 equality_constraints: vec![],
1429 description: "Trid function".to_string(),
1430 multimodal: false,
1431 dimensions: vec![2],
1432 },
1433 );
1434
1435 metadata.insert(
1436 "vincent".to_string(),
1437 FunctionMetadata {
1438 name: "vincent".to_string(),
1439 bounds: vec![(0.25, 10.0); 2],
1440 global_minima: vec![(vec![7.70628, 7.70628], -2.0)],
1441 inequality_constraints: vec![],
1442 equality_constraints: vec![],
1443 description: "Vincent function".to_string(),
1444 multimodal: true,
1445 dimensions: vec![2],
1446 },
1447 );
1448
1449 metadata.insert(
1450 "whitley".to_string(),
1451 FunctionMetadata {
1452 name: "whitley".to_string(),
1453 bounds: vec![(-10.24, 10.24); 2],
1454 global_minima: vec![(vec![1.0, 1.0], 0.0)],
1455 inequality_constraints: vec![],
1456 equality_constraints: vec![],
1457 description: "Whitley function".to_string(),
1458 multimodal: true,
1459 dimensions: vec![2],
1460 },
1461 );
1462
1463 metadata.insert(
1464 "xin_she_yang_n1".to_string(),
1465 FunctionMetadata {
1466 name: "xin_she_yang_n1".to_string(),
1467 bounds: vec![(-2.0 * std::f64::consts::PI, 2.0 * std::f64::consts::PI); 2],
1468 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1469 inequality_constraints: vec![],
1470 equality_constraints: vec![],
1471 description: "Xin-She Yang N.1 function".to_string(),
1472 multimodal: true,
1473 dimensions: vec![2],
1474 },
1475 );
1476
1477 metadata.insert(
1478 "xin_she_yang_n2".to_string(),
1479 FunctionMetadata {
1480 name: "xin_she_yang_n2".to_string(),
1481 bounds: vec![(-2.0 * std::f64::consts::PI, 2.0 * std::f64::consts::PI); 2],
1482 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1483 inequality_constraints: vec![],
1484 equality_constraints: vec![],
1485 description: "Xin-She Yang N.2 function".to_string(),
1486 multimodal: true,
1487 dimensions: vec![2],
1488 },
1489 );
1490
1491 metadata.insert(
1492 "xin_she_yang_n3".to_string(),
1493 FunctionMetadata {
1494 name: "xin_she_yang_n3".to_string(),
1495 bounds: vec![(-20.0, 20.0); 2],
1496 global_minima: vec![(vec![0.0, 0.0], -1.0)],
1497 inequality_constraints: vec![],
1498 equality_constraints: vec![],
1499 description: "Xin-She Yang N.3 function".to_string(),
1500 multimodal: true,
1501 dimensions: vec![2],
1502 },
1503 );
1504
1505 metadata.insert(
1506 "xin_she_yang_n4".to_string(),
1507 FunctionMetadata {
1508 name: "xin_she_yang_n4".to_string(),
1509 bounds: vec![(-10.0, 10.0); 2],
1510 global_minima: vec![(vec![0.0, 0.0], -1.0)],
1511 inequality_constraints: vec![],
1512 equality_constraints: vec![],
1513 description: "Xin-She Yang N.4 function".to_string(),
1514 multimodal: true,
1515 dimensions: vec![2],
1516 },
1517 );
1518
1519 metadata.insert(
1520 "zakharov".to_string(),
1521 FunctionMetadata {
1522 name: "zakharov".to_string(),
1523 bounds: vec![(-5.0, 10.0); 2],
1524 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1525 inequality_constraints: vec![],
1526 equality_constraints: vec![],
1527 description: "Zakharov function".to_string(),
1528 multimodal: false,
1529 dimensions: vec![2],
1530 },
1531 );
1532
1533 metadata.insert(
1534 "zakharov2".to_string(),
1535 FunctionMetadata {
1536 name: "zakharov2".to_string(),
1537 bounds: vec![(-5.0, 10.0); 2],
1538 global_minima: vec![(vec![0.0, 0.0], 0.0)],
1539 inequality_constraints: vec![],
1540 equality_constraints: vec![],
1541 description: "Zakharov function variant 2".to_string(),
1542 multimodal: false,
1543 dimensions: vec![2],
1544 },
1545 );
1546
1547 println!(
1548 "š Loaded metadata for {} test functions (explicit definitions)",
1549 metadata.len()
1550 );
1551 metadata
1552}
1553
1554pub fn get_function_bounds(function_name: &str) -> Option<Vec<(f64, f64)>> {
1557 let metadata = get_function_metadata();
1558 metadata.get(function_name).map(|meta| meta.bounds.clone())
1559}
1560
1561pub fn get_function_bounds_2d(function_name: &str, default_bounds: (f64, f64)) -> [(f64, f64); 2] {
1564 if let Some(bounds) = get_function_bounds(function_name) {
1565 if bounds.len() >= 2 {
1566 [bounds[0], bounds[1]]
1567 } else {
1568 [default_bounds; 2]
1569 }
1570 } else {
1571 [default_bounds; 2]
1572 }
1573}
1574
1575pub fn get_function_bounds_vec(function_name: &str, default_bounds: (f64, f64)) -> Vec<(f64, f64)> {
1578 if let Some(bounds) = get_function_bounds(function_name) {
1579 if bounds.len() >= 2 {
1580 bounds
1581 } else {
1582 vec![default_bounds; 2]
1583 }
1584 } else {
1585 vec![default_bounds; 2]
1586 }
1587}
1588
1589#[cfg(test)]
1590mod tests {
1591 use super::*;
1592 use ndarray::Array1;
1593
1594 fn call_function(name: &str, x: &Array1<f64>) -> Option<f64> {
1597 match name {
1598 "sphere" => Some(sphere(x)),
1600 "rosenbrock" => Some(rosenbrock(x)),
1601 "booth" => Some(booth(x)),
1602 "matyas" => Some(matyas(x)),
1603 "beale" => Some(beale(x)),
1604 "himmelblau" => Some(himmelblau(x)),
1605 "sum_squares" => Some(sum_squares(x)),
1606 "different_powers" => Some(different_powers(x)),
1607 "elliptic" => Some(elliptic(x)),
1608 "cigar" => Some(cigar(x)),
1609 "tablet" => Some(tablet(x)),
1610 "discus" => Some(discus(x)),
1611 "ridge" => Some(ridge(x)),
1612 "sharp_ridge" => Some(sharp_ridge(x)),
1613 "perm_0_d_beta" => Some(perm_0_d_beta(x)),
1614 "perm_d_beta" => Some(perm_d_beta(x)),
1615
1616 "ackley" => Some(ackley(x)),
1618 "rastrigin" => Some(rastrigin(x)),
1619 "griewank" => Some(griewank(x)),
1620 "schwefel" => Some(schwefel(x)),
1621 "branin" => Some(branin(x)),
1622 "goldstein_price" => Some(goldstein_price(x)),
1623 "six_hump_camel" => Some(six_hump_camel(x)),
1624 "hartman_4d" => Some(hartman_4d(x)),
1625 "xin_she_yang_n1" => Some(xin_she_yang_n1(x)),
1626 "katsuura" => Some(katsuura(x)),
1627 "happycat" => Some(happycat(x)),
1628
1629 "gramacy_lee_2012" => Some(gramacy_lee_2012(x)),
1631 "forrester_2008" => Some(forrester_2008(x)),
1632 "power_sum" => Some(power_sum(x)),
1633 "shekel" => Some(shekel(x)),
1634 "gramacy_lee_function" => Some(gramacy_lee_function(x)),
1635
1636 "expanded_griewank_rosenbrock" => Some(expanded_griewank_rosenbrock(x)),
1638
1639 "rosenbrock_disk_constraint" | "binh_korn_constraint1" => None,
1641
1642 _ => None,
1643 }
1644 }
1645
1646 #[test]
1647 fn test_all_function_minima() {
1648 let metadata = get_function_metadata();
1649 let tolerance = 1e-10; let loose_tolerance = 1e-3; for (func_name, meta) in metadata.iter() {
1653 if !meta.inequality_constraints.is_empty() || !meta.equality_constraints.is_empty() {
1655 continue;
1656 }
1657
1658 println!("Testing function: {}", func_name);
1659
1660 for (minimum_location, expected_value) in &meta.global_minima {
1662 let x = Array1::from_vec(minimum_location.clone());
1663
1664 if let Some(actual_value) = call_function(func_name, &x) {
1665 let error = (actual_value - expected_value).abs();
1666
1667 let test_tolerance = if expected_value.abs() > 1.0 {
1669 loose_tolerance * expected_value.abs()
1670 } else {
1671 loose_tolerance
1672 };
1673
1674 println!(
1675 " {} at {:?}: expected {:.6}, got {:.6}, error {:.2e}",
1676 func_name, minimum_location, expected_value, actual_value, error
1677 );
1678
1679 assert!(
1680 error <= test_tolerance,
1681 "Function {} failed: at {:?}, expected {:.10}, got {:.10}, error {:.2e} > tolerance {:.2e}",
1682 func_name,
1683 minimum_location,
1684 expected_value,
1685 actual_value,
1686 error,
1687 test_tolerance
1688 );
1689
1690 println!(" ā {} passed with error {:.2e}", func_name, error);
1691 } else {
1692 println!(
1693 " ā Skipped {} (not implemented in test dispatcher)",
1694 func_name
1695 );
1696 }
1697 }
1698 }
1699
1700 println!("\nš All function minima tests completed!");
1701 }
1702
1703 #[test]
1704 fn test_specific_challenging_functions() {
1705 let tolerance = 1e-5;
1706
1707 let x = Array1::from_vec(vec![0.548563444114526]);
1711 let result = gramacy_lee_2012(&x);
1712 let expected = -0.869011134989500;
1713 assert!(
1714 (result - expected).abs() < tolerance,
1715 "Gramacy & Lee 2012: expected {}, got {}",
1716 expected,
1717 result
1718 );
1719
1720 let x = Array1::from_vec(vec![0.757249]);
1722 let result = forrester_2008(&x);
1723 let expected = -6.02074;
1724 assert!(
1725 (result - expected).abs() < tolerance,
1726 "Forrester 2008: expected {}, got {}",
1727 expected,
1728 result
1729 );
1730
1731 let x = Array1::from_vec(vec![0.1873, 0.1936, 0.5576, 0.2647]);
1733 let result = hartman_4d(&x);
1734 let expected = -3.72983;
1735 assert!(
1736 (result - expected).abs() < tolerance,
1737 "Hartmann 4D: expected {}, got {}",
1738 expected,
1739 result
1740 );
1741
1742 let x = Array1::from_vec(vec![4.0, 4.0, 4.0, 4.0]);
1744 let result = shekel(&x);
1745 let expected = -10.5364;
1746 let shekel_tolerance = 1e-3; assert!(
1748 (result - expected).abs() < shekel_tolerance,
1749 "Shekel: expected {}, got {}",
1750 expected,
1751 result
1752 );
1753 }
1754
1755 #[test]
1756 fn test_simple_unimodal_functions() {
1757 let tolerance = 1e-12;
1758
1759 let x = Array1::from_vec(vec![0.0, 0.0]);
1761
1762 assert_eq!(sphere(&x), 0.0);
1763 assert_eq!(sum_squares(&x), 0.0);
1764 assert_eq!(different_powers(&x), 0.0);
1765 assert_eq!(elliptic(&x), 0.0);
1766 assert_eq!(cigar(&x), 0.0);
1767 assert_eq!(tablet(&x), 0.0);
1768 assert_eq!(discus(&x), 0.0);
1769 assert_eq!(ridge(&x), 0.0);
1770 assert_eq!(sharp_ridge(&x), 0.0);
1771 assert_eq!(xin_she_yang_n1(&x), 0.0);
1772
1773 let x = Array1::from_vec(vec![1.0, 1.0]);
1775 assert!((rosenbrock(&x) - 0.0).abs() < tolerance);
1776 assert!((expanded_griewank_rosenbrock(&x) - 0.0).abs() < tolerance);
1777
1778 let x = Array1::from_vec(vec![1.0, 3.0]);
1779 assert!((booth(&x) - 0.0).abs() < tolerance);
1780
1781 let x = Array1::from_vec(vec![0.0, 0.0]);
1782 assert!((matyas(&x) - 0.0).abs() < tolerance);
1783
1784 let x = Array1::from_vec(vec![3.0, 0.5]);
1785 assert!((beale(&x) - 0.0).abs() < tolerance);
1786 }
1787
1788 #[test]
1789 fn test_multimodal_functions() {
1790 let tolerance = 1e-10;
1791
1792 let x = Array1::from_vec(vec![0.0, 0.0]);
1794
1795 assert!((ackley(&x) - 0.0).abs() < tolerance);
1796 assert!((rastrigin(&x) - 0.0).abs() < tolerance);
1797 assert!((griewank(&x) - 0.0).abs() < tolerance);
1798
1799 let x = Array1::from_vec(vec![420.9687, 420.9687]);
1801 assert!((schwefel(&x) - 0.0).abs() < 1e-3); }
1803
1804 #[test]
1805 fn test_perm_functions() {
1806 let tolerance = 1e-12;
1807
1808 let x = Array1::from_vec(vec![1.0, 0.5]);
1810 assert!((perm_0_d_beta(&x) - 0.0).abs() < tolerance);
1811 assert!((perm_d_beta(&x) - 0.0).abs() < tolerance);
1812 }
1813
1814 #[test]
1815 fn test_function_metadata_completeness() {
1816 let metadata = get_function_metadata();
1817
1818 for (name, meta) in metadata.iter() {
1820 assert!(!meta.name.is_empty(), "Function {} has empty name", name);
1821 assert!(!meta.bounds.is_empty(), "Function {} has no bounds", name);
1822 assert!(
1825 !meta.description.is_empty(),
1826 "Function {} has no description",
1827 name
1828 );
1829 assert!(
1830 !meta.dimensions.is_empty(),
1831 "Function {} has no dimensions",
1832 name
1833 );
1834
1835 for (lower, upper) in &meta.bounds {
1837 assert!(
1838 lower < upper,
1839 "Function {} has invalid bounds: {} >= {}",
1840 name,
1841 lower,
1842 upper
1843 );
1844 }
1845
1846 for (location, _value) in &meta.global_minima {
1848 if !meta.bounds.is_empty() {
1849 if location.len() != meta.bounds.len() {
1852 println!(
1853 "ā ļø Function {} has dimension mismatch: global minimum {}D vs bounds {}D",
1854 name,
1855 location.len(),
1856 meta.bounds.len()
1857 );
1858 if location.len() > meta.bounds.len() * 2 {
1860 panic!(
1861 "Function {} has severe dimension mismatch: {} vs bounds {}",
1862 name,
1863 location.len(),
1864 meta.bounds.len()
1865 );
1866 }
1867 }
1868 }
1869 }
1870 }
1871
1872 println!("ā All {} functions have complete metadata", metadata.len());
1873 }
1874}