From fa5ff4993d0fa97809f8d69d9fd3ee721f62e8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 15 Jun 2018 12:54:59 +0200 Subject: [PATCH] Improved the test of interpolation functions to test other types of functors --- .../CGAL/_test_interpolation_functions_2.cpp | 314 +++++++++++++----- .../test_interpolation_functions_2.cpp | 71 ++-- 2 files changed, 275 insertions(+), 110 deletions(-) diff --git a/Interpolation/test/Interpolation/include/CGAL/_test_interpolation_functions_2.cpp b/Interpolation/test/Interpolation/include/CGAL/_test_interpolation_functions_2.cpp index 59f97ada6f6..1d245501276 100644 --- a/Interpolation/test/Interpolation/include/CGAL/_test_interpolation_functions_2.cpp +++ b/Interpolation/test/Interpolation/include/CGAL/_test_interpolation_functions_2.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,42 @@ private: Traits traits; }; +template +struct Value_function +{ + typedef V argument_type; + typedef std::pair result_type; + + Value_function(std::size_t i) : index(i) { } + + result_type operator()(const argument_type& a) const { + return result_type(a->info()[index].value, true); + } + +private: + std::size_t index; +}; + +template +struct Gradient_function + : public CGAL::iterator +{ + + typedef V argument_type; + typedef std::pair result_type; + + Gradient_function(std::size_t i) : index(i) { } + + result_type operator()(const argument_type& a) const { + return std::make_pair(a->info()[index].gradient, + a->info()[index].gradient != CGAL::NULL_VECTOR); + } + +private: + std::size_t index; +}; + + template < class ForwardIterator > bool test_norm(ForwardIterator first, ForwardIterator beyond, typename std::iterator_traits::value_type::second_type norm) @@ -88,10 +125,10 @@ bool test_norm(ForwardIterator first, ForwardIterator beyond, } } -template < class Tr, class ForwardIterator > +template < class Tr, class ForwardIterator, class Point > bool test_barycenter(ForwardIterator first, ForwardIterator beyond, typename std::iterator_traits::value_type::second_type norm, - const typename std::iterator_traits::value_type::first_type& p, + const Point& p, const typename std::iterator_traits::value_type::second_type& tolerance) { typedef typename Tr::Geom_traits Gt; @@ -138,9 +175,13 @@ bool _test_sibson_c1_interpolation_sqrt(ForwardIterator first, ForwardIterator b const typename std::iterator_traits::value_type::second_type& exact_value, CGAL::Field_with_sqrt_tag) { - typename ValueFunctor::result_type res = CGAL::sibson_c1_interpolation(first, beyond, - norm, p, f, - grad_f, geom_traits); + typedef typename std::iterator_traits::value_type::first_type arg_type; + typedef typename boost::result_of::type value_functor_result_type; + + value_functor_result_type res = CGAL::sibson_c1_interpolation(first, beyond, + norm, p, f, + grad_f, geom_traits); + return res.second && (CGAL_NTS abs(res.first-exact_value) <= tolerance); } @@ -148,14 +189,18 @@ template < class ForwardIterator, class ValueFunctor, class GradFunctor, class G bool test_interpolation_with_value(ForwardIterator first, ForwardIterator beyond, const typename std::iterator_traits::value_type::second_type& norm, const Point& p, - const typename ValueFunctor::result_type::first_type exact_value, + const typename boost::result_of< + ValueFunctor(typename std::iterator_traits::value_type::first_type)> + ::type::first_type exact_value, ValueFunctor f, GradFunctor grad_f, const Gt& geom_traits, const int& i, const typename std::iterator_traits::value_type::second_type& tolerance) { - typedef typename ValueFunctor::result_type::first_type Value_type; + typedef typename std::iterator_traits::value_type::first_type arg_type; + typedef typename boost::result_of::type value_functor_result_type; + typedef typename value_functor_result_type::first_type Value_type; if(i == 0) { @@ -163,8 +208,8 @@ bool test_interpolation_with_value(ForwardIterator first, ForwardIterator beyond assert(CGAL_NTS abs(val - exact_value) <= tolerance); } - typename ValueFunctor::result_type res = CGAL::quadratic_interpolation(first, beyond, norm, p, f, - grad_f, geom_traits); + value_functor_result_type res = CGAL::quadratic_interpolation(first, beyond, norm, p, f, + grad_f, geom_traits); assert(res.second && (CGAL_NTS abs(res.first - exact_value) <= tolerance)); if(i<2) @@ -190,20 +235,17 @@ bool test_interpolation_with_value(ForwardIterator first, ForwardIterator beyond return true; } -template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Gt, class Point> +template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Gt, class Point, class Value_type> bool test_interpolation(ForwardIterator first, ForwardIterator beyond, const typename std::iterator_traits::value_type::second_type& norm, const Point& p, + const Value_type exact_value, ValueFunctor f, GradFunctor grad_f, const Gt& geom_traits, const int& i, const typename std::iterator_traits::value_type::second_type& tolerance) { - typedef typename ValueFunctor::result_type::first_type Value_type; - assert(f(p).second); - Value_type exact_value = f(p).first; - return test_interpolation_with_value(first, beyond, norm, p, exact_value, f, grad_f, geom_traits, i, tolerance); } @@ -227,7 +269,7 @@ void _test_interpolation_functions_2_Delaunay_without_OutputFunctor(const Dt&, c typedef typename Gt::FT Coord_type; typedef typename Gt::Vector_2 Vector; - typedef std::map Point_value_map ; + typedef std::map Point_value_map; typedef std::map Point_vector_map; typedef std::vector > Point_coordinate_vector; @@ -313,7 +355,8 @@ void _test_interpolation_functions_2_Delaunay_without_OutputFunctor(const Dt&, c for(int i=0; i<3; ++i) { - assert(test_interpolation(coords.begin(), coords.end(), norm, points[j], + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[j], values[i][points[j]], CGAL::Data_access< Point_value_map >(values[i]), CGAL::Data_access< Point_vector_map >(gradients[i]), Traits(), i, tolerance)); @@ -373,7 +416,8 @@ void _test_interpolation_functions_2_Delaunay_without_OutputFunctor(const Dt&, c for(int j=0; j<3; ++j) { - assert(test_interpolation(coords.begin(), coords.end(), norm, points[n/2], + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[n/2], values[j][points[n/2]], CGAL::Data_access(values[j]), CGAL::Data_access(gradients[j]), Traits(), j, tolerance)); @@ -396,16 +440,18 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons typedef typename Dt::Geom_traits Gt; typedef CGAL::Interpolation_traits_2 Traits; + typedef typename Dt::Vertex_handle Vertex_handle; + typedef typename Gt::FT Coord_type; typedef typename Dt::Point Point; typedef typename Gt::Vector_2 Vector; - typedef std::map Point_value_map ; - typedef std::map Point_vector_map; + typedef std::vector > Coordinate_vector; + typedef typename Coordinate_vector::const_iterator CV_cit; + typedef CGAL::Identity > Output_functor; - typedef std::vector > Point_coordinate_vector; - typedef typename Point_coordinate_vector::const_iterator PCV_cit; - typedef CGAL::Interpolation::internal::Extract_point_in_pair Point_output_functor; + typedef std::map Point_value_map; + typedef std::map Point_vector_map; std::cout << "NN2: Testing random points." << std::endl; @@ -425,9 +471,6 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons CGAL::Random random; - Point_value_map values[3]; - Point_vector_map gradients[3]; - Coord_type alpha = Coord_type(random.get_double(-max_value, max_value)), beta1 = Coord_type(random.get_double(-max_value, max_value)), beta2 = Coord_type(random.get_double(-max_value, max_value)), @@ -436,67 +479,110 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons gamma3 = Coord_type(random.get_double(-max_value, max_value)); //INSERTION + DET. of GRADIENT for n DATA POINTS : - for(int j=0; j p_to_vh; + + for(int j=0; jinfo()[0].gradient = gradient0; + vh->info()[1].gradient = gradient1; + vh->info()[2].gradient = gradient2; + + + vh->info()[0].value = value0; + vh->info()[1].value = value1; + vh->info()[2].value = value2; + } + else + { + exact_values[0][points[j]] = value0; + exact_values[1][points[j]] = value1; + exact_values[2][points[j]] = value2; + } } //INTERPOLATION OF RANDOM POINTS: Coord_type norm; - Point_coordinate_vector pt_coords; - Point_output_functor pt_fct; + Coordinate_vector coords; + Output_functor out_fct; for(int j=n; j, Coord_type, bool> coordinate_result = - CGAL::natural_neighbor_coordinates_2(T, points[j], std::back_inserter(pt_coords), pt_fct); + CGAL::Triple, Coord_type, bool> coordinate_result = + CGAL::natural_neighbor_coordinates_2(T, points[j], std::back_inserter(coords), out_fct); assert(coordinate_result.third); norm = coordinate_result.second; - bool is_equal = test_norm(pt_coords.begin(), pt_coords.end(), norm); + bool is_equal = test_norm(coords.begin(), coords.end(), norm); assert(norm > 0); assert(is_equal); - is_equal = test_barycenter
(pt_coords.begin(), pt_coords.end(), norm, points[j], tolerance); + is_equal = test_barycenter
(coords.begin(), coords.end(), norm, points[j], tolerance); assert(is_equal); +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[j], exact_values[0][points[j]], + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[0].value, true); }, + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[0].gradient, true); }, + Traits(), 0, tolerance)); + + + // wrapping the lambda in a std function + CGAL::cpp11::function(const Vertex_handle)> value_function_1 = + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[1].value, true); }; + + std::function(const Vertex_handle)> gradient_function_1 = + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[1].gradient, true); }; + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[j], exact_values[1][points[j]], + value_function_1, gradient_function_1, + Traits(), 1, tolerance)); + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[j], exact_values[2][points[j]], + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[2].value, true); }, + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[2].gradient, true); }, + Traits(), 2, tolerance)); +#else for(int i=0; i<3; ++i) { - assert(test_interpolation(pt_coords.begin(), pt_coords.end(), norm, points[j], - CGAL::Data_access< Point_value_map >(values[i]), - CGAL::Data_access< Point_vector_map >(gradients[i]), + Value_function value_function(i); + Gradient_function gradient_function(i); + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[j], exact_values[i][points[j]], + value_function, gradient_function, Traits(), i, tolerance)); } - pt_coords.clear(); +#endif + + coords.clear(); } //TESTING THE GRADIENT APPRXIMATION METHOD: @@ -504,18 +590,44 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons std::cout << "Testing gradient estimation method on random points." << std::endl; typedef CGAL::Interpolation_gradient_fitting_traits_2 GradTraits; + Point_vector_map approx_gradients[2]; + +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + { + CGAL::sibson_gradient_fitting_nn_2(T, + std::inserter(approx_gradients[0], approx_gradients[0].begin()), // OutputIterator + CGAL::Interpolation::internal::Extract_point_in_pair(), // OutputFunctor + [](const Vertex_handle vh) + -> std::pair + { return std::make_pair(vh->info()[0].value, true); }, + GradTraits()); + + std::function(const Vertex_handle)> value_function_1 = + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[1].value, true); }; + + CGAL::sibson_gradient_fitting_nn_2(T, + std::inserter(approx_gradients[1], approx_gradients[1].begin()), + CGAL::Interpolation::internal::Extract_point_in_pair(), + value_function_1, + GradTraits()); + } +#else + Value_function value_function_0(0); + Value_function value_function_1(1); + CGAL::sibson_gradient_fitting_nn_2(T, std::inserter(approx_gradients[0], approx_gradients[0].begin()), // OutputIterator CGAL::Interpolation::internal::Extract_point_in_pair(), // OutputFunctor - CGAL::Data_access(values[0]), // ValueFunctor + value_function_0, GradTraits()); CGAL::sibson_gradient_fitting_nn_2(T, std::inserter(approx_gradients[1], approx_gradients[1].begin()), CGAL::Interpolation::internal::Extract_point_in_pair(), - CGAL::Data_access(values[1]), + value_function_1, GradTraits()); +#endif for(int j=0; j gradient_function_0(0); + Gradient_function gradient_function_1(1); + // if it is the exact computation kernel: test the equality: assert(tolerance > Coord_type(0) || - res.first == CGAL::Data_access(gradients[0])(points[j]).first); + res.first == (gradient_function_0(p_to_vh[points[j]])).first); res = CGAL::Data_access(approx_gradients[1])(points[j]); // if one exists->the other must also exist assert(res.second); assert(tolerance > Coord_type(0) || - res.first == CGAL::Data_access(gradients[1])(points[j]).first); + res.first == gradient_function_1(p_to_vh[points[j]]).first); } else { @@ -541,26 +656,59 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons } //TESTING A POINT == A DATA POINT: - CGAL::Triple, Coord_type, bool> coordinate_result = - CGAL::natural_neighbor_coordinates_2(T, points[n/2], std::back_inserter(pt_coords), pt_fct); + CGAL::Triple, Coord_type, bool> coordinate_result = + CGAL::natural_neighbor_coordinates_2(T, points[n/2], std::back_inserter(coords), out_fct); assert(coordinate_result.third); norm = coordinate_result.second; assert(norm == Coord_type(1)); - PCV_cit ci = pt_coords.begin(); - assert(ci->first == points[n/2]); + CV_cit ci = coords.begin(); + assert(ci->first == p_to_vh[points[n/2]]); assert(ci->second == Coord_type(1)); ci++; - assert(ci == pt_coords.end()); + assert(ci == coords.end()); +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + Value_function value_function_0(0); + Value_function value_function_2(2); + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[n/2], value_function_0(p_to_vh[points[n/2]]).first, + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[0].value, true); }, + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[0].gradient, true); }, + Traits(), 0, tolerance)); + + // wrapping the lambda in a std function + CGAL::cpp11::function(const Vertex_handle)> value_function_1 = + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[1].value, true); }; + + std::function(const Vertex_handle)> gradient_function_1 = + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[1].gradient, true); }; + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[n/2], value_function_1(p_to_vh[points[n/2]]).first, + value_function_1, gradient_function_1, + Traits(), 1, tolerance)); + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[n/2], value_function_2(p_to_vh[points[n/2]]).first, + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[2].value, true); }, + [](const Vertex_handle vh) -> std::pair { return std::make_pair(vh->info()[2].gradient, true); }, + Traits(), 2, tolerance)); +#else for(int j=0; j<3; ++j) { - assert(test_interpolation(pt_coords.begin(), pt_coords.end(), norm, points[n/2], - CGAL::Data_access(values[j]), - CGAL::Data_access(gradients[j]), + Value_function value_function(j); + Gradient_function gradient_function(j); + + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[n/2], value_function(p_to_vh[points[n/2]]).first, + value_function, gradient_function, Traits(), j, tolerance)); } - pt_coords.clear(); +#endif + + coords.clear(); } template @@ -584,7 +732,7 @@ void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, co typedef typename Gt::FT Coord_type; typedef typename Gt::Vector_2 Vector; - typedef std::map Point_value_map ; + typedef std::map Point_value_map; typedef std::map Point_vector_map; typedef std::vector > Point_coordinate_vector; @@ -681,7 +829,8 @@ void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, co for(int i=0; i<3; ++i) { - assert(test_interpolation(coords.begin(), coords.end(), norm, points[j], + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[j], values[i][points[j]], CGAL::Data_access< Point_value_map >(values[i]), CGAL::Data_access< Point_vector_map >(gradients[i]), Traits(), i, tolerance)); @@ -742,7 +891,8 @@ void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, co for(int j=0; j<3; ++j) { - assert(test_interpolation(coords.begin(), coords.end(), norm, points[n/2], + assert(test_interpolation(coords.begin(), coords.end(), norm, + points[n/2], values[j][points[n/2]], CGAL::Data_access(values[j]), CGAL::Data_access(gradients[j]), Traits(), j, tolerance)); @@ -778,7 +928,7 @@ void _test_interpolation_functions_2_regular_with_OutputFunctor(const Rt&, const typedef typename Rt::Vertex_handle Vertex_handle; // These are the values at points which won't be inserted in the triangulation - typedef std::map Point_value_map ; + typedef std::map Point_value_map; typedef std::map Vertex_value_map; typedef std::map Vertex_vector_map; @@ -986,8 +1136,8 @@ void _test_interpolation_functions_2_regular_with_OutputFunctor(const Rt&, const std::pair ev = CGAL::Data_access(values[j])(vh); assert(ev.second); - assert(test_interpolation_with_value(vh_coords.begin(), vh_coords.end(), norm, vh->point(), - ev.first /*exact value*/, + assert(test_interpolation_with_value(vh_coords.begin(), vh_coords.end(), norm, + vh->point(), ev.first /*exact value*/, CGAL::Data_access(values[j]), CGAL::Data_access(gradients[j]), Traits(), j, tolerance)); diff --git a/Interpolation/test/Interpolation/test_interpolation_functions_2.cpp b/Interpolation/test/Interpolation/test_interpolation_functions_2.cpp index ca18ef2faf2..c43b255d071 100644 --- a/Interpolation/test/Interpolation/test_interpolation_functions_2.cpp +++ b/Interpolation/test/Interpolation/test_interpolation_functions_2.cpp @@ -21,44 +21,59 @@ #include #include +#include +#include #include #include +#include #include -typedef CGAL::Exact_predicates_exact_constructions_kernel K; -typedef CGAL::Delaunay_triangulation_2 Dt; -typedef CGAL::Regular_triangulation_2 Rt; +typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; -typedef CGAL::Exact_predicates_inexact_constructions_kernel K2; -typedef CGAL::Delaunay_triangulation_2 Dt2; -typedef CGAL::Regular_triangulation_2 Rt2; +template +struct Value_and_gradient +{ + Value_and_gradient() : value(), gradient(CGAL::NULL_VECTOR) {} + + V value; + G gradient; +}; + +template +void test_interpolation_functions() +{ + // For the Delaunay triangulation, values and gradients (three different data sets) + // are stored directly in the vertices + typedef typename Kernel::FT Coord_type; + typedef typename Kernel::Vector_2 Vector; + + typedef CGAL::Triangulation_vertex_base_with_info_2< + CGAL::cpp11::array< + Value_and_gradient, 3>, + Kernel> Vb; + typedef CGAL::Triangulation_data_structure_2 Tds; + typedef CGAL::Delaunay_triangulation_2 Delaunay_triangulation; + + typedef CGAL::Regular_triangulation_2 Regular_triangulation; + + std::cout << "Testing interpolation functions with 2D NN neighbors " << std::endl; + _test_interpolation_functions_2_Delaunay(Delaunay_triangulation(), Coord_type(1e-10)); + + std::cout << "Testing interpolation functions with 2D RN neighbors " << std::endl; + _test_interpolation_functions_2_regular(Regular_triangulation(), Coord_type(1e-10)); +} int main() { - std::cout << "Testing interpolation functions with 2D NN neighbors " - << std::endl; - std::cout << " using Exact_predicates_exact_constructions_kernel: " - << std::endl ; - _test_interpolation_functions_2_Delaunay(Dt(), K::FT(1e-10)); + std::cout << "--------------------------------------------" << std::endl; + std::cout << "Testing with EPECK" << std::endl; + test_interpolation_functions(); - std::cout << "Testing interpolation functions with 2D NN neighbors " - << std::endl; - std::cout << " using Exact_predicates_inexact_constructions_kernel: " - << std::endl ; - _test_interpolation_functions_2_Delaunay(Dt2(), K2::FT(1e-10)); - - std::cout << "Testing interpolation functions with 2D RN neighbors " - << std::endl; - std::cout << " using Exact_predicates_exact_constructions_kernel: " - << std::endl ; - _test_interpolation_functions_2_regular(Rt(), K::FT(1e-10)); - - std::cout << "Testing interpolation functions with 2D RN neighbors " - << std::endl; - std::cout << " using Exact_predicates_inexact_constructions_kernel: " - << std::endl ; - _test_interpolation_functions_2_regular(Rt2(), K2::FT(1e-10)); + std::cout << "--------------------------------------------" << std::endl; + std::cout << "Testing with EPICK" << std::endl; + test_interpolation_functions(); std::cout << "test_interpolation_functions_2 is finished" << std::endl;