summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2018-11-27 09:10:33 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2018-11-27 09:10:33 +0000
commit954d62e67a1126d206ed5c14a3c3b5f3c81235f6 (patch)
tree51461185f148f2f5fab5318ead9cffaac4c84f7e /src
parent2ead33fd01bbe97e3b88070d169647c68c3db359 (diff)
parentbfd989dae36a22450c1da3dc21cea57bb7d2e96e (diff)
Merge alpha_complex_3d_module_vincent after second review round
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@4014 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d2f4f38b34ef898ed3b1f267278aaa2ae4cab58f
Diffstat (limited to 'src')
-rw-r--r--src/Alpha_complex/benchmark/Alpha_complex_3d_benchmark.cpp64
-rw-r--r--src/Alpha_complex/doc/Intro_alpha_complex.h6
-rw-r--r--src/Alpha_complex/example/Alpha_complex_3d_from_points.cpp2
-rw-r--r--src/Alpha_complex/example/Weighted_alpha_complex_3d_from_points.cpp15
-rw-r--r--src/Alpha_complex/include/gudhi/Alpha_complex_3d.h227
-rw-r--r--src/Alpha_complex/test/Alpha_complex_3d_unit_test.cpp504
-rw-r--r--src/Alpha_complex/test/CMakeLists.txt12
-rw-r--r--src/Alpha_complex/test/Periodic_alpha_complex_3d_unit_test.cpp190
-rw-r--r--src/Alpha_complex/test/Weighted_alpha_complex_3d_unit_test.cpp147
-rw-r--r--src/Alpha_complex/test/Weighted_periodic_alpha_complex_3d_unit_test.cpp239
-rw-r--r--src/common/doc/main_page.h7
11 files changed, 769 insertions, 644 deletions
diff --git a/src/Alpha_complex/benchmark/Alpha_complex_3d_benchmark.cpp b/src/Alpha_complex/benchmark/Alpha_complex_3d_benchmark.cpp
index 1a33f2b4..005a712a 100644
--- a/src/Alpha_complex/benchmark/Alpha_complex_3d_benchmark.cpp
+++ b/src/Alpha_complex/benchmark/Alpha_complex_3d_benchmark.cpp
@@ -25,7 +25,7 @@ void benchmark_points_on_torus_dD(const std::string& msg) {
results_csv << "\"nb_points\";"
<< "\"nb_simplices\";"
<< "\"alpha_creation_time(sec.)\";"
- << "\"simplex_creation_time(sec.)\";" << std::endl;
+ << "\"complex_creation_time(sec.)\";" << std::endl;
using K = CGAL::Epick_d<CGAL::Dimension_tag<3>>;
for (int nb_points = 1000; nb_points <= 125000; nb_points *= 5) {
@@ -43,17 +43,17 @@ void benchmark_points_on_torus_dD(const std::string& msg) {
ac_create_clock.end();
std::cout << ac_create_clock;
- Gudhi::Simplex_tree<> simplex;
- Gudhi::Clock st_create_clock(" benchmark_points_on_torus_dD - simplex tree creation");
+ Gudhi::Simplex_tree<> complex;
+ Gudhi::Clock st_create_clock(" benchmark_points_on_torus_dD - complex creation");
st_create_clock.begin();
- alpha_complex_from_points.create_complex(simplex);
+ alpha_complex_from_points.create_complex(complex);
st_create_clock.end();
std::cout << st_create_clock;
- results_csv << nb_points << ";" << simplex.num_simplices() << ";" << ac_create_clock.num_seconds() << ";"
+ results_csv << nb_points << ";" << complex.num_simplices() << ";" << ac_create_clock.num_seconds() << ";"
<< st_create_clock.num_seconds() << ";" << std::endl;
- std::cout << " benchmark_points_on_torus_dD - nb simplices = " << simplex.num_simplices() << std::endl;
+ std::cout << " benchmark_points_on_torus_dD - nb simplices = " << complex.num_simplices() << std::endl;
}
}
@@ -66,7 +66,7 @@ void benchmark_points_on_torus_3D(const std::string& msg) {
results_csv << "\"nb_points\";"
<< "\"nb_simplices\";"
<< "\"alpha_creation_time(sec.)\";"
- << "\"simplex_creation_time(sec.)\";" << std::endl;
+ << "\"complex_creation_time(sec.)\";" << std::endl;
for (int nb_points = 1000; nb_points <= 125000; nb_points *= 5) {
std::cout << " Alpha complex 3d on torus with " << nb_points << " points." << std::endl;
@@ -83,17 +83,17 @@ void benchmark_points_on_torus_3D(const std::string& msg) {
ac_create_clock.end();
std::cout << ac_create_clock;
- Gudhi::Simplex_tree<> simplex;
- Gudhi::Clock st_create_clock(" benchmark_points_on_torus_3D - simplex tree creation");
+ Gudhi::Simplex_tree<> complex;
+ Gudhi::Clock st_create_clock(" benchmark_points_on_torus_3D - complex creation");
st_create_clock.begin();
- alpha_complex_from_points.create_complex(simplex);
+ alpha_complex_from_points.create_complex(complex);
st_create_clock.end();
std::cout << st_create_clock;
- results_csv << nb_points << ";" << simplex.num_simplices() << ";" << ac_create_clock.num_seconds() << ";"
+ results_csv << nb_points << ";" << complex.num_simplices() << ";" << ac_create_clock.num_seconds() << ";"
<< st_create_clock.num_seconds() << ";" << std::endl;
- std::cout << " benchmark_points_on_torus_3D - nb simplices = " << simplex.num_simplices() << std::endl;
+ std::cout << " benchmark_points_on_torus_3D - nb simplices = " << complex.num_simplices() << std::endl;
}
}
@@ -107,7 +107,7 @@ void benchmark_weighted_points_on_torus_3D(const std::string& msg) {
results_csv << "\"nb_points\";"
<< "\"nb_simplices\";"
<< "\"alpha_creation_time(sec.)\";"
- << "\"simplex_creation_time(sec.)\";" << std::endl;
+ << "\"complex_creation_time(sec.)\";" << std::endl;
CGAL::Random random(8);
@@ -116,7 +116,7 @@ void benchmark_weighted_points_on_torus_3D(const std::string& msg) {
std::vector<K::Point_d> points_on_torus = Gudhi::generate_points_on_torus_3D<K>(nb_points, 1.0, 0.5);
using Point = typename Weighted_alpha_complex_3d::Point_3;
- using Weighted_point = typename Weighted_alpha_complex_3d::Triangulation_3::Weighted_point;
+ using Weighted_point = typename Weighted_alpha_complex_3d::Weighted_point_3;
std::vector<Weighted_point> points;
@@ -130,17 +130,17 @@ void benchmark_weighted_points_on_torus_3D(const std::string& msg) {
ac_create_clock.end();
std::cout << ac_create_clock;
- Gudhi::Simplex_tree<> simplex;
- Gudhi::Clock st_create_clock(" benchmark_weighted_points_on_torus_3D - simplex tree creation");
+ Gudhi::Simplex_tree<> complex;
+ Gudhi::Clock st_create_clock(" benchmark_weighted_points_on_torus_3D - complex creation");
st_create_clock.begin();
- alpha_complex_from_points.create_complex(simplex);
+ alpha_complex_from_points.create_complex(complex);
st_create_clock.end();
std::cout << st_create_clock;
- results_csv << nb_points << ";" << simplex.num_simplices() << ";" << ac_create_clock.num_seconds() << ";"
+ results_csv << nb_points << ";" << complex.num_simplices() << ";" << ac_create_clock.num_seconds() << ";"
<< st_create_clock.num_seconds() << ";" << std::endl;
- std::cout << " benchmark_weighted_points_on_torus_3D - nb simplices = " << simplex.num_simplices() << std::endl;
+ std::cout << " benchmark_weighted_points_on_torus_3D - nb simplices = " << complex.num_simplices() << std::endl;
}
}
@@ -152,7 +152,7 @@ void benchmark_periodic_points(const std::string& msg) {
results_csv << "\"nb_points\";"
<< "\"nb_simplices\";"
<< "\"alpha_creation_time(sec.)\";"
- << "\"simplex_creation_time(sec.)\";" << std::endl;
+ << "\"complex_creation_time(sec.)\";" << std::endl;
CGAL::Random random(8);
@@ -176,17 +176,17 @@ void benchmark_periodic_points(const std::string& msg) {
ac_create_clock.end();
std::cout << ac_create_clock;
- Gudhi::Simplex_tree<> simplex;
- Gudhi::Clock st_create_clock(" benchmark_periodic_points - simplex tree creation");
+ Gudhi::Simplex_tree<> complex;
+ Gudhi::Clock st_create_clock(" benchmark_periodic_points - complex creation");
st_create_clock.begin();
- alpha_complex_from_points.create_complex(simplex);
+ alpha_complex_from_points.create_complex(complex);
st_create_clock.end();
std::cout << st_create_clock;
- results_csv << nb_points * nb_points * nb_points << ";" << simplex.num_simplices() << ";"
+ results_csv << nb_points * nb_points * nb_points << ";" << complex.num_simplices() << ";"
<< ac_create_clock.num_seconds() << ";" << st_create_clock.num_seconds() << ";" << std::endl;
- std::cout << " benchmark_periodic_points - nb simplices = " << simplex.num_simplices() << std::endl;
+ std::cout << " benchmark_periodic_points - nb simplices = " << complex.num_simplices() << std::endl;
}
}
@@ -198,7 +198,7 @@ void benchmark_weighted_periodic_points(const std::string& msg) {
results_csv << "\"nb_points\";"
<< "\"nb_simplices\";"
<< "\"alpha_creation_time(sec.)\";"
- << "\"simplex_creation_time(sec.)\";" << std::endl;
+ << "\"complex_creation_time(sec.)\";" << std::endl;
CGAL::Random random(8);
@@ -207,7 +207,7 @@ void benchmark_weighted_periodic_points(const std::string& msg) {
<< std::endl;
using Point = typename Weighted_periodic_alpha_complex_3d::Point_3;
- using Weighted_point = typename Weighted_periodic_alpha_complex_3d::Triangulation_3::Weighted_point;
+ using Weighted_point = typename Weighted_periodic_alpha_complex_3d::Weighted_point_3;
std::vector<Weighted_point> points;
for (double i = 0; i < nb_points; i++) {
@@ -226,17 +226,17 @@ void benchmark_weighted_periodic_points(const std::string& msg) {
ac_create_clock.end();
std::cout << ac_create_clock;
- Gudhi::Simplex_tree<> simplex;
- Gudhi::Clock st_create_clock(" benchmark_weighted_periodic_points - simplex tree creation");
+ Gudhi::Simplex_tree<> complex;
+ Gudhi::Clock st_create_clock(" benchmark_weighted_periodic_points - complex creation");
st_create_clock.begin();
- alpha_complex_from_points.create_complex(simplex);
+ alpha_complex_from_points.create_complex(complex);
st_create_clock.end();
std::cout << st_create_clock;
- results_csv << nb_points * nb_points * nb_points << ";" << simplex.num_simplices() << ";"
+ results_csv << nb_points * nb_points * nb_points << ";" << complex.num_simplices() << ";"
<< ac_create_clock.num_seconds() << ";" << st_create_clock.num_seconds() << ";" << std::endl;
- std::cout << " benchmark_weighted_periodic_points - nb simplices = " << simplex.num_simplices() << std::endl;
+ std::cout << " benchmark_weighted_periodic_points - nb simplices = " << complex.num_simplices() << std::endl;
}
}
diff --git a/src/Alpha_complex/doc/Intro_alpha_complex.h b/src/Alpha_complex/doc/Intro_alpha_complex.h
index 2fe9f4ca..ab7c4794 100644
--- a/src/Alpha_complex/doc/Intro_alpha_complex.h
+++ b/src/Alpha_complex/doc/Intro_alpha_complex.h
@@ -168,8 +168,10 @@ namespace alpha_complex {
*
* \section weighted3dexample 3d specific example
*
- * A specific module for Alpha complex is available in 3d (cf. Alpha_complex_3d) and allows to construct default, exact,
- * weighted, periodic or weighted and periodic versions of alpha complexes
+ * A specific module for Alpha complex is available in 3d (cf. Alpha_complex_3d) and allows to construct standard,
+ * weighted, periodic or weighted and periodic versions of alpha complexes. Alpha values computation can be
+ * Gudhi::alpha_complex::complexity::FAST, Gudhi::alpha_complex::complexity::SAFE (default value) or
+ * Gudhi::alpha_complex::complexity::EXACT.
*
* This example builds the CGAL 3d weighted alpha shapes from a small molecule, and initializes the alpha complex with
* it. This example is taken from <a href="https://doc.cgal.org/latest/Alpha_shapes_3/index.html#title13">CGAL 3d
diff --git a/src/Alpha_complex/example/Alpha_complex_3d_from_points.cpp b/src/Alpha_complex/example/Alpha_complex_3d_from_points.cpp
index 3acebd2e..0e359a27 100644
--- a/src/Alpha_complex/example/Alpha_complex_3d_from_points.cpp
+++ b/src/Alpha_complex/example/Alpha_complex_3d_from_points.cpp
@@ -7,7 +7,7 @@
#include <vector>
#include <limits> // for numeric limits
-using Alpha_complex_3d = Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, false, false>;
+using Alpha_complex_3d = Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, false, false>;
using Point = Alpha_complex_3d::Point_3;
using Vector_of_points = std::vector<Point>;
diff --git a/src/Alpha_complex/example/Weighted_alpha_complex_3d_from_points.cpp b/src/Alpha_complex/example/Weighted_alpha_complex_3d_from_points.cpp
index 68f72f0a..ac11b68c 100644
--- a/src/Alpha_complex/example/Weighted_alpha_complex_3d_from_points.cpp
+++ b/src/Alpha_complex/example/Weighted_alpha_complex_3d_from_points.cpp
@@ -7,24 +7,17 @@
#include <vector>
#include <limits> // for numeric limits
+// Complexity = FAST, weighted = true, periodic = false
using Weighted_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, true, false>;
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, true, false>;
using Point = Weighted_alpha_complex_3d::Point_3;
-using Weighted_point = Weighted_alpha_complex_3d::Triangulation_3::Weighted_point;
-using Vector_of_weighted_points = std::vector<Weighted_point>;
-using Vector_of_weights = std::vector<Weighted_alpha_complex_3d::Alpha_shape_3::FT>;
+using Weighted_point = Weighted_alpha_complex_3d::Weighted_point_3;
int main(int argc, char **argv) {
- if (argc != 1) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct\n";
- std::cerr << "Usage: " << (argv[0] - 1) << " \n";
- exit(-1); // ----- >>
- }
-
// ----------------------------------------------------------------------------
// Init of a list of points and weights from a small molecule
// ----------------------------------------------------------------------------
- Vector_of_weighted_points weighted_points;
+ std::vector<Weighted_point> weighted_points;
weighted_points.push_back(Weighted_point(Point(1, -1, -1), 4.));
weighted_points.push_back(Weighted_point(Point(-1, 1, -1), 4.));
weighted_points.push_back(Weighted_point(Point(-1, -1, 1), 4.));
diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h b/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h
index 00a47d5c..19445637 100644
--- a/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h
+++ b/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h
@@ -26,10 +26,6 @@
#include <boost/version.hpp>
#include <boost/variant.hpp>
-#if BOOST_VERSION >= 105400
-#include <boost/container/static_vector.hpp>
-#endif
-
#include <gudhi/Debug_utils.h>
#include <gudhi/Alpha_complex_options.h>
@@ -50,6 +46,8 @@
#include <CGAL/iterator.h>
#include <CGAL/version.h>
+#include <boost/container/static_vector.hpp>
+
#include <iostream>
#include <vector>
#include <unordered_map>
@@ -60,7 +58,7 @@
#if CGAL_VERSION_NR < 1041101000
// Make compilation fail - required for external projects - https://gitlab.inria.fr/GUDHI/gudhi-devel/issues/10
-static_assert(false, "Alpha_complex_3d is only available for CGAL >= 4.11");
+# error Alpha_complex_3d is only available for CGAL >= 4.11
#endif
namespace Gudhi {
@@ -74,62 +72,22 @@ thread_local
// Value_from_iterator returns the filtration value from an iterator on alpha shapes values
//
-// FAST SAFE EXACT
-// not weighted and *iterator Specific case due to CGAL CGAL::to_double(iterator->exact())
-// not periodic issue # 3153
-//
-// otherwise *iterator CGAL::to_double(*iterator) CGAL::to_double(iterator->exact())
+// FAST SAFE EXACT
+// CGAL::to_double(*iterator) CGAL::to_double(*iterator) CGAL::to_double(iterator->exact())
-template <complexity Complexity, bool Weighted_or_periodic>
+template <complexity Complexity>
struct Value_from_iterator {
template <typename Iterator>
static double perform(Iterator it) {
- // Default behaviour is to return the value pointed by the given iterator
- return *it;
- }
-};
-
-template <>
-struct Value_from_iterator<complexity::SAFE, true> {
- template <typename Iterator>
- static double perform(Iterator it) {
- // In SAFE mode, we are with Epick with EXACT value set to CGAL::Tag_true.
+ // Default behaviour
return CGAL::to_double(*it);
}
};
template <>
-struct Value_from_iterator<complexity::SAFE, false> {
+struct Value_from_iterator<complexity::EXACT> {
template <typename Iterator>
static double perform(Iterator it) {
- // In SAFE mode, we are with Epeck with EXACT value set to CGAL::Tag_true.
- // Specific case due to CGAL issue https://github.com/CGAL/cgal/issues/3153
- auto approx = it->approx();
- double r;
- if (CGAL::fit_in_double(approx, r)) return r;
-
- // If it's precise enough, then OK.
- if (CGAL::has_smaller_relative_precision(approx, RELATIVE_PRECISION_OF_TO_DOUBLE)) return CGAL::to_double(approx);
-
- it->exact();
- return CGAL::to_double(it->approx());
- }
-};
-
-template <>
-struct Value_from_iterator<complexity::EXACT, true> {
- template <typename Iterator>
- static double perform(Iterator it) {
- // In EXACT mode, we are with Epeck or Epick with EXACT value set to CGAL::Tag_true.
- return CGAL::to_double(it->exact());
- }
-};
-
-template <>
-struct Value_from_iterator<complexity::EXACT, false> {
- template <typename Iterator>
- static double perform(Iterator it) {
- // In EXACT mode, we are with Epeck or Epick with EXACT value set to CGAL::Tag_true.
return CGAL::to_double(it->exact());
}
};
@@ -145,8 +103,8 @@ struct Value_from_iterator<complexity::EXACT, false> {
* Shapes</a> from a range of points (can be read from an OFF file, cf. Points_off_reader).
* Duplicate points are inserted once in the Alpha_complex. This is the reason why the vertices may be not contiguous.
*
- * \tparam Complexity shall be `Gudhi::alpha_complex::complexity`. Default value is
- * `Gudhi::alpha_complex::complexity::FAST`.
+ * \tparam Complexity shall be `Gudhi::alpha_complex::complexity` type. Default value is
+ * `Gudhi::alpha_complex::complexity::SAFE`.
*
* \tparam Weighted Boolean used to set/unset the weighted version of Alpha_complex_3d. Default value is false.
*
@@ -169,22 +127,22 @@ struct Value_from_iterator<complexity::EXACT, false> {
* 3d Delaunay complex.
*
*/
-template <complexity Complexity = complexity::FAST, bool Weighted = false, bool Periodic = false>
+template <complexity Complexity = complexity::SAFE, bool Weighted = false, bool Periodic = false>
class Alpha_complex_3d {
// Epick = Exact_predicates_inexact_constructions_kernel
// Epeck = Exact_predicates_exact_constructions_kernel
- // ExactAlphaComparisonTag = exact version of CGAL Alpha_shape_3 and of its objects (Alpha_shape_vertex_base_3 and
+ // Exact_alpha_comparison_tag = exact version of CGAL Alpha_shape_3 and of its objects (Alpha_shape_vertex_base_3 and
// Alpha_shape_cell_base_3). Not available if weighted or periodic.
- // Can be CGAL::Tag_false or CGAL::Tag_true
+ // Can be CGAL::Tag_false or CGAL::Tag_true. Default is False.
// cf. https://doc.cgal.org/latest/Alpha_shapes_3/classCGAL_1_1Alpha__shape__3.html
//
+ // We could use Epick + CGAL::Tag_true for not weighted nor periodic, but during benchmark, we found a bug
+ // https://github.com/CGAL/cgal/issues/3460
+ // This is the reason we only use Epick + CGAL::Tag_false, or Epeck
//
- // FAST SAFE EXACT
- // not weighted and Epick + CGAL::Tag_false Epick + CGAL::Tag_true Epick + CGAL::Tag_true
- // not periodic
- //
- // otherwise Epick + CGAL::Tag_false Epeck Epeck
- using Predicates = typename std::conditional<((!Weighted && !Periodic) || (Complexity == complexity::FAST)),
+ // FAST SAFE EXACT
+ // Epick + CGAL::Tag_false Epeck Epeck
+ using Predicates = typename std::conditional<(Complexity == complexity::FAST),
CGAL::Exact_predicates_inexact_constructions_kernel,
CGAL::Exact_predicates_exact_constructions_kernel>::type;
@@ -192,14 +150,11 @@ class Alpha_complex_3d {
template <typename Predicates, bool Weighted_version, bool Periodic_version>
struct Kernel_3 {};
- template <typename Predicates>
- struct Kernel_3<Predicates, false, false> {
- using Kernel = Predicates;
- };
- template <typename Predicates>
- struct Kernel_3<Predicates, true, false> {
+ template <typename Predicates, bool Is_periodic>
+ struct Kernel_3<Predicates, Is_periodic, false> {
using Kernel = Predicates;
};
+
template <typename Predicates>
struct Kernel_3<Predicates, false, true> {
using Kernel = CGAL::Periodic_3_Delaunay_triangulation_traits_3<Predicates>;
@@ -211,15 +166,13 @@ class Alpha_complex_3d {
using Kernel = typename Kernel_3<Predicates, Weighted, Periodic>::Kernel;
- using Exact_tag = typename std::conditional<(Complexity == complexity::FAST), CGAL::Tag_false, CGAL::Tag_true>::type;
-
using TdsVb = typename std::conditional<Periodic, CGAL::Periodic_3_triangulation_ds_vertex_base_3<>,
CGAL::Triangulation_ds_vertex_base_3<>>::type;
using Tvb = typename std::conditional<Weighted, CGAL::Regular_triangulation_vertex_base_3<Kernel, TdsVb>,
CGAL::Triangulation_vertex_base_3<Kernel, TdsVb>>::type;
- using Vb = CGAL::Alpha_shape_vertex_base_3<Kernel, Tvb, Exact_tag>;
+ using Vb = CGAL::Alpha_shape_vertex_base_3<Kernel, Tvb>;
using TdsCb = typename std::conditional<Periodic, CGAL::Periodic_3_triangulation_ds_cell_base_3<>,
CGAL::Triangulation_ds_cell_base_3<>>::type;
@@ -227,64 +180,101 @@ class Alpha_complex_3d {
using Tcb = typename std::conditional<Weighted, CGAL::Regular_triangulation_cell_base_3<Kernel, TdsCb>,
CGAL::Triangulation_cell_base_3<Kernel, TdsCb>>::type;
- using Cb = CGAL::Alpha_shape_cell_base_3<Kernel, Tcb, Exact_tag>;
+ using Cb = CGAL::Alpha_shape_cell_base_3<Kernel, Tcb>;
using Tds = CGAL::Triangulation_data_structure_3<Vb, Cb>;
// The other way to do a conditional type. Here there 4 possibilities, cannot use std::conditional
template <typename Kernel, typename Tds, bool Weighted_version, bool Periodic_version>
- struct Triangulation {};
+ struct Triangulation_3 {};
template <typename Kernel, typename Tds>
- struct Triangulation<Kernel, Tds, false, false> {
- using Triangulation_3 = CGAL::Delaunay_triangulation_3<Kernel, Tds>;
+ struct Triangulation_3<Kernel, Tds, false, false> {
+ using Dt = CGAL::Delaunay_triangulation_3<Kernel, Tds>;
+ using Weighted_point_3 = void;
};
template <typename Kernel, typename Tds>
- struct Triangulation<Kernel, Tds, true, false> {
- using Triangulation_3 = CGAL::Regular_triangulation_3<Kernel, Tds>;
+ struct Triangulation_3<Kernel, Tds, true, false> {
+ using Dt = CGAL::Regular_triangulation_3<Kernel, Tds>;
+ using Weighted_point_3 = typename Dt::Weighted_point;
};
template <typename Kernel, typename Tds>
- struct Triangulation<Kernel, Tds, false, true> {
- using Triangulation_3 = CGAL::Periodic_3_Delaunay_triangulation_3<Kernel, Tds>;
+ struct Triangulation_3<Kernel, Tds, false, true> {
+ using Dt = CGAL::Periodic_3_Delaunay_triangulation_3<Kernel, Tds>;
+ using Weighted_point_3 = void;
};
template <typename Kernel, typename Tds>
- struct Triangulation<Kernel, Tds, true, true> {
- using Triangulation_3 = CGAL::Periodic_3_regular_triangulation_3<Kernel, Tds>;
+ struct Triangulation_3<Kernel, Tds, true, true> {
+ using Dt = CGAL::Periodic_3_regular_triangulation_3<Kernel, Tds>;
+ using Weighted_point_3 = typename Dt::Weighted_point;
};
- public:
- using Triangulation_3 = typename Triangulation<Kernel, Tds, Weighted, Periodic>::Triangulation_3;
-
- using Alpha_shape_3 = CGAL::Alpha_shape_3<Triangulation_3, Exact_tag>;
+ /** \brief Is either Delaunay_triangulation_3 (Weighted = false and Periodic = false),
+ * Regular_triangulation_3 (Weighted = true and Periodic = false),
+ * Periodic_3_Delaunay_triangulation_3 (Weighted = false and Periodic = true)
+ * or Periodic_3_regular_triangulation_3 (Weighted = true and Periodic = true).
+ *
+ * This type is required by `Gudhi::alpha_complex::Alpha_complex_3d::Alpha_shape_3`.
+ * */
+ using Dt = typename Triangulation_3<Kernel, Tds, Weighted, Periodic>::Dt;
+public:
+ /** \brief The <a href="https://doc.cgal.org/latest/Alpha_shapes_3/classCGAL_1_1Alpha__shape__3.html">CGAL 3D Alpha
+ * Shapes</a> type.
+ *
+ * The `Gudhi::alpha_complex::Alpha_complex_3d` is a wrapper on top of this class to ease the standard, weighted
+ * and/or periodic build of the Alpha complex 3d.*/
+ using Alpha_shape_3 = CGAL::Alpha_shape_3<Dt>;
+
+ /** \brief The alpha values type.
+ * Must be compatible with double. */
+ using FT = typename Alpha_shape_3::FT;
+
+ /** \brief Gives public access to the Point_3 type. Here is a Point_3 constructor example:
+\code{.cpp}
+using Alpha_complex_3d = Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, false, false>;
+
+// x0 = 1., y0 = -1.1, z0 = -1..
+Alpha_complex_3d::Point_3 p0(1., -1.1, -1.);
+\endcode
+ * */
using Point_3 = typename Kernel::Point_3;
- private:
- using Alpha_value_type = typename Alpha_shape_3::FT;
+ /** \brief Gives public access to the Weighted_point_3 type. A Weighted point can be constructed as follows:
+\code{.cpp}
+using Weighted_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, true, false>;
+
+// x0 = 1., y0 = -1.1, z0 = -1., weight = 4.
+Weighted_alpha_complex_3d::Weighted_point_3 wp0(Weighted_alpha_complex_3d::Point_3(1., -1.1, -1.), 4.);
+\endcode
+ *
+ * Note: This type is defined to void if Alpha complex is not weighted.
+ *
+ * */
+ using Weighted_point_3 = typename Triangulation_3<Kernel, Tds, Weighted, Periodic>::Weighted_point_3;
+
+private:
using Dispatch =
- CGAL::Dispatch_output_iterator<CGAL::cpp11::tuple<CGAL::Object, Alpha_value_type>,
+ CGAL::Dispatch_output_iterator<CGAL::cpp11::tuple<CGAL::Object, FT>,
CGAL::cpp11::tuple<std::back_insert_iterator<std::vector<CGAL::Object>>,
- std::back_insert_iterator<std::vector<Alpha_value_type>>>>;
+ std::back_insert_iterator<std::vector<FT>>>>;
using Cell_handle = typename Alpha_shape_3::Cell_handle;
using Facet = typename Alpha_shape_3::Facet;
using Edge = typename Alpha_shape_3::Edge;
using Alpha_vertex_handle = typename Alpha_shape_3::Vertex_handle;
-#if BOOST_VERSION >= 105400
using Vertex_list = boost::container::static_vector<Alpha_vertex_handle, 4>;
-#else
- using Vertex_list = std::vector<Alpha_vertex_handle>;
-#endif
public:
/** \brief Alpha_complex constructor from a list of points.
*
* @param[in] points Range of points to triangulate. Points must be in `Alpha_complex_3d::Point_3` or
- * `Alpha_complex_3d::Triangulation_3::Weighted_point`.
+ * `Alpha_complex_3d::Weighted_point_3`.
*
* @pre Available if Alpha_complex_3d is not Periodic.
*
* The type InputPointRange must be a range for which std::begin and std::end return input iterators on a
- * `Alpha_complex_3d::Point_3` or a `Alpha_complex_3d::Triangulation_3::Weighted_point`.
+ * `Alpha_complex_3d::Point_3` or a `Alpha_complex_3d::Weighted_point_3`.
*/
template <typename InputPointRange>
Alpha_complex_3d(const InputPointRange& points) {
@@ -298,15 +288,15 @@ class Alpha_complex_3d {
*
* @exception std::invalid_argument In debug mode, if points and weights do not have the same size.
*
- * @param[in] points Range of points to triangulate. Points must be in `Alpha_complex_3d::Point_3`
- * @param[in] weights Range of weights on points. Weights shall be in `Alpha_complex_3d::Alpha_shape_3::FT`
+ * @param[in] points Range of points to triangulate. Points must be in `Alpha_complex_3d::Point_3`.
+ * @param[in] weights Range of weights on points. Weights shall be in double.
*
* @pre Available if Alpha_complex_3d is Weighted and not Periodic.
*
* The type InputPointRange must be a range for which std::begin and
* std::end return input iterators on a `Alpha_complex_3d::Point_3`.
* The type WeightRange must be a range for which std::begin and
- * std::end return an input iterator on a `Alpha_complex_3d::Alpha_shape_3::FT`.
+ * std::end return an input iterator on a double.
*/
template <typename InputPointRange, typename WeightRange>
Alpha_complex_3d(const InputPointRange& points, WeightRange weights) {
@@ -315,7 +305,6 @@ class Alpha_complex_3d {
GUDHI_CHECK((weights.size() == points.size()),
std::invalid_argument("Points number in range different from weights range number"));
- using Weighted_point_3 = typename Triangulation_3::Weighted_point;
std::vector<Weighted_point_3> weighted_points_3;
std::size_t index = 0;
@@ -334,7 +323,7 @@ class Alpha_complex_3d {
* @exception std::invalid_argument In debug mode, if the size of the cuboid in every directions is not the same.
*
* @param[in] points Range of points to triangulate. Points must be in `Alpha_complex_3d::Point_3` or
- * `Alpha_complex_3d::Triangulation_3::Weighted_point`.
+ * `Alpha_complex_3d::Weighted_point_3`.
* @param[in] x_min Iso-oriented cuboid x_min.
* @param[in] y_min Iso-oriented cuboid y_min.
* @param[in] z_min Iso-oriented cuboid z_min.
@@ -345,14 +334,14 @@ class Alpha_complex_3d {
* @pre Available if Alpha_complex_3d is Periodic.
*
* The type InputPointRange must be a range for which std::begin and std::end return input iterators on a
- * `Alpha_complex_3d::Point_3` or a `Alpha_complex_3d::Triangulation_3::Weighted_point`.
+ * `Alpha_complex_3d::Point_3` or a `Alpha_complex_3d::Weighted_point_3`.
*
* @note In weighted version, please check weights are greater than zero, and lower than 1/64*cuboid length
* squared.
*/
template <typename InputPointRange>
- Alpha_complex_3d(const InputPointRange& points, Alpha_value_type x_min, Alpha_value_type y_min,
- Alpha_value_type z_min, Alpha_value_type x_max, Alpha_value_type y_max, Alpha_value_type z_max) {
+ Alpha_complex_3d(const InputPointRange& points, FT x_min, FT y_min,
+ FT z_min, FT x_max, FT y_max, FT z_max) {
static_assert(Periodic, "This constructor is not available for non-periodic versions of Alpha_complex_3d");
// Checking if the cuboid is the same in x,y and z direction. If not, CGAL will not process it.
GUDHI_CHECK(
@@ -360,7 +349,7 @@ class Alpha_complex_3d {
std::invalid_argument("The size of the cuboid in every directions is not the same."));
// Define the periodic cube
- Triangulation_3 pdt(typename Kernel::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max));
+ Dt pdt(typename Kernel::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max));
// Heuristic for inserting large point sets (if pts is reasonably large)
pdt.insert(std::begin(points), std::end(points), true);
// As pdt won't be modified anymore switch to 1-sheeted cover if possible
@@ -381,8 +370,8 @@ class Alpha_complex_3d {
* @exception std::invalid_argument In debug mode, if a weight is negative, zero, or greater than 1/64*cuboid length
* squared.
*
- * @param[in] points Range of points to triangulate. Points must be in `Alpha_complex_3d::Point_3`
- * @param[in] weights Range of weights on points. Weights shall be in `Alpha_complex_3d::Alpha_shape_3::FT`
+ * @param[in] points Range of points to triangulate. Points must be in `Alpha_complex_3d::Point_3`.
+ * @param[in] weights Range of weights on points. Weights shall be in double.
* @param[in] x_min Iso-oriented cuboid x_min.
* @param[in] y_min Iso-oriented cuboid y_min.
* @param[in] z_min Iso-oriented cuboid z_min.
@@ -395,12 +384,12 @@ class Alpha_complex_3d {
* The type InputPointRange must be a range for which std::begin and
* std::end return input iterators on a `Alpha_complex_3d::Point_3`.
* The type WeightRange must be a range for which std::begin and
- * std::end return an input iterator on a `Alpha_complex_3d::Alpha_shape_3::FT`.
- * The type of x_min, y_min, z_min, x_max, y_max and z_max is `Alpha_complex_3d::Alpha_shape_3::FT`.
+ * std::end return an input iterator on a double.
+ * The type of x_min, y_min, z_min, x_max, y_max and z_max must be a double.
*/
template <typename InputPointRange, typename WeightRange>
- Alpha_complex_3d(const InputPointRange& points, WeightRange weights, Alpha_value_type x_min, Alpha_value_type y_min,
- Alpha_value_type z_min, Alpha_value_type x_max, Alpha_value_type y_max, Alpha_value_type z_max) {
+ Alpha_complex_3d(const InputPointRange& points, WeightRange weights, FT x_min, FT y_min,
+ FT z_min, FT x_max, FT y_max, FT z_max) {
static_assert(Weighted, "This constructor is not available for non-weighted versions of Alpha_complex_3d");
static_assert(Periodic, "This constructor is not available for non-periodic versions of Alpha_complex_3d");
GUDHI_CHECK((weights.size() == points.size()),
@@ -410,7 +399,6 @@ class Alpha_complex_3d {
(x_max - x_min == y_max - y_min) && (x_max - x_min == z_max - z_min) && (z_max - z_min == y_max - y_min),
std::invalid_argument("The size of the cuboid in every directions is not the same."));
- using Weighted_point_3 = typename Triangulation_3::Weighted_point;
std::vector<Weighted_point_3> weighted_points_3;
std::size_t index = 0;
@@ -418,7 +406,7 @@ class Alpha_complex_3d {
#ifdef GUDHI_DEBUG
// Defined in GUDHI_DEBUG to avoid unused variable warning for GUDHI_CHECK
- Alpha_value_type maximal_possible_weight = 0.015625 * (x_max - x_min) * (x_max - x_min);
+ FT maximal_possible_weight = 0.015625 * (x_max - x_min) * (x_max - x_min);
#endif
while ((index < weights.size()) && (index < points.size())) {
@@ -431,7 +419,7 @@ class Alpha_complex_3d {
}
// Define the periodic cube
- Triangulation_3 pdt(typename Kernel::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max));
+ Dt pdt(typename Kernel::Iso_cuboid_3(x_min, y_min, z_min, x_max, y_max, z_max));
// Heuristic for inserting large point sets (if pts is reasonably large)
pdt.insert(std::begin(weighted_points_3), std::end(weighted_points_3), true);
// As pdt won't be modified anymore switch to 1-sheeted cover if possible
@@ -451,13 +439,12 @@ class Alpha_complex_3d {
* \tparam SimplicialComplexForAlpha3d must meet `SimplicialComplexForAlpha3d` concept.
*
* @param[in] complex SimplicialComplexForAlpha3d to be created.
- * @param[in] max_alpha_square maximum for alpha square value. Default value is +\f$\infty\f$.
+ * @param[in] max_alpha_square maximum for alpha square value. Default value is +\f$\infty\f$, and there is very
+ * little point using anything else since it does not save time.
*
* @return true if creation succeeds, false otherwise.
*
- * @pre The simplicial complex must be empty (no vertices)
- *
- * Initialization can be launched once.
+ * @pre The simplicial complex must be empty (no vertices).
*
*/
template <typename SimplicialComplexForAlpha3d,
@@ -481,9 +468,9 @@ class Alpha_complex_3d {
std::size_t count_cells = 0;
#endif // DEBUG_TRACES
std::vector<CGAL::Object> objects;
- std::vector<Alpha_value_type> alpha_values;
+ std::vector<FT> alpha_values;
- Dispatch dispatcher = CGAL::dispatch_output<CGAL::Object, Alpha_value_type>(std::back_inserter(objects),
+ Dispatch dispatcher = CGAL::dispatch_output<CGAL::Object, FT>(std::back_inserter(objects),
std::back_inserter(alpha_values));
alpha_shape_3_ptr_->filtration_with_alpha_values(dispatcher);
@@ -492,7 +479,7 @@ class Alpha_complex_3d {
#endif // DEBUG_TRACES
Alpha_shape_simplex_tree_map map_cgal_simplex_tree;
- using Alpha_value_iterator = typename std::vector<Alpha_value_type>::const_iterator;
+ using Alpha_value_iterator = typename std::vector<FT>::const_iterator;
Alpha_value_iterator alpha_value_iterator = alpha_values.begin();
for (auto object_iterator : objects) {
Vertex_list vertex_list;
@@ -559,7 +546,7 @@ class Alpha_complex_3d {
}
}
// Construction of the simplex_tree
- Filtration_value filtr = Value_from_iterator<Complexity, (Weighted || Periodic)>::perform(alpha_value_iterator);
+ Filtration_value filtr = Value_from_iterator<Complexity>::perform(alpha_value_iterator);
#ifdef DEBUG_TRACES
std::cout << "filtration = " << filtr << std::endl;
diff --git a/src/Alpha_complex/test/Alpha_complex_3d_unit_test.cpp b/src/Alpha_complex/test/Alpha_complex_3d_unit_test.cpp
index 9e071195..ec905d5b 100644
--- a/src/Alpha_complex/test/Alpha_complex_3d_unit_test.cpp
+++ b/src/Alpha_complex/test/Alpha_complex_3d_unit_test.cpp
@@ -23,7 +23,6 @@
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "alpha_complex_3d"
#include <boost/test/unit_test.hpp>
-#include <boost/mpl/list.hpp>
#include <cmath> // float comparison
#include <limits>
@@ -49,41 +48,27 @@ using Safe_alpha_complex_3d =
using Exact_alpha_complex_3d =
Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, false, false>;
-using Fast_weighted_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::FAST, true, false>;
-using Safe_weighted_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, true, false>;
-using Exact_weighted_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, true, false>;
-
-using Fast_periodic_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::FAST, false, true>;
-using Safe_periodic_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, false, true>;
-using Exact_periodic_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, false, true>;
+template <typename Point>
+std::vector<Point> get_points() {
+ std::vector<Point> points;
+ points.push_back(Point(0.0, 0.0, 0.0));
+ points.push_back(Point(0.0, 0.0, 0.2));
+ points.push_back(Point(0.2, 0.0, 0.2));
+ points.push_back(Point(0.6, 0.6, 0.0));
+ points.push_back(Point(0.8, 0.8, 0.2));
+ points.push_back(Point(0.2, 0.8, 0.6));
+
+ return points;
+}
-using Fast_weighted_periodic_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::FAST, true, true>;
-using Safe_weighted_periodic_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, true, true>;
-using Exact_weighted_periodic_alpha_complex_3d =
- Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, true, true>;
BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
// -----------------
// Fast version
// -----------------
std::cout << "Fast alpha complex 3d" << std::endl;
- std::vector<Fast_alpha_complex_3d::Point_3> points;
- points.push_back(Fast_alpha_complex_3d::Point_3(0.0, 0.0, 0.0));
- points.push_back(Fast_alpha_complex_3d::Point_3(0.0, 0.0, 0.2));
- points.push_back(Fast_alpha_complex_3d::Point_3(0.2, 0.0, 0.2));
- points.push_back(Fast_alpha_complex_3d::Point_3(0.6, 0.6, 0.0));
- points.push_back(Fast_alpha_complex_3d::Point_3(0.8, 0.8, 0.2));
- points.push_back(Fast_alpha_complex_3d::Point_3(0.2, 0.8, 0.6));
- Fast_alpha_complex_3d alpha_complex(points);
+ Fast_alpha_complex_3d alpha_complex(get_points<Fast_alpha_complex_3d::Point_3>());
Gudhi::Simplex_tree<> stree;
alpha_complex.create_complex(stree);
@@ -93,7 +78,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
// -----------------
std::cout << "Exact alpha complex 3d" << std::endl;
- Exact_alpha_complex_3d exact_alpha_complex(points);
+ Exact_alpha_complex_3d exact_alpha_complex(get_points<Exact_alpha_complex_3d::Point_3>());
Gudhi::Simplex_tree<> exact_stree;
exact_alpha_complex.create_complex(exact_stree);
@@ -101,13 +86,13 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
// ---------------------
// Compare both versions
// ---------------------
- std::cout << "Exact Alpha complex 3d is of dimension " << exact_stree.dimension() << " - Non exact is "
+ std::cout << "Exact Alpha complex 3d is of dimension " << exact_stree.dimension() << " - Fast is "
<< stree.dimension() << std::endl;
BOOST_CHECK(exact_stree.dimension() == stree.dimension());
- std::cout << "Exact Alpha complex 3d num_simplices " << exact_stree.num_simplices() << " - Non exact is "
+ std::cout << "Exact Alpha complex 3d num_simplices " << exact_stree.num_simplices() << " - Fast is "
<< stree.num_simplices() << std::endl;
BOOST_CHECK(exact_stree.num_simplices() == stree.num_simplices());
- std::cout << "Exact Alpha complex 3d num_vertices " << exact_stree.num_vertices() << " - Non exact is "
+ std::cout << "Exact Alpha complex 3d num_vertices " << exact_stree.num_vertices() << " - Fast is "
<< stree.num_vertices() << std::endl;
BOOST_CHECK(exact_stree.num_vertices() == stree.num_vertices());
@@ -115,19 +100,18 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
while (sh != stree.filtration_simplex_range().end()) {
std::vector<int> simplex;
std::vector<int> exact_simplex;
- std::cout << "Non-exact ( ";
+ std::cout << "Fast ( ";
for (auto vertex : stree.simplex_vertex_range(*sh)) {
simplex.push_back(vertex);
std::cout << vertex << " ";
}
- std::cout << ") -> "
- << "[" << stree.filtration(*sh) << "] ";
- std::cout << std::endl;
+ std::cout << ") -> [" << stree.filtration(*sh) << "] ";
// Find it in the exact structure
auto sh_exact = exact_stree.find(simplex);
BOOST_CHECK(sh_exact != exact_stree.null_simplex());
+ std::cout << " versus [" << exact_stree.filtration(sh_exact) << "] " << std::endl;
// Exact and non-exact version is not exactly the same due to float comparison
GUDHI_TEST_FLOAT_EQUALITY_CHECK(exact_stree.filtration(sh_exact), stree.filtration(*sh));
@@ -138,7 +122,7 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
// -----------------
std::cout << "Safe alpha complex 3d" << std::endl;
- Safe_alpha_complex_3d safe_alpha_complex(points);
+ Safe_alpha_complex_3d safe_alpha_complex(get_points<Safe_alpha_complex_3d::Point_3>());
Gudhi::Simplex_tree<> safe_stree;
safe_alpha_complex.create_complex(safe_stree);
@@ -146,13 +130,13 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
// ---------------------
// Compare both versions
// ---------------------
- std::cout << "Exact Alpha complex 3d is of dimension " << safe_stree.dimension() << " - Non exact is "
+ std::cout << "Safe Alpha complex 3d is of dimension " << safe_stree.dimension() << " - Fast is "
<< stree.dimension() << std::endl;
BOOST_CHECK(safe_stree.dimension() == stree.dimension());
- std::cout << "Exact Alpha complex 3d num_simplices " << safe_stree.num_simplices() << " - Non exact is "
+ std::cout << "Safe Alpha complex 3d num_simplices " << safe_stree.num_simplices() << " - Fast is "
<< stree.num_simplices() << std::endl;
BOOST_CHECK(safe_stree.num_simplices() == stree.num_simplices());
- std::cout << "Exact Alpha complex 3d num_vertices " << safe_stree.num_vertices() << " - Non exact is "
+ std::cout << "Safe Alpha complex 3d num_vertices " << safe_stree.num_vertices() << " - Fast is "
<< stree.num_vertices() << std::endl;
BOOST_CHECK(safe_stree.num_vertices() == stree.num_vertices());
@@ -160,453 +144,21 @@ BOOST_AUTO_TEST_CASE(Alpha_complex_3d_from_points) {
while (safe_sh != stree.filtration_simplex_range().end()) {
std::vector<int> simplex;
std::vector<int> exact_simplex;
-#ifdef DEBUG_TRACES
- std::cout << "Non-exact ( ";
-#endif
+ std::cout << "Fast ( ";
for (auto vertex : stree.simplex_vertex_range(*safe_sh)) {
simplex.push_back(vertex);
-#ifdef DEBUG_TRACES
std::cout << vertex << " ";
-#endif
}
-#ifdef DEBUG_TRACES
- std::cout << ") -> "
- << "[" << stree.filtration(*safe_sh) << "] ";
- std::cout << std::endl;
-#endif
+ std::cout << ") -> [" << stree.filtration(*safe_sh) << "] ";
// Find it in the exact structure
auto sh_exact = safe_stree.find(simplex);
BOOST_CHECK(sh_exact != safe_stree.null_simplex());
+ std::cout << " versus [" << safe_stree.filtration(sh_exact) << "] " << std::endl;
// Exact and non-exact version is not exactly the same due to float comparison
- GUDHI_TEST_FLOAT_EQUALITY_CHECK(safe_stree.filtration(sh_exact), stree.filtration(*safe_sh));
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(safe_stree.filtration(sh_exact), stree.filtration(*safe_sh), 1e-15);
++safe_sh;
}
}
-
-typedef boost::mpl::list<Fast_weighted_alpha_complex_3d, Safe_weighted_alpha_complex_3d,
- Exact_weighted_alpha_complex_3d>
- weighted_variants_type_list;
-
-#ifdef GUDHI_DEBUG
-BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_weighted_throw, Weighted_alpha_complex_3d, weighted_variants_type_list) {
- using Point_3 = typename Weighted_alpha_complex_3d::Point_3;
- std::vector<Point_3> w_points;
- w_points.push_back(Point_3(0.0, 0.0, 0.0));
- w_points.push_back(Point_3(0.0, 0.0, 0.2));
- w_points.push_back(Point_3(0.2, 0.0, 0.2));
- // w_points.push_back(Point_3(0.6, 0.6, 0.0));
- // w_points.push_back(Point_3(0.8, 0.8, 0.2));
- // w_points.push_back(Point_3(0.2, 0.8, 0.6));
-
- // weights size is different from w_points size to make weighted Alpha_complex_3d throw in debug mode
- std::vector<double> weights = {0.01, 0.005, 0.006, 0.01, 0.009, 0.001};
-
- std::cout << "Check exception throw in debug mode" << std::endl;
- BOOST_CHECK_THROW(Weighted_alpha_complex_3d wac(w_points, weights), std::invalid_argument);
-}
-#endif
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_weighted, Weighted_alpha_complex_3d, weighted_variants_type_list) {
- std::cout << "Weighted alpha complex 3d from points and weights" << std::endl;
- using Point_3 = typename Weighted_alpha_complex_3d::Point_3;
- std::vector<Point_3> w_points;
- w_points.push_back(Point_3(0.0, 0.0, 0.0));
- w_points.push_back(Point_3(0.0, 0.0, 0.2));
- w_points.push_back(Point_3(0.2, 0.0, 0.2));
- w_points.push_back(Point_3(0.6, 0.6, 0.0));
- w_points.push_back(Point_3(0.8, 0.8, 0.2));
- w_points.push_back(Point_3(0.2, 0.8, 0.6));
-
- // weights size is different from w_points size to make weighted Alpha_complex_3d throw in debug mode
- std::vector<double> weights = {0.01, 0.005, 0.006, 0.01, 0.009, 0.001};
-
- Weighted_alpha_complex_3d alpha_complex_p_a_w(w_points, weights);
- Gudhi::Simplex_tree<> stree;
- alpha_complex_p_a_w.create_complex(stree);
-
- std::cout << "Weighted alpha complex 3d from weighted points" << std::endl;
- using Weighted_point_3 = typename Weighted_alpha_complex_3d::Triangulation_3::Weighted_point;
-
- std::vector<Weighted_point_3> weighted_points;
-
- for (std::size_t i = 0; i < w_points.size(); i++) {
- weighted_points.push_back(Weighted_point_3(w_points[i], weights[i]));
- }
- Weighted_alpha_complex_3d alpha_complex_w_p(weighted_points);
-
- Gudhi::Simplex_tree<> stree_bis;
- alpha_complex_w_p.create_complex(stree_bis);
-
- // ---------------------
- // Compare both versions
- // ---------------------
- std::cout << "Weighted alpha complex 3d is of dimension " << stree_bis.dimension() << " - versus "
- << stree.dimension() << std::endl;
- BOOST_CHECK(stree_bis.dimension() == stree.dimension());
- std::cout << "Weighted alpha complex 3d num_simplices " << stree_bis.num_simplices() << " - versus "
- << stree.num_simplices() << std::endl;
- BOOST_CHECK(stree_bis.num_simplices() == stree.num_simplices());
- std::cout << "Weighted alpha complex 3d num_vertices " << stree_bis.num_vertices() << " - versus "
- << stree.num_vertices() << std::endl;
- BOOST_CHECK(stree_bis.num_vertices() == stree.num_vertices());
-
- auto sh = stree.filtration_simplex_range().begin();
- while (sh != stree.filtration_simplex_range().end()) {
- std::vector<int> simplex;
- std::vector<int> exact_simplex;
-#ifdef DEBUG_TRACES
- std::cout << " ( ";
-#endif
- for (auto vertex : stree.simplex_vertex_range(*sh)) {
- simplex.push_back(vertex);
-#ifdef DEBUG_TRACES
- std::cout << vertex << " ";
-#endif
- }
-#ifdef DEBUG_TRACES
- std::cout << ") -> "
- << "[" << stree.filtration(*sh) << "] ";
- std::cout << std::endl;
-#endif
-
- // Find it in the exact structure
- auto sh_exact = stree_bis.find(simplex);
- BOOST_CHECK(sh_exact != stree_bis.null_simplex());
-
- // Exact and non-exact version is not exactly the same due to float comparison
- GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree_bis.filtration(sh_exact), stree.filtration(*sh));
-
- ++sh;
- }
-}
-
-#ifdef GUDHI_DEBUG
-typedef boost::mpl::list<Fast_periodic_alpha_complex_3d, Safe_periodic_alpha_complex_3d,
- Exact_periodic_alpha_complex_3d>
- periodic_variants_type_list;
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_periodic_throw, Periodic_alpha_complex_3d, periodic_variants_type_list) {
- std::cout << "Periodic alpha complex 3d exception throw" << std::endl;
- using Point_3 = typename Periodic_alpha_complex_3d::Point_3;
- std::vector<Point_3> p_points;
-
- // Not important, this is not what we want to check
- p_points.push_back(Point_3(0.0, 0.0, 0.0));
-
- std::cout << "Check exception throw in debug mode" << std::endl;
- // Check it throws an exception when the cuboid is not iso
- BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 0.9, 1., 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 0.9, 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 1., 0.9),
- std::invalid_argument);
- BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1.1, 1., 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 1.1, 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 1., 1.1),
- std::invalid_argument);
-}
-#endif
-
-BOOST_AUTO_TEST_CASE(Alpha_complex_periodic) {
- // ---------------------
- // Fast periodic version
- // ---------------------
- std::cout << "Fast periodic alpha complex 3d" << std::endl;
-
- using Creator = CGAL::Creator_uniform_3<double, Fast_periodic_alpha_complex_3d::Point_3>;
- CGAL::Random random(7);
- CGAL::Random_points_in_cube_3<Fast_periodic_alpha_complex_3d::Point_3, Creator> in_cube(1, random);
- std::vector<Fast_periodic_alpha_complex_3d::Point_3> p_points;
-
- for (int i = 0; i < 50; i++) {
- Fast_periodic_alpha_complex_3d::Point_3 p = *in_cube++;
- p_points.push_back(p);
- }
-
- Fast_periodic_alpha_complex_3d periodic_alpha_complex(p_points, -1., -1., -1., 1., 1., 1.);
-
- Gudhi::Simplex_tree<> stree;
- periodic_alpha_complex.create_complex(stree);
-
- // ----------------------
- // Exact periodic version
- // ----------------------
- std::cout << "Exact periodic alpha complex 3d" << std::endl;
-
- std::vector<Exact_periodic_alpha_complex_3d::Point_3> e_p_points;
-
- for (auto p : p_points) {
- e_p_points.push_back(Exact_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
- }
-
- Exact_periodic_alpha_complex_3d exact_alpha_complex(e_p_points, -1., -1., -1., 1., 1., 1.);
-
- Gudhi::Simplex_tree<> exact_stree;
- exact_alpha_complex.create_complex(exact_stree);
-
- // ---------------------
- // Compare both versions
- // ---------------------
- std::cout << "Exact periodic alpha complex 3d is of dimension " << exact_stree.dimension() << " - Non exact is "
- << stree.dimension() << std::endl;
- BOOST_CHECK(exact_stree.dimension() == stree.dimension());
- std::cout << "Exact periodic alpha complex 3d num_simplices " << exact_stree.num_simplices() << " - Non exact is "
- << stree.num_simplices() << std::endl;
- BOOST_CHECK(exact_stree.num_simplices() == stree.num_simplices());
- std::cout << "Exact periodic alpha complex 3d num_vertices " << exact_stree.num_vertices() << " - Non exact is "
- << stree.num_vertices() << std::endl;
- BOOST_CHECK(exact_stree.num_vertices() == stree.num_vertices());
-
- // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
- // cf. https://github.com/CGAL/cgal/issues/3346
- auto sh = stree.filtration_simplex_range().begin();
- auto sh_exact = exact_stree.filtration_simplex_range().begin();
-
- while (sh != stree.filtration_simplex_range().end() || sh_exact != exact_stree.filtration_simplex_range().end()) {
- GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), exact_stree.filtration(*sh_exact), 1e-14);
-
- std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
- std::vector<int> exact_vh(exact_stree.simplex_vertex_range(*sh_exact).begin(),
- exact_stree.simplex_vertex_range(*sh_exact).end());
-
- BOOST_CHECK(vh.size() == exact_vh.size());
- ++sh;
- ++sh_exact;
- }
-
- BOOST_CHECK(sh == stree.filtration_simplex_range().end());
- BOOST_CHECK(sh_exact == exact_stree.filtration_simplex_range().end());
-
- // ----------------------
- // Safe periodic version
- // ----------------------
- std::cout << "Safe periodic alpha complex 3d" << std::endl;
-
- std::vector<Safe_periodic_alpha_complex_3d::Point_3> s_p_points;
-
- for (auto p : p_points) {
- s_p_points.push_back(Safe_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
- }
-
- Safe_periodic_alpha_complex_3d safe_alpha_complex(s_p_points, -1., -1., -1., 1., 1., 1.);
-
- Gudhi::Simplex_tree<> safe_stree;
- safe_alpha_complex.create_complex(safe_stree);
-
- // ---------------------
- // Compare both versions
- // ---------------------
- // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
- // cf. https://github.com/CGAL/cgal/issues/3346
- sh = stree.filtration_simplex_range().begin();
- auto sh_safe = safe_stree.filtration_simplex_range().begin();
-
- while (sh != stree.filtration_simplex_range().end() || sh_safe != safe_stree.filtration_simplex_range().end()) {
- GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), safe_stree.filtration(*sh_safe), 1e-14);
-
- std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
- std::vector<int> safe_vh(safe_stree.simplex_vertex_range(*sh_safe).begin(),
- safe_stree.simplex_vertex_range(*sh_safe).end());
-
- BOOST_CHECK(vh.size() == safe_vh.size());
- ++sh;
- ++sh_safe;
- }
-
- BOOST_CHECK(sh == stree.filtration_simplex_range().end());
- BOOST_CHECK(sh_safe == safe_stree.filtration_simplex_range().end());
-}
-
-typedef boost::mpl::list<Fast_weighted_periodic_alpha_complex_3d, Exact_weighted_periodic_alpha_complex_3d,
- Safe_weighted_periodic_alpha_complex_3d>
- wp_variants_type_list;
-
-#ifdef GUDHI_DEBUG
-BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_weighted_periodic_throw, Weighted_periodic_alpha_complex_3d,
- wp_variants_type_list) {
- std::cout << "Weighted periodic alpha complex 3d exception throw" << std::endl;
-
- using Creator = CGAL::Creator_uniform_3<double, Weighted_periodic_alpha_complex_3d::Point_3>;
- CGAL::Random random(7);
- CGAL::Random_points_in_cube_3<Weighted_periodic_alpha_complex_3d::Point_3, Creator> in_cube(1, random);
- std::vector<Weighted_periodic_alpha_complex_3d::Point_3> wp_points;
-
- for (int i = 0; i < 50; i++) {
- Weighted_periodic_alpha_complex_3d::Point_3 p = *in_cube++;
- wp_points.push_back(p);
- }
- std::vector<double> p_weights;
- // Weights must be in range ]0, 1/64 = 0.015625[
- for (std::size_t i = 0; i < wp_points.size(); ++i) {
- p_weights.push_back(random.get_double(0., 0.01));
- }
-
- std::cout << "Cuboid is not iso exception" << std::endl;
- // Check it throws an exception when the cuboid is not iso
- BOOST_CHECK_THROW(
- Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 0.9, 1., 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(
- Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 0.9, 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(
- Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 1., 0.9),
- std::invalid_argument);
- BOOST_CHECK_THROW(
- Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1.1, 1., 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(
- Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 1.1, 1.),
- std::invalid_argument);
- BOOST_CHECK_THROW(
- Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 1., 1.1),
- std::invalid_argument);
-
- std::cout << "0 <= point.weight() < 1/64 * domain_size * domain_size exception" << std::endl;
- // Weights must be in range ]0, 1/64 = 0.015625[
- double temp = p_weights[25];
- p_weights[25] = 1.0;
- BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
- std::invalid_argument);
- // Weights must be in range ]0, 1/64 = 0.015625[
- p_weights[25] = temp;
- temp = p_weights[14];
- p_weights[14] = -1e-10;
- BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
- std::invalid_argument);
- p_weights[14] = temp;
-
- std::cout << "wp_points and p_weights size exception" << std::endl;
- // Weights and points must have the same size
- // + 1
- p_weights.push_back(1e-10);
- BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
- std::invalid_argument);
- // - 1
- p_weights.pop_back();
- p_weights.pop_back();
- BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
- std::invalid_argument);
-}
-#endif
-
-BOOST_AUTO_TEST_CASE(Alpha_complex_weighted_periodic) {
- // ---------------------
- // Fast weighted periodic version
- // ---------------------
- std::cout << "Fast weighted periodic alpha complex 3d" << std::endl;
-
- using Creator = CGAL::Creator_uniform_3<double, Fast_weighted_periodic_alpha_complex_3d::Point_3>;
- CGAL::Random random(7);
- CGAL::Random_points_in_cube_3<Fast_weighted_periodic_alpha_complex_3d::Point_3, Creator> in_cube(1, random);
- std::vector<Fast_weighted_periodic_alpha_complex_3d::Point_3> p_points;
-
- for (int i = 0; i < 50; i++) {
- Fast_weighted_periodic_alpha_complex_3d::Point_3 p = *in_cube++;
- p_points.push_back(p);
- }
- std::vector<double> p_weights;
- // Weights must be in range ]0, 1/64 = 0.015625[
- for (std::size_t i = 0; i < p_points.size(); ++i) {
- p_weights.push_back(random.get_double(0., 0.01));
- }
-
- Fast_weighted_periodic_alpha_complex_3d periodic_alpha_complex(p_points, p_weights, -1., -1., -1., 1., 1., 1.);
-
- Gudhi::Simplex_tree<> stree;
- periodic_alpha_complex.create_complex(stree);
-
- // ----------------------
- // Exact weighted periodic version
- // ----------------------
- std::cout << "Exact weighted periodic alpha complex 3d" << std::endl;
-
- std::vector<Exact_weighted_periodic_alpha_complex_3d::Point_3> e_p_points;
-
- for (auto p : p_points) {
- e_p_points.push_back(Exact_weighted_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
- }
-
- Exact_weighted_periodic_alpha_complex_3d exact_alpha_complex(e_p_points, p_weights, -1., -1., -1., 1., 1., 1.);
-
- Gudhi::Simplex_tree<> exact_stree;
- exact_alpha_complex.create_complex(exact_stree);
-
- // ---------------------
- // Compare both versions
- // ---------------------
- std::cout << "Exact weighted periodic alpha complex 3d is of dimension " << exact_stree.dimension()
- << " - Non exact is " << stree.dimension() << std::endl;
- BOOST_CHECK(exact_stree.dimension() == stree.dimension());
- std::cout << "Exact weighted periodic alpha complex 3d num_simplices " << exact_stree.num_simplices()
- << " - Non exact is " << stree.num_simplices() << std::endl;
- BOOST_CHECK(exact_stree.num_simplices() == stree.num_simplices());
- std::cout << "Exact weighted periodic alpha complex 3d num_vertices " << exact_stree.num_vertices()
- << " - Non exact is " << stree.num_vertices() << std::endl;
- BOOST_CHECK(exact_stree.num_vertices() == stree.num_vertices());
-
- // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
- // cf. https://github.com/CGAL/cgal/issues/3346
- auto sh = stree.filtration_simplex_range().begin();
- auto sh_exact = exact_stree.filtration_simplex_range().begin();
-
- while (sh != stree.filtration_simplex_range().end() || sh_exact != exact_stree.filtration_simplex_range().end()) {
- GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), exact_stree.filtration(*sh_exact), 1e-14);
-
- std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
- std::vector<int> exact_vh(exact_stree.simplex_vertex_range(*sh_exact).begin(),
- exact_stree.simplex_vertex_range(*sh_exact).end());
-
- BOOST_CHECK(vh.size() == exact_vh.size());
- ++sh;
- ++sh_exact;
- }
-
- BOOST_CHECK(sh == stree.filtration_simplex_range().end());
- BOOST_CHECK(sh_exact == exact_stree.filtration_simplex_range().end());
-
- // ----------------------
- // Safe weighted periodic version
- // ----------------------
- std::cout << "Safe weighted periodic alpha complex 3d" << std::endl;
-
- std::vector<Safe_weighted_periodic_alpha_complex_3d::Point_3> s_p_points;
-
- for (auto p : p_points) {
- s_p_points.push_back(Safe_weighted_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
- }
-
- Safe_weighted_periodic_alpha_complex_3d safe_alpha_complex(s_p_points, p_weights, -1., -1., -1., 1., 1., 1.);
-
- Gudhi::Simplex_tree<> safe_stree;
- safe_alpha_complex.create_complex(safe_stree);
-
- // ---------------------
- // Compare both versions
- // ---------------------
- // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
- // cf. https://github.com/CGAL/cgal/issues/3346
- sh = stree.filtration_simplex_range().begin();
- auto sh_safe = safe_stree.filtration_simplex_range().begin();
-
- while (sh != stree.filtration_simplex_range().end() || sh_safe != safe_stree.filtration_simplex_range().end()) {
- GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), safe_stree.filtration(*sh_safe), 1e-14);
-
- std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
- std::vector<int> safe_vh(safe_stree.simplex_vertex_range(*sh_safe).begin(),
- safe_stree.simplex_vertex_range(*sh_safe).end());
-
- BOOST_CHECK(vh.size() == safe_vh.size());
- ++sh;
- ++sh_safe;
- }
-
- BOOST_CHECK(sh == stree.filtration_simplex_range().end());
- BOOST_CHECK(sh_safe == safe_stree.filtration_simplex_range().end());
-}
diff --git a/src/Alpha_complex/test/CMakeLists.txt b/src/Alpha_complex/test/CMakeLists.txt
index 380380f4..7c6bf9aa 100644
--- a/src/Alpha_complex/test/CMakeLists.txt
+++ b/src/Alpha_complex/test/CMakeLists.txt
@@ -19,10 +19,22 @@ endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0)
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0)
add_executable ( Alpha_complex_3d_test_unit Alpha_complex_3d_unit_test.cpp )
target_link_libraries(Alpha_complex_3d_test_unit ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ add_executable ( Weighted_alpha_complex_3d_test_unit Weighted_alpha_complex_3d_unit_test.cpp )
+ target_link_libraries(Weighted_alpha_complex_3d_test_unit ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ add_executable ( Periodic_alpha_complex_3d_test_unit Periodic_alpha_complex_3d_unit_test.cpp )
+ target_link_libraries(Periodic_alpha_complex_3d_test_unit ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+ add_executable ( Weighted_periodic_alpha_complex_3d_test_unit Weighted_periodic_alpha_complex_3d_unit_test.cpp )
+ target_link_libraries(Weighted_periodic_alpha_complex_3d_test_unit ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
if (TBB_FOUND)
target_link_libraries(Alpha_complex_3d_test_unit ${TBB_LIBRARIES})
+ target_link_libraries(Weighted_alpha_complex_3d_test_unit ${TBB_LIBRARIES})
+ target_link_libraries(Periodic_alpha_complex_3d_test_unit ${TBB_LIBRARIES})
+ target_link_libraries(Weighted_periodic_alpha_complex_3d_test_unit ${TBB_LIBRARIES})
endif()
gudhi_add_coverage_test(Alpha_complex_3d_test_unit)
+ gudhi_add_coverage_test(Weighted_alpha_complex_3d_test_unit)
+ gudhi_add_coverage_test(Periodic_alpha_complex_3d_test_unit)
+ gudhi_add_coverage_test(Weighted_periodic_alpha_complex_3d_test_unit)
endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0)
diff --git a/src/Alpha_complex/test/Periodic_alpha_complex_3d_unit_test.cpp b/src/Alpha_complex/test/Periodic_alpha_complex_3d_unit_test.cpp
new file mode 100644
index 00000000..ed4cbff0
--- /dev/null
+++ b/src/Alpha_complex/test/Periodic_alpha_complex_3d_unit_test.cpp
@@ -0,0 +1,190 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2015 Inria
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "alpha_complex_3d"
+#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
+
+#include <cmath> // float comparison
+#include <limits>
+#include <string>
+#include <vector>
+#include <random>
+#include <cstddef> // for std::size_t
+
+#include <gudhi/Alpha_complex_3d.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Unitary_tests_utils.h>
+// to construct Alpha_complex from a OFF file of points
+#include <gudhi/Points_3D_off_io.h>
+
+#include <CGAL/Random.h>
+#include <CGAL/point_generators_3.h>
+
+using Fast_periodic_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::FAST, false, true>;
+using Safe_periodic_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, false, true>;
+using Exact_periodic_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, false, true>;
+
+#ifdef GUDHI_DEBUG
+typedef boost::mpl::list<Fast_periodic_alpha_complex_3d, Safe_periodic_alpha_complex_3d,
+ Exact_periodic_alpha_complex_3d>
+ periodic_variants_type_list;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_periodic_throw, Periodic_alpha_complex_3d, periodic_variants_type_list) {
+ std::cout << "Periodic alpha complex 3d exception throw" << std::endl;
+ using Point_3 = typename Periodic_alpha_complex_3d::Point_3;
+ std::vector<Point_3> p_points;
+
+ // Not important, this is not what we want to check
+ p_points.push_back(Point_3(0.0, 0.0, 0.0));
+
+ std::cout << "Check exception throw in debug mode" << std::endl;
+ // Check it throws an exception when the cuboid is not iso
+ BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 0.9, 1., 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 0.9, 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 1., 0.9),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1.1, 1., 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 1.1, 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(Periodic_alpha_complex_3d periodic_alpha_complex(p_points, 0., 0., 0., 1., 1., 1.1),
+ std::invalid_argument);
+}
+#endif
+
+BOOST_AUTO_TEST_CASE(Alpha_complex_periodic) {
+ // ---------------------
+ // Fast periodic version
+ // ---------------------
+ std::cout << "Fast periodic alpha complex 3d" << std::endl;
+
+ using Creator = CGAL::Creator_uniform_3<double, Fast_periodic_alpha_complex_3d::Point_3>;
+ CGAL::Random random(7);
+ CGAL::Random_points_in_cube_3<Fast_periodic_alpha_complex_3d::Point_3, Creator> in_cube(1, random);
+ std::vector<Fast_periodic_alpha_complex_3d::Point_3> p_points;
+
+ for (int i = 0; i < 50; i++) {
+ Fast_periodic_alpha_complex_3d::Point_3 p = *in_cube++;
+ p_points.push_back(p);
+ }
+
+ Fast_periodic_alpha_complex_3d periodic_alpha_complex(p_points, -1., -1., -1., 1., 1., 1.);
+
+ Gudhi::Simplex_tree<> stree;
+ periodic_alpha_complex.create_complex(stree);
+
+ // ----------------------
+ // Exact periodic version
+ // ----------------------
+ std::cout << "Exact periodic alpha complex 3d" << std::endl;
+
+ std::vector<Exact_periodic_alpha_complex_3d::Point_3> e_p_points;
+
+ for (auto p : p_points) {
+ e_p_points.push_back(Exact_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
+ }
+
+ Exact_periodic_alpha_complex_3d exact_alpha_complex(e_p_points, -1., -1., -1., 1., 1., 1.);
+
+ Gudhi::Simplex_tree<> exact_stree;
+ exact_alpha_complex.create_complex(exact_stree);
+
+ // ---------------------
+ // Compare both versions
+ // ---------------------
+ std::cout << "Exact periodic alpha complex 3d is of dimension " << exact_stree.dimension() << " - Non exact is "
+ << stree.dimension() << std::endl;
+ BOOST_CHECK(exact_stree.dimension() == stree.dimension());
+ std::cout << "Exact periodic alpha complex 3d num_simplices " << exact_stree.num_simplices() << " - Non exact is "
+ << stree.num_simplices() << std::endl;
+ BOOST_CHECK(exact_stree.num_simplices() == stree.num_simplices());
+ std::cout << "Exact periodic alpha complex 3d num_vertices " << exact_stree.num_vertices() << " - Non exact is "
+ << stree.num_vertices() << std::endl;
+ BOOST_CHECK(exact_stree.num_vertices() == stree.num_vertices());
+
+ // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
+ // cf. https://github.com/CGAL/cgal/issues/3346
+ auto sh = stree.filtration_simplex_range().begin();
+ auto sh_exact = exact_stree.filtration_simplex_range().begin();
+
+ while (sh != stree.filtration_simplex_range().end() || sh_exact != exact_stree.filtration_simplex_range().end()) {
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), exact_stree.filtration(*sh_exact), 1e-14);
+
+ std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
+ std::vector<int> exact_vh(exact_stree.simplex_vertex_range(*sh_exact).begin(),
+ exact_stree.simplex_vertex_range(*sh_exact).end());
+
+ BOOST_CHECK(vh.size() == exact_vh.size());
+ ++sh;
+ ++sh_exact;
+ }
+
+ BOOST_CHECK(sh == stree.filtration_simplex_range().end());
+ BOOST_CHECK(sh_exact == exact_stree.filtration_simplex_range().end());
+
+ // ----------------------
+ // Safe periodic version
+ // ----------------------
+ std::cout << "Safe periodic alpha complex 3d" << std::endl;
+
+ std::vector<Safe_periodic_alpha_complex_3d::Point_3> s_p_points;
+
+ for (auto p : p_points) {
+ s_p_points.push_back(Safe_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
+ }
+
+ Safe_periodic_alpha_complex_3d safe_alpha_complex(s_p_points, -1., -1., -1., 1., 1., 1.);
+
+ Gudhi::Simplex_tree<> safe_stree;
+ safe_alpha_complex.create_complex(safe_stree);
+
+ // ---------------------
+ // Compare both versions
+ // ---------------------
+ // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
+ // cf. https://github.com/CGAL/cgal/issues/3346
+ sh = stree.filtration_simplex_range().begin();
+ auto sh_safe = safe_stree.filtration_simplex_range().begin();
+
+ while (sh != stree.filtration_simplex_range().end() || sh_safe != safe_stree.filtration_simplex_range().end()) {
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), safe_stree.filtration(*sh_safe), 1e-14);
+
+ std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
+ std::vector<int> safe_vh(safe_stree.simplex_vertex_range(*sh_safe).begin(),
+ safe_stree.simplex_vertex_range(*sh_safe).end());
+
+ BOOST_CHECK(vh.size() == safe_vh.size());
+ ++sh;
+ ++sh_safe;
+ }
+
+ BOOST_CHECK(sh == stree.filtration_simplex_range().end());
+ BOOST_CHECK(sh_safe == safe_stree.filtration_simplex_range().end());
+}
diff --git a/src/Alpha_complex/test/Weighted_alpha_complex_3d_unit_test.cpp b/src/Alpha_complex/test/Weighted_alpha_complex_3d_unit_test.cpp
new file mode 100644
index 00000000..c16b3718
--- /dev/null
+++ b/src/Alpha_complex/test/Weighted_alpha_complex_3d_unit_test.cpp
@@ -0,0 +1,147 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2015 Inria
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "alpha_complex_3d"
+#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
+
+#include <cmath> // float comparison
+#include <limits>
+#include <string>
+#include <vector>
+#include <random>
+#include <cstddef> // for std::size_t
+
+#include <gudhi/Alpha_complex_3d.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Unitary_tests_utils.h>
+// to construct Alpha_complex from a OFF file of points
+#include <gudhi/Points_3D_off_io.h>
+
+#include <CGAL/Random.h>
+#include <CGAL/point_generators_3.h>
+
+using Fast_weighted_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::FAST, true, false>;
+using Safe_weighted_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, true, false>;
+using Exact_weighted_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, true, false>;
+
+typedef boost::mpl::list<Fast_weighted_alpha_complex_3d, Safe_weighted_alpha_complex_3d,
+ Exact_weighted_alpha_complex_3d>
+ weighted_variants_type_list;
+
+#ifdef GUDHI_DEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_weighted_throw, Weighted_alpha_complex_3d, weighted_variants_type_list) {
+ using Point_3 = typename Weighted_alpha_complex_3d::Point_3;
+ std::vector<Point_3> w_points;
+ w_points.push_back(Point_3(0.0, 0.0, 0.0));
+ w_points.push_back(Point_3(0.0, 0.0, 0.2));
+ w_points.push_back(Point_3(0.2, 0.0, 0.2));
+ // w_points.push_back(Point_3(0.6, 0.6, 0.0));
+ // w_points.push_back(Point_3(0.8, 0.8, 0.2));
+ // w_points.push_back(Point_3(0.2, 0.8, 0.6));
+
+ // weights size is different from w_points size to make weighted Alpha_complex_3d throw in debug mode
+ std::vector<double> weights = {0.01, 0.005, 0.006, 0.01, 0.009, 0.001};
+
+ std::cout << "Check exception throw in debug mode" << std::endl;
+ BOOST_CHECK_THROW(Weighted_alpha_complex_3d wac(w_points, weights), std::invalid_argument);
+}
+#endif
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_weighted, Weighted_alpha_complex_3d, weighted_variants_type_list) {
+ std::cout << "Weighted alpha complex 3d from points and weights" << std::endl;
+ using Point_3 = typename Weighted_alpha_complex_3d::Point_3;
+ std::vector<Point_3> w_points;
+ w_points.push_back(Point_3(0.0, 0.0, 0.0));
+ w_points.push_back(Point_3(0.0, 0.0, 0.2));
+ w_points.push_back(Point_3(0.2, 0.0, 0.2));
+ w_points.push_back(Point_3(0.6, 0.6, 0.0));
+ w_points.push_back(Point_3(0.8, 0.8, 0.2));
+ w_points.push_back(Point_3(0.2, 0.8, 0.6));
+
+ // weights size is different from w_points size to make weighted Alpha_complex_3d throw in debug mode
+ std::vector<double> weights = {0.01, 0.005, 0.006, 0.01, 0.009, 0.001};
+
+ Weighted_alpha_complex_3d alpha_complex_p_a_w(w_points, weights);
+ Gudhi::Simplex_tree<> stree;
+ alpha_complex_p_a_w.create_complex(stree);
+
+ std::cout << "Weighted alpha complex 3d from weighted points" << std::endl;
+ using Weighted_point_3 = typename Weighted_alpha_complex_3d::Weighted_point_3;
+
+ std::vector<Weighted_point_3> weighted_points;
+
+ for (std::size_t i = 0; i < w_points.size(); i++) {
+ weighted_points.push_back(Weighted_point_3(w_points[i], weights[i]));
+ }
+ Weighted_alpha_complex_3d alpha_complex_w_p(weighted_points);
+
+ Gudhi::Simplex_tree<> stree_bis;
+ alpha_complex_w_p.create_complex(stree_bis);
+
+ // ---------------------
+ // Compare both versions
+ // ---------------------
+ std::cout << "Weighted alpha complex 3d is of dimension " << stree_bis.dimension() << " - versus "
+ << stree.dimension() << std::endl;
+ BOOST_CHECK(stree_bis.dimension() == stree.dimension());
+ std::cout << "Weighted alpha complex 3d num_simplices " << stree_bis.num_simplices() << " - versus "
+ << stree.num_simplices() << std::endl;
+ BOOST_CHECK(stree_bis.num_simplices() == stree.num_simplices());
+ std::cout << "Weighted alpha complex 3d num_vertices " << stree_bis.num_vertices() << " - versus "
+ << stree.num_vertices() << std::endl;
+ BOOST_CHECK(stree_bis.num_vertices() == stree.num_vertices());
+
+ auto sh = stree.filtration_simplex_range().begin();
+ while (sh != stree.filtration_simplex_range().end()) {
+ std::vector<int> simplex;
+ std::vector<int> exact_simplex;
+#ifdef DEBUG_TRACES
+ std::cout << " ( ";
+#endif
+ for (auto vertex : stree.simplex_vertex_range(*sh)) {
+ simplex.push_back(vertex);
+#ifdef DEBUG_TRACES
+ std::cout << vertex << " ";
+#endif
+ }
+#ifdef DEBUG_TRACES
+ std::cout << ") -> "
+ << "[" << stree.filtration(*sh) << "] ";
+ std::cout << std::endl;
+#endif
+
+ // Find it in the exact structure
+ auto sh_exact = stree_bis.find(simplex);
+ BOOST_CHECK(sh_exact != stree_bis.null_simplex());
+
+ // Exact and non-exact version is not exactly the same due to float comparison
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree_bis.filtration(sh_exact), stree.filtration(*sh));
+
+ ++sh;
+ }
+}
diff --git a/src/Alpha_complex/test/Weighted_periodic_alpha_complex_3d_unit_test.cpp b/src/Alpha_complex/test/Weighted_periodic_alpha_complex_3d_unit_test.cpp
new file mode 100644
index 00000000..e8ac83e5
--- /dev/null
+++ b/src/Alpha_complex/test/Weighted_periodic_alpha_complex_3d_unit_test.cpp
@@ -0,0 +1,239 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2015 Inria
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "alpha_complex_3d"
+#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
+
+#include <cmath> // float comparison
+#include <limits>
+#include <string>
+#include <vector>
+#include <random>
+#include <cstddef> // for std::size_t
+
+#include <gudhi/Alpha_complex_3d.h>
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/Simplex_tree.h>
+#include <gudhi/Unitary_tests_utils.h>
+// to construct Alpha_complex from a OFF file of points
+#include <gudhi/Points_3D_off_io.h>
+
+#include <CGAL/Random.h>
+#include <CGAL/point_generators_3.h>
+
+using Fast_weighted_periodic_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::FAST, true, true>;
+using Safe_weighted_periodic_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::SAFE, true, true>;
+using Exact_weighted_periodic_alpha_complex_3d =
+ Gudhi::alpha_complex::Alpha_complex_3d<Gudhi::alpha_complex::complexity::EXACT, true, true>;
+
+
+typedef boost::mpl::list<Fast_weighted_periodic_alpha_complex_3d, Exact_weighted_periodic_alpha_complex_3d,
+ Safe_weighted_periodic_alpha_complex_3d>
+ wp_variants_type_list;
+
+#ifdef GUDHI_DEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(Alpha_complex_weighted_periodic_throw, Weighted_periodic_alpha_complex_3d,
+ wp_variants_type_list) {
+ std::cout << "Weighted periodic alpha complex 3d exception throw" << std::endl;
+
+ using Creator = CGAL::Creator_uniform_3<double, typename Weighted_periodic_alpha_complex_3d::Point_3>;
+ CGAL::Random random(7);
+ CGAL::Random_points_in_cube_3<typename Weighted_periodic_alpha_complex_3d::Point_3, Creator> in_cube(1, random);
+ std::vector<typename Weighted_periodic_alpha_complex_3d::Point_3> wp_points;
+
+ for (int i = 0; i < 50; i++) {
+ typename Weighted_periodic_alpha_complex_3d::Point_3 p = *in_cube++;
+ wp_points.push_back(p);
+ }
+ std::vector<double> p_weights;
+ // Weights must be in range ]0, 1/64 = 0.015625[
+ for (std::size_t i = 0; i < wp_points.size(); ++i) {
+ p_weights.push_back(random.get_double(0., 0.01));
+ }
+
+ std::cout << "Cuboid is not iso exception" << std::endl;
+ // Check it throws an exception when the cuboid is not iso
+ BOOST_CHECK_THROW(
+ Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 0.9, 1., 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(
+ Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 0.9, 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(
+ Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 1., 0.9),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(
+ Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1.1, 1., 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(
+ Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 1.1, 1.),
+ std::invalid_argument);
+ BOOST_CHECK_THROW(
+ Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, -1., -1., -1., 1., 1., 1.1),
+ std::invalid_argument);
+
+ std::cout << "0 <= point.weight() < 1/64 * domain_size * domain_size exception" << std::endl;
+ // Weights must be in range ]0, 1/64 = 0.015625[
+ double temp = p_weights[25];
+ p_weights[25] = 1.0;
+ BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
+ std::invalid_argument);
+ // Weights must be in range ]0, 1/64 = 0.015625[
+ p_weights[25] = temp;
+ temp = p_weights[14];
+ p_weights[14] = -1e-10;
+ BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
+ std::invalid_argument);
+ p_weights[14] = temp;
+
+ std::cout << "wp_points and p_weights size exception" << std::endl;
+ // Weights and points must have the same size
+ // + 1
+ p_weights.push_back(1e-10);
+ BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
+ std::invalid_argument);
+ // - 1
+ p_weights.pop_back();
+ p_weights.pop_back();
+ BOOST_CHECK_THROW(Weighted_periodic_alpha_complex_3d wp_alpha_complex(wp_points, p_weights, 0., 0., 0., 1., 1., 1.),
+ std::invalid_argument);
+}
+#endif
+
+BOOST_AUTO_TEST_CASE(Alpha_complex_weighted_periodic) {
+ // ---------------------
+ // Fast weighted periodic version
+ // ---------------------
+ std::cout << "Fast weighted periodic alpha complex 3d" << std::endl;
+
+ using Creator = CGAL::Creator_uniform_3<double, Fast_weighted_periodic_alpha_complex_3d::Point_3>;
+ CGAL::Random random(7);
+ CGAL::Random_points_in_cube_3<Fast_weighted_periodic_alpha_complex_3d::Point_3, Creator> in_cube(1, random);
+ std::vector<Fast_weighted_periodic_alpha_complex_3d::Point_3> p_points;
+
+ for (int i = 0; i < 50; i++) {
+ Fast_weighted_periodic_alpha_complex_3d::Point_3 p = *in_cube++;
+ p_points.push_back(p);
+ }
+ std::vector<double> p_weights;
+ // Weights must be in range ]0, 1/64 = 0.015625[
+ for (std::size_t i = 0; i < p_points.size(); ++i) {
+ p_weights.push_back(random.get_double(0., 0.01));
+ }
+
+ Fast_weighted_periodic_alpha_complex_3d periodic_alpha_complex(p_points, p_weights, -1., -1., -1., 1., 1., 1.);
+
+ Gudhi::Simplex_tree<> stree;
+ periodic_alpha_complex.create_complex(stree);
+
+ // ----------------------
+ // Exact weighted periodic version
+ // ----------------------
+ std::cout << "Exact weighted periodic alpha complex 3d" << std::endl;
+
+ std::vector<Exact_weighted_periodic_alpha_complex_3d::Point_3> e_p_points;
+
+ for (auto p : p_points) {
+ e_p_points.push_back(Exact_weighted_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
+ }
+
+ Exact_weighted_periodic_alpha_complex_3d exact_alpha_complex(e_p_points, p_weights, -1., -1., -1., 1., 1., 1.);
+
+ Gudhi::Simplex_tree<> exact_stree;
+ exact_alpha_complex.create_complex(exact_stree);
+
+ // ---------------------
+ // Compare both versions
+ // ---------------------
+ std::cout << "Exact weighted periodic alpha complex 3d is of dimension " << exact_stree.dimension()
+ << " - Non exact is " << stree.dimension() << std::endl;
+ BOOST_CHECK(exact_stree.dimension() == stree.dimension());
+ std::cout << "Exact weighted periodic alpha complex 3d num_simplices " << exact_stree.num_simplices()
+ << " - Non exact is " << stree.num_simplices() << std::endl;
+ BOOST_CHECK(exact_stree.num_simplices() == stree.num_simplices());
+ std::cout << "Exact weighted periodic alpha complex 3d num_vertices " << exact_stree.num_vertices()
+ << " - Non exact is " << stree.num_vertices() << std::endl;
+ BOOST_CHECK(exact_stree.num_vertices() == stree.num_vertices());
+
+ // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
+ // cf. https://github.com/CGAL/cgal/issues/3346
+ auto sh = stree.filtration_simplex_range().begin();
+ auto sh_exact = exact_stree.filtration_simplex_range().begin();
+
+ while (sh != stree.filtration_simplex_range().end() || sh_exact != exact_stree.filtration_simplex_range().end()) {
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), exact_stree.filtration(*sh_exact), 1e-14);
+
+ std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
+ std::vector<int> exact_vh(exact_stree.simplex_vertex_range(*sh_exact).begin(),
+ exact_stree.simplex_vertex_range(*sh_exact).end());
+
+ BOOST_CHECK(vh.size() == exact_vh.size());
+ ++sh;
+ ++sh_exact;
+ }
+
+ BOOST_CHECK(sh == stree.filtration_simplex_range().end());
+ BOOST_CHECK(sh_exact == exact_stree.filtration_simplex_range().end());
+
+ // ----------------------
+ // Safe weighted periodic version
+ // ----------------------
+ std::cout << "Safe weighted periodic alpha complex 3d" << std::endl;
+
+ std::vector<Safe_weighted_periodic_alpha_complex_3d::Point_3> s_p_points;
+
+ for (auto p : p_points) {
+ s_p_points.push_back(Safe_weighted_periodic_alpha_complex_3d::Point_3(p[0], p[1], p[2]));
+ }
+
+ Safe_weighted_periodic_alpha_complex_3d safe_alpha_complex(s_p_points, p_weights, -1., -1., -1., 1., 1., 1.);
+
+ Gudhi::Simplex_tree<> safe_stree;
+ safe_alpha_complex.create_complex(safe_stree);
+
+ // ---------------------
+ // Compare both versions
+ // ---------------------
+ // We cannot compare as objects from dispatcher on the alpha shape is not deterministic.
+ // cf. https://github.com/CGAL/cgal/issues/3346
+ sh = stree.filtration_simplex_range().begin();
+ auto sh_safe = safe_stree.filtration_simplex_range().begin();
+
+ while (sh != stree.filtration_simplex_range().end() || sh_safe != safe_stree.filtration_simplex_range().end()) {
+ GUDHI_TEST_FLOAT_EQUALITY_CHECK(stree.filtration(*sh), safe_stree.filtration(*sh_safe), 1e-14);
+
+ std::vector<int> vh(stree.simplex_vertex_range(*sh).begin(), stree.simplex_vertex_range(*sh).end());
+ std::vector<int> safe_vh(safe_stree.simplex_vertex_range(*sh_safe).begin(),
+ safe_stree.simplex_vertex_range(*sh_safe).end());
+
+ BOOST_CHECK(vh.size() == safe_vh.size());
+ ++sh;
+ ++sh_safe;
+ }
+
+ BOOST_CHECK(sh == stree.filtration_simplex_range().end());
+ BOOST_CHECK(sh_safe == safe_stree.filtration_simplex_range().end());
+}
diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h
index 35b84d2e..b33a95a1 100644
--- a/src/common/doc/main_page.h
+++ b/src/common/doc/main_page.h
@@ -29,7 +29,9 @@
<b>Author:</b> Vincent Rouvreau<br>
<b>Introduced in:</b> GUDHI 1.3.0<br>
<b>Copyright:</b> GPL v3<br>
- <b>Requires:</b> \ref cgal &ge; 4.11.0 and \ref eigen3
+ <b>Requires:</b> \ref eigen3 and<br>
+ \ref cgal &ge; 4.7.0 for Alpha_complex<br>
+ \ref cgal &ge; 4.11.0 for Alpha_complex_3d
</td>
<td width="75%">
Alpha_complex is a simplicial complex constructed from the finite cells of a Delaunay Triangulation.<br>
@@ -38,7 +40,8 @@
values of the codimension 1 cofaces that make it not Gabriel otherwise.
All simplices that have a filtration value strictly greater than a given alpha squared value are not inserted into
the complex.<br>
- <b>User manual:</b> \ref alpha_complex - <b>Reference manual:</b> Gudhi::alpha_complex::Alpha_complex
+ <b>User manual:</b> \ref alpha_complex - <b>Reference manual:</b> Gudhi::alpha_complex::Alpha_complex and
+ Gudhi::alpha_complex::Alpha_complex_3d
</td>
</tr>
</table>