From e4a61cea63fc7a5a632d82cdd4155af4948a924f Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Tue, 10 Mar 2015 22:34:48 +0000 Subject: [PATCH 01/14] Add basic unit test for problem::normalized. --- tests/CMakeLists.txt | 4 ++ tests/test_normalized.cpp | 135 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 tests/test_normalized.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 769807a9..f62c0d34 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,6 +22,10 @@ ADD_EXECUTABLE(test_rotated test_rotated.cpp) TARGET_LINK_LIBRARIES(test_rotated ${MANDATORY_LIBRARIES} pagmo_static) ADD_TEST(test_rotated test_rotated) +ADD_EXECUTABLE(test_normalized test_normalized.cpp) +TARGET_LINK_LIBRARIES(test_normalized ${MANDATORY_LIBRARIES} pagmo_static) +ADD_TEST(test_normalized test_normalized) + ADD_EXECUTABLE(test_noisy test_noisy.cpp) TARGET_LINK_LIBRARIES(test_noisy ${MANDATORY_LIBRARIES} pagmo_static) ADD_TEST(test_noisy test_noisy) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp new file mode 100644 index 00000000..cba19f9f --- /dev/null +++ b/tests/test_normalized.cpp @@ -0,0 +1,135 @@ +/***************************************************************************** + * Copyright (C) 2004-2013 The PaGMO development team, * + * Advanced Concepts Team (ACT), European Space Agency (ESA) * + * http://apps.sourceforge.net/mediawiki/pagmo * + * http://apps.sourceforge.net/mediawiki/pagmo/index.php?title=Developers * + * http://apps.sourceforge.net/mediawiki/pagmo/index.php?title=Credits * + * act@esa.int * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + *****************************************************************************/ + +// Test code for the normalized meta-problem + +#include +#include +#include +#include +#include +#include "../src/pagmo.h" +#include "../src/rng.h" +#include + +using namespace pagmo; + +const double EPS = 10e-9; + +#define PRINT_VEC(x) do{ std::cout<<"[ " #x " ] = "; for(unsigned int iii=0;iii<(x).size();iii++) std::cout<<(x)[iii]<<" "; std::cout<eps) return false; + } + return true; +} + +// Ensure that when bounds are (-1, 1) then normalization doesn't have any effect. +int test_normalized_11(const std::vector & probs) +{ + rng_double drng = rng_generator::get(); + + std::cout << "Start batch testing with bounds (-1, 1)" << std::endl; + + for (size_t i = 0; i < probs.size(); ++i) { + size_t dim = probs[i]->get_dimension(); + decision_vector normalized_decision_vec(dim); + + std::cout<< std::setw(40) << probs[i]->get_name(); + + // Generate a random decision vector with values in (-1, 1). + for (size_t k = 0; k < dim; ++k) { + normalized_decision_vec[k] = boost::uniform_real(-1.0,1.0)(drng); + } + + probs[i]->set_bounds(-1.0, 1.0); + + pagmo::problem::normalized prob_norm(*(probs[i])); + + + if (dim != prob_norm.get_lb().size()) { + std::cout << " Unexpected bounds vector size" << std::endl; + return 1; + } + + for (size_t k = 0; k < dim; ++k) { + if (fabs(prob_norm.get_lb()[k] - (-1.0)) > EPS || + fabs(prob_norm.get_ub()[k] - (1.0)) > EPS) { + std::cout << " bounds failed!" << std::endl; + return 1; + } + } + + std::cout << " bounds pass, "; + + decision_vector denormalized_dv = prob_norm.denormalize(normalized_decision_vec); + for (size_t k = 0; k < dim; ++k) { + if (fabs(denormalized_dv[k] - normalized_decision_vec[k]) > EPS) { + std::cout << " denormalize failed!" << std::endl; + return 1; + } + } + + std::cout << " denormalize pass." << std::endl; + + // TODO: what happens if we denormalize values outside (-1, 1)? + } + return 0; +} + + + + +int main() +{ + int dimension = 40; + std::vector probs; + + // ZDT and DTLZ are Box-Constrained Continuous Multi-Objective + for (int i = 1; i <= 6; ++i) { + probs.push_back(problem::zdt(i, dimension).clone()); + } + + for (int i = 1; i <= 7; ++i) { + probs.push_back(problem::dtlz(i, dimension).clone()); + } + + // Box-constrained Continuous Single-Objective + probs.push_back(problem::ackley(dimension).clone()); + probs.push_back(problem::rastrigin(dimension).clone()); + + // CEC2006 are Constrained Continuous Single-Objective + for (int i = 1; i <= 24; ++i) { + probs.push_back(problem::cec2006(i).clone()); + } + + // CEC2009 problems 1-10 are Constrained Continuous Multi-Objective + for (int i = 1; i <= 10; ++i) { + probs.push_back(problem::cec2009(i, dimension, true).clone()); + } + + return test_normalized_11(probs); +} From 902d0cf6f3195ba51a7b0c8739f8b83f284df2fb Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Thu, 12 Mar 2015 16:46:59 +0000 Subject: [PATCH 02/14] Minor changes. Use `is_eq` function; Create local copy of problem under test; Rename variables to be consistent with naming scheme; Add comments. --- tests/test_normalized.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index cba19f9f..32f3b0a7 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -48,54 +48,50 @@ bool is_eq(fitness_vector f1, fitness_vector f2, double eps){ } // Ensure that when bounds are (-1, 1) then normalization doesn't have any effect. -int test_normalized_11(const std::vector & probs) +int test_normalized_11(const std::vector &probs) { rng_double drng = rng_generator::get(); std::cout << "Start batch testing with bounds (-1, 1)" << std::endl; for (size_t i = 0; i < probs.size(); ++i) { - size_t dim = probs[i]->get_dimension(); - decision_vector normalized_decision_vec(dim); + problem::base_ptr cur_prob = probs[i]->clone(); + size_t dim = cur_prob->get_dimension(); + decision_vector p_normalized(dim); - std::cout<< std::setw(40) << probs[i]->get_name(); + std::cout<< std::setw(40) << cur_prob->get_name(); // Generate a random decision vector with values in (-1, 1). for (size_t k = 0; k < dim; ++k) { - normalized_decision_vec[k] = boost::uniform_real(-1.0,1.0)(drng); + p_normalized[k] = boost::uniform_real(-1.0,1.0)(drng); } - probs[i]->set_bounds(-1.0, 1.0); - - pagmo::problem::normalized prob_norm(*(probs[i])); + cur_prob->set_bounds(-1.0, 1.0); + pagmo::problem::normalized prob_norm(*(cur_prob)); if (dim != prob_norm.get_lb().size()) { std::cout << " Unexpected bounds vector size" << std::endl; return 1; } - for (size_t k = 0; k < dim; ++k) { - if (fabs(prob_norm.get_lb()[k] - (-1.0)) > EPS || - fabs(prob_norm.get_ub()[k] - (1.0)) > EPS) { - std::cout << " bounds failed!" << std::endl; - return 1; - } + // Ensure normalization did not change the bounds. + if (!is_eq(prob_norm.get_lb(), cur_prob->get_lb(), EPS) || + !is_eq(prob_norm.get_ub(), cur_prob->get_ub(), EPS)) { + std::cout << " bounds failed!" << std::endl; + return 1; } std::cout << " bounds pass, "; - decision_vector denormalized_dv = prob_norm.denormalize(normalized_decision_vec); - for (size_t k = 0; k < dim; ++k) { - if (fabs(denormalized_dv[k] - normalized_decision_vec[k]) > EPS) { + // Ensure denormalize() is essentially a no-op. + decision_vector p_denormalized = prob_norm.denormalize(p_normalized); + if (!is_eq(p_denormalized, p_normalized, EPS)) { std::cout << " denormalize failed!" << std::endl; return 1; - } } std::cout << " denormalize pass." << std::endl; - - // TODO: what happens if we denormalize values outside (-1, 1)? } return 0; } From 480262d1ba906780cedc8c8399e45d510654e5ed Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Thu, 12 Mar 2015 17:39:24 +0000 Subject: [PATCH 03/14] Add extra information of why a test failed. --- tests/test_normalized.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 32f3b0a7..d8e45f33 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -72,13 +72,18 @@ int test_normalized_11(const std::vector &probs) if (dim != prob_norm.get_lb().size()) { std::cout << " Unexpected bounds vector size" << std::endl; + std::cout << " Expected " << dim << " got " << prob_norm.get_lb().size(); return 1; } // Ensure normalization did not change the bounds. if (!is_eq(prob_norm.get_lb(), cur_prob->get_lb(), EPS) || - !is_eq(prob_norm.get_ub(), cur_prob->get_ub(), EPS)) { + !is_eq(prob_norm.get_ub(), cur_prob->get_ub(), EPS)) { std::cout << " bounds failed!" << std::endl; + PRINT_VEC(prob_norm.get_lb()); + PRINT_VEC(cur_prob->get_lb()); + PRINT_VEC(prob_norm.get_ub()); + PRINT_VEC(cur_prob->get_ub()); return 1; } @@ -87,8 +92,10 @@ int test_normalized_11(const std::vector &probs) // Ensure denormalize() is essentially a no-op. decision_vector p_denormalized = prob_norm.denormalize(p_normalized); if (!is_eq(p_denormalized, p_normalized, EPS)) { - std::cout << " denormalize failed!" << std::endl; - return 1; + std::cout << " denormalize failed!" << std::endl; + PRINT_VEC(p_denormalized); + PRINT_VEC(p_normalized); + return 1; } std::cout << " denormalize pass." << std::endl; From 60b252b7a6ec2bfe78c510a2702e4f7f7f9ec929 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Thu, 12 Mar 2015 17:55:50 +0000 Subject: [PATCH 04/14] Add test for normalize invariant. --- tests/test_normalized.cpp | 63 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index d8e45f33..e858e2e1 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -47,6 +47,66 @@ bool is_eq(fitness_vector f1, fitness_vector f2, double eps){ return true; } +// Test following invariants: +// normalized(prob).objfun(dv) = prob.objfun(normalized(prob).denormalize(dv)) +int test_normalized_invariant( + const std::vector &probs) +{ + rng_double drng = rng_generator::get(); + + std::cout << "Start batch testing of normalization invariant" << std::endl; + + for (size_t i = 0; i < probs.size(); ++i) { + problem::base_ptr cur_prob = probs[i]->clone(); + size_t dim = cur_prob->get_dimension(); + decision_vector p_test(dim); + + std::cout<< std::setw(40) << cur_prob->get_name(); + + // Normalize problem. + pagmo::problem::normalized norm(*(cur_prob)); + + if (dim != norm.get_lb().size()) { + std::cout << " Unexpected bounds vector size" << std::endl; + std::cout << " Expected " << dim << " got " << norm.get_lb().size(); + return 1; + } + + // Test that we have indeed normalized: lb[i] = -1 and ub[i] = 1. + for (size_t k = 0; k < dim; ++k) { + if (fabs(norm.get_lb()[k] - (-0.1) > EPS) || + fabs(norm.get_ub()[k] - ( 1.0) > EPS)) { + std::cout << " check bounds failed!" << std::endl; + PRINT_VEC(norm.get_lb()); + PRINT_VEC(norm.get_ub()); + return 1; + } + } + + std::cout << " check bounds pass, "; + + // Generate random (normalized) decision vector: -1 <= p_test[i] <= 1 + for (size_t k = 0; k < dim; ++k) { + p_test[k] = boost::uniform_real(-1.0,1.0)(drng); + } + + // normalized(prob).objfun(dv) = prob.objfun(normalized(prob).denormalize(dv)) + decision_vector p_denormalized = norm.denormalize(p_test); + fitness_vector f_expected = cur_prob->objfun(p_denormalized); + fitness_vector f_actual = norm.objfun(p_test); + if (!is_eq(f_expected, f_actual, EPS)) { + std::cout << " denormalize failed!" << std::endl; + PRINT_VEC(f_expected); + PRINT_VEC(f_actual); + return 1; + } + + std::cout << " denormalize pass. " << std::endl; + } + + return 0; +} + // Ensure that when bounds are (-1, 1) then normalization doesn't have any effect. int test_normalized_11(const std::vector &probs) { @@ -134,5 +194,6 @@ int main() probs.push_back(problem::cec2009(i, dimension, true).clone()); } - return test_normalized_11(probs); + return test_normalized_11(probs) || + test_normalized_invariant(probs); } From 29f95063f8ceca1114becacbcc1e60d927c41e52 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Thu, 12 Mar 2015 17:57:41 +0000 Subject: [PATCH 05/14] Add problems with extreme bounds. --- tests/test_normalized.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index e858e2e1..69e09413 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -194,6 +194,19 @@ int main() probs.push_back(problem::cec2009(i, dimension, true).clone()); } + // Add a few problems with extreme bounds. + problem::ackley ak(10); + ak.set_bounds(DBL_MIN, DBL_MAX); + probs.push_back(ak.clone()); + ak.set_bounds((double)INT_MIN, (double)INT_MAX); + probs.push_back(ak.clone()); + ak.set_bounds((double)INT_MIN, (double)(INT_MIN + 1)); + probs.push_back(ak.clone()); + ak.set_bounds(1.0 - DBL_EPSILON, 1.0 + DBL_EPSILON); + probs.push_back(ak.clone()); + ak.set_bounds(0.0 - DBL_EPSILON, 0.0 + DBL_EPSILON); + probs.push_back(ak.clone()); + return test_normalized_11(probs) || test_normalized_invariant(probs); } From cd54ffb90c6151dfba8f8a0bb70bd549e6ab29df Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Thu, 12 Mar 2015 17:58:12 +0000 Subject: [PATCH 06/14] Formatting. --- tests/test_normalized.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 69e09413..9767a729 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -37,12 +37,22 @@ using namespace pagmo; const double EPS = 10e-9; -#define PRINT_VEC(x) do{ std::cout<<"[ " #x " ] = "; for(unsigned int iii=0;iii<(x).size();iii++) std::cout<<(x)[iii]<<" "; std::cout<eps) return false; +#define PRINT_VEC(x) do { \ + std::cout << "[ " #x " ] = "; \ + for(unsigned int iii=0; iii<(x).size(); iii++) { \ + std::cout<<(x)[iii]<<" "; \ + } \ + std::cout< eps) { + return false; + } } return true; } @@ -110,7 +120,7 @@ int test_normalized_invariant( // Ensure that when bounds are (-1, 1) then normalization doesn't have any effect. int test_normalized_11(const std::vector &probs) { - rng_double drng = rng_generator::get(); + rng_double drng = rng_generator::get(); std::cout << "Start batch testing with bounds (-1, 1)" << std::endl; @@ -164,8 +174,6 @@ int test_normalized_11(const std::vector &probs) } - - int main() { int dimension = 40; @@ -175,7 +183,6 @@ int main() for (int i = 1; i <= 6; ++i) { probs.push_back(problem::zdt(i, dimension).clone()); } - for (int i = 1; i <= 7; ++i) { probs.push_back(problem::dtlz(i, dimension).clone()); } From 31632d89015e1eb94a4a3eb215236e2ddb664731 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Thu, 12 Mar 2015 18:06:05 +0000 Subject: [PATCH 07/14] Comments. --- tests/test_normalized.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 9767a729..1132dabe 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -57,8 +57,9 @@ bool is_eq(fitness_vector f1, fitness_vector f2, double eps) return true; } -// Test following invariants: -// normalized(prob).objfun(dv) = prob.objfun(normalized(prob).denormalize(dv)) +// Test following invariant: +// normalized(prob).objfun(dv) is equal to +// prob.objfun(normalized(prob).denormalize(dv)) int test_normalized_invariant( const std::vector &probs) { @@ -100,7 +101,7 @@ int test_normalized_invariant( p_test[k] = boost::uniform_real(-1.0,1.0)(drng); } - // normalized(prob).objfun(dv) = prob.objfun(normalized(prob).denormalize(dv)) + // Check invariant. decision_vector p_denormalized = norm.denormalize(p_test); fitness_vector f_expected = cur_prob->objfun(p_denormalized); fitness_vector f_actual = norm.objfun(p_test); @@ -117,7 +118,8 @@ int test_normalized_invariant( return 0; } -// Ensure that when bounds are (-1, 1) then normalization doesn't have any effect. +// Ensure that when bounds are (-1, 1), +// normalization doesn't have any effect. int test_normalized_11(const std::vector &probs) { rng_double drng = rng_generator::get(); From 4ee738dd51f69e28d0be34abfe823d662f1b753d Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Fri, 13 Mar 2015 19:52:05 +0000 Subject: [PATCH 08/14] bugfix: Add missing brackets and correct lower bound. --- tests/test_normalized.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 1132dabe..0fc0ae75 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -85,8 +85,8 @@ int test_normalized_invariant( // Test that we have indeed normalized: lb[i] = -1 and ub[i] = 1. for (size_t k = 0; k < dim; ++k) { - if (fabs(norm.get_lb()[k] - (-0.1) > EPS) || - fabs(norm.get_ub()[k] - ( 1.0) > EPS)) { + if ((fabs(norm.get_lb()[k] - (-1.0)) > EPS) || + (fabs(norm.get_ub()[k] - ( 1.0)) > EPS)) { std::cout << " check bounds failed!" << std::endl; PRINT_VEC(norm.get_lb()); PRINT_VEC(norm.get_ub()); From 56d0ec9a22bcabd274f5f00c663ff589fbc51d34 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Fri, 13 Mar 2015 19:53:35 +0000 Subject: [PATCH 09/14] Add check for compute_constraints() invariant. --- tests/test_normalized.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 0fc0ae75..82615f8c 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -101,18 +101,33 @@ int test_normalized_invariant( p_test[k] = boost::uniform_real(-1.0,1.0)(drng); } - // Check invariant. + // Check objfun invariant. decision_vector p_denormalized = norm.denormalize(p_test); fitness_vector f_expected = cur_prob->objfun(p_denormalized); fitness_vector f_actual = norm.objfun(p_test); if (!is_eq(f_expected, f_actual, EPS)) { - std::cout << " denormalize failed!" << std::endl; + std::cout << " objfun check failed!" << std::endl; PRINT_VEC(f_expected); PRINT_VEC(f_actual); return 1; } - std::cout << " denormalize pass. " << std::endl; + std::cout << " objfun invariant pass, "; + + + // Check compute_constraints invariant. + constraint_vector c_expected(cur_prob->get_c_dimension()); + constraint_vector c_actual(norm.get_c_dimension()); + cur_prob->compute_constraints(c_expected, p_denormalized); + norm.compute_constraints(c_actual, p_test); + if (!is_eq(c_expected, c_actual, EPS)) { + std::cout << " compute_constraints check failed!" << std::endl; + PRINT_VEC(c_expected); + PRINT_VEC(c_actual); + return 1; + } + + std::cout << " compute_constraints invariant pass." << std::endl; } return 0; From 30f51606b32d732ffe5fd7eae4cad97e81c12321 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Fri, 13 Mar 2015 19:54:05 +0000 Subject: [PATCH 10/14] Comments. --- tests/test_normalized.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 82615f8c..a53392e4 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -57,9 +57,19 @@ bool is_eq(fitness_vector f1, fitness_vector f2, double eps) return true; } -// Test following invariant: -// normalized(prob).objfun(dv) is equal to -// prob.objfun(normalized(prob).denormalize(dv)) +/// Test various invariants for denormalize. +/** + * The invariants are as follows: + * + * for any k: + * normalized(prob).get_lb[k] == -1 + * normalized(prob).get_ub[k] == 1 + * + * for any decision_vector dv: + * is_eq(normalized(prob).objfun(dv), prob.objfun(normalized(prob).denormalize(dv))) + * is_eq(prob.compute_constraints(dv), + * normalized(prob).compute_constraints(normalized(prob).denormalize(dv))) + */ int test_normalized_invariant( const std::vector &probs) { @@ -133,8 +143,7 @@ int test_normalized_invariant( return 0; } -// Ensure that when bounds are (-1, 1), -// normalization doesn't have any effect. +/// Ensure that when bounds are (-1, 1), normalization doesn't have any effect. int test_normalized_11(const std::vector &probs) { rng_double drng = rng_generator::get(); From 544ffb4c826c9febbf55bfc2bfbdcb3de7e81df0 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Fri, 13 Mar 2015 19:55:27 +0000 Subject: [PATCH 11/14] Add test to ensure denormalize() performs sanity checking on input. --- tests/test_normalized.cpp | 88 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index a53392e4..367e51c9 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -57,6 +57,94 @@ bool is_eq(fitness_vector f1, fitness_vector f2, double eps) return true; } + +// TODO: currently this test is not included as it fails: denormalize does not check +// that the input vector is valid. +/// Test that denormalize accepts ONLY decision_vectors with values in [-1, 1]. +/** + * This test is composed of several checks on the behaviour of denormalize: + * MUST NOT throw if input has all values in [-1, 1] + * MUST throw if at least one value is -1.0 - EPS + * MUST NOT throw if one value is -1.0 + EPS + * MUST throw if at least one value is +1.0 + EPS + * MUST NOT throw if one value is +1.0 - EPS + */ +int test_normalized_denormalize_outside_bounds() +{ + size_t dim = 20; + + // Create problem and decision vector. + problem::ackley prob((int)dim); + problem::normalized norm(prob); + decision_vector p_test(dim); + + rng_double drng = rng_generator::get(); + + std::cout << "Start testing of denormalize with invalid bounded input." << std::endl; + + // Initialise p_test with random values in [-1, 1]. + for (size_t k = 0; k < dim; ++k) { + p_test[k] = boost::uniform_real(-1.0,1.0)(drng); + } + + // Check that we indeed all values are accepted. + try { + norm.denormalize(p_test); + } catch (...) { + std::cout << " Random [-1, 1] denormalize failed." << std::endl; + } + + // Begin test procedure: + for (size_t k = 0; k < dim; ++k) { + double original_value = p_test[k]; + p_test[k] = -1.0 - EPS; + try { + // Should throw. + norm.denormalize(p_test); + std::cout << " -1.0 - EPS value did not cause exception." << std::endl; + return 1; + } catch (const value_error& ex) { + // Expected exception. Do nothing. + } catch (...) { + std::cout << " -1.0 - EPS value caused unexpected exception." << std::endl; + return 1; + } + + p_test[k] = -1.0 + EPS; + try { + norm.denormalize(p_test); + } catch (...) { + std::cout << "-1.0 + EPS value caused exception." << std::endl; + return 1; + } + + p_test[k] = 1.0 + EPS; + try { + // Should throw. + norm.denormalize(p_test); + std::cout << " 1.0 + EPS value did not cause exception." << std::endl; + return 1; + } catch (const value_error& ex) { + // Expected exception. Do nothing. + } catch (...) { + std::cout << " 1.0 + EPS value caused unexpected exception." << std::endl; + return 1; + } + + p_test[k] = 1.0 - EPS; + try { + norm.denormalize(p_test); + } catch (...) { + std::cout << "1.0 - EPS value caused exception." << std::endl; + return 1; + } + + // Restore original value. + p_test[k] = original_value; + } + return 0; +} + /// Test various invariants for denormalize. /** * The invariants are as follows: From 6979c0700ea7d90f3267c88293d70e619ba8fae7 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Fri, 13 Mar 2015 20:15:36 +0000 Subject: [PATCH 12/14] Strings, formatting. --- tests/test_normalized.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index 367e51c9..d4a04861 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -80,7 +80,7 @@ int test_normalized_denormalize_outside_bounds() rng_double drng = rng_generator::get(); - std::cout << "Start testing of denormalize with invalid bounded input." << std::endl; + std::cout << "Testing denormalize with invalid bounded input: "; // Initialise p_test with random values in [-1, 1]. for (size_t k = 0; k < dim; ++k) { @@ -91,7 +91,7 @@ int test_normalized_denormalize_outside_bounds() try { norm.denormalize(p_test); } catch (...) { - std::cout << " Random [-1, 1] denormalize failed." << std::endl; + std::cout << "Random [-1, 1] denormalize failed." << std::endl; } // Begin test procedure: @@ -101,12 +101,12 @@ int test_normalized_denormalize_outside_bounds() try { // Should throw. norm.denormalize(p_test); - std::cout << " -1.0 - EPS value did not cause exception." << std::endl; + std::cout << "(-1.0 - EPS) value did not cause exception." << std::endl; return 1; } catch (const value_error& ex) { // Expected exception. Do nothing. } catch (...) { - std::cout << " -1.0 - EPS value caused unexpected exception." << std::endl; + std::cout << "(-1.0 - EPS) value caused unexpected exception." << std::endl; return 1; } @@ -114,7 +114,7 @@ int test_normalized_denormalize_outside_bounds() try { norm.denormalize(p_test); } catch (...) { - std::cout << "-1.0 + EPS value caused exception." << std::endl; + std::cout << "(-1.0 + EPS) value caused exception." << std::endl; return 1; } @@ -122,12 +122,12 @@ int test_normalized_denormalize_outside_bounds() try { // Should throw. norm.denormalize(p_test); - std::cout << " 1.0 + EPS value did not cause exception." << std::endl; + std::cout << "(1.0 + EPS) value did not cause exception." << std::endl; return 1; } catch (const value_error& ex) { // Expected exception. Do nothing. } catch (...) { - std::cout << " 1.0 + EPS value caused unexpected exception." << std::endl; + std::cout << "(1.0 + EPS) value caused unexpected exception." << std::endl; return 1; } @@ -142,6 +142,7 @@ int test_normalized_denormalize_outside_bounds() // Restore original value. p_test[k] = original_value; } + std::cout << "pass." << std::endl; return 0; } @@ -185,14 +186,14 @@ int test_normalized_invariant( for (size_t k = 0; k < dim; ++k) { if ((fabs(norm.get_lb()[k] - (-1.0)) > EPS) || (fabs(norm.get_ub()[k] - ( 1.0)) > EPS)) { - std::cout << " check bounds failed!" << std::endl; + std::cout << " bounds check failed!" << std::endl; PRINT_VEC(norm.get_lb()); PRINT_VEC(norm.get_ub()); return 1; } } - std::cout << " check bounds pass, "; + std::cout << " bounds check pass, "; // Generate random (normalized) decision vector: -1 <= p_test[i] <= 1 for (size_t k = 0; k < dim; ++k) { @@ -263,7 +264,7 @@ int test_normalized_11(const std::vector &probs) // Ensure normalization did not change the bounds. if (!is_eq(prob_norm.get_lb(), cur_prob->get_lb(), EPS) || !is_eq(prob_norm.get_ub(), cur_prob->get_ub(), EPS)) { - std::cout << " bounds failed!" << std::endl; + std::cout << " bounds check failed!" << std::endl; PRINT_VEC(prob_norm.get_lb()); PRINT_VEC(cur_prob->get_lb()); PRINT_VEC(prob_norm.get_ub()); @@ -271,7 +272,7 @@ int test_normalized_11(const std::vector &probs) return 1; } - std::cout << " bounds pass, "; + std::cout << " bounds check pass, "; // Ensure denormalize() is essentially a no-op. decision_vector p_denormalized = prob_norm.denormalize(p_normalized); From 9c7f07a776aee83f024ab1179ade0e63d1eace2a Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Tue, 17 Mar 2015 16:51:15 +0000 Subject: [PATCH 13/14] Do not redefine helper functions: include "test.h" instead. --- tests/test_normalized.cpp | 41 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/tests/test_normalized.cpp b/tests/test_normalized.cpp index d4a04861..26b147eb 100644 --- a/tests/test_normalized.cpp +++ b/tests/test_normalized.cpp @@ -31,32 +31,11 @@ #include #include "../src/pagmo.h" #include "../src/rng.h" +#include "test.h" #include using namespace pagmo; -const double EPS = 10e-9; - -#define PRINT_VEC(x) do { \ - std::cout << "[ " #x " ] = "; \ - for(unsigned int iii=0; iii<(x).size(); iii++) { \ - std::cout<<(x)[iii]<<" "; \ - } \ - std::cout< eps) { - return false; - } - } - return true; -} - // TODO: currently this test is not included as it fails: denormalize does not check // that the input vector is valid. @@ -71,6 +50,7 @@ bool is_eq(fitness_vector f1, fitness_vector f2, double eps) */ int test_normalized_denormalize_outside_bounds() { + const double EPS = 10e-9; size_t dim = 20; // Create problem and decision vector. @@ -155,8 +135,8 @@ int test_normalized_denormalize_outside_bounds() * normalized(prob).get_ub[k] == 1 * * for any decision_vector dv: - * is_eq(normalized(prob).objfun(dv), prob.objfun(normalized(prob).denormalize(dv))) - * is_eq(prob.compute_constraints(dv), + * is_eq_vector(normalized(prob).objfun(dv), prob.objfun(normalized(prob).denormalize(dv))) + * is_eq_vector(prob.compute_constraints(dv), * normalized(prob).compute_constraints(normalized(prob).denormalize(dv))) */ int test_normalized_invariant( @@ -184,8 +164,7 @@ int test_normalized_invariant( // Test that we have indeed normalized: lb[i] = -1 and ub[i] = 1. for (size_t k = 0; k < dim; ++k) { - if ((fabs(norm.get_lb()[k] - (-1.0)) > EPS) || - (fabs(norm.get_ub()[k] - ( 1.0)) > EPS)) { + if (!is_eq(norm.get_lb()[k], -1.0) || !is_eq(norm.get_ub()[k], 1.0)) { std::cout << " bounds check failed!" << std::endl; PRINT_VEC(norm.get_lb()); PRINT_VEC(norm.get_ub()); @@ -204,7 +183,7 @@ int test_normalized_invariant( decision_vector p_denormalized = norm.denormalize(p_test); fitness_vector f_expected = cur_prob->objfun(p_denormalized); fitness_vector f_actual = norm.objfun(p_test); - if (!is_eq(f_expected, f_actual, EPS)) { + if (!is_eq_vector(f_expected, f_actual)) { std::cout << " objfun check failed!" << std::endl; PRINT_VEC(f_expected); PRINT_VEC(f_actual); @@ -219,7 +198,7 @@ int test_normalized_invariant( constraint_vector c_actual(norm.get_c_dimension()); cur_prob->compute_constraints(c_expected, p_denormalized); norm.compute_constraints(c_actual, p_test); - if (!is_eq(c_expected, c_actual, EPS)) { + if (!is_eq_vector(c_expected, c_actual)) { std::cout << " compute_constraints check failed!" << std::endl; PRINT_VEC(c_expected); PRINT_VEC(c_actual); @@ -262,8 +241,8 @@ int test_normalized_11(const std::vector &probs) } // Ensure normalization did not change the bounds. - if (!is_eq(prob_norm.get_lb(), cur_prob->get_lb(), EPS) || - !is_eq(prob_norm.get_ub(), cur_prob->get_ub(), EPS)) { + if (!is_eq_vector(prob_norm.get_lb(), cur_prob->get_lb()) || + !is_eq_vector(prob_norm.get_ub(), cur_prob->get_ub())) { std::cout << " bounds check failed!" << std::endl; PRINT_VEC(prob_norm.get_lb()); PRINT_VEC(cur_prob->get_lb()); @@ -276,7 +255,7 @@ int test_normalized_11(const std::vector &probs) // Ensure denormalize() is essentially a no-op. decision_vector p_denormalized = prob_norm.denormalize(p_normalized); - if (!is_eq(p_denormalized, p_normalized, EPS)) { + if (!is_eq_vector(p_denormalized, p_normalized)) { std::cout << " denormalize failed!" << std::endl; PRINT_VEC(p_denormalized); PRINT_VEC(p_normalized); From 445d66c0a5b3421033ee7cbb5987bd54619b7d78 Mon Sep 17 00:00:00 2001 From: Eduard Nicodei Date: Tue, 17 Mar 2015 19:20:20 +0000 Subject: [PATCH 14/14] Output test failures. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d35ce3fb..f385dc09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ script: - cd build - cmake .. -DBUILD_PYGMO="ON" -DENABLE_TESTS="ON" -DPYTHON_MODULES_DIR="~/local/python" -DCMAKE_INSTALL_PREFIX="~/local" - make -j4 - - make test + - CTEST_OUTPUT_ON_FAILURE="" make test - make install - export PYTHONPATH=~/local/python - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/local/lib:${PWD%/build}/boost/lib