1 /* Copyright 2017-2021 PaGMO development team
2 
3 This file is part of the PaGMO library.
4 
5 The PaGMO library is free software; you can redistribute it and/or modify
6 it under the terms of either:
7 
8   * the GNU Lesser General Public License as published by the Free
9     Software Foundation; either version 3 of the License, or (at your
10     option) any later version.
11 
12 or
13 
14   * the GNU General Public License as published by the Free Software
15     Foundation; either version 3 of the License, or (at your option) any
16     later version.
17 
18 or both in parallel, as here.
19 
20 The PaGMO library is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 for more details.
24 
25 You should have received codetail::pi()es of the GNU General Public License and the
26 GNU Lesser General Public License along with the PaGMO library.  If not,
27 see https://www.gnu.org/licenses/. */
28 
29 #include <cmath>
30 #include <initializer_list>
31 #include <stdexcept>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 #include <pagmo/detail/constants.hpp>
37 #include <pagmo/exceptions.hpp>
38 #include <pagmo/problem.hpp>
39 #include <pagmo/problems/cec2009.hpp>
40 #include <pagmo/s11n.hpp>
41 #include <pagmo/types.hpp>
42 
43 // MINGW-specific warnings.
44 #if defined(__GNUC__) && defined(__MINGW32__)
45 #pragma GCC diagnostic push
46 #pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
47 #endif
48 
49 namespace pagmo
50 {
51 
52 namespace detail
53 {
54 
55 namespace cec2009_data
56 {
57 
58 namespace
59 {
60 
61 // Number of objectives
62 const std::vector<unsigned short> nobj = {2, 2, 2, 2, 2, 2, 2, 3, 3, 3};
63 
64 // Inequality constraints dimension
65 const std::vector<unsigned short> nic = {1, 1, 1, 1, 1, 2, 2, 1, 1, 1};
66 
67 } // namespace
68 
69 } // namespace cec2009_data
70 
71 } // namespace detail
72 
73 // Pointers to the member functions to be used in fitness
74 const std::vector<detail::cec2009_data::func_ptr> cec2009::s_u_ptr
75     = {&cec2009::UF1, &cec2009::UF2, &cec2009::UF3, &cec2009::UF4, &cec2009::UF5,
76        &cec2009::UF6, &cec2009::UF7, &cec2009::UF8, &cec2009::UF9, &cec2009::UF10};
77 
78 const std::vector<detail::cec2009_data::func_ptr> cec2009::s_c_ptr
79     = {&cec2009::CF1, &cec2009::CF2, &cec2009::CF3, &cec2009::CF4, &cec2009::CF5,
80        &cec2009::CF6, &cec2009::CF7, &cec2009::CF8, &cec2009::CF9, &cec2009::CF10};
81 
cec2009(unsigned prob_id,bool is_constrained,unsigned dim)82 cec2009::cec2009(unsigned prob_id, bool is_constrained, unsigned dim)
83     : m_prob_id(prob_id), m_is_constrained(is_constrained), m_dim(dim)
84 {
85     if (prob_id < 1u || prob_id > 10u) {
86         pagmo_throw(std::invalid_argument,
87                     "Error: CEC2009 Test functions are only defined for prob_id in [1, 10], a prob_id of "
88                         + std::to_string(prob_id) + " was requested.");
89     }
90     if (dim < 1u) {
91         pagmo_throw(std::invalid_argument,
92                     "Error: CEC2009 Test functions must have a non zero dimension: a dimension of "
93                         + std::to_string(dim) + " was requested.");
94     }
95 }
96 
97 /// Inequality constraint dimension
98 /**
99  * Returns the number of inequality constraints
100  *
101  * @return the number of inequality constraints
102  */
get_nic() const103 vector_double::size_type cec2009::get_nic() const
104 {
105     if (m_is_constrained) {
106         return detail::cec2009_data::nic[m_prob_id - 1u];
107     } else {
108         return 0u;
109     }
110 }
111 
112 /// Number of objectives
113 /**
114  * Returns the number of objectives
115  *
116  * @return the number of objectives
117  */
get_nobj() const118 vector_double::size_type cec2009::get_nobj() const
119 {
120     return detail::cec2009_data::nobj[m_prob_id - 1u];
121 }
122 
123 /// Box-bounds
124 /**
125  * It returns the box-bounds for this UDP.
126  *
127  * @return the lower and upper bounds for each of the decision vector components
128  */
get_bounds() const129 std::pair<vector_double, vector_double> cec2009::get_bounds() const
130 {
131     vector_double lb(m_dim, 0), ub(m_dim, 0);
132 
133     if (!m_is_constrained) { // For UF
134         if (m_prob_id == 1u || m_prob_id == 2u || m_prob_id == 5u || m_prob_id == 6u || m_prob_id == 7u) {
135             // [0,1] x [-1,1]^{n-1}
136             lb[0] = 0.0;
137             ub[0] = 1.0;
138             for (decltype(m_dim) i = 1u; i < m_dim; ++i) {
139                 lb[i] = -1.0;
140                 ub[i] = 1.0;
141             }
142         } else if (m_prob_id == 3u) {
143             // [0,1]^{n}
144             for (decltype(m_dim) i = 0u; i < m_dim; ++i) {
145                 lb[i] = 0.0;
146                 ub[i] = 1.0;
147             }
148         } else if (m_prob_id == 4u) {
149             // [0,1] x [-2,2]^{n-1}
150             lb[0] = 0.0;
151             ub[0] = 1.0;
152             for (decltype(m_dim) i = 1u; i < m_dim; ++i) {
153                 lb[i] = -2.0;
154                 ub[i] = 2.0;
155             }
156         } else if (m_prob_id == 8u || m_prob_id == 9u || m_prob_id == 10u) {
157             // [0,1]^{2} x [-2,2]^{n-2}
158             lb[0] = 0.0;
159             ub[0] = 1.0;
160             lb[1] = 0.0;
161             ub[1] = 1.0;
162             for (decltype(m_dim) i = 2u; i < m_dim; ++i) {
163                 lb[i] = -2.0;
164                 ub[i] = 2.0;
165             }
166         }
167     } else { // For CF
168         if (m_prob_id == 2u) {
169             // [0,1] x [-1,1]^{n-1}
170             lb[0] = 0.0;
171             ub[0] = 1.0;
172             for (decltype(m_dim) i = 1u; i < m_dim; ++i) {
173                 lb[i] = -1.0;
174                 ub[i] = 1.0;
175             }
176         } else if (m_prob_id == 1u) {
177             // [0,1]^{n}
178             for (decltype(m_dim) i = 0u; i < m_dim; ++i) {
179                 lb[i] = 0.0;
180                 ub[i] = 1.0;
181             }
182         } else if (m_prob_id == 3u || m_prob_id == 4u || m_prob_id == 5u || m_prob_id == 6u || m_prob_id == 7u) {
183             // [0,1] x [-2,2]^{n-1}
184             lb[0] = 0.0;
185             ub[0] = 1.0;
186             for (decltype(m_dim) i = 1u; i < m_dim; ++i) {
187                 lb[i] = -2.0;
188                 ub[i] = 2.0;
189             }
190         } else if (m_prob_id == 8u) {
191             // [0,1]^{2} x [-4,4]^{n-2}
192             lb[0] = 0.0;
193             ub[0] = 1.0;
194             lb[1] = 0.0;
195             ub[1] = 1.0;
196             for (decltype(m_dim) i = 2u; i < m_dim; ++i) {
197                 lb[i] = -4.0;
198                 ub[i] = 4.0;
199             }
200         } else if (m_prob_id == 9u || m_prob_id == 10u) {
201             // [0,1]^{2} x [-2,2]^{n-2}
202             lb[0] = 0.0;
203             ub[0] = 1.0;
204             lb[1] = 0.0;
205             ub[1] = 1.0;
206             for (decltype(m_dim) i = 2u; i < m_dim; ++i) {
207                 lb[i] = -2.0;
208                 ub[i] = 2.0;
209             }
210         }
211     }
212     return std::make_pair(std::move(lb), std::move(ub));
213 }
214 
215 /// Fitness computation
216 /**
217  * Computes the fitness for this UDP
218  *
219  * @param x the decision vector.
220  *
221  * @return the fitness of \p x.
222  */
fitness(const vector_double & x) const223 vector_double cec2009::fitness(const vector_double &x) const
224 {
225     if (m_is_constrained) {
226         return fitness_impl(s_c_ptr[m_prob_id - 1], x);
227     } else {
228         return fitness_impl(s_u_ptr[m_prob_id - 1], x);
229     }
230 }
231 
232 /// Problem name
233 /**
234  * @return a string containing the problem name
235  */
get_name() const236 std::string cec2009::get_name() const
237 {
238     std::string retval("CEC2009 - ");
239     if (!m_is_constrained) {
240         retval.append("UF");
241     } else {
242         retval.append("CF");
243     }
244     retval.append(std::to_string(m_prob_id));
245     return retval;
246 }
247 
248 // Object serialization
249 template <typename Archive>
serialize(Archive & ar,unsigned)250 void cec2009::serialize(Archive &ar, unsigned)
251 {
252     detail::archive(ar, m_prob_id, m_is_constrained, m_dim);
253 }
254 
255 namespace
256 {
257 
258 // Small helper for getting the sign of
259 // a double.
sgn(double val)260 double sgn(double val)
261 {
262     return ((val) > 0 ? 1.0 : -1.0);
263 }
264 
265 } // namespace
266 
267 // Pointers to member functions are used
fitness_impl(detail::cec2009_data::func_ptr f,const vector_double & x) const268 vector_double cec2009::fitness_impl(detail::cec2009_data::func_ptr f, const vector_double &x) const
269 {
270     const auto nic = m_is_constrained ? detail::cec2009_data::nic[m_prob_id - 1u] : 0u;
271     vector_double retval(nic + detail::cec2009_data::nobj[m_prob_id - 1u], 0.);
272     // Syntax is ugly as these are member function pointers.
273     ((*this).*(f))(retval, x); // calls f
274     return retval;
275 }
276 
277 // Let's disable a few compiler warnings emitted by the cec2009 code.
278 #if defined(__clang__) || defined(__GNUC__)
279 #pragma GCC diagnostic push
280 #pragma GCC diagnostic ignored "-Wold-style-cast"
281 #endif
282 
283 // For the coverage analysis we do not cover the code below as its derived from a third party source
284 // LCOV_EXCL_START
285 
286 // -------------------------------------------
UF1(vector_double & f,const vector_double & x) const287 void cec2009::UF1(vector_double &f, const vector_double &x) const
288 {
289     double count1, count2;
290     double sum1, sum2, yj;
291 
292     sum1 = sum2 = 0.0;
293     count1 = count2 = 0;
294     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
295         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
296         yj = yj * yj;
297         if (j % 2 == 0u) {
298             sum2 += yj;
299             count2++;
300         } else {
301             sum1 += yj;
302             count1++;
303         }
304     }
305     f[0] = x[0] + 2.0 * sum1 / count1;
306     f[1] = 1.0 - std::sqrt(x[0]) + 2.0 * sum2 / count2;
307 }
308 
UF2(vector_double & f,const vector_double & x) const309 void cec2009::UF2(vector_double &f, const vector_double &x) const
310 {
311     double count1, count2;
312     double sum1, sum2, yj;
313 
314     sum1 = sum2 = 0.0;
315     count1 = count2 = 0;
316     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
317         if (j % 2 == 0u) {
318             yj = x[j - 1]
319                  - 0.3 * x[0]
320                        * (x[0] * std::cos(24.0 * detail::pi() * x[0] + 4.0 * j * detail::pi() / (double)m_dim) + 2.0)
321                        * std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
322             sum2 += yj * yj;
323             count2++;
324         } else {
325             yj = x[j - 1]
326                  - 0.3 * x[0]
327                        * (x[0] * std::cos(24.0 * detail::pi() * x[0] + 4.0 * j * detail::pi() / (double)m_dim) + 2.0)
328                        * std::cos(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
329             sum1 += yj * yj;
330             count1++;
331         }
332     }
333     f[0] = x[0] + 2.0 * sum1 / count1;
334     f[1] = 1.0 - std::sqrt(x[0]) + 2.0 * sum2 / count2;
335 }
336 
UF3(vector_double & f,const vector_double & x) const337 void cec2009::UF3(vector_double &f, const vector_double &x) const
338 {
339     double count1, count2;
340     double sum1, sum2, prod1, prod2, yj, pj;
341 
342     sum1 = sum2 = 0.0;
343     count1 = count2 = 0;
344     prod1 = prod2 = 1.0;
345     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
346         yj = x[j - 1] - std::pow(x[0], 0.5 * (1.0 + 3.0 * (j - 2.0) / ((double)m_dim - 2.0)));
347         pj = std::cos(20.0 * yj * detail::pi() / std::sqrt(j + 0.0));
348         if (j % 2 == 0u) {
349             sum2 += yj * yj;
350             prod2 *= pj;
351             count2++;
352         } else {
353             sum1 += yj * yj;
354             prod1 *= pj;
355             count1++;
356         }
357     }
358     f[0] = x[0] + 2.0 * (4.0 * sum1 - 2.0 * prod1 + 2.0) / count1;
359     f[1] = 1.0 - std::sqrt(x[0]) + 2.0 * (4.0 * sum2 - 2.0 * prod2 + 2.0) / count2;
360 }
361 
UF4(vector_double & f,const vector_double & x) const362 void cec2009::UF4(vector_double &f, const vector_double &x) const
363 {
364     double count1, count2;
365     double sum1, sum2, yj, hj;
366 
367     sum1 = sum2 = 0.0;
368     count1 = count2 = 0;
369     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
370         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
371         hj = std::abs(yj) / (1.0 + std::exp(2.0 * std::abs(yj)));
372         if (j % 2 == 0u) {
373             sum2 += hj;
374             count2++;
375         } else {
376             sum1 += hj;
377             count1++;
378         }
379     }
380     f[0] = x[0] + 2.0 * sum1 / count1;
381     f[1] = 1.0 - x[0] * x[0] + 2.0 * sum2 / count2;
382 }
383 
UF5(vector_double & f,const vector_double & x) const384 void cec2009::UF5(vector_double &f, const vector_double &x) const
385 {
386     double count1, count2;
387     double sum1, sum2, yj, hj, N, E;
388 
389     sum1 = sum2 = 0.0;
390     count1 = count2 = 0;
391     N = 10.0;
392     E = 0.1;
393     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
394         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
395         hj = 2.0 * yj * yj - std::cos(4.0 * detail::pi() * yj) + 1.0;
396         if (j % 2 == 0u) {
397             sum2 += hj;
398             count2++;
399         } else {
400             sum1 += hj;
401             count1++;
402         }
403     }
404     hj = (0.5 / N + E) * std::abs(std::sin(2.0 * N * detail::pi() * x[0]));
405     f[0] = x[0] + hj + 2.0 * sum1 / count1;
406     f[1] = 1.0 - x[0] + hj + 2.0 * sum2 / count2;
407 }
408 
UF6(vector_double & f,const vector_double & x) const409 void cec2009::UF6(vector_double &f, const vector_double &x) const
410 {
411     double count1, count2;
412     double sum1, sum2, prod1, prod2, yj, hj, pj, N, E;
413     N = 2.0;
414     E = 0.1;
415 
416     sum1 = sum2 = 0.0;
417     count1 = count2 = 0;
418     prod1 = prod2 = 1.0;
419     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
420         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
421         pj = std::cos(20.0 * yj * detail::pi() / std::sqrt(j + 0.0));
422         if (j % 2 == 0u) {
423             sum2 += yj * yj;
424             prod2 *= pj;
425             count2++;
426         } else {
427             sum1 += yj * yj;
428             prod1 *= pj;
429             count1++;
430         }
431     }
432 
433     hj = 2.0 * (0.5 / N + E) * std::sin(2.0 * N * detail::pi() * x[0]);
434     if (hj < 0.0) hj = 0.0;
435     f[0] = x[0] + hj + 2.0 * (4.0 * sum1 - 2.0 * prod1 + 2.0) / count1;
436     f[1] = 1.0 - x[0] + hj + 2.0 * (4.0 * sum2 - 2.0 * prod2 + 2.0) / count2;
437 }
438 
UF7(vector_double & f,const vector_double & x) const439 void cec2009::UF7(vector_double &f, const vector_double &x) const
440 {
441     double count1, count2;
442     double sum1, sum2, yj;
443 
444     sum1 = sum2 = 0.0;
445     count1 = count2 = 0;
446     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
447         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
448         if (j % 2 == 0u) {
449             sum2 += yj * yj;
450             count2++;
451         } else {
452             sum1 += yj * yj;
453             count1++;
454         }
455     }
456     yj = std::pow(x[0], 0.2);
457     f[0] = yj + 2.0 * sum1 / count1;
458     f[1] = 1.0 - yj + 2.0 * sum2 / count2;
459 }
460 
UF8(vector_double & f,const vector_double & x) const461 void cec2009::UF8(vector_double &f, const vector_double &x) const
462 {
463     double count1, count2, count3;
464     double sum1, sum2, sum3, yj;
465 
466     sum1 = sum2 = sum3 = 0.0;
467     count1 = count2 = count3 = 0;
468     for (decltype(m_dim) j = 3u; j <= m_dim; ++j) {
469         yj = x[j - 1] - 2.0 * x[1] * std::sin(2.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
470         if (j % 3 == 1u) {
471             sum1 += yj * yj;
472             count1++;
473         } else if (j % 3 == 2u) {
474             sum2 += yj * yj;
475             count2++;
476         } else {
477             sum3 += yj * yj;
478             count3++;
479         }
480     }
481     f[0] = std::cos(0.5 * detail::pi() * x[0]) * std::cos(0.5 * detail::pi() * x[1]) + 2.0 * sum1 / count1;
482     f[1] = std::cos(0.5 * detail::pi() * x[0]) * std::sin(0.5 * detail::pi() * x[1]) + 2.0 * sum2 / count2;
483     f[2] = std::sin(0.5 * detail::pi() * x[0]) + 2.0 * sum3 / count3;
484 }
485 
UF9(vector_double & f,const vector_double & x) const486 void cec2009::UF9(vector_double &f, const vector_double &x) const
487 {
488     double count1, count2, count3;
489     double sum1, sum2, sum3, yj, E;
490 
491     E = 0.1;
492     sum1 = sum2 = sum3 = 0.0;
493     count1 = count2 = count3 = 0;
494     for (decltype(m_dim) j = 3u; j <= m_dim; ++j) {
495         yj = x[j - 1] - 2.0 * x[1] * std::sin(2.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
496         if (j % 3 == 1u) {
497             sum1 += yj * yj;
498             count1++;
499         } else if (j % 3 == 2u) {
500             sum2 += yj * yj;
501             count2++;
502         } else {
503             sum3 += yj * yj;
504             count3++;
505         }
506     }
507     yj = (1.0 + E) * (1.0 - 4.0 * (2.0 * x[0] - 1.0) * (2.0 * x[0] - 1.0));
508     if (yj < 0.0) yj = 0.0;
509     f[0] = 0.5 * (yj + 2 * x[0]) * x[1] + 2.0 * sum1 / count1;
510     f[1] = 0.5 * (yj - 2 * x[0] + 2.0) * x[1] + 2.0 * sum2 / count2;
511     f[2] = 1.0 - x[1] + 2.0 * sum3 / count3;
512 }
513 
UF10(vector_double & f,const vector_double & x) const514 void cec2009::UF10(vector_double &f, const vector_double &x) const
515 {
516     double count1, count2, count3;
517     double sum1, sum2, sum3, yj, hj;
518 
519     sum1 = sum2 = sum3 = 0.0;
520     count1 = count2 = count3 = 0;
521     for (decltype(m_dim) j = 3u; j <= m_dim; ++j) {
522         yj = x[j - 1] - 2.0 * x[1] * std::sin(2.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
523         hj = 4.0 * yj * yj - std::cos(8.0 * detail::pi() * yj) + 1.0;
524         if (j % 3 == 1u) {
525             sum1 += hj;
526             count1++;
527         } else if (j % 3 == 2u) {
528             sum2 += hj;
529             count2++;
530         } else {
531             sum3 += hj;
532             count3++;
533         }
534     }
535     f[0] = std::cos(0.5 * detail::pi() * x[0]) * std::cos(0.5 * detail::pi() * x[1]) + 2.0 * sum1 / count1;
536     f[1] = std::cos(0.5 * detail::pi() * x[0]) * std::sin(0.5 * detail::pi() * x[1]) + 2.0 * sum2 / count2;
537     f[2] = std::sin(0.5 * detail::pi() * x[0]) + 2.0 * sum3 / count3;
538 }
539 
540 /****************************************************************************/
541 // constraint test instances
542 /****************************************************************************/
CF1(vector_double & f,const vector_double & x) const543 void cec2009::CF1(vector_double &f, const vector_double &x) const
544 {
545     double count1, count2;
546     double sum1, sum2, yj, N, a;
547     N = 10.0;
548     a = 1.0;
549 
550     sum1 = sum2 = 0.0;
551     count1 = count2 = 0;
552     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
553         yj = x[j - 1] - std::pow(x[0], 0.5 * (1.0 + 3.0 * (j - 2.0) / ((double)m_dim - 2.0)));
554         if (j % 2 == 1u) {
555             sum1 += yj * yj;
556             count1++;
557         } else {
558             sum2 += yj * yj;
559             count2++;
560         }
561     }
562     f[0] = x[0] + 2.0 * sum1 / count1;
563     f[1] = 1.0 - x[0] + 2.0 * sum2 / count2;
564     // Inequality constraint
565     f[2] = f[1] + f[0] - a * std::abs(std::sin(N * detail::pi() * (f[0] - f[1] + 1.0))) - 1.0;
566     f[2] = -f[2]; // convert to g(x) <= 0 form
567 }
568 
CF2(vector_double & f,const vector_double & x) const569 void cec2009::CF2(vector_double &f, const vector_double &x) const
570 {
571     double count1, count2;
572     double sum1, sum2, yj, N, a, t;
573     N = 2.0;
574     a = 1.0;
575 
576     sum1 = sum2 = 0.0;
577     count1 = count2 = 0;
578     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
579         if (j % 2 == 1) {
580             yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
581             sum1 += yj * yj;
582             count1++;
583         } else {
584             yj = x[j - 1] - std::cos(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
585             sum2 += yj * yj;
586             count2++;
587         }
588     }
589     f[0] = x[0] + 2.0 * sum1 / count1;
590     f[1] = 1.0 - std::sqrt(x[0]) + 2.0 * sum2 / count2;
591     // Inequality constraint
592     t = f[1] + std::sqrt(f[0]) - a * std::sin(N * detail::pi() * (sqrt(f[0]) - f[1] + 1.0)) - 1.0;
593     f[2] = sgn(t) * std::abs(t) / (1 + std::exp(4.0 * std::abs(t)));
594     f[2] = -f[2]; // convert to g(x) <= 0 form
595 }
596 
CF3(vector_double & f,const vector_double & x) const597 void cec2009::CF3(vector_double &f, const vector_double &x) const
598 {
599     double count1, count2;
600     double sum1, sum2, prod1, prod2, yj, pj, N, a;
601     N = 2.0;
602     a = 1.0;
603 
604     sum1 = sum2 = 0.0;
605     count1 = count2 = 0;
606     prod1 = prod2 = 1.0;
607     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
608         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
609         pj = std::cos(20.0 * yj * detail::pi() / std::sqrt(j + 0.0));
610         if (j % 2 == 0u) {
611             sum2 += yj * yj;
612             prod2 *= pj;
613             count2++;
614         } else {
615             sum1 += yj * yj;
616             prod1 *= pj;
617             count1++;
618         }
619     }
620 
621     f[0] = x[0] + 2.0 * (4.0 * sum1 - 2.0 * prod1 + 2.0) / count1;
622     f[1] = 1.0 - x[0] * x[0] + 2.0 * (4.0 * sum2 - 2.0 * prod2 + 2.0) / count2;
623     // Inequality constraint
624     f[2] = f[1] + f[0] * f[0] - a * std::sin(N * detail::pi() * (f[0] * f[0] - f[1] + 1.0)) - 1.0;
625     f[2] = -f[2]; // convert to g(x) <= 0 form
626 }
627 
CF4(vector_double & f,const vector_double & x) const628 void cec2009::CF4(vector_double &f, const vector_double &x) const
629 {
630     double sum1, sum2, yj, t;
631 
632     sum1 = sum2 = 0.0;
633     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
634         yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
635         if (j % 2 == 1u) {
636             sum1 += yj * yj;
637         } else {
638             if (j == 2u)
639                 sum2 += yj < 1.5 - 0.75 * std::sqrt(2.0) ? std::abs(yj) : (0.125 + (yj - 1) * (yj - 1));
640             else
641                 sum2 += yj * yj;
642         }
643     }
644     f[0] = x[0] + sum1;
645     f[1] = 1.0 - x[0] + sum2;
646     // Inequality constraint
647     t = x[1] - std::sin(6.0 * x[0] * detail::pi() + 2.0 * detail::pi() / (double)m_dim) - 0.5 * x[0] + 0.25;
648     f[2] = sgn(t) * std::abs(t) / (1 + std::exp(4.0 * std::abs(t)));
649     f[2] = -f[2]; // convert to g(x) <= 0 form
650 }
651 
CF5(vector_double & f,const vector_double & x) const652 void cec2009::CF5(vector_double &f, const vector_double &x) const
653 {
654     double sum1, sum2, yj;
655 
656     sum1 = sum2 = 0.0;
657     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
658         if (j % 2 == 1u) {
659             yj = x[j - 1] - 0.8 * x[0] * std::cos(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
660             sum1 += 2.0 * yj * yj - std::cos(4.0 * detail::pi() * yj) + 1.0;
661         } else {
662             yj = x[j - 1] - 0.8 * x[0] * std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
663             if (j == 2u)
664                 sum2 += yj < 1.5 - 0.75 * std::sqrt(2.0) ? std::abs(yj) : (0.125 + (yj - 1) * (yj - 1));
665             else
666                 sum2 += 2.0 * yj * yj - std::cos(4.0 * detail::pi() * yj) + 1.0;
667         }
668     }
669     f[0] = x[0] + sum1;
670     f[1] = 1.0 - x[0] + sum2;
671     // Inequality constraint
672     f[2] = x[1] - 0.8 * x[0] * std::sin(6.0 * x[0] * detail::pi() + 2.0 * detail::pi() / (double)m_dim) - 0.5 * x[0]
673            + 0.25;
674     f[2] = -f[2]; // convert to g(x) <= 0 form
675 }
676 
CF6(vector_double & f,const vector_double & x) const677 void cec2009::CF6(vector_double &f, const vector_double &x) const
678 {
679     double sum1, sum2, yj;
680 
681     sum1 = sum2 = 0.0;
682     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
683         if (j % 2 == 1u) {
684             yj = x[j - 1] - 0.8 * x[0] * std::cos(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
685             sum1 += yj * yj;
686         } else {
687             yj = x[j - 1] - 0.8 * x[0] * std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
688             sum2 += yj * yj;
689         }
690     }
691     f[0] = x[0] + sum1;
692     f[1] = (1.0 - x[0]) * (1.0 - x[0]) + sum2;
693     // Inequality constraint
694     f[2] = x[1] - 0.8 * x[0] * std::sin(6.0 * x[0] * detail::pi() + 2.0 * detail::pi() / (double)m_dim)
695            - sgn((x[0] - 0.5) * (1.0 - x[0])) * std::sqrt(std::abs((x[0] - 0.5) * (1.0 - x[0])));
696     f[3] = x[3] - 0.8 * x[0] * std::sin(6.0 * x[0] * detail::pi() + 4.0 * detail::pi() / (double)m_dim)
697            - sgn(0.25 * std::sqrt(1 - x[0]) - 0.5 * (1.0 - x[0]))
698                  * std::sqrt(std::abs(0.25 * std::sqrt(1 - x[0]) - 0.5 * (1.0 - x[0])));
699     // convert to g(x) <= 0 form
700     f[2] = -f[2];
701     f[3] = -f[3];
702 }
703 
CF7(vector_double & f,const vector_double & x) const704 void cec2009::CF7(vector_double &f, const vector_double &x) const
705 {
706     double sum1, sum2, yj;
707 
708     sum1 = sum2 = 0.0;
709     for (decltype(m_dim) j = 2u; j <= m_dim; ++j) {
710         if (j % 2 == 1u) {
711             yj = x[j - 1] - std::cos(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
712             sum1 += 2.0 * yj * yj - std::cos(4.0 * detail::pi() * yj) + 1.0;
713         } else {
714             yj = x[j - 1] - std::sin(6.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
715             if (j == 2u || j == 4u)
716                 sum2 += yj * yj;
717             else
718                 sum2 += 2.0 * yj * yj - std::cos(4.0 * detail::pi() * yj) + 1.0;
719         }
720     }
721     f[0] = x[0] + sum1;
722     f[1] = (1.0 - x[0]) * (1.0 - x[0]) + sum2;
723     // Inequality constraint
724     f[2] = x[1] - std::sin(6.0 * x[0] * detail::pi() + 2.0 * detail::pi() / (double)m_dim)
725            - sgn((x[0] - 0.5) * (1.0 - x[0])) * std::sqrt(std::abs((x[0] - 0.5) * (1.0 - x[0])));
726     f[3] = x[3] - std::sin(6.0 * x[0] * detail::pi() + 4.0 * detail::pi() / (double)m_dim)
727            - sgn(0.25 * std::sqrt(1 - x[0]) - 0.5 * (1.0 - x[0]))
728                  * std::sqrt(std::abs(0.25 * std::sqrt(1 - x[0]) - 0.5 * (1.0 - x[0])));
729     // convert to g(x) <= 0 form
730     f[2] = -f[2];
731     f[3] = -f[3];
732 }
733 
CF8(vector_double & f,const vector_double & x) const734 void cec2009::CF8(vector_double &f, const vector_double &x) const
735 {
736     double count1, count2, count3;
737     double sum1, sum2, sum3, yj, N, a;
738     N = 2.0;
739     a = 4.0;
740 
741     sum1 = sum2 = sum3 = 0.0;
742     count1 = count2 = count3 = 0;
743     for (decltype(m_dim) j = 3u; j <= m_dim; ++j) {
744         yj = x[j - 1] - 2.0 * x[1] * std::sin(2.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
745         if (j % 3 == 1u) {
746             sum1 += yj * yj;
747             count1++;
748         } else if (j % 3 == 2u) {
749             sum2 += yj * yj;
750             count2++;
751         } else {
752             sum3 += yj * yj;
753             count3++;
754         }
755     }
756     f[0] = std::cos(0.5 * detail::pi() * x[0]) * std::cos(0.5 * detail::pi() * x[1]) + 2.0 * sum1 / count1;
757     f[1] = std::cos(0.5 * detail::pi() * x[0]) * std::sin(0.5 * detail::pi() * x[1]) + 2.0 * sum2 / count2;
758     f[2] = std::sin(0.5 * detail::pi() * x[0]) + 2.0 * sum3 / count3;
759     // Inequality constraint
760     f[3] = (f[0] * f[0] + f[1] * f[1]) / (1 - f[2] * f[2])
761            - a * std::abs(sin(N * detail::pi() * ((f[0] * f[0] - f[1] * f[1]) / (1 - f[2] * f[2]) + 1.0))) - 1.0;
762     f[3] = -f[3]; // convert to g(x) <= 0 form
763 }
764 
CF9(vector_double & f,const vector_double & x) const765 void cec2009::CF9(vector_double &f, const vector_double &x) const
766 {
767     double count1, count2, count3;
768     double sum1, sum2, sum3, yj, N, a;
769     N = 2.0;
770     a = 3.0;
771 
772     sum1 = sum2 = sum3 = 0.0;
773     count1 = count2 = count3 = 0;
774     for (decltype(m_dim) j = 3u; j <= m_dim; ++j) {
775         yj = x[j - 1] - 2.0 * x[1] * std::sin(2.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
776         if (j % 3 == 1u) {
777             sum1 += yj * yj;
778             count1++;
779         } else if (j % 3 == 2u) {
780             sum2 += yj * yj;
781             count2++;
782         } else {
783             sum3 += yj * yj;
784             count3++;
785         }
786     }
787     f[0] = std::cos(0.5 * detail::pi() * x[0]) * std::cos(0.5 * detail::pi() * x[1]) + 2.0 * sum1 / count1;
788     f[1] = std::cos(0.5 * detail::pi() * x[0]) * std::sin(0.5 * detail::pi() * x[1]) + 2.0 * sum2 / count2;
789     f[2] = std::sin(0.5 * detail::pi() * x[0]) + 2.0 * sum3 / count3;
790     // Inequality constraint
791     f[3] = (f[0] * f[0] + f[1] * f[1]) / (1 - f[2] * f[2])
792            - a * std::sin(N * detail::pi() * ((f[0] * f[0] - f[1] * f[1]) / (1 - f[2] * f[2]) + 1.0)) - 1.0;
793     f[3] = -f[3]; // convert to g(x) <= 0 form
794 }
795 
CF10(vector_double & f,const vector_double & x) const796 void cec2009::CF10(vector_double &f, const vector_double &x) const
797 {
798     double count1, count2, count3;
799     double sum1, sum2, sum3, yj, hj, N, a;
800     N = 2.0;
801     a = 1.0;
802 
803     sum1 = sum2 = sum3 = 0.0;
804     count1 = count2 = count3 = 0;
805     for (decltype(m_dim) j = 3u; j <= m_dim; ++j) {
806         yj = x[j - 1] - 2.0 * x[1] * std::sin(2.0 * detail::pi() * x[0] + j * detail::pi() / (double)m_dim);
807         hj = 4.0 * yj * yj - std::cos(8.0 * detail::pi() * yj) + 1.0;
808         if (j % 3 == 1u) {
809             sum1 += hj;
810             count1++;
811         } else if (j % 3 == 2u) {
812             sum2 += hj;
813             count2++;
814         } else {
815             sum3 += hj;
816             count3++;
817         }
818     }
819     f[0] = std::cos(0.5 * detail::pi() * x[0]) * std::cos(0.5 * detail::pi() * x[1]) + 2.0 * sum1 / count1;
820     f[1] = std::cos(0.5 * detail::pi() * x[0]) * std::sin(0.5 * detail::pi() * x[1]) + 2.0 * sum2 / count2;
821     f[2] = std::sin(0.5 * detail::pi() * x[0]) + 2.0 * sum3 / count3;
822     // Inequality constraint
823     f[3] = (f[0] * f[0] + f[1] * f[1]) / (1 - f[2] * f[2])
824            - a * std::sin(N * detail::pi() * ((f[0] * f[0] - f[1] * f[1]) / (1 - f[2] * f[2]) + 1.0)) - 1.0;
825     f[3] = -f[3]; // convert to g(x) <= 0 form
826 }
827 // -------------------------------------------
828 // LCOV_EXCL_STOP
829 
830 #if defined(__clang__) || defined(__GNUC__)
831 #pragma GCC diagnostic pop
832 #endif
833 
834 } // namespace pagmo
835 
836 PAGMO_S11N_PROBLEM_IMPLEMENT(pagmo::cec2009)
837