-
Notifications
You must be signed in to change notification settings - Fork 1
/
coco.c
16401 lines (14465 loc) · 601 KB
/
coco.c
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/************************************************************************
* WARNING
*
* This file is an auto-generated amalgamation. Any changes made to this
* file will be lost when it is regenerated!
************************************************************************/
#line 1 "code-experiments/src/coco_random.c"
/**
* @file coco_random.c
* @brief Definitions of functions regarding COCO random numbers.
*
* @note This file contains non-C89-standard types (such as uint32_t and uint64_t), which should
* eventually be fixed.
*/
#include <math.h>
#line 1 "code-experiments/src/coco.h"
/**
* @file coco.h
* @brief All public COCO functions, constants and variables are defined in this file.
*
* It is the authoritative reference, if any function deviates from the documented behavior it is considered
* a bug. See the function definitions for their detailed descriptions.
*/
#ifndef __COCO_H__
#define __COCO_H__
#include <stddef.h>
/* Definitions of some 32 and 64-bit types (used by the random number generator) */
#ifdef _MSC_VER
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
/* Include definition for NAN among other things */
#include <math.h>
#include <float.h>
#ifndef NAN
/** @brief Definition of NAN to be used only if undefined by the included headers */
#define NAN 8.8888e88
#endif
#ifndef isnan
/** @brief Definition of isnan to be used only if undefined by the included headers */
#define isnan(x) (0)
#endif
#ifndef INFINITY
/** @brief Definition of INFINITY to be used only if undefined by the included headers */
#define INFINITY 1e22
#endif
#ifndef isinf
/** @brief Definition of isinf to be used only if undefined by the included headers */
#define isinf(x) (0)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief COCO's version.
*
* Automatically updated by do.py.
*/
/**@{*/
static const char coco_version[32] = "1.2.1.2";
/**@}*/
/***********************************************************************************************************/
/**
* @brief COCO's own pi constant. Simplifies the case, when the value of pi changes.
*/
/**@{*/
static const double coco_pi = 3.14159265358979323846;
static const double coco_two_pi = 2.0 * 3.14159265358979323846;
/**@}*/
/***********************************************************************************************************/
/** @brief Logging level type. */
typedef enum {
COCO_ERROR, /**< @brief only error messages are output */
COCO_WARNING, /**< @brief error and warning messages are output */
COCO_INFO, /**< @brief error, warning and info messages are output */
COCO_DEBUG /**< @brief error, warning, info and debug messages are output */
} coco_log_level_type_e;
/***********************************************************************************************************/
/** @brief Structure containing a COCO problem. */
struct coco_problem_s;
/**
* @brief The COCO problem type.
*
* See coco_problem_s for more information on its fields. */
typedef struct coco_problem_s coco_problem_t;
/** @brief Structure containing a COCO suite. */
struct coco_suite_s;
/**
* @brief The COCO suite type.
*
* See coco_suite_s for more information on its fields. */
typedef struct coco_suite_s coco_suite_t;
/** @brief Structure containing a COCO observer. */
struct coco_observer_s;
/**
* @brief The COCO observer type.
*
* See coco_observer_s for more information on its fields. */
typedef struct coco_observer_s coco_observer_t;
/** @brief Structure containing a COCO archive. */
struct coco_archive_s;
/**
* @brief The COCO archive type.
*
* See coco_archive_s for more information on its fields. */
typedef struct coco_archive_s coco_archive_t;
/** @brief Structure containing a COCO random state. */
struct coco_random_state_s;
/**
* @brief The COCO random state type.
*
* See coco_random_state_s for more information on its fields. */
typedef struct coco_random_state_s coco_random_state_t;
/***********************************************************************************************************/
/**
* @name Methods regarding COCO suite
*/
/**@{*/
/**
* @brief Constructs a COCO suite.
*/
coco_suite_t *coco_suite(const char *suite_name, const char *suite_instance, const char *suite_options);
/**
* @brief Frees the given suite.
*/
void coco_suite_free(coco_suite_t *suite);
/**
* @brief Returns the next (observed) problem of the suite or NULL if there is no next problem left.
*/
coco_problem_t *coco_suite_get_next_problem(coco_suite_t *suite, coco_observer_t *observer);
/**
* @brief Returns the problem of the suite defined by problem_index.
*/
coco_problem_t *coco_suite_get_problem(coco_suite_t *suite, const size_t problem_index);
/**
* @brief Returns the first problem of the suite defined by function, dimension and instance numbers.
*/
coco_problem_t *coco_suite_get_problem_by_function_dimension_instance(coco_suite_t *suite,
const size_t function,
const size_t dimension,
const size_t instance);
/**
* @brief Returns the number of problems in the given suite.
*/
size_t coco_suite_get_number_of_problems(const coco_suite_t *suite);
/**
* @brief Returns the function number in the suite in position function_idx (counting from 0).
*/
size_t coco_suite_get_function_from_function_index(const coco_suite_t *suite, const size_t function_idx);
/**
* @brief Returns the dimension number in the suite in position dimension_idx (counting from 0).
*/
size_t coco_suite_get_dimension_from_dimension_index(const coco_suite_t *suite, const size_t dimension_idx);
/**
* @brief Returns the instance number in the suite in position instance_idx (counting from 0).
*/
size_t coco_suite_get_instance_from_instance_index(const coco_suite_t *suite, const size_t instance_idx);
/**@}*/
/**
* @name Encoding/decoding problem index
*
* General schema for encoding/decoding a problem index. Note that the index depends on the number of
* instances a suite is defined with (it should be called a suite-instance-depending index...).
* Also, while functions, instances and dimensions start from 1, function_idx, instance_idx and dimension_idx
* as well as suite_dep_index start from 0!
*
* Showing an example with 2 dimensions (2, 3), 5 instances (6, 7, 8, 9, 10) and 2 functions (1, 2):
*
\verbatim
index | instance | function | dimension
------+----------+----------+-----------
0 | 6 | 1 | 2
1 | 7 | 1 | 2
2 | 8 | 1 | 2
3 | 9 | 1 | 2
4 | 10 | 1 | 2
5 | 6 | 2 | 2
6 | 7 | 2 | 2
7 | 8 | 2 | 2
8 | 9 | 2 | 2
9 | 10 | 2 | 2
10 | 6 | 1 | 3
11 | 7 | 1 | 3
12 | 8 | 1 | 3
13 | 9 | 1 | 3
14 | 10 | 1 | 3
15 | 6 | 2 | 2
16 | 7 | 2 | 3
17 | 8 | 2 | 3
18 | 9 | 2 | 3
19 | 10 | 2 | 3
index | instance_idx | function_idx | dimension_idx
------+--------------+--------------+---------------
0 | 0 | 0 | 0
1 | 1 | 0 | 0
2 | 2 | 0 | 0
3 | 3 | 0 | 0
4 | 4 | 0 | 0
5 | 0 | 1 | 0
6 | 1 | 1 | 0
7 | 2 | 1 | 0
8 | 3 | 1 | 0
9 | 4 | 1 | 0
10 | 0 | 0 | 1
11 | 1 | 0 | 1
12 | 2 | 0 | 1
13 | 3 | 0 | 1
14 | 4 | 0 | 1
15 | 0 | 1 | 1
16 | 1 | 1 | 1
17 | 2 | 1 | 1
18 | 3 | 1 | 1
19 | 4 | 1 | 1
\endverbatim
*/
/**@{*/
/**
* @brief Computes the index of the problem in the suite that corresponds to the given function, dimension
* and instance indices.
*/
size_t coco_suite_encode_problem_index(const coco_suite_t *suite,
const size_t function_idx,
const size_t dimension_idx,
const size_t instance_idx);
/**
* @brief Computes the function, dimension and instance indexes of the problem with problem_index in the
* given suite.
*/
void coco_suite_decode_problem_index(const coco_suite_t *suite,
const size_t problem_index,
size_t *function_idx,
size_t *dimension_idx,
size_t *instance_idx);
/**@}*/
/***********************************************************************************************************/
/**
* @name Methods regarding COCO observer
*/
/**@{*/
/**
* @brief Constructs a COCO observer.
*/
coco_observer_t *coco_observer(const char *observer_name, const char *options);
/**
* @brief Frees the given observer.
*/
void coco_observer_free(coco_observer_t *observer);
/**
* @brief Adds an observer to the given problem.
*/
coco_problem_t *coco_problem_add_observer(coco_problem_t *problem, coco_observer_t *observer);
/**
* @brief Removes an observer from the given problem.
*/
coco_problem_t *coco_problem_remove_observer(coco_problem_t *problem, coco_observer_t *observer);
/**@}*/
/***********************************************************************************************************/
/**
* @name Methods regarding COCO problem
*/
/**@{*/
/**
* @brief Evaluates the problem function in point x and save the result in y.
*/
void coco_evaluate_function(coco_problem_t *problem, const double *x, double *y);
/**
* @brief Evaluates the problem constraints in point x and save the result in y.
*/
void coco_evaluate_constraint(coco_problem_t *problem, const double *x, double *y);
/**
* @brief Recommends a solution as the current best guesses to the problem.
*/
void coco_recommend_solution(coco_problem_t *problem, const double *x);
/**
* @brief Frees the given problem.
*/
void coco_problem_free(coco_problem_t *problem);
/**
* @brief Returns the name of the problem.
*/
const char *coco_problem_get_name(const coco_problem_t *problem);
/**
* @brief Returns the ID of the problem.
*/
const char *coco_problem_get_id(const coco_problem_t *problem);
/**
* @brief Returns the number of variables i.e. the dimension of the problem.
*/
size_t coco_problem_get_dimension(const coco_problem_t *problem);
/**
* @brief Returns the number of objectives of the problem.
*/
size_t coco_problem_get_number_of_objectives(const coco_problem_t *problem);
/**
* @brief Returns the number of constraints of the problem.
*/
size_t coco_problem_get_number_of_constraints(const coco_problem_t *problem);
/**
* @brief Returns the number of evaluations done on the problem.
*/
size_t coco_problem_get_evaluations(const coco_problem_t *problem);
/**
* @brief Returns 1 if the final target was hit, 0 otherwise.
*/
int coco_problem_final_target_hit(const coco_problem_t *problem);
/**
* @brief Returns the best observed value for the first objective.
*/
double coco_problem_get_best_observed_fvalue1(const coco_problem_t *problem);
/**
* @brief Returns the target value for the first objective.
*/
double depreciated_coco_problem_get_final_target_fvalue1(const coco_problem_t *problem);
/**
* @brief Returns a vector of size 'dimension' with lower bounds of the region of interest in
* the decision space.
*/
const double *coco_problem_get_smallest_values_of_interest(const coco_problem_t *problem);
/**
* @brief Returns a vector of size 'dimension' with upper bounds of the region of interest in
* the decision space.
*/
const double *coco_problem_get_largest_values_of_interest(const coco_problem_t *problem);
/**
* @brief Returns the problem_index of the problem in its current suite.
*/
size_t coco_problem_get_suite_dep_index(const coco_problem_t *problem);
/**
* @brief Returns an initial solution, i.e. a feasible variable setting, to the problem.
*/
void coco_problem_get_initial_solution(const coco_problem_t *problem, double *initial_solution);
/**@}*/
/***********************************************************************************************************/
/**
* @name Methods regarding random numbers
*/
/**@{*/
/**
* @brief Creates and returns a new random number state using the given seed.
*/
coco_random_state_t *coco_random_new(uint32_t seed);
/**
* @brief Frees all memory associated with the random state.
*/
void coco_random_free(coco_random_state_t *state);
/**
* @brief Returns one uniform [0, 1) random value from the random number generator associated with the given
* state.
*/
double coco_random_uniform(coco_random_state_t *state);
/**
* @brief Generates an approximately normal random number.
*/
double coco_random_normal(coco_random_state_t *state);
/**@}*/
/***********************************************************************************************************/
/**
* @name Methods managing memory
*/
/**@{*/
/**
* @brief Safe memory allocation that either succeeds or triggers a coco_error.
*/
void *coco_allocate_memory(const size_t size);
/**
* @brief Safe memory allocation for a vector of doubles that either succeeds or triggers a coco_error.
*/
double *coco_allocate_vector(const size_t size);
/**
* @brief Frees the allocated memory.
*/
void coco_free_memory(void *data);
/**@}*/
/***********************************************************************************************************/
/**
* @name Methods regarding COCO messages
*/
/**@{*/
/**
* @brief Signals a fatal error.
*/
void coco_error(const char *message, ...);
/**
* @brief Warns about error conditions.
*/
void coco_warning(const char *message, ...);
/**
* @brief Outputs some information.
*/
void coco_info(const char *message, ...);
/**
* @brief Prints only the given message without any prefix and new line.
*
* A function similar to coco_info but producing no additional text than
* the given message.
*
* The output is only produced if coco_log_level >= COCO_INFO.
*/
void coco_info_partial(const char *message, ...);
/**
* @brief Outputs detailed information usually used for debugging.
*/
void coco_debug(const char *message, ...);
/**
* @brief Sets the COCO log level to the given value and returns the previous value of the log level.
*/
const char *coco_set_log_level(const char *level);
/**@}*/
/***********************************************************************************************************/
/**
* @name Methods regarding COCO archives and log files (used when pre-processing MO data)
*/
/**@{*/
/**
* @brief Constructs a COCO archive.
*/
coco_archive_t *coco_archive(const char *suite_name,
const size_t function,
const size_t dimension,
const size_t instance);
/**
* @brief Adds a solution with objectives (y1, y2) to the archive if none of the existing solutions in the
* archive dominates it. In this case, returns 1, otherwise the archive is not updated and the method
* returns 0.
*/
int coco_archive_add_solution(coco_archive_t *archive, const double y1, const double y2, const char *text);
/**
* @brief Returns the number of (non-dominated) solutions in the archive (computed first, if needed).
*/
size_t coco_archive_get_number_of_solutions(coco_archive_t *archive);
/**
* @brief Returns the hypervolume of the archive (computed first, if needed).
*/
double coco_archive_get_hypervolume(coco_archive_t *archive);
/**
* @brief Returns the text of the next (non-dominated) solution in the archive and "" when there are no
* solutions left. The first two solutions are always the extreme ones.
*/
const char *coco_archive_get_next_solution_text(coco_archive_t *archive);
/**
* @brief Frees the archive.
*/
void coco_archive_free(coco_archive_t *archive);
/**
* @brief Feeds the solution to the bi-objective logger for logger output reconstruction purposes.
*/
int coco_logger_biobj_feed_solution(coco_problem_t *problem, const size_t evaluation, const double *y);
/**@}*/
/***********************************************************************************************************/
/**
* @name Other useful methods
*/
/**@{*/
/**
* @brief Removes the given directory and all its contents.
*/
int coco_remove_directory(const char *path);
/**
* @brief Formatted string duplication.
*/
char *coco_strdupf(const char *str, ...);
/**@}*/
/***********************************************************************************************************/
#ifdef __cplusplus
}
#endif
#endif
#line 12 "code-experiments/src/coco_random.c"
#define COCO_NORMAL_POLAR /* Use polar transformation method */
#define COCO_SHORT_LAG 273
#define COCO_LONG_LAG 607
/**
* @brief A structure containing the state of the COCO random generator.
*/
struct coco_random_state_s {
double x[COCO_LONG_LAG];
size_t index;
};
/**
* @brief A lagged Fibonacci random number generator.
*
* This generator is nice because it is reasonably small and directly generates double values. The chosen
* lags (607 and 273) lead to a generator with a period in excess of 2^607-1.
*/
static void coco_random_generate(coco_random_state_t *state) {
size_t i;
for (i = 0; i < COCO_SHORT_LAG; ++i) {
double t = state->x[i] + state->x[i + (COCO_LONG_LAG - COCO_SHORT_LAG)];
if (t >= 1.0)
t -= 1.0;
state->x[i] = t;
}
for (i = COCO_SHORT_LAG; i < COCO_LONG_LAG; ++i) {
double t = state->x[i] + state->x[i - COCO_SHORT_LAG];
if (t >= 1.0)
t -= 1.0;
state->x[i] = t;
}
state->index = 0;
}
coco_random_state_t *coco_random_new(uint32_t seed) {
coco_random_state_t *state = (coco_random_state_t *) coco_allocate_memory(sizeof(*state));
size_t i;
/* Expand seed to fill initial state array. */
for (i = 0; i < COCO_LONG_LAG; ++i) {
/* Uses uint64_t to silence the compiler ("shift count negative or too big, undefined behavior" warning) */
state->x[i] = ((double) seed) / (double) (((uint64_t) 1UL << 32) - 1);
/* Advance seed based on simple RNG from TAOCP */
seed = (uint32_t) 1812433253UL * (seed ^ (seed >> 30)) + ((uint32_t) i + 1);
}
state->index = 0;
return state;
}
void coco_random_free(coco_random_state_t *state) {
coco_free_memory(state);
}
double coco_random_uniform(coco_random_state_t *state) {
/* If we have consumed all random numbers in our archive, it is time to run the actual generator for one
* iteration to refill the state with 'LONG_LAG' new values. */
if (state->index >= COCO_LONG_LAG)
coco_random_generate(state);
return state->x[state->index++];
}
/**
* Instead of using the (expensive) polar method, we may cheat and abuse the central limit theorem. The sum
* of 12 uniform random values has mean 6, variance 1 and is approximately normal. Subtract 6 and you get
* an approximately N(0, 1) random number.
*/
double coco_random_normal(coco_random_state_t *state) {
double normal;
#ifdef COCO_NORMAL_POLAR
const double u1 = coco_random_uniform(state);
const double u2 = coco_random_uniform(state);
normal = sqrt(-2 * log(u1)) * cos(2 * coco_pi * u2);
#else
int i;
normal = 0.0;
for (i = 0; i < 12; ++i) {
normal += coco_random_uniform(state);
}
normal -= 6.0;
#endif
return normal;
}
/* Be hygienic (for amalgamation) and undef lags. */
#undef COCO_SHORT_LAG
#undef COCO_LONG_LAG
#line 1 "code-experiments/src/coco_suite.c"
/**
* @file coco_suite.c
* @brief Definitions of functions regarding COCO suites.
*
* When a new suite is added, the functions coco_suite_intialize, coco_suite_get_instances_by_year and
* coco_suite_get_problem_from_indices need to be updated.
*
* @see <a href="index.html">Instructions</a> on how to write new test functions and combine them into test
* suites.
*/
#include <time.h>
#line 15 "code-experiments/src/coco_suite.c"
#line 1 "code-experiments/src/coco_internal.h"
/**
* @file coco_internal.h
* @brief Definitions of internal COCO structures and typedefs.
*
* These are used throughout the COCO code base but should not be used by any external code.
*/
#ifndef __COCO_INTERNAL__
#define __COCO_INTERNAL__
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************************************************/
/**
* @brief The data free function type.
*
* This is a template for functions that free the contents of data (used to free the contents of data
* fields in coco_problem, coco_suite and coco_observer).
*/
typedef void (*coco_data_free_function_t)(void *data);
/**
* @brief The problem free function type.
*
* This is a template for functions that free the problem structure.
*/
typedef void (*coco_problem_free_function_t)(coco_problem_t *problem);
/**
* @brief The initial solution function type.
*
* This is a template for functions that return an initial solution of the problem.
*/
typedef void (*coco_initial_solution_function_t)(const coco_problem_t *problem, double *y);
/**
* @brief The evaluate function type.
*
* This is a template for functions that perform an evaluation of the problem (to evaluate the problem
* function, the problems constraints etc.).
*/
typedef void (*coco_evaluate_function_t)(coco_problem_t *problem, const double *x, double *y);
/**
* @brief The recommend solutions function type.
*
* This is a template for functions that log a recommended solution.
*/
typedef void (*coco_recommend_function_t)(coco_problem_t *problem, const double *x);
/**
* @brief The allocate logger function type.
*
* This is a template for functions that allocate a logger (wrap a logger around the given problem and return
* the wrapped problem).
*/
typedef coco_problem_t *(*coco_logger_allocate_function_t)(coco_observer_t *observer,
coco_problem_t *problem);
/**
* @brief The free logger function type.
*
* This is a template for functions that free a logger.
*/
typedef void (*coco_logger_free_function_t)(void *logger);
/**
* @brief The transformed COCO problem data type.
*
* This is a type of a generic structure for a transformed ("outer") coco_problem. It makes possible the
* wrapping of problems as layers of an onion. Initialized in the coco_problem_transformed_allocate function,
* it makes the current ("outer") transformed problem a "derived problem class", which inherits from the
* "inner" problem, the "base class".
*
* From the perspective of the inner problem:
* - data holds the meta-information to administer the inheritance
* - data->data holds the additional fields of the derived class (the outer problem)
* - data->inner_problem points to the inner problem (now we have a linked list)
*/
typedef struct {
coco_problem_t *inner_problem; /**< @brief Pointer to the inner problem */
void *data; /**< @brief Pointer to data, which enables further
wrapping of the problem */
coco_data_free_function_t data_free_function; /**< @brief Function to free the contents of data */
} coco_problem_transformed_data_t;
/**
* @brief The stacked COCO problem data type.
*
* This is a type of a structure used when stacking two problems (especially useful for constructing
* multi-objective problems).
*/
typedef struct {
coco_problem_t *problem1; /**< @brief Pointer to the first problem (objective) */
coco_problem_t *problem2; /**< @brief Pointer to the second problem (objective) */
} coco_problem_stacked_data_t;
/**
* @brief The option keys data type.
*
* This is a type of a structure used to contain a set of known option keys (used by suites and observers).
*/
typedef struct {
size_t count; /**< @brief Number of option keys */
char **keys; /**< @brief Pointer to option keys */
} coco_option_keys_t;
/***********************************************************************************************************/
/**
* @brief The COCO problem structure.
*
* This is one of the main structures in COCO. It contains information about a problem to be optimized. The
* problems can be wrapped around each other (similar to the onion layers) by means of the data field and
* the coco_problem_transformed_data_t structure creating some kind of "object inheritance". Even the logger
* is considered as just another coco_problem instance wrapped around the original problem.
*/
struct coco_problem_s {
coco_initial_solution_function_t initial_solution; /**< @brief The function for creating an initial solution. */
coco_evaluate_function_t evaluate_function; /**< @brief The function for evaluating the problem. */
coco_evaluate_function_t evaluate_constraint; /**< @brief The function for evaluating the constraints. */
coco_recommend_function_t recommend_solution; /**< @brief The function for recommending a solution. */
coco_problem_free_function_t problem_free_function; /**< @brief The function for freeing this problem. */
size_t number_of_variables; /**< @brief Number of variables expected by the function, i.e.
problem dimension */
size_t number_of_objectives; /**< @brief Number of objectives. */
size_t number_of_constraints; /**< @brief Number of constraints. */
double *smallest_values_of_interest; /**< @brief The lower bounds of the ROI in the decision space. */
double *largest_values_of_interest; /**< @brief The upper bounds of the ROI in the decision space. */
double *best_value; /**< @brief Optimal (smallest) function value */
double *nadir_value; /**< @brief The nadir point (defined when number_of_objectives > 1) */
double *best_parameter; /**< @brief Optimal decision vector (defined only when unique) */
char *problem_name; /**< @brief Problem name. */
char *problem_id; /**< @brief Problem ID (unique in the containing suite) */
char *problem_type; /**< @brief Problem type */
size_t evaluations; /**< @brief Number of evaluations performed on the problem. */
/* Convenience fields for output generation */
double final_target_delta[1]; /**< @brief Final target delta. */
double best_observed_fvalue[1]; /**< @brief The best observed value so far. */
size_t best_observed_evaluation[1]; /**< @brief The evaluation when the best value so far was achieved. */
/* Fields depending on the containing benchmark suite */
coco_suite_t *suite; /**< @brief Pointer to the containing suite (NULL if not given) */
size_t suite_dep_index; /**< @brief Suite-depending problem index (starting from 0) */
size_t suite_dep_function; /**< @brief Suite-depending function */
size_t suite_dep_instance; /**< @brief Suite-depending instance */
void *data; /**< @brief Pointer to a data instance @see coco_problem_transformed_data_t */
};
/**
* @brief The COCO observer structure.
*
* An observer observes the whole benchmark process. It is independent of suites and problems. Each time a
* new problem of the suite is being observed, the observer initializes a new logger (wraps the observed
* problem with the corresponding logger).
*/
struct coco_observer_s {
int is_active; /**< @brief Whether the observer is active (the logger will log some output). */
char *observer_name; /**< @brief Name of the observer for identification purposes. */
char *result_folder; /**< @brief Name of the result folder. */
char *algorithm_name; /**< @brief Name of the algorithm to be used in logger output. */
char *algorithm_info; /**< @brief Additional information on the algorithm to be used in logger output. */
size_t number_target_triggers;
/**< @brief The number of targets between each 10**i and 10**(i+1). */
double target_precision; /**< @brief The minimal precision used for targets. */
size_t number_evaluation_triggers;
/**< @brief The number of triggers between each 10**i and 10**(i+1) evaluation number. */
char *base_evaluation_triggers;
/**< @brief The "base evaluations" used to evaluations that trigger logging. */
int precision_x; /**< @brief Output precision for decision variables. */
int precision_f; /**< @brief Output precision for function values. */
void *data; /**< @brief Void pointer that can be used to point to data specific to an observer. */
coco_data_free_function_t data_free_function; /**< @brief The function for freeing this observer. */
coco_logger_allocate_function_t logger_allocate_function; /**< @brief The function for allocating the logger. */
coco_logger_free_function_t logger_free_function; /**< @brief The function for freeing the logger. */
};
/**
* @brief The COCO suite structure.
*
* A suite is a collection of problems constructed by a Cartesian product of the suite's optimization
* functions, dimensions and instances. The functions and dimensions are fixed for a suite with some name,
* while the instances are defined dynamically. The suite can be filtered - only the chosen functions,
* dimensions and instances will be taken into account when iterating through the suite.
*/
struct coco_suite_s {
char *suite_name; /**< @brief Name of the suite. */
size_t number_of_dimensions; /**< @brief Number of dimensions contained in the suite. */
size_t *dimensions; /**< @brief The dimensions contained in the suite. */
size_t number_of_functions; /**< @brief Number of functions contained in the suite. */
size_t *functions; /**< @brief The functions contained in the suite. */
size_t number_of_instances; /**< @brief Number of instances contained in the suite. */
char *default_instances; /**< @brief The instances contained in the suite by default. */
size_t *instances; /**< @brief The instances contained in the suite. */
coco_problem_t *current_problem; /**< @brief Pointer to the currently tackled problem. */
long current_dimension_idx; /**< @brief The dimension index of the currently tackled problem. */
long current_function_idx; /**< @brief The function index of the currently tackled problem. */
long current_instance_idx; /**< @brief The instance index of the currently tackled problem. */
void *data; /**< @brief Void pointer that can be used to point to data specific to a suite. */
coco_data_free_function_t data_free_function; /**< @brief The function for freeing this suite. */
};
#ifdef __cplusplus
}
#endif
#endif
#line 16 "code-experiments/src/coco_suite.c"
#line 1 "code-experiments/src/coco_utilities.c"
/**
* @file coco_utilities.c
* @brief Definitions of miscellaneous functions used throughout the COCO framework.
*/
#line 1 "code-experiments/src/coco_platform.h"
/**
* @file coco_platform.h
* @brief Automatic platform-dependent configuration of the COCO framework.
*
* Some platforms and standard conforming compilers require extra defines or includes to provide some
* functionality.
*
* Because most feature defines need to be set before the first system header is included and we do not
* know when a system header is included for the first time in the amalgamation, all internal files
* that need these definitions should include this file before any system headers.
*/
#ifndef __COCO_PLATFORM__
#define __COCO_PLATFORM__
#include <stddef.h>
/* Definitions of COCO_PATH_MAX, coco_path_separator, HAVE_GFA and HAVE_STAT heavily used by functions in
* coco_utilities.c */
#if defined(_WIN32) || defined(_WIN64) || defined(__MINGW64__) || defined(__CYGWIN__)
#include <windows.h>
static const char *coco_path_separator = "\\";
#define COCO_PATH_MAX MAX_PATH
#define HAVE_GFA 1
#elif defined(__gnu_linux__)
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/limits.h>
static const char *coco_path_separator = "/";
#define HAVE_STAT 1
#define COCO_PATH_MAX PATH_MAX
#elif defined(__APPLE__)
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/syslimits.h>
static const char *coco_path_separator = "/";
#define HAVE_STAT 1
#define COCO_PATH_MAX PATH_MAX
#elif defined(__FreeBSD__)
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
static const char *coco_path_separator = "/";
#define HAVE_STAT 1
#define COCO_PATH_MAX PATH_MAX
#elif (defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__))
/* Solaris */
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
static const char *coco_path_separator = "/";
#define HAVE_STAT 1
#define COCO_PATH_MAX PATH_MAX
#else
#error Unknown platform
#endif
#if !defined(COCO_PATH_MAX)
#error COCO_PATH_MAX undefined
#endif
/* Definitions needed for creating and removing directories */
/* Separately handle the special case of Microsoft Visual Studio 2008 with x86_64-w64-mingw32-gcc */
#if _MSC_VER
#include <direct.h>
#elif defined(__MINGW32__) || defined(__MINGW64__)
#include <dirent.h>
#else
#include <dirent.h>
#ifdef __cplusplus
extern "C" {
#endif
/* To silence the compiler (implicit-function-declaration warning). */
/** @cond */
int rmdir(const char *pathname);
int unlink(const char *file_name);
int mkdir(const char *pathname, mode_t mode);
/** @endcond */
#endif
/* Definition of the S_IRWXU constant needed to set file permissions */
#if defined(HAVE_GFA)
#define S_IRWXU 0700
#endif
/* To silence the Visual Studio compiler (C4996 warnings in the python build). */
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
#ifdef __cplusplus
}