From 1079b18ed23ad20b87ec194415ab31ba3091a271 Mon Sep 17 00:00:00 2001 From: Siargey Kachanovich Date: Thu, 17 Oct 2019 21:40:00 +0200 Subject: Changed CMakeLists --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b40d506a..147956db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,7 @@ add_gudhi_module(Bitmap_cubical_complex) add_gudhi_module(Bottleneck_distance) add_gudhi_module(Cech_complex) add_gudhi_module(Contraction) +add_gudhi_module(Coxeter_triangulation) add_gudhi_module(Hasse_complex) add_gudhi_module(Persistence_representations) add_gudhi_module(Persistent_cohomology) -- cgit v1.2.3 From ec9953f0dbe0f69074f25cc95442ea0012db7d98 Mon Sep 17 00:00:00 2001 From: Siargey Kachanovich Date: Thu, 17 Oct 2019 21:40:20 +0200 Subject: Added the files from the coxeter branch --- .../concept/FunctionForImplicitManifold.h | 46 ++ .../concept/IntersectionOracle.h | 109 ++++ .../concept/SimplexInCoxeterTriangulation.h | 82 +++ .../concept/TriangulationForManifoldTracing.h | 59 +++ src/Coxeter_triangulation/doc/custom_function.png | Bin 0 -> 256301 bytes .../doc/flat_torus_with_boundary.png | Bin 0 -> 222900 bytes .../doc/intro_coxeter_triangulation.h | 146 +++++ .../doc/two_triangulations.png | Bin 0 -> 39507 bytes src/Coxeter_triangulation/example/CMakeLists.txt | 10 + .../example/manifold_tracing_custom_function.cpp | 97 ++++ .../manifold_tracing_flat_torus_with_boundary.cpp | 75 +++ .../include/gudhi/Cell_complex.h | 376 +++++++++++++ .../gudhi/Cell_complex/Hasse_diagram_cell.h | 310 +++++++++++ .../include/gudhi/Coxeter_triangulation.h | 94 ++++ .../include/gudhi/Freudenthal_triangulation.h | 239 +++++++++ .../include/gudhi/Functions/Cartesian_product.h | 171 ++++++ .../include/gudhi/Functions/Constant_function.h | 71 +++ .../include/gudhi/Functions/Embed_in_Rd.h | 106 ++++ .../include/gudhi/Functions/Function.h | 54 ++ .../include/gudhi/Functions/Function_Sm_in_Rd.h | 131 +++++ .../gudhi/Functions/Function_affine_plane_in_Rd.h | 101 ++++ .../include/gudhi/Functions/Function_chair_in_R3.h | 87 +++ .../include/gudhi/Functions/Function_iron_in_R3.h | 73 +++ .../Function_lemniscate_revolution_in_R3.h | 90 ++++ .../gudhi/Functions/Function_moment_curve_in_Rd.h | 89 ++++ .../include/gudhi/Functions/Function_torus_in_R3.h | 77 +++ .../Functions/Function_whitney_umbrella_in_R3.h | 82 +++ .../gudhi/Functions/Linear_transformation.h | 96 ++++ .../include/gudhi/Functions/Negation.h | 92 ++++ .../include/gudhi/Functions/PL_approximation.h | 125 +++++ .../include/gudhi/Functions/Translate.h | 96 ++++ .../gudhi/Functions/random_orthogonal_matrix.h | 70 +++ .../include/gudhi/IO/Mesh_medit.h | 57 ++ .../gudhi/IO/build_mesh_from_cell_complex.h | 174 ++++++ .../include/gudhi/IO/output_debug_traces_to_html.h | 589 +++++++++++++++++++++ .../include/gudhi/IO/output_meshes_to_medit.h | 181 +++++++ .../gudhi/Implicit_manifold_intersection_oracle.h | 279 ++++++++++ .../include/gudhi/Manifold_tracing.h | 307 +++++++++++ .../include/gudhi/Permutahedral_representation.h | 257 +++++++++ .../Combination_iterator.h | 101 ++++ .../Integer_combination_iterator.h | 128 +++++ .../Ordered_set_partition_iterator.h | 108 ++++ .../Permutahedral_representation_iterators.h | 288 ++++++++++ .../Permutation_iterator.h | 137 +++++ .../Set_partition_iterator.h | 137 +++++ .../Simplex_comparator.h | 64 +++ .../Permutahedral_representation/Size_range.h | 89 ++++ .../face_from_indices.h | 71 +++ .../include/gudhi/Query_result.h | 42 ++ src/Coxeter_triangulation/test/CMakeLists.txt | 33 ++ .../test/cell_complex_test.cpp | 62 +++ .../test/freud_triang_test.cpp | 104 ++++ src/Coxeter_triangulation/test/function_test.cpp | 177 +++++++ .../test/manifold_tracing_test.cpp | 62 +++ src/Coxeter_triangulation/test/oracle_test.cpp | 60 +++ src/Coxeter_triangulation/test/perm_rep_test.cpp | 66 +++ 56 files changed, 6827 insertions(+) create mode 100644 src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h create mode 100644 src/Coxeter_triangulation/concept/IntersectionOracle.h create mode 100644 src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h create mode 100644 src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h create mode 100644 src/Coxeter_triangulation/doc/custom_function.png create mode 100644 src/Coxeter_triangulation/doc/flat_torus_with_boundary.png create mode 100644 src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h create mode 100644 src/Coxeter_triangulation/doc/two_triangulations.png create mode 100644 src/Coxeter_triangulation/example/CMakeLists.txt create mode 100644 src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp create mode 100644 src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp create mode 100644 src/Coxeter_triangulation/include/gudhi/Cell_complex.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Negation.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Translate.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h create mode 100644 src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h create mode 100644 src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h create mode 100644 src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h create mode 100644 src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Query_result.h create mode 100644 src/Coxeter_triangulation/test/CMakeLists.txt create mode 100644 src/Coxeter_triangulation/test/cell_complex_test.cpp create mode 100644 src/Coxeter_triangulation/test/freud_triang_test.cpp create mode 100644 src/Coxeter_triangulation/test/function_test.cpp create mode 100644 src/Coxeter_triangulation/test/manifold_tracing_test.cpp create mode 100644 src/Coxeter_triangulation/test/oracle_test.cpp create mode 100644 src/Coxeter_triangulation/test/perm_rep_test.cpp (limited to 'src') diff --git a/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h b/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h new file mode 100644 index 00000000..2339817e --- /dev/null +++ b/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h @@ -0,0 +1,46 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef CONCEPT_COXETER_TRIANGULATION_FUNCTION_FOR_IMPLICIT_MANIFOLD_H_ +#define CONCEPT_COXETER_TRIANGULATION_FUNCTION_FOR_IMPLICIT_MANIFOLD_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief The concept FunctionForImplicitManifold describes the requirements + * for a type to implement an implicit function class used for example in Manifold_tracing. + */ +struct FunctionForImplicitManifold { + + /** \brief Value of the function at a specified point 'p'. + * @param[in] p The input point given by its Cartesian coordinates. + * Its size needs to be equal to amb_d(). + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const; + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const; + + /** \brief Returns a point on the zero-set of the function. */ + Eigen::VectorXd seed() const; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/concept/IntersectionOracle.h b/src/Coxeter_triangulation/concept/IntersectionOracle.h new file mode 100644 index 00000000..642317f2 --- /dev/null +++ b/src/Coxeter_triangulation/concept/IntersectionOracle.h @@ -0,0 +1,109 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef CONCEPT_COXETER_TRIANGULATION_INTERSECTION_ORACLE_H_ +#define CONCEPT_COXETER_TRIANGULATION_INTERSECTION_ORACLE_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief The concept IntersectionOracle describes the requirements + * for a type to implement an intersection oracle class used for example in Manifold_tracing. + * + */ +struct IntersectionOracle { + + /** \brief Returns the domain (ambient) dimension of the underlying manifold. */ + std::size_t amb_d() const; + + /** \brief Returns the codomain dimension of the underlying manifold. */ + std::size_t cod_d() const; + + /** \brief Intersection query with the relative interior of the manifold. + * + * \details The returned structure Query_result contains the boolean value + * that is true only if the intersection point of the query simplex and + * the relative interior of the manifold exists, the intersection point + * and the face of the query simplex that contains + * the intersection point. + * + * \tparam Simplex_handle The class of the query simplex. + * Needs to be a model of the concept SimplexInCoxeterTriangulation. + * \tparam Triangulation The class of the triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + * + * @param[in] simplex The query simplex. The dimension of the simplex + * should be the same as the codimension of the manifold + * (the codomain dimension of the function). + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold + * (the domain dimension of the function). + */ + template + Query_result intersects(const Simplex_handle& simplex, + const Triangulation& triangulation) const; + + /** \brief Intersection query with the boundary of the manifold. + * + * \details The returned structure Query_result contains the boolean value + * that is true only if the intersection point of the query simplex and + * the boundary of the manifold exists, the intersection point + * and the face of the query simplex that contains + * the intersection point. + * + * \tparam Simplex_handle The class of the query simplex. + * Needs to be a model of the concept SimplexInCoxeterTriangulation. + * \tparam Triangulation The class of the triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + * + * @param[in] simplex The query simplex. The dimension of the simplex + * should be the same as the codimension of the boundary of the manifold + * (the codomain dimension of the function + 1). + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold + * (the domain dimension of the function). + */ + template + Query_result intersects_boundary(const Simplex_handle& simplex, + const Triangulation& triangulation) const; + + /** \brief Returns true if the input point lies inside the piecewise-linear + * domain induced by the given ambient triangulation that defines the relative + * interior of the piecewise-linear approximation of the manifold. + * + * @param p The input point. Needs to have the same dimension as the ambient + * dimension of the manifold (the domain dimension of the function). + * @param triangulation The ambient triangulation. Needs to have the same + * dimension as the ambient dimension of the manifold + * (the domain dimension of the function). + */ + template + bool lies_in_domain(const Eigen::VectorXd& p, + const Triangulation& triangulation) const { + Eigen::VectorXd pl_p = make_pl_approximation(domain_fun_, triangulation)(p); + return pl_p(0) < 0; + } + + /** \brief Returns the function that defines the interior of the manifold */ + const Function_& function() const; + +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h b/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h new file mode 100644 index 00000000..c1562066 --- /dev/null +++ b/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h @@ -0,0 +1,82 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef CONCEPT_COXETER_TRIANGULATION_SIMPLEX_IN_COXETER_TRIANGULATION_H_ +#define CONCEPT_COXETER_TRIANGULATION_SIMPLEX_IN_COXETER_TRIANGULATION_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief The concept SimplexInCoxeterTriangulation describes the requirements + * for a type to implement a representation of simplices in Freudenthal_triangulation + * or in Coxeter_triangulation. + */ +struct SimplexInCoxeterTriangulation { + + /** \brief Type of the vertex. */ + typedef Vertex_ Vertex; + + /** \brief Type of the ordered partition. */ + typedef Ordered_set_partition_ OrderedSetPartition; + + /** \brief Dimension of the simplex. */ + unsigned dimension() const; + + /** \brief Type of a range of vertices, each of type Vertex. */ + typedef Vertex_range; + + /** \brief Returns a range of vertices of the simplex. + */ + Vertex_range vertex_range() const; + + /** \brief Type of a range of faces, each of type that + * is a model of the concept SimplexInCoxeterTriangulation. + */ + typedef Face_range; + + /** \brief Returns a range of permutahedral representations of k-dimensional faces + * of the simplex for some given integer parameter 'k'. + */ + Face_range face_range(std::size_t k) const; + + /** \brief Returns a range of permutahedral representations of facets of the simplex. + * The dimension of the simplex must be strictly positive. + */ + Face_range facet_range() const; + + /** \brief Type of a range of cofaces, each of type that + * is a model of the concept SimplexInCoxeterTriangulation. + */ + typedef Coface_range; + + /** \brief Returns a range of permutahedral representations of k-dimensional cofaces + * of the simplex for some given integer parameter 'k'. + */ + Coface_range coface_range(std::size_t k) const; + + /** \brief Returns a range of permutahedral representations of cofacets of the simplex. + * The dimension of the simplex must be strictly different from the ambient dimension. + */ + Coface_range cofacet_range() const; + + /** \brief Returns true, if the simplex is a face of other simplex. */ + bool is_face_of(const Permutahedral_representation& other) const; + +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h b/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h new file mode 100644 index 00000000..e64d3b97 --- /dev/null +++ b/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h @@ -0,0 +1,59 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef CONCEPT_COXETER_TRIANGULATION_TRIANGULATION_FOR_MANIFOLD_TRACING_H_ +#define CONCEPT_COXETER_TRIANGULATION_TRIANGULATION_FOR_MANIFOLD_TRACING_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief The concept TriangulationForManifoldTracing describes the requirements + * for a type to implement a triangulation class used for example in Manifold_tracing. + */ +struct TriangulationForManifoldTracing { + + /** \brief Type of the simplices in the triangulation. + * Needs to be a model of the concept SimplexInCoxeterTriangulation. */ + typedef Simplex_handle; + + /** \brief Type of the vertices in the triangulation. + * Needs to be a random-access range of integer values. */ + typedef Vertex_handle; + + /** \brief Returns the permutahedral representation of the simplex in the + * triangulation that contains a given query point 'p'. + * \tparam Point_d A class that represents a point in d-dimensional Euclidean space. + * The coordinates should be random-accessible. Needs to provide the method size(). + * @param[in] point The query point. + */ + template + Simplex_handle locate_point(const Point_d& point) const; + + /** \brief Returns the Cartesian coordinates of the given vertex 'v'. + * @param[in] v The input vertex. + */ + Eigen::VectorXd cartesian_coordinates(const Vertex_handle& v) const; + + /** \brief Returns the Cartesian coordinates of the barycenter of a given simplex 's'. + * @param[in] s The input simplex given by permutahedral representation. + */ + Eigen::VectorXd barycenter(const Simplex_handle& s) const; + +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/doc/custom_function.png b/src/Coxeter_triangulation/doc/custom_function.png new file mode 100644 index 00000000..8bb8ba9a Binary files /dev/null and b/src/Coxeter_triangulation/doc/custom_function.png differ diff --git a/src/Coxeter_triangulation/doc/flat_torus_with_boundary.png b/src/Coxeter_triangulation/doc/flat_torus_with_boundary.png new file mode 100644 index 00000000..338b39fe Binary files /dev/null and b/src/Coxeter_triangulation/doc/flat_torus_with_boundary.png differ diff --git a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h new file mode 100644 index 00000000..80ca5b37 --- /dev/null +++ b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h @@ -0,0 +1,146 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef DOC_TANGENTIAL_COMPLEX_INTRO_COXETER_TRIANGULATION_H_ +#define DOC_TANGENTIAL_COMPLEX_INTRO_COXETER_TRIANGULATION_H_ + +// needs namespaces for Doxygen to link on classes +namespace Gudhi { +namespace tangential_complex { + +/** \defgroup coxeter_triangulation Coxeter triangulation + +\author Siargey Kachanovich + +@{ + +\section overview Module overview + +Coxeter triangulation module is designed to provide tools for constructing a piecewise-linear approximation of an \f$m\f$-dimensional smooth manifold embedded in \f$ \mathbb{R}^d \f$ using an ambient triangulation. +For a more detailed description of the module see \cite KachanovichThesis. + +\section manifoldtracing Manifold tracing algorithm +The central piece of the module is the manifold tracing algorithm represented by the class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing". +The manifold tracing algorithm takes as input a manifold of some dimension \f$m\f$ embedded in \f$\mathbb{R}^d\f$ represented by an intersection oracle (see Section \ref intersectionoracle "Intersection oracle"), a point on the manifold and an ambient triangulation (see Section \ref ambienttriangulations "Ambient triangulations"). +The output consists of one map (or two maps in the case of manifolds with boundary) from the \f$(d-m)\f$-dimensional (and \f$(d-m+1)\f$-dimensional in the case of manifolds with boundary) simplices in the ambient triangulation that intersect the manifold to their intersection points. +From this output, it is possible to construct the cell complex of the piecewise-linear approximation of the input manifold. + +There are two methods that execute the manifold tracing algorithm: the method \ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" for manifolds without boundary and \ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" for manifolds with boundary. +The algorithm functions as follows. +It starts at the specified seed points and inserts a \f$(d-m)\f$-dimensional simplices nearby each seed point that intersect the manifold into the output. +Starting from this simplex, the algorithm propagates the search for other \f$(d-m)\f$-dimensional simplices that intersect the manifold by marching from a simplex to neighbouring simplices via their common cofaces. + +This class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing" has one template parameter Triangulation_ which specifies the ambient triangulation which is used by the algorithm. +The template type Triangulation_ has to be a model of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". + +The module also provides two static methods: \ref Gudhi::coxeter_triangulation::manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" for manifolds without boundary and \ref manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" for manifolds with boundary. +For these static methods it is not necessary to specify any template arguments. + +\section ambienttriangulations Ambient triangulations + +The ambient triangulations supported by the manifold tracing algorithm have to be models of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". +This module offers two such models: the class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and the derived class \ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation". + +Both these classes encode affine transformations of the so-called Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. +The Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ is defined as the simplicial subdivision of the unit cubic partition of \f$\mathbb{R}^d\f$. +Each simplex is encoded using the permutahedral representation, which consists of an integer-valued vector \f$y\f$ that positions the simplex in a specific cube in the cubical partition and an ordered partition \f$\omega\f$ of the set \f$\{1,\ldots,d+1\}\f$, which positions the simplex in the simplicial subdivision of the cube. +The default constructor \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation::Freudenthal_triangulation(std::size_t) "Freudenthal_triangulation(d)" the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. +The class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" can also encode any affine transformation of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ using an invertible matrix \f$\Lambda\f$ and an offset vector \f$b\f$ that can be specified in the constructor and which can be changed using the methods change_matrix and change_offset. +The class \ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation" is derived from \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and its default constructor \ref Gudhi::coxeter_triangulation::Coxeter_triangulation::Coxeter_triangulation(std::size_t) "Coxeter_triangulation(d)" builds a Coxeter triangulation of type \f$\tilde{A}_d\f$, which has the best simplex quality of all linear transformations of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. + +\image html two_triangulations.png "On the left: Coxeter triangulation of type \f$\tilde{A}_2\f$. On the right: Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$." + + +\section intersectionoracle Intersection oracle + +The input \f$m\f$-dimensional manifold in \f$\mathbb{R}^d\f$ needs to be given via the intersection oracle that answers the following query: given a \f$(d-m)\f$-dimensional simplex, does it intersect the manifold? +The concept \ref Gudhi::coxeter_triangulation::IntersectionOracle "IntersectionOracle" describes all requirements for an intersection oracle class to be compatible with the class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing". +This module offers one model of the concept \ref Gudhi::coxeter_triangulation::IntersectionOracle "IntersectionOracle", which is the class \ref Gudhi::coxeter_triangulation::Implicit_manifold_intersection_oracle "Implicit_manifold_intersection_oracle". +This class represents a manifold given as the zero-set of a specified function \f$F: \mathbb{R}^d \rightarrow \mathbb{R}^{d-m}\f$. +The function \f$F\f$ is given by a class which is a model of the concept \ref Gudhi::coxeter_triangulation::FunctionForImplicitManifold "FunctionForImplicitManifold". +There are multiple function classes that are already implemented in this module. + +\li \ref Gudhi::coxeter_triangulation::Constant_function(std::size_t, std::size_t, Eigen::VectorXd) "Constant_function(d,k,v)" defines a constant function \f$F\f$ such that for all \f$x \in \mathbb{R}^d\f$, we have \f$F(x) = v \in \mathbb{R}^k\f$. + The class Constant_function does not define an implicit manifold, but is useful as the domain function when defining boundaryless implicit manifolds. +\li \ref Gudhi::coxeter_triangulation::Function_affine_plane_in_Rd(N,b) "Function_affine_plane_in_Rd(N,b)" defines an \f$m\f$-dimensional implicit affine plane in the \f$d\f$-dimensional Euclidean space given by a normal matrix \f$N\f$ and an offset vector \f$b\f$. +\li \ref Gudhi::coxeter_triangulation::Function_Sm_in_Rd(r,m,d,center) "Function_Sm_in_Rd(r,m,d,center)" defines an \f$m\f$-dimensional implicit sphere embedded in the \f$d\f$-dimensional Euclidean space of radius \f$r\f$ centered at the point 'center'. +\li \ref Gudhi::coxeter_triangulation::Function_moment_curve_in_Rd(r,d) "Function_moment_curve(r,d)" defines the moment curve in the \f$d\f$-dimensional Euclidean space of radius \f$r\f$ given as the parameterized curve (but implemented as an implicit curve): + \f[ (r, rt, \ldots, rt^{d-1}) \in \mathbb{R}^d,\text{ for $t \in \mathbb{R}$.} \f] +\li \ref Gudhi::coxeter_triangulation::Function_torus_in_R3(R, r) "Function_torus_in_R3(R, r)" defines a torus in \f$\mathbb{R}^3\f$ with the outer radius \f$R\f$ and the inner radius, given by the equation: + \f[ z^2 + (\sqrt{x^2 + y^2} - r)^2 - R^2 = 0. \f] +\li \ref Gudhi::coxeter_triangulation::Function_chair_in_R3(a, b, k) "Function_chair_in_R3(a, b, k)" defines the ``Chair'' surface in \f$\mathbb{R}^3\f$ defined by the equation: + \f[ (x^2 + y^2 + z^2 - ak^2)^2 - b((z-k)^2 - 2x^2)((z+k)^2 - 2y^2) = 0. \f] +\li \ref Gudhi::coxeter_triangulation::Function_iron_in_R3() "Function_iron_in_R3()" defines the ``Iron'' surface in \f$\mathbb{R}^3\f$ defined by the equation: + \f[ \frac{-x^6-y^6-z^6}{300} + \frac{xy^2z}{2.1} + y^2 + (z-2)^2 = 1. \f] +\li \ref Gudhi::coxeter_triangulation::Function_lemniscate_revolution_in_R3(a) "Function_lemniscate_revolution_in_R3(a)" defines a revolution surface in \f$\mathbb{R}^3\f$ obtained from the lemniscate of Bernoulli defined by the equation: + \f[ (x^2 + y^2 + z^2)^2 - 2a^2(x^2 - y^2 - z^2) = 0. \f] +\li \ref Gudhi::coxeter_triangulation::Function_whitney_umbrella_in_R3() "Function_whitney_umbrella_in_R3()" defines the Whitney umbrella surface in \f$\mathbb{R}^3\f$ defined by the equation: + \f[ x^2 - y^2z = 0. \f] + +The base function classes above can be composed or modified into new functions using the following classes and methods: + +\li \ref Gudhi::coxeter_triangulation::Cartesian_product "Cartesian_product(functions...)" expresses the Cartesian product \f$F_1^{-1}(0) \times \ldots \times F_k^{-1}(0)\f$ of multiple implicit manifolds as an implicit manifold. + For convenience, a static function \ref Gudhi::coxeter_triangulation::make_product_function() "make_product_function(functions...)" is provided that takes a pack of function-typed objects as the argument. +\li \ref Gudhi::coxeter_triangulation::Embed_in_Rd "Embed_in_Rd(F, d)" expresses an implicit manifold given as the zero-set of a function \f$F\f$ embedded in a higher-dimensional Euclidean space \f$\mathbb{R}^d\f$. + For convenience, a static function \ref Gudhi::coxeter_triangulation::make_embedding() "make_embedding(F, d)" is provided. +\li \ref Gudhi::coxeter_triangulation::Linear_transformation "Linear_transformation(F, M)" applies a linear transformation given by a matrix \f$M\f$ on an implicit manifold given as the zero-set of the function \f$F\f$. + For convenience, a static function \ref Gudhi::coxeter_triangulation::linear_transformation() "linear_transformation(F, M)" is provided. +\li \ref Gudhi::coxeter_triangulation::Translate "Translate(F, v)" translates an implicit manifold given as the zero-set of ththe function \f$F\f$ by a vector \f$v\f$. + For convenience, a static function \ref Gudhi::coxeter_triangulation::translate(F, v) "translate(F, v)" is provided. +\li \ref Gudhi::coxeter_triangulation::Negation() "Negation(F)" defines the negative of the given function \f$F\f$. + This class is useful to define the complementary of a given domain, when defining a manifold with boundary. + For convenience, a static function \ref Gudhi::coxeter_triangulation::negation() "negation(F)" is provided. +\li \ref Gudhi::coxeter_triangulation::PL_approximation "PL_approximation(F, T)" defines a piecewise-linear approximation of a given function \f$F\f$ induced by an ambient triangulation \f$T\f$. + The purpose of this class is to define a piecewise-linear function that is compatible with the requirements for the domain function \f$D\f$ when defining a manifold with boundary. + For convenience, a static function \ref Gudhi::coxeter_triangulation::make_pl_approximation() "make_pl_approximation(F, T)" is provided. + The type of \f$T\f$ is required to be a model of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". + +\section cellcomplex Cell complex construction + +The output of the manifold tracing algorithm can be transformed into the Hasse diagram of a cell complex that approximates the input manifold using the class \ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex". +The type of the cells in the Hasse diagram is \ref Gudhi::Hasse_diagram::Hasse_diagram_cell "Hasse_cell" provided by the module Hasse diagram. +The cells in the cell complex given by an object of the class \ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex" are accessed through several maps that are accessed through the following methods. + +\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::interior_simplex_cell_maps() "interior_simplex_cell_maps()" returns a vector of maps from the cells of various dimensions in the interior of the cell complex to the permutahedral representations of the corresponding simplices in the ambient triangulation. +Each individual map for cells of a specific dimension \f$l\f$ can be accessed using the method \ref Gudhi::coxeter_triangulation::Cell_complex::interior_simplex_cell_map() "interior_simplex_cell_map(l)". +\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::boundary_simplex_cell_maps() "boundary_simplex_cell_maps()" returns a vector of maps from the cells of various dimensions on the boundary of the cell complex to the permutahedral representations of the corresponding simplices in the ambient triangulation. +Each individual map for cells of a specific dimension \f$l\f$ can be accessed using the method \ref Gudhi::coxeter_triangulation::Cell_complex::boundary_simplex_cell_map() "boundary_simplex_cell_map(l)". +\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_simplex_map() "cell_simplex_map()" returns a map from the cells in the cell complex to the permutahedral representations of the corresponding simplices in the ambient triangulation. +\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_point_map() "cell_point_map()" returns a map from the vertex cells in the cell complex to their Cartesian coordinates. + +\section example Examples + +Here is an example of constructing a piecewise-linear approximation of a flat torus embedded in \f$\mathbb{R}^4\f$, rotated by a random rotation in \f$\mathbb{R}^4\f$ and cut by a hyperplane. + +\include Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp + +The output in medit is: + +\image html "flat_torus_with_boundary.png" "Output from the example of a flat torus with boundary" + +In the following more complex example, we define a custom function for the implicit manifold. + +\include Coxeter_triangulation/manifold_tracing_custom_function.cpp + +The output in medit looks as follows: + +\image html "custom_function.png" "Output from the example with a custom function" + + + */ +/** @} */ // end defgroup coxeter_triangulation + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif // DOC_TANGENTIAL_COMPLEX_INTRO_TANGENTIAL_COMPLEX_H_ diff --git a/src/Coxeter_triangulation/doc/two_triangulations.png b/src/Coxeter_triangulation/doc/two_triangulations.png new file mode 100644 index 00000000..055d93e7 Binary files /dev/null and b/src/Coxeter_triangulation/doc/two_triangulations.png differ diff --git a/src/Coxeter_triangulation/example/CMakeLists.txt b/src/Coxeter_triangulation/example/CMakeLists.txt new file mode 100644 index 00000000..345949ae --- /dev/null +++ b/src/Coxeter_triangulation/example/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 2.6) +project(Coxeter_triangulation_example) + +add_executable ( Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example manifold_tracing_flat_torus_with_boundary.cpp ) +add_executable ( Coxeter_triangulation_manifold_tracing_custom_function_example manifold_tracing_custom_function.cpp ) + +if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${TBB_LIBRARIES}) + target_link_libraries(Coxeter_triangulation_manifold_tracing_custom_function_example ${TBB_LIBRARIES}) +endif() diff --git a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp new file mode 100644 index 00000000..7a89a32f --- /dev/null +++ b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp @@ -0,0 +1,97 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +/* A definition of a function that defines a 2d surface embedded in R^4, but that normally + * lives on a complex projective plane. + * In terms of harmonic coordinates [x:y:z] of points on the complex projective plane, + * the equation of the manifold is x^3*y + y^3*z + z^3*x = 0. + * The embedding consists of restricting the manifold to the affine subspace z = 1. + */ +struct Function_surface_on_CP2_in_R4 : public Function { + + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + // The real and imaginary parts of the variables x and y + double xr = p(0), xi = p(1), yr = p(2), yi = p(3); + Eigen::VectorXd result(cod_d()); + + // Squares and cubes of real and imaginary parts used in the computations + double + xr2 = xr*xr, xi2 = xi*xi, yr2 = yr*yr, yi2 = yi*yi, + xr3 = xr2*xr, xi3 = xi2*xi, yr3 = yr2*yr, yi3 = yi2*yi; + + // The first coordinate of the output is Re(x^3*y + y^3 + x) + result(0) = + xr3*yr - 3*xr*xi2*yr - 3*xr2*xi*yi + xi3*yi + + yr3 - 3*yr*yi2 + xr; + // The second coordinate of the output is Im(x^3*y + y^3 + x) + result(1) = + 3*xr2*xi*yr + xr3*yi - 3*xr*xi2*yi - xi3*yr + + 3*yr2*yi - yi3 + xi; + return result; + } + + std::size_t amb_d() const {return 4;}; + std::size_t cod_d() const {return 2;}; + + Eigen::VectorXd seed() const { + Eigen::VectorXd result = Eigen::VectorXd::Zero(4); + return result; + } + + Function_surface_on_CP2_in_R4() {} +}; + +int main(int argc, char** argv) { + + // The function for the (non-compact) manifold + Function_surface_on_CP2_in_R4 fun; + + // Seed of the function + Eigen::VectorXd seed = fun.seed(); + + // Creating the function that defines the boundary of a compact region on the manifold + double radius = 3.0; + Function_Sm_in_Rd fun_sph(radius, 3, seed); + + // Defining the intersection oracle + auto oracle = make_oracle(fun, fun_sph); + + // Define a Coxeter triangulation scaled by a factor lambda. + // The triangulation is translated by a random vector to avoid violating the genericity hypothesis. + double lambda = 0.2; + Coxeter_triangulation<> cox_tr(oracle.amb_d()); + cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); + cox_tr.change_matrix(lambda * cox_tr.matrix()); + + // Manifold tracing algorithm + using MT = Manifold_tracing >; + using Out_simplex_map = typename MT::Out_simplex_map; + std::vector seed_points(1, seed); + Out_simplex_map interior_simplex_map, boundary_simplex_map; + manifold_tracing_algorithm(seed_points, cox_tr, oracle, interior_simplex_map, boundary_simplex_map); + + // Constructing the cell complex + std::size_t intr_d = oracle.amb_d() - oracle.cod_d(); + Cell_complex cell_complex(intr_d); + cell_complex.construct_complex(interior_simplex_map, boundary_simplex_map); + + // Output the cell complex to a file readable by medit + output_meshes_to_medit(3, + "manifold_on_CP2_with_boundary", + build_mesh_from_cell_complex(cell_complex, + Configuration(true, true, true, 1, 5, 3), + Configuration(true, true, true, 2, 13, 14))); + return 0; +} diff --git a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp new file mode 100644 index 00000000..c83fdd5d --- /dev/null +++ b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp @@ -0,0 +1,75 @@ +// workaround for the annoying boost message in boost 1.69 +#define BOOST_PENDING_INTEGER_LOG2_HPP +#include +// end workaround + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +int main(int argc, char** argv) { + + // Creating a circle S1 in R2 of specified radius + double radius = 1.0; + Function_Sm_in_Rd fun_circle(radius, 1); + + // Creating a flat torus S1xS1 in R4 from two circle functions + auto fun_flat_torus = make_product_function(fun_circle, fun_circle); + + // Apply a random rotation in R4 + auto matrix = random_orthogonal_matrix(4); + auto fun_flat_torus_rotated = make_linear_transformation(fun_flat_torus, matrix); + + // Computing the seed of the function fun_flat_torus + Eigen::VectorXd seed = fun_flat_torus_rotated.seed(); + + // Defining a domain function that defines the boundary, which is a hyperplane passing by the origin and orthogonal to x. + Eigen::MatrixXd normal_matrix = Eigen::MatrixXd::Zero(4, 1); + for (std::size_t i = 0; i < 4; i++) + normal_matrix(i,0) = -seed(i); + Function_affine_plane_in_Rd fun_bound(normal_matrix, -seed/2); + + // Defining the intersection oracle + auto oracle = make_oracle(fun_flat_torus_rotated, fun_bound); + + // Define a Coxeter triangulation scaled by a factor lambda. + // The triangulation is translated by a random vector to avoid violating the genericity hypothesis. + double lambda = 0.2; + Coxeter_triangulation<> cox_tr(oracle.amb_d()); + cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); + cox_tr.change_matrix(lambda * cox_tr.matrix()); + + // Manifold tracing algorithm + using MT = Manifold_tracing >; + using Out_simplex_map = typename MT::Out_simplex_map; + std::vector seed_points(1, seed); + Out_simplex_map interior_simplex_map, boundary_simplex_map; + manifold_tracing_algorithm(seed_points, cox_tr, oracle, interior_simplex_map, boundary_simplex_map); + + // Constructing the cell complex + std::size_t intr_d = oracle.amb_d() - oracle.cod_d(); + Cell_complex cell_complex(intr_d); + cell_complex.construct_complex(interior_simplex_map, boundary_simplex_map); + + // Output the cell complex to a file readable by medit + output_meshes_to_medit(3, + "flat_torus_with_boundary", + build_mesh_from_cell_complex(cell_complex, + Configuration(true, true, true, 1, 5, 3), + Configuration(true, true, true, 2, 13, 14))); + + return 0; +} diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h new file mode 100644 index 00000000..51109bcb --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -0,0 +1,376 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef CELL_COMPLEX_H_ +#define CELL_COMPLEX_H_ + +#include + +#include +#include +#include // for Hasse_diagram_persistence.h + +#include // for Hasse_cell + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \ingroup coxeter_triangulation + */ + +/** \class Cell_complex + * \brief A class that constructs the cell complex from the output provided by the class + * Gudhi::Manifold_tracing. + * + * \tparam Out_simplex_map_ The type of a map from a simplex type that is a + * model of SimplexInCoxeterTriangulation to Eigen::VectorXd. + * + * \ingroup coxeter_triangulation + */ +template +class Cell_complex { +public: + + /** \brief Type of a simplex in the ambient triangulation. + * Is a model of the concept SimplexInCoxeterTriangulation. + */ + typedef typename Out_simplex_map_::key_type Simplex_handle; + /** \brief Type of a cell in the cell complex. + * Always is Gudhi::Hasse_cell from the Hasse diagram module. + * The additional information is the boolean that is true if and only if the cell lies + * on the boundary. + */ + typedef Gudhi::Hasse_diagram::Hasse_diagram_cell Hasse_cell; + /** \brief Type of a map from permutahedral representations of simplices in the + * ambient triangulation to the corresponding cells in the cell complex of some + * specific dimension. + */ + typedef std::map > Simplex_cell_map; + /** \brief Type of a vector of maps from permutahedral representations of simplices in the + * ambient triangulation to the corresponding cells in the cell complex of various dimensions. + */ + typedef std::vector Simplex_cell_maps; + + /** \brief Type of a map from cells in the cell complex to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + */ + typedef std::map Cell_simplex_map; + + /** \brief Type of a map from vertex cells in the cell complex to the permutahedral representations + * of their Cartesian coordinates. + */ + typedef std::map Cell_point_map; + +private: + + Hasse_cell* insert_cell(const Simplex_handle& simplex, + std::size_t cell_d, + bool is_boundary) { + Simplex_cell_maps& simplex_cell_maps + = (is_boundary? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + CC_detail_list& cc_detail_list = + (is_boundary? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); + cc_detail_list.emplace_back(CC_detail_info(simplex)); +#endif + Simplex_cell_map& simplex_cell_map = simplex_cell_maps[cell_d]; + auto map_it = simplex_cell_map.find(simplex); + if (map_it == simplex_cell_map.end()) { + hasse_cells_.push_back(new Hasse_cell(is_boundary, cell_d)); + Hasse_cell* new_cell = hasse_cells_.back(); + simplex_cell_map.emplace(std::make_pair(simplex, new_cell)); + cell_simplex_map_.emplace(std::make_pair(new_cell, simplex)); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + cc_detail_list.back().status_ = CC_detail_info::Result_type::inserted; +#endif + return new_cell; + } +#ifdef GUDHI_COX_OUTPUT_TO_HTML + CC_detail_info& cc_info = cc_detail_list.back(); + cc_info.trigger_ = to_string(map_it->first); + cc_info.status_ = CC_detail_info::Result_type::self; +#endif + return map_it->second; + } + + void expand_level(std::size_t cell_d) { + bool is_manifold_with_boundary = boundary_simplex_cell_maps_.size() > 0; + for (auto& sc_pair: interior_simplex_cell_maps_[cell_d - 1]) { + const Simplex_handle& simplex = sc_pair.first; + Hasse_cell* cell = sc_pair.second; + for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d)) { + Hasse_cell* new_cell = insert_cell(coface, cell_d, false); + new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + } + } + + if (is_manifold_with_boundary) { + for (auto& sc_pair: boundary_simplex_cell_maps_[cell_d - 1]) { + const Simplex_handle& simplex = sc_pair.first; + Hasse_cell* cell = sc_pair.second; + if (cell_d != intr_d_) + for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d + 1)) { + Hasse_cell* new_cell = insert_cell(coface, cell_d, true); + new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + } + auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex); + if (map_it == interior_simplex_cell_maps_[cell_d].end()) + std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n"; + else { + Hasse_cell* i_cell = map_it->second; + i_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + } + } + } + } + + void construct_complex_(const Out_simplex_map_& out_simplex_map) { +#ifdef GUDHI_COX_OUTPUT_TO_HTML + cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); +#endif + for (auto& os_pair: out_simplex_map) { + const Simplex_handle& simplex = os_pair.first; + const Eigen::VectorXd& point = os_pair.second; + Hasse_cell* new_cell = insert_cell(simplex, 0, false); + cell_point_map_.emplace(std::make_pair(new_cell, point)); + } + for (std::size_t cell_d = 1; + cell_d < interior_simplex_cell_maps_.size() && + !interior_simplex_cell_maps_[cell_d - 1].empty(); + ++cell_d) { + expand_level(cell_d); + } + } + + void construct_complex_(const Out_simplex_map_& interior_simplex_map, + const Out_simplex_map_& boundary_simplex_map) { +#ifdef GUDHI_COX_OUTPUT_TO_HTML + cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); + cc_boundary_summary_lists.resize(boundary_simplex_cell_maps_.size()); + cc_boundary_prejoin_lists.resize(boundary_simplex_cell_maps_.size()); + cc_boundary_detail_lists.resize(boundary_simplex_cell_maps_.size()); +#endif + for (auto& os_pair: boundary_simplex_map) { + const Simplex_handle& simplex = os_pair.first; + const Eigen::VectorXd& point = os_pair.second; + Hasse_cell* new_cell = insert_cell(simplex, 0, true); + cell_point_map_.emplace(std::make_pair(new_cell, point)); + } + for (auto& os_pair: interior_simplex_map) { + const Simplex_handle& simplex = os_pair.first; + const Eigen::VectorXd& point = os_pair.second; + Hasse_cell* new_cell = insert_cell(simplex, 0, false); + cell_point_map_.emplace(std::make_pair(new_cell, point)); + } +#ifdef GUDHI_COX_OUTPUT_TO_HTML + for (const auto& sc_pair: interior_simplex_cell_maps_[0]) + cc_interior_summary_lists[0].push_back(CC_summary_info(sc_pair)); + for (const auto& sc_pair: boundary_simplex_cell_maps_[0]) + cc_boundary_summary_lists[0].push_back(CC_summary_info(sc_pair)); +#endif + + for (std::size_t cell_d = 1; + cell_d < interior_simplex_cell_maps_.size() && + !interior_simplex_cell_maps_[cell_d - 1].empty(); + ++cell_d) { + expand_level(cell_d); + +#ifdef GUDHI_COX_OUTPUT_TO_HTML + for (const auto& sc_pair: interior_simplex_cell_maps_[cell_d]) + cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); + if (cell_d < boundary_simplex_cell_maps_.size()) + for (const auto& sc_pair: boundary_simplex_cell_maps_[cell_d]) + cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); +#endif + } + } + +public: + + /** + * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold + * without boundary embedded in the \f$ d \f$-dimensional Euclidean space + * from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + */ + void construct_complex(const Out_simplex_map_& out_simplex_map) { + interior_simplex_cell_maps_.resize(intr_d_ + 1); + if (!out_simplex_map.empty()) + cod_d_ = out_simplex_map.begin()->first.dimension(); + construct_complex_(out_simplex_map); + } + + /** + * \brief Constructs the skeleton of the cell complex that approximates + * an \f$m\f$-dimensional manifold without boundary embedded + * in the \f$d\f$-dimensional Euclidean space + * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + * \param[in] limit_dimension The dimension of the constructed skeleton. + */ + void construct_complex(const Out_simplex_map_& out_simplex_map, + std::size_t limit_dimension) { + interior_simplex_cell_maps_.resize(limit_dimension + 1); + if (!out_simplex_map.empty()) + cod_d_ = out_simplex_map.begin()->first.dimension(); + construct_complex_(out_simplex_map); + } + + /** + * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold + * with boundary embedded in the \f$ d \f$-dimensional Euclidean space + * from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ + * in the ambient triangulation that intersect the boundary of the manifold + * to the intersection points. + */ + void construct_complex(const Out_simplex_map_& interior_simplex_map, + const Out_simplex_map_& boundary_simplex_map) { + interior_simplex_cell_maps_.resize(intr_d_ + 1); + boundary_simplex_cell_maps_.resize(intr_d_); + if (!interior_simplex_map.empty()) + cod_d_ = interior_simplex_map.begin()->first.dimension(); + construct_complex_(interior_simplex_map, boundary_simplex_map); + } + + /** + * \brief Constructs the skeleton of the cell complex that approximates + * an \f$m\f$-dimensional manifold with boundary embedded + * in the \f$d\f$-dimensional Euclidean space + * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ + * in the ambient triangulation that intersect the boundary of the manifold + * to the intersection points. + * \param[in] limit_dimension The dimension of the constructed skeleton. + */ + void construct_complex(const Out_simplex_map_& interior_simplex_map, + const Out_simplex_map_& boundary_simplex_map, + std::size_t limit_dimension) { + interior_simplex_cell_maps_.resize(limit_dimension + 1); + boundary_simplex_cell_maps_.resize(limit_dimension); + if (!interior_simplex_map.empty()) + cod_d_ = interior_simplex_map.begin()->first.dimension(); + construct_complex_(interior_simplex_map, boundary_simplex_map); + } + + /** + * \brief Returns the dimension of the cell complex. + */ + std::size_t intrinsic_dimension() const { + return intr_d_; + } + + /** + * \brief Returns a vector of maps from the cells of various dimensions in the interior + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + */ + const Simplex_cell_maps& interior_simplex_cell_maps() const { + return interior_simplex_cell_maps_; + } + + /** + * \brief Returns a vector of maps from the cells of various dimensions on the boundary + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + */ + const Simplex_cell_maps& boundary_simplex_cell_maps() const { + return boundary_simplex_cell_maps_; + } + + /** + * \brief Returns a map from the cells of a given dimension in the interior + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + * + * \param[in] cell_d The dimension of the cells. + */ + const Simplex_cell_map& interior_simplex_cell_map(std::size_t cell_d) const { + return interior_simplex_cell_maps_[cell_d]; + } + + /** + * \brief Returns a map from the cells of a given dimension on the boundary + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + * + * \param[in] cell_d The dimension of the cells. + */ + const Simplex_cell_map& boundary_simplex_cell_map(std::size_t cell_d) const { + return boundary_simplex_cell_maps_[cell_d]; + } + + /** + * \brief Returns a map from the cells in the cell complex of type Gudhi::Hasse_cell + * to the permutahedral representations of the corresponding simplices in the + * ambient triangulation. + */ + const Cell_simplex_map& cell_simplex_map() const { + return cell_simplex_map_; + } + + /** + * \brief Returns a map from the vertex cells in the cell complex of type Gudhi::Hasse_cell + * to their Cartesian coordinates. + */ + const Cell_point_map& cell_point_map() const { + return cell_point_map_; + } + + /** + * \brief Conxtructor for the class Cell_complex. + * + * \param[in] intrinsic_dimension The dimension of the cell complex. + */ + Cell_complex(std::size_t intrinsic_dimension) + : intr_d_(intrinsic_dimension) {} + + ~Cell_complex() { + for (Hasse_cell* hs_ptr: hasse_cells_) + delete hs_ptr; + } + +private: + std::size_t intr_d_, cod_d_; + Simplex_cell_maps interior_simplex_cell_maps_, boundary_simplex_cell_maps_; + Cell_simplex_map cell_simplex_map_; + Cell_point_map cell_point_map_; + std::vector hasse_cells_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h new file mode 100644 index 00000000..bd730368 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -0,0 +1,310 @@ +/* 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): Pawel Dlotko + * + * Copyright (C) 2017 Swansea University UK + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + + + +#ifndef HASSE_DIAGRAM_CELL_H +#define HASSE_DIAGRAM_CELL_H + + +namespace Gudhi { +namespace Hasse_diagram { + + +template < typename Cell_type > class Hasse_diagram; + + + +/** + * \class Hasse_diagram_cell + * \brief Data structure to store a cell in a Hasse diagram. + * + * \ingroup Hasse_diagram + * + * \details + * This is a data structure to store a cell in a general Hasse diagram data structure. It store the following information about the cell: + * References to boundary and coBoundary elements, dimension of a cell and its filtration. It also allow to store any additional + * information of a type Additional_information which is a template parameter of the class (set by default to void). + * + * Please refer to \ref Hasse_diagram for examples. + * + * The complex is a template class requiring the following parameters: + * Incidence_type_ - determine the type of incidence coefficients. Use integers in most general case. + * Filtration_type_ - type of filtration of cells. + * Additional_information_ (set by default to void) - allows to store any + * additional information in the cells of Hasse diagrams. + * + */ +template +class Hasse_diagram_cell +{ +public: + typedef Incidence_type_ Incidence_type; + typedef Filtration_type_ Filtration_type; + typedef Additional_information_ Additional_information; + using Cell_range = std::vector< std::pair >; + + /** + * Default constructor. + **/ + Hasse_diagram_cell():dimension(0),position(0),deleted_(false){} + + /** + * Constructor of a cell of dimension dim. + **/ + Hasse_diagram_cell( int dim ):dimension(dim),position(0),deleted_(false){} + + /** + * Constructor of a cell of dimension dim. + **/ + Hasse_diagram_cell( int dim , Filtration_type filt_ ):dimension(dim),position(0),deleted_(false),filtration(filt_){} + + /** + * Constructor of a cell of dimension dim with a given boundary. + **/ + Hasse_diagram_cell( const Cell_range& boundary_ , int dim ): + dimension(dim),boundary(boundary_),position(0),deleted_(false){} + + /** + * Constructor of a cell of dimension dim with a given boundary and coboundary. + **/ + Hasse_diagram_cell( const Cell_range& boundary_ , const Cell_range& coboundary_, + int dim ):dimension(dim),boundary(boundary_),coBoundary(coboundary_), + position(0),deleted_(false){} + + /** + * Constructor of a cell of dimension dim with a given boundary, coboundary and + * additional information. + **/ + Hasse_diagram_cell( const Cell_range& boundary_ , const Cell_range& coboundary_, + const Additional_information& ai, int dim ): + dimension(dim),boundary(boundary_),coBoundary(coboundary_),additional_info(ai), + position(0),deleted_(false){} + + /** + * Construcor of a cell of dimension dim having given additional information. + **/ + Hasse_diagram_cell(Additional_information ai, int dim ): + dimension(dim),additional_info(ai),position(0),deleted_(false){} + + /** + * Procedure to get the boundary of a fiven cell. The output format + * is a vector of pairs of pointers to boundary elements and incidence + * coefficients. + **/ + inline Cell_range& get_boundary(){return this->boundary;} + + /** + * Procedure to get the coboundary of a fiven cell. The output format + * is a vector of pairs of pointers to coboundary elements and incidence + * coefficients. + **/ + inline Cell_range& get_coBoundary(){return this->coBoundary;} + + /** + * Procedure to get the dimension of a cell. + **/ + inline int& get_dimension(){return this->dimension;} + + /** + * Procedure to get additional information about the cell.s + **/ + inline Additional_information& get_additional_information(){return this->additional_info;} + + /** + * Procedure to retrive position of the cell in the structure. It is used in + * the implementation of Hasse diagram and set by it. Note that removal of + * cell and subsequent call of clean_up_the_structure will change those + * positions. + **/ + inline unsigned& get_position(){return this->position;} + + /** + * Accessing the filtration of the cell. + **/ + inline Filtration_type& get_filtration() + { + //std::cout << "Accessing the filtration of a cell : " << *this << std::endl; + return this->filtration; + } + + /** + * A procedure used to check if the cell is deleted. It is used by the + * subsequent implementation of Hasse diagram that is absed on lazy + * delete. + **/ + inline bool deleted(){return this->deleted_;} + + template < typename Cell_type > + friend class Hasse_diagram; + + template < typename Cell_type > + friend class is_before_in_filtration; + + + template + friend std::vector convert_to_vector_of_Cell_type( Complex_type& cmplx ); + + /** + * Procedure to remove deleted boundary and coboundary elements from the + * vectors of boundary and coboundary elements of this cell. + **/ + void remove_deleted_elements_from_boundary_and_coboundary() + { + Cell_range new_boundary; + new_boundary.reserve( this->boundary.size() ); + for ( size_t bd = 0 ; bd != this->boundary.size() ; ++bd ) + { + if ( !this->boundary[bd].first->deleted() ) + { + new_boundary.push_back( this->boundary[bd] ); + } + } + this->boundary.swap( new_boundary ); + + Cell_range new_coBoundary; + new_coBoundary.reserve( this->coBoundary.size() ); + for ( size_t cbd = 0 ; cbd != this->coBoundary.size() ; ++cbd ) + { + if ( !this->coBoundary[cbd].first->deleted() ) + { + new_coBoundary.push_back( this->coBoundary[cbd] ); + } + } + this->coBoundary.swap( new_coBoundary ); + } + + /** + * Writing to a stream operator. + **/ + friend std::ostream& operator<<( std::ostream& out, const Hasse_diagram_cell& c ) + { + //cout << "position : " << c.position << ", dimension : " << c.dimension << ", filtration: " << c.filtration << ", size of boudary : " << c.boundary.size() << "\n"; + out << c.position << " " << c.dimension << " " << c.filtration << std::endl; + for ( size_t bd = 0 ; bd != c.boundary.size() ; ++bd ) + { + //do not write out the cells that has been deleted + if ( c.boundary[bd].first->deleted() )continue; + out << c.boundary[bd].first->position << " " << c.boundary[bd].second << " "; + } + out << std::endl; + return out; + } + + + /** + * Procedure that return vector of pointers to boundary elements of a given cell. + **/ + inline std::vector< Hasse_diagram_cell* > get_list_of_boundary_elements() + { + std::vector< Hasse_diagram_cell* > result; + size_t size_of_boundary = this->boundary.size(); + result.reserve( size_of_boundary ); + for ( size_t bd = 0 ; bd != size_of_boundary ; ++bd ) + { + result.push_back( this->boundary[bd].first ); + } + return result; + } + + /** + * Procedure that return vector of positios of boundary elements of a given cell. + **/ + inline std::vector< unsigned > get_list_of_positions_of_boundary_elements() + { + std::vector< unsigned > result; + size_t size_of_boundary = this->boundary.size(); + result.reserve( size_of_boundary ); + for ( size_t bd = 0 ; bd != size_of_boundary ; ++bd ) + { + result.push_back( this->boundary[bd].first->position ); + } + return result; + } + + /** + * Function that display a string being a signature of a structure. + * Used mainly for debugging purposes. + **/ + std::string full_signature_of_the_structure() + { + std::string result; + result += "dimension: "; + result += std::to_string(this->dimension); + result += " filtration: "; + result += std::to_string(this->filtration); + result += " position: "; + result += std::to_string(this->position); + result += " deleted_: "; + result += std::to_string(this->deleted_); + + //if the Additional_information is not void, add them to + //the signature as well. + if ( std::is_same::value ) + { + result += " Additional_information: "; + result += std::to_string(this->additional_info); + } + result += " boundary "; + for ( size_t bd = 0 ; bd != this->boundary.size() ; ++bd ) + { + result += "( " + std::to_string(this->boundary[bd].first->position); + result += " " + std::to_string(this->boundary[bd].second); + result += ") "; + } + + result += " coBoundary "; + for ( size_t cbd = 0 ; cbd != this->coBoundary.size() ; ++cbd ) + { + result += "( " + std::to_string(this->coBoundary[cbd].first->position); + result += " " + std::to_string(this->coBoundary[cbd].second); + result += ") "; + } + + return result; + } + + +protected: + Cell_range boundary; + Cell_range coBoundary; + int dimension; + Additional_information additional_info; + unsigned position; + bool deleted_; + Filtration_type filtration; + + /** + * A procedure to delete a cell. It is a private function of the Hasse_diagram_cell + * class, since in the Hasse_diagram class I want to have a control + * of removal of cells. Therefore, to remove cell please use + * remove_cell in the Hasse_diagram structure. + **/ + void delete_cell(){ this->deleted_ = true; } +};//Hasse_diagram_cell + + + +}//namespace Hasse_diagram +}//namespace Gudhi + +#endif //CELL_H diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h new file mode 100644 index 00000000..bc59ac12 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h @@ -0,0 +1,94 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef COXETER_TRIANGULATION_H_ +#define COXETER_TRIANGULATION_H_ + +#include +#include +#include //iota + +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Coxeter_triangulation + * \brief A class that stores Coxeter triangulation of type \f$\tilde{A}_d\f$. + * This triangulation has the greatest simplex quality out of all linear transformations + * of the Freudenthal-Kuhn triangulation. + * + * \ingroup coxeter_triangulation + * + * \tparam Permutahedral_representation_ Type of a simplex given by a permutahedral representation. + * Needs to be a model of SimplexInCoxeterTriangulation. + */ +template , std::vector > > > +class Coxeter_triangulation : public Freudenthal_triangulation { + + typedef Eigen::MatrixXd Matrix; + + Matrix root_matrix(unsigned d) { + Matrix cartan(d,d); + for (unsigned i = 0; i < d; i++) { + cartan(i,i) = 1.0; + } + for (unsigned i = 1; i < d; i++) { + cartan(i-1,i) = -0.5; + cartan(i,i-1) = -0.5; + } + for (unsigned i = 0; i < d; i++) + for (unsigned j = 0; j < d; j++) + if (j+1 < i || j > i+1) + cartan(i,j) = 0; + Eigen::SelfAdjointEigenSolver saes(cartan); + Eigen::VectorXd sqrt_diag(d); + for (unsigned i = 0; i < d; ++i) + sqrt_diag(i) = std::sqrt(saes.eigenvalues()[i]); + + Matrix lower(d,d); + for (unsigned i = 0; i < d; i++) + for (unsigned j = 0; j < d; j++) + if (i < j) + lower(i,j) = 0; + else + lower(i,j) = 1; + Matrix result = (lower * saes.eigenvectors()*sqrt_diag.asDiagonal()).inverse(); + return result; + } + +public: + + /** \brief Constructor of Coxeter triangulation of a given dimension. + * @param[in] dimension The dimension of the triangulation. + */ + Coxeter_triangulation(std::size_t dimension) + : Freudenthal_triangulation(dimension, root_matrix(dimension)) {} +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h new file mode 100644 index 00000000..be5d275c --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FREUDENTHAL_TRIANGULATION_H_ +#define FREUDENTHAL_TRIANGULATION_H_ + +#include +#include +#include //iota + +#include +#include +#include + +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Freudenthal_triangulation + * \brief A class that stores any affine transformation of the Freudenthal-Kuhn + * triangulation. + * + * \ingroup coxeter_triangulation + * + * \details The data structure is a record that consists of a matrix + * that represents the linear transformation of the Freudenthal-Kuhn triangulation + * and a vector that represents the offset. + * + * \tparam Permutahedral_representation_ Type of a simplex given by a permutahedral representation. + * Needs to be a model of SimplexInCoxeterTriangulation. + */ +template , std::vector > > > +class Freudenthal_triangulation { + + typedef Eigen::MatrixXd Matrix; + typedef Eigen::VectorXd Vector; + typedef Eigen::SparseMatrix SparseMatrix; + typedef Eigen::Triplet Triplet; + +public: + + /** \brief Type of the simplices in the triangulation. */ + typedef Permutahedral_representation_ Simplex_handle; + + /** \brief Type of the vertices in the triangulation. */ + typedef typename Permutahedral_representation_::Vertex Vertex_handle; + + + /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension. + * @param[in] dimension The dimension of the triangulation. + */ + Freudenthal_triangulation(std::size_t dimension) + : dimension_(dimension), + matrix_(Matrix::Identity(dimension, dimension)), + offset_(Vector::Zero(dimension)), + colpivhouseholderqr_(matrix_.colPivHouseholderQr()), + is_freudenthal(true) { + } + + /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension under + * a linear transformation by a given matrix. + * @param[in] dimension The dimension of the triangulation. + * @param[in] matrix The matrix that defines the linear transformation. + * Needs to be invertible. + */ + Freudenthal_triangulation(std::size_t dimension, const Matrix& matrix) + : dimension_(dimension), + matrix_(matrix), + offset_(Vector::Zero(dimension)), + colpivhouseholderqr_(matrix_.colPivHouseholderQr()), + is_freudenthal(false) { + } + + /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension under + * an affine transformation by a given matrix and a translation vector. + * @param[in] dimension The dimension of the triangulation. + * @param[in] matrix The matrix that defines the linear transformation. + * Needs to be invertible. + * @param[in] offset The offset vector. + */ + Freudenthal_triangulation(unsigned dimension, const Matrix& matrix, const Vector& offset) + : dimension_(dimension), + matrix_(matrix), + offset_(offset), + colpivhouseholderqr_(matrix_.colPivHouseholderQr()), + is_freudenthal(false) { + } + + + /** \brief Dimension of the triangulation. */ + unsigned dimension() const { + return dimension_; + } + + /** \brief Matrix that defines the linear transformation of the triangulation. */ + const Matrix& matrix() const { + return matrix_; + } + + /** \brief Vector that defines the offset of the triangulation. */ + const Vector& offset() const { + return offset_; + } + + /** \brief Change the linear transformation matrix to a given value. + * @param[in] matrix New value of the linear transformation matrix. + */ + void change_matrix(const Eigen::MatrixXd& matrix) { + matrix_ = matrix; + colpivhouseholderqr_ = matrix.colPivHouseholderQr(); + is_freudenthal = false; + } + + /** \brief Change the offset vector to a given value. + * @param[in] offset New value of the offset vector. + */ + void change_offset(const Eigen::VectorXd& offset) { + offset_ = offset; + is_freudenthal = false; + } + + /** \brief Returns the permutahedral representation of the simplex in the + * triangulation that contains a given query point. + * \details Using the additional parameter scale, the search can be done in a + * triangulation that shares the origin, but is scaled by a given factor. + * This parameter can be useful to simulate the point location in a subdivided + * triangulation. + * The returned simplex is always minimal by inclusion. + * + * \tparam Point_d A class that represents a point in d-dimensional Euclidean space. + * The coordinates should be random-accessible. Needs to provide the method size(). + * + * @param[in] point The query point. + * @param[in] scale The scale of the triangulation. + */ + template + Simplex_handle locate_point(const Point_d& point, double scale=1) const { + using Ordered_set_partition = typename Simplex_handle::OrderedSetPartition; + using Part = typename Ordered_set_partition::value_type; + unsigned d = point.size(); + assert(d == dimension_); + double error = 1e-9; + Simplex_handle output; + std::vector z; + if (is_freudenthal) { + for (std::size_t i = 0; i < d; i++) { + double x_i = scale * point[i]; + int y_i = std::floor(x_i); + output.vertex().push_back(y_i); + z.push_back(x_i - y_i); + } + } + else { + Eigen::VectorXd p_vect(d); + for (std::size_t i = 0; i < d; i++) + p_vect(i) = point[i]; + Eigen::VectorXd x_vect = colpivhouseholderqr_.solve(p_vect - offset_); + for (std::size_t i = 0; i < d; i++) { + double x_i = scale * x_vect(i); + int y_i = std::floor(x_i); + output.vertex().push_back(y_i); + z.push_back(x_i - y_i); + } + } + z.push_back(0); + Part indices(d+1); + std::iota(indices.begin(), indices.end(), 0); + std::sort(indices.begin(), + indices.end(), + [&z](std::size_t i1, std::size_t i2) {return z[i1] > z[i2];}); + + output.partition().push_back(Part(1, indices[0])); + for (std::size_t i = 1; i <= d; ++i) + if (z[indices[i-1]] > z[indices[i]] + error) + output.partition().push_back(Part(1, indices[i])); + else + output.partition().back().push_back(indices[i]); + return output; + } + + /** \brief Returns the Cartesian coordinates of the given vertex. + * \details Using the additional parameter scale, the search can be done in a + * triangulation that shares the origin, but is scaled by a given factor. + * This parameter can be useful to simulate the computation of Cartesian coordinates + * of a vertex in a subdivided triangulation. + * @param[in] vertex The query vertex. + * @param[in] scale The scale of the triangulation. + */ + Eigen::VectorXd cartesian_coordinates(const Vertex_handle& vertex, double scale = 1) const { + Eigen::VectorXd v_vect(dimension_); + for (std::size_t j = 0; j < dimension_; j++) + v_vect(j) = vertex[j] / scale; + return matrix_ * v_vect + offset_; + } + + /** \brief Returns the Cartesian coordinates of the barycenter of a given simplex. + * \details Using the additional parameter scale, the search can be done in a + * triangulation that shares the origin, but is scaled by a given factor. + * This parameter can be useful to simulate the computation of Cartesian coordinates + * of the barycenter of a simplex in a subdivided triangulation. + * @param[in] simplex The query simplex. + * @param[in] scale The scale of the triangulation. + */ + Eigen::VectorXd barycenter(const Simplex_handle& simplex, double scale = 1) const { + Eigen::VectorXd res_vector(dimension_); + for (size_t i = 0; i < dimension_; ++i) + res_vector(i) = 0; + for (auto v: simplex.vertex_range()) { + res_vector += cartesian_coordinates(v, scale); + } + return (1./(simplex.dimension()+1)) * res_vector; + } + +protected: + unsigned dimension_; + Matrix matrix_; + Vector offset_; + Eigen::ColPivHouseholderQR colpivhouseholderqr_; + bool is_freudenthal; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h new file mode 100644 index 00000000..43198b89 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -0,0 +1,171 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_CARTESIAN_PRODUCT_H_ +#define FUNCTIONS_CARTESIAN_PRODUCT_H_ + +#include +#include +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/* Get the domain dimension of the tuple of functions. + */ +template +inline typename std::enable_if::type +get_amb_d (const std::tuple& tuple) { + return 0; +} + +template +inline typename std::enable_if::type +get_amb_d (const std::tuple& tuple) { + return std::get(tuple).amb_d() + get_amb_d(tuple); +} + +/* Get the codomain dimension of the tuple of functions. + */ +template +inline typename std::enable_if::type +get_cod_d (const std::tuple& tuple) { + return 0; +} + +template +inline typename std::enable_if::type +get_cod_d (const std::tuple& tuple) { + return std::get(tuple).cod_d() + get_cod_d(tuple); +} + +/* Get the seed of the tuple of functions. + */ +template +inline typename std::enable_if::type +get_seed (const std::tuple& tuple, Eigen::VectorXd& point, std::size_t i = 0) { +} + +template +inline typename std::enable_if::type +get_seed (const std::tuple& tuple, Eigen::VectorXd& point, std::size_t i = 0) { + const auto& f = std::get(tuple); + std::size_t n = f.amb_d(); + Eigen::VectorXd seed = f.seed(); + for (std::size_t j = 0; j < n; ++j) + point(i+j) = seed(j); + get_seed(tuple, point, i+n); +} + +/* Get the seed of the tuple of functions. + */ +template +inline typename std::enable_if::type +get_value (const std::tuple& tuple, const Eigen::VectorXd& x, Eigen::VectorXd& point, std::size_t i = 0, std::size_t j = 0) { +} + +template +inline typename std::enable_if::type +get_value (const std::tuple& tuple, const Eigen::VectorXd& x, Eigen::VectorXd& point, std::size_t i = 0, std::size_t j = 0) { + const auto& f = std::get(tuple); + std::size_t n = f.amb_d(); + std::size_t k = f.cod_d(); + Eigen::VectorXd x_i(n); + for (std::size_t l = 0; l < n; ++l) + x_i(l) = x(i+l); + Eigen::VectorXd res = f(x_i); + for (std::size_t l = 0; l < k; ++l) + point(j+l) = res(l); + get_value(tuple, x, point, i+n, j+k); +} + + +/** + * \class Cartesian_product + * \brief Constructs the function the zero-set of which is the Cartesian product + * of the zero-sets of some given functions. + * + * \tparam Functions A pack template parameter for functions. All functions should be models of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +struct Cartesian_product : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result(cod_d_); + get_value(function_tuple_, p, result, 0, 0); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return amb_d_;} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return cod_d_;} + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result(amb_d_); + get_seed(function_tuple_, result, 0); + return result; + } + + /** + * \brief Constructor of the Cartesian product function. + * + * @param[in] functions The functions the zero-sets of which are factors in the + * Cartesian product of the resulting function. + */ + Cartesian_product(const Functions&... functions) + : function_tuple_(std::make_tuple(functions...)) { + amb_d_ = get_amb_d(function_tuple_); + cod_d_ = get_cod_d(function_tuple_); + } + +private: + std::tuple function_tuple_; + std::size_t amb_d_, cod_d_; +}; + + +/** + * \brief Static constructor of a Cartesian product function. + * + * @param[in] functions The functions the zero-sets of which are factors in the + * Cartesian product of the resulting function. + * + * \tparam Functions A pack template parameter for functions. All functions should be models of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +Cartesian_product make_product_function(const Functions&... functions) { + return Cartesian_product(functions...); +} + + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h new file mode 100644 index 00000000..ea354fac --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -0,0 +1,71 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_CONSTANT_FUNCTION_H_ +#define FUNCTIONS_CONSTANT_FUNCTION_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Constant_function + * \brief A class that encodes a constant function from R^d to R^k. + * This class does not have any implicit manifold in correspondence. + * + * \ingroup coxeter_triangulation + */ +struct Constant_function : public Function { + + /** \brief Value of the function at a specified point. The value is constant. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = value_; + return result; + } + + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ + std::size_t amb_d() const {return d_;}; + + /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ + std::size_t cod_d() const {return k_;}; + + /** \brief No seed point is available. Throws an exception on evocation. */ + Eigen::VectorXd seed() const { + throw "Seed invoked on a constant function.\n"; + } + + Constant_function() {} + + /** + * \brief Constructor of a constant function from R^d to R^m. + * + * @param[in] d The domain dimension. + * @param[in] k The codomain dimension. + * @param[in] value The constant value of the function. + */ + Constant_function(std::size_t d, std::size_t k, const Eigen::VectorXd& value) + : d_(d), k_(k), value_(value) {} + + std::size_t d_, k_; + Eigen::VectorXd value_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h new file mode 100644 index 00000000..9476944b --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -0,0 +1,106 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_EMBED_IN_RD_H_ +#define FUNCTIONS_EMBED_IN_RD_H_ + +#include +#include + +#include +#include + + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Embed_in_Rd + * \brief Embedding of an implicit manifold in a higher dimension. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +struct Embed_in_Rd : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd x = p; + Eigen::VectorXd x_k(fun_.amb_d()), x_rest(d_ - fun_.amb_d()); + for (std::size_t i = 0; i < fun_.amb_d(); ++i) + x_k(i) = x(i); + for (std::size_t i = fun_.amb_d(); i < d_; ++i) + x_rest(i - fun_.amb_d()) = x(i); + Eigen::VectorXd result = fun_(x_k); + result.conservativeResize(this->cod_d()); + for (std::size_t i = fun_.cod_d(); i < this->cod_d(); ++i) + result(i) = x_rest(i - fun_.cod_d()); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return d_;} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return d_-(fun_.amb_d() - fun_.cod_d());} + + /** \brief Returns a point on the zero-set of the embedded function. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + result.conservativeResize(d_); + for (std::size_t l = fun_.amb_d(); l < d_; ++l) + result(l) = 0; + return result; + } + + /** + * \brief Constructor of the embedding function. + * + * @param[in] function The function to be embedded in higher dimension. + * @param[in] d Embedding dimension. + */ + Embed_in_Rd(const Function_& function, std::size_t d) : + fun_(function), d_(d) { + } + Function_ fun_; + std::size_t d_; +}; + + +/** + * \brief Static constructor of an embedding function. + * + * @param[in] function The function to be embedded in higher dimension. + * @param[in] d Embedding dimension. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +Embed_in_Rd make_embedding(const Function_& function, std::size_t d) { + return Embed_in_Rd(function, d); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h new file mode 100644 index 00000000..dbcb0142 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h @@ -0,0 +1,54 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_H_ +#define FUNCTIONS_FUNCTION_H_ + +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function + * \brief The parent class for all functions implemented in the module. + * Contains virtual methods needed to be a model of the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +struct Function { + + /** \brief Virtual method for the value of the function at a specified point. + * @param[in] p The input point. + */ + virtual Eigen::VectorXd evaluate(const Eigen::VectorXd& p) const {return Eigen::VectorXd(0);} + + /** \brief Virtual method for the domain dimension. */ + virtual std::size_t amb_d() const {return 0;}; + + /** \brief Virtual method for the codomain dimension. */ + virtual std::size_t cod_d() const {return 0;}; + + /** \brief Virtual method for the seed point. */ + virtual Eigen::VectorXd seed() const {return Eigen::VectorXd(0);} + + /** \brief Virtual destructor. */ + virtual ~Function() {} +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h new file mode 100644 index 00000000..a7d4a965 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -0,0 +1,131 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_SM_IN_RD_H_ +#define FUNCTIONS_FUNCTION_SM_IN_RD_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_Sm_in_Rd + * \brief A class for the function that defines an m-dimensional implicit sphere embedded + * in the d-dimensional Euclidean space. + * + * \ingroup coxeter_triangulation + */ +struct Function_Sm_in_Rd: public Function { + +/** \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd x = p; + for (std::size_t i = 0; i < d_; ++i) + x(i) -= center_[i]; + Eigen::VectorXd result = Eigen::VectorXd::Zero(k_); + for (std::size_t i = 0; i < m_+1; ++i) + result(0) += x(i)*x(i); + result(0) -= r_*r_; + for (std::size_t j = 1; j < k_; ++j) + result(j) = x(m_+j); + return result; + } + + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ + std::size_t amb_d() const {return d_;}; + + /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ + std::size_t cod_d() const {return k_;}; + + /** \brief Returns a point on the sphere. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); + result(0) += r_; + for (std::size_t i = 0; i < d_; ++i) + result(i) += center_[i]; + return result; + } + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the d-dimensional Euclidean space. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + * @param[in] d The ambient dimension of the sphere. + * @param[in] center The center of the sphere. + */ + Function_Sm_in_Rd(double r, + std::size_t m, + std::size_t d, + Eigen::VectorXd center) + : m_(m), k_(d-m), d_(d), r_(r), center_(center) {} + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the d-dimensional Euclidean space centered at the origin. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + * @param[in] d The ambient dimension of the sphere. + */ + Function_Sm_in_Rd(double r, + std::size_t m, + std::size_t d) + : m_(m), k_(d-m), d_(d), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} + + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the (m+1)-dimensional Euclidean space. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + * @param[in] center The center of the sphere. + */ + Function_Sm_in_Rd(double r, + std::size_t m, + Eigen::VectorXd center) + : m_(m), k_(1), d_(m_+1), r_(r), center_(center) {} + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the (m+1)-dimensional Euclidean space centered at the origin. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + */ + Function_Sm_in_Rd(double r, + std::size_t m) + : m_(m), k_(1), d_(m_+1), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} + + Function_Sm_in_Rd(const Function_Sm_in_Rd& rhs) + : Function_Sm_in_Rd(rhs.r_, rhs.m_, rhs.d_, rhs.center_) {} + + +protected: + std::size_t m_, k_, d_; + double r_; + Eigen::VectorXd center_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h new file mode 100644 index 00000000..cb3af848 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -0,0 +1,101 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_AFFINE_PLANE_IN_RD_H_ +#define FUNCTIONS_FUNCTION_AFFINE_PLANE_IN_RD_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_affine_plane_in_Rd + * \brief A class for the function that defines an m-dimensional implicit affine plane + * embedded in d-dimensional Euclidean space. + * + * \ingroup coxeter_triangulation + */ +struct Function_affine_plane_in_Rd : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = normal_matrix_.transpose() * (p - off_); + return result; + } + + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ + std::size_t amb_d() const {return d_;}; + + /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ + std::size_t cod_d() const {return k_;}; + + /** \brief Returns a point on the affine plane. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = off_; + return result; + } + + /** + * \brief Constructor of the function that defines an m-dimensional implicit affine + * plane in the d-dimensional Euclidean space. + * + * @param[in] normal_matrix A normal matrix of the affine plane. The number of rows should + * correspond to the ambient dimension, the number of columns should corespond to + * the size of the normal basis (codimension). + * @param[in] offset The offset vector of the affine plane. + * The dimension of the vector should be the ambient dimension of the manifold. + */ + Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix, + const Eigen::VectorXd& offset) + : normal_matrix_(normal_matrix), + d_(normal_matrix.rows()), + k_(normal_matrix.cols()), + m_(d_ - k_), + off_(offset) { + normal_matrix_.colwise().normalize(); + } + + /** + * \brief Constructor of the function that defines an m-dimensional implicit affine + * plane in the d-dimensional Euclidean space that passes through origin. + * + * @param[in] normal_matrix A normal matrix of the affine plane. The number of rows should + * correspond to the ambient dimension, the number of columns should corespond to + * the size of the normal basis (codimension). + */ + Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix) + : normal_matrix_(normal_matrix), + d_(normal_matrix.rows()), + k_(normal_matrix.cols()), + m_(d_ - k_), + off_(Eigen::VectorXd::Zero(d_)) { + normal_matrix_.colwise().normalize(); + } + +protected: + Eigen::MatrixXd normal_matrix_; + std::size_t d_, k_, m_; + Eigen::VectorXd off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h new file mode 100644 index 00000000..2a76e631 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -0,0 +1,87 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ +#define FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_chair_in_R3 + * \brief A class that encodes the function, the zero-set of which is a so-called + * "chair" surface embedded in R^3. + * + * \ingroup coxeter_triangulation + */ +struct Function_chair_in_R3 : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + Eigen::VectorXd result(cod_d()); + result(0) = std::pow(x*x + y*y + z*z - a_*k_*k_, 2) - b_*((z-k_)*(z-k_) - 2*x*x)*((z+k_)*(z+k_) - 2*y*y); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return 3;} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return 1;} + + /** \brief Returns a point on the surface. */ + Eigen::VectorXd seed() const { + double t1 = a_-b_; + double discr = t1*t1 - (1.0 - b_)*(a_*a_ - b_); + double z0 = k_*std::sqrt((t1+std::sqrt(discr))/(1-b_)); + Eigen::Vector3d result(off_[0], off_[1], z0+off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines the 'chair' surface + * embedded in R^3. + * + * @param[in] a A numerical parameter. + * @param[in] b A numerical parameter. + * @param[in] k A numerical parameter. + * @param[in] off Offset vector. + */ + Function_chair_in_R3(double a = 0.8, + double b = 0.4, + double k = 1.0, + Eigen::Vector3d off = Eigen::Vector3d::Zero()) : + a_(a), b_(b), k_(k), off_(off) {} + +protected: + double a_, b_, k_; + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif + +// (x^2 + y^2 + z^2 - a*k^2)^2 - b*((z-k)^2 - 2*x^2)*((z+k)^2 - 2*y^2) +// sqrt(k/(1-b))*sqrt(a-b + sqrt((a-b)^2 - (1-b)*(a^2 - b)*k^2)) diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h new file mode 100644 index 00000000..af323c94 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -0,0 +1,73 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_IRON_IN_R3_H_ +#define FUNCTIONS_FUNCTION_IRON_IN_R3_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_iron_in_R3 + * \brief A class that encodes the function, the zero-set of which is a surface + * embedded in R^3 that ressembles an iron. + * + * \ingroup coxeter_triangulation + */ +struct Function_iron_in_R3 : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0), y = p(1), z = p(2); + Eigen::VectorXd result(cod_d()); + result(0) = - std::pow(x,6)/300. - std::pow(y,6)/300. - std::pow(z,6)/300. + x*y*y*z/2.1 + y*y + std::pow(z-2, 4) - 1; + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return 3;}; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return 1;}; + + /** \brief Returns a point on the surface. */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(std::pow(4500, 1./6), 0, 0); + return result; + } + + /** + * \brief Constructor of the function that defines a surface embedded in R^3 + * that ressembles an iron. + * + * @param[in] off Offset vector. + */ + Function_iron_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : + off_(off) {} + +protected: + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h new file mode 100644 index 00000000..cd03a0a5 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -0,0 +1,90 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ +#define FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_lemniscate_revolution_in_R3 + * \brief A class that encodes the function, the zero-set of which is a surface of revolution + * around the x axis based on the lemniscate of Bernoulli embedded in R^3. + * + * \ingroup coxeter_triangulation + */ +struct Function_lemniscate_revolution_in_R3 : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + Eigen::VectorXd result(cod_d()); + double x2 = x*x, y2 = y*y, z2 = z*z, a2 = a_*a_; + double t1 = x2 + y2 + z2; + result(0) = t1*t1 - 2*a2*(x2 - y2 - z2); + return result; + } + + /** \brief Returns the (ambient) domain dimension.*/ + std::size_t amb_d() const {return 3;}; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return 1;}; + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed2() for the other point. + */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(sqrt(2*a_)+off_[0], off_[1], off_[2]); + return result; + } + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed() for the other point. + */ + Eigen::VectorXd seed2() const { + Eigen::Vector3d result(-sqrt(2*a_)+off_[0], off_[1], off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines a surface of revolution + * around the x axis based on the lemniscate of Bernoulli embedded in R^3. + * + * @param[in] a A numerical parameter. + * @param[in] off Offset vector. + */ + Function_lemniscate_revolution_in_R3(double a = 1, + Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : a_(a), off_(off) {} + +protected: + double a_; + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h new file mode 100644 index 00000000..91eb016b --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -0,0 +1,89 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_MOMENT_CURVE_IN_RD_H_ +#define FUNCTIONS_FUNCTION_MOMENT_CURVE_IN_RD_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_moment_curve_in_Rd + * \brief A class for the function that defines an implicit moment curve + * in the d-dimensional Euclidean space. + * + * \ingroup coxeter_triangulation + */ +struct Function_moment_curve_in_Rd : public Function { + +/** \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result(k_); + for (std::size_t i = 1; i < d_; ++i) + result(i-1) = p(i) - p(0) * p(i-1); + return result; + } + + /** \brief Returns the domain (ambient) dimension.. */ + std::size_t amb_d() const {return d_;}; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return k_;}; + + /** \brief Returns a point on the moment curve. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); + return result; + } + + /** + * \brief Constructor of the function that defines an implicit moment curve + * in the d-dimensional Euclidean space. + * + * @param[in] r Numerical parameter. + * @param[in] d The ambient dimension. + */ + Function_moment_curve_in_Rd(double r, + std::size_t d) + : m_(1), k_(d-1), d_(d), r_(r) {} + + /** + * \brief Constructor of the function that defines an implicit moment curve + * in the d-dimensional Euclidean space. + * + * @param[in] r Numerical parameter. + * @param[in] d The ambient dimension. + * @param[in] offset The offset of the moment curve. + */ + Function_moment_curve_in_Rd(double r, + std::size_t d, + Eigen::VectorXd& offset) + : m_(1), k_(d-1), d_(d), r_(r), off_(offset) {} + +protected: + std::size_t m_, k_, d_; + double r_; + Eigen::VectorXd off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h new file mode 100644 index 00000000..3cda2518 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -0,0 +1,77 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ +#define FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_torus_in_R3 + * \brief A class that encodes the function, the zero-set of which is a torus + * surface embedded in R^3. + * + * \ingroup coxeter_triangulation + */ +struct Function_torus_in_R3 : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + Eigen::VectorXd result(cod_d()); + result(0) = (z*z + (std::sqrt(x*x + y*y) - r_)*(std::sqrt(x*x + y*y) - r_) - R_*R_); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return 3;}; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return 1;}; + + /** \brief Returns a point on the surface. */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(R_ + r_ +off_[0], off_[1], off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines a torus embedded in R^3. + * + * @param[in] R The outer radius of the torus. + * @param[in] r The inner radius of the torus. + * @param[in] off Offset vector. + */ + Function_torus_in_R3(double R = 1, + double r = 0.5, + Eigen::Vector3d off = Eigen::Vector3d::Zero()) : + R_(R), r_(r), off_(off) {} + +protected: + double R_, r_; + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h new file mode 100644 index 00000000..3d825f8f --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -0,0 +1,82 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_WHITNEY_UMBRELLA_IN_R3_H_ +#define FUNCTIONS_FUNCTION_WHITNEY_UMBRELLA_IN_R3_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_whitney_umbrella_in_R3 + * \brief A class that encodes the function, the zero-set of which is the Whitney umbrella + * surface embedded in R^3. + * + * \ingroup coxeter_triangulation + */ +struct Function_whitney_umbrella_in_R3 : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + Eigen::VectorXd result(cod_d()); + result(0) = x*x - y*y*z; + return result; + } + + /** \brief Returns the (ambient) domain dimension.*/ + std::size_t amb_d() const {return 3;}; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return 1;}; + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed2() for the other point. + */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(1+off_[0], 1+off_[1], 1+off_[2]); + return result; + } + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed() for the other point. + */ + Eigen::VectorXd seed2() const { + Eigen::Vector3d result(-1+off_[0], -1+off_[1], 1+off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines the Whitney umbrella in R^3. + * + * @param[in] off Offset vector. + */ + Function_whitney_umbrella_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : off_(off) {} + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h new file mode 100644 index 00000000..4cb5ca84 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -0,0 +1,96 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_LINEAR_TRANSFORMATION_H_ +#define FUNCTIONS_LINEAR_TRANSFORMATION_H_ + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Linear_transformation + * \brief Transforms the zero-set of the function by a given linear transformation. + * The underlying function corresponds to f(M*x), where M is the transformation matrix. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +struct Linear_transformation : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = fun_(matrix_.householderQr().solve(p)); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return fun_.amb_d();} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return fun_.cod_d();} + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + result = matrix_ * result; + return result; + } + + /** + * \brief Constructor of a linearly transformed function. + * + * @param[in] function The function to be linearly transformed. + * @param[in] matrix The transformation matrix. Its dimension should be d*d, + * where d is the domain (ambient) dimension of 'function'. + */ + Linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) : + fun_(function), matrix_(matrix) { + } + +private: + Function_ fun_; + Eigen::MatrixXd matrix_; +}; + + +/** + * \brief Static constructor of a linearly transformed function. + * + * @param[in] function The function to be linearly transformed. + * @param[in] matrix The transformation matrix. Its dimension should be d*d, + * where d is the domain (ambient) dimension of 'function'. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + */ +template +Linear_transformation make_linear_transformation(const Function_& function, + const Eigen::MatrixXd& matrix) { + return Linear_transformation(function, matrix); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h new file mode 100644 index 00000000..6b7feff5 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -0,0 +1,92 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_NEGATION_H_ +#define FUNCTIONS_NEGATION_H_ + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + *\class Negation + * \brief Constructs the "minus" function. The zero-set is the same, but + * the values at other points are the negative of their original value. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +struct Negation : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = -fun_(p); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return fun_.amb_d();} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return fun_.cod_d();} + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + return result; + } + + /** + * \brief Constructor of the negative function. + * + * @param[in] function The function to be negated. + */ + Negation(const Function_& function) : + fun_(function) { + } + Function_ fun_; +}; + + +/** + * \brief Static constructor of the negative function. + * + * @param[in] function The function to be translated. + * @param[in] off The offset vector. The dimension should correspond to the + * domain (ambient) dimension of 'function'. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +Negation negation(const Function_& function) { + return Negation(function); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h new file mode 100644 index 00000000..25c8a139 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -0,0 +1,125 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_PL_APPROXIMATION_H_ +#define FUNCTIONS_PL_APPROXIMATION_H_ + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class PL_approximation + * \brief Constructs a piecewise-linear approximation of a function induced by + * an ambient triangulation. + * + * \tparam Function The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * \tparam Triangulation The triangulation template parameter. Should be a model of + * the concept TriangulationForManifoldTracing. + * + * \ingroup coxeter_triangulation + */ +template +struct PL_approximation : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + std::size_t cod_d = this->cod_d(); + std::size_t amb_d = this->amb_d(); + auto s = tr_.locate_point(p); + Eigen::MatrixXd matrix(cod_d, s.dimension() + 1); + Eigen::MatrixXd vertex_matrix(amb_d + 1, s.dimension() + 1); + for (std::size_t i = 0; i < s.dimension() + 1; ++i) + vertex_matrix(0, i) = 1; + std::size_t j = 0; + for (auto v: s.vertex_range()) { + Eigen::VectorXd pt_v = tr_.cartesian_coordinates(v); + Eigen::VectorXd fun_v = fun_(pt_v); + for (std::size_t i = 1; i < amb_d + 1; ++i) + vertex_matrix(i, j) = pt_v(i-1); + for (std::size_t i = 0; i < cod_d; ++i) + matrix(i, j) = fun_v(i); + j++; + } + assert(j == s.dimension()+1); + Eigen::VectorXd z(amb_d + 1); + z(0) = 1; + for (std::size_t i = 1; i < amb_d + 1; ++i) + z(i) = p(i-1); + Eigen::VectorXd lambda = vertex_matrix.colPivHouseholderQr().solve(z); + Eigen::VectorXd result = matrix * lambda; + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return fun_.amb_d();} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return fun_.cod_d();} + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + // TODO: not finished. Should use an oracle. + return Eigen::VectorXd(amb_d()); + } + + /** + * \brief Constructor of the piecewise-linear approximation of a function + * induced by an ambient triangulation. + * + * @param[in] function The function. + * @param[in] triangulation The ambient triangulation. + */ + PL_approximation(const Function_& function, const Triangulation_& triangulation) + : fun_(function), tr_(triangulation) {} + +private: + Function_ fun_; + Triangulation_ tr_; +}; + + +/** + * \brief Static constructor of the piecewise-linear approximation of a function + * induced by an ambient triangulation. + * + * @param[in] function The function. + * @param[in] triangulation The ambient triangulation. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +PL_approximation +make_pl_approximation(const Function_& function, + const Triangulation_& triangulation) { + return PL_approximation(function, triangulation); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h new file mode 100644 index 00000000..6edac28c --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -0,0 +1,96 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_TRANSLATE_H_ +#define FUNCTIONS_TRANSLATE_H_ + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Translate + * \brief Translates the zero-set of the function by a vector. + * The underlying function corresponds to f(x-off), where off is the offset vector. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +struct Translate : public Function { + + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = fun_(p - off_); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const {return fun_.amb_d();} + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const {return fun_.cod_d();} + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + result += off_; + return result; + } + + /** + * \brief Constructor of the translated function. + * + * @param[in] function The function to be translated. + * @param[in] off The offset vector. The dimension should correspond to the + * domain (ambient) dimension of 'function'. + */ + Translate(const Function_& function, const Eigen::VectorXd& off) : + fun_(function), off_(off) { + } + Function_ fun_; + Eigen::VectorXd off_; +}; + + +/** + * \brief Static constructor of a translated function. + * + * @param[in] function The function to be translated. + * @param[in] off The offset vector. The dimension should correspond to the + * domain (ambient) dimension of 'function'. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +Translate translate(const Function_& function, Eigen::VectorXd off) { + return Translate(function, off); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h new file mode 100644 index 00000000..8979669e --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -0,0 +1,70 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ +#define FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ + +#include +#include + +#include +#include +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief Generates a uniform random orthogonal matrix using the "subgroup algorithm" by + * Diaconis & Shashahani. + * \details Taken from https://en.wikipedia.org/wiki/Rotation_matrix#Uniform_random_rotation_matrices. + * The idea: take a random rotation matrix of dimension d-1, embed it + * as a d*d matrix M with the last column (0,...,0,1). + * Pick a random vector v on a sphere S^d. rotate the matrix M so that its last column is v. + * The determinant of the matrix can be either 1 or -1 + */ +// Note: the householderQR operation at the end seems to take a lot of time at compilation. +// The CGAL headers are another source of long compilation time. +Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) { + typedef CGAL::Epick_d Kernel; + typedef typename Kernel::Point_d Point_d; + if (d == 1) + return Eigen::VectorXd::Constant(1, 1.0); + if (d == 2) { + double X = 2 * 3.14159265358; + double alpha = static_cast (rand()) / (static_cast (RAND_MAX/X)); + Eigen::Matrix2d rot; + rot << cos(alpha), -sin(alpha), sin(alpha), cos(alpha); + return rot; + } + Eigen::MatrixXd low_dim_rot = random_orthogonal_matrix(d-1); + Eigen::MatrixXd rot(d,d); + Point_d v = *CGAL::Random_points_on_sphere_d(d, 1); + for (std::size_t i = 0; i < d; ++i) + rot(i,0) = v[i]; + for (std::size_t i = 0; i < d-1; ++i) + for (std::size_t j = 1; j < d-1; ++j) + rot(i,j) = low_dim_rot(i,j-1); + for (std::size_t j = 1; j < d; ++j) + rot(d-1,j) = 0; + rot = rot.householderQr().householderQ(); // a way to do Gram-Schmidt, see https://forum.kde.org/viewtopic.php?f=74&t=118568#p297246 + return rot; +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h new file mode 100644 index 00000000..b1cc0fe5 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h @@ -0,0 +1,57 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef IO_MESH_MEDIT_H_ +#define IO_MESH_MEDIT_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/* \class Mesh_medit + * \brief Structure to store a mesh that can be output in Medit .mesh file format + * using the output_meshes_to_medit method. + * + * \ingroup coxeter_triangulation + */ +struct Mesh_medit { + /** \brief Type of a range of vertices. */ + typedef std::vector Vertex_points; + /** \brief Type of a mesh element. + * A pair consisting of a vector of vertex indices of type std::size_t + * and of an integer that represents the common reference number for + * the mesh elements of this type. */ + typedef std::pair, std::size_t> Mesh_element; + /** \brief Type of a range of mesh elements. */ + typedef std::vector Mesh_elements; + /** \brief Type of a range of scalar field . */ + typedef std::vector Scalar_field_range; + + /** \brief Range of vertices of type Eigen::VectorXd to output. */ + Vertex_points vertex_points; + /** \brief Range of edges. */ + Mesh_elements edges; + /** \brief Range of triangles. */ + Mesh_elements triangles; + /** \brief Range of tetrahedra. */ + Mesh_elements tetrahedra; + /** \brief Range of scalar values over triangles. */ + Scalar_field_range triangles_scalar_range; + /** \brief Range of scalar values over tetrahedra. */ + Scalar_field_range tetrahedra_scalar_range; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h new file mode 100644 index 00000000..5044660e --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -0,0 +1,174 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef IO_BUILD_MESH_FROM_CELL_COMPLEX_H_ +#define IO_BUILD_MESH_FROM_CELL_COMPLEX_H_ + +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +struct Configuration { + bool toggle_edges = true, + toggle_triangles = true, + toggle_tetrahedra = true; + std::size_t ref_edges = 1, + ref_triangles = 1, + ref_tetrahedra = 1; + + Configuration(bool t_edges, bool t_triangles, bool t_tetrahedra, + std::size_t r_edges, std::size_t r_triangles, std::size_t r_tetrahedra) + : toggle_edges(t_edges), toggle_triangles(t_triangles), toggle_tetrahedra(t_tetrahedra), + ref_edges(r_edges), ref_triangles(r_triangles), ref_tetrahedra(r_tetrahedra) {} +}; + + +template +void populate_mesh(Mesh_medit& output, + Simplex_cell_map& sc_map, + Configuration configuration, + std::size_t amb_d, + std::map vi_map) { + using Mesh_element_vertices = Mesh_medit::Mesh_elements::value_type::first_type; + std::map ci_map; + std::size_t index = vi_map.size() + 1; // current size of output.vertex_points + if (sc_map.size() >= 3) + for (const auto& sc_pair: sc_map[2]) { + Eigen::VectorXd barycenter = Eigen::VectorXd::Zero(amb_d); + std::set vertex_indices; + Hasse_cell* cell = sc_pair.second; + for (const auto& ei_pair: cell->get_boundary()) + for (const auto& vi_pair: ei_pair.first->get_boundary()) + vertex_indices.emplace(vi_map[vi_pair.first]); + for (const std::size_t& v: vertex_indices) + barycenter += output.vertex_points[v-1]; + ci_map.emplace(std::make_pair(cell, index++)); + output.vertex_points.emplace_back((1./vertex_indices.size()) * barycenter); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + std::string vlist = " (" + std::to_string(index-1) + ")"; + for (const std::size_t& v: vertex_indices) + vlist += " " + std::to_string(v); + cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); +#endif + } + + if (configuration.toggle_edges && sc_map.size() >= 2) + for (const auto& sc_map: sc_map[1]) { + Hasse_cell* edge_cell = sc_map.second; + Mesh_element_vertices edge; + for (const auto& vi_pair: edge_cell->get_boundary()) + edge.push_back(vi_map[vi_pair.first]); + output.edges.emplace_back(std::make_pair(edge, configuration.ref_edges)); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + std::string vlist; + for (const std::size_t& v: edge) + vlist += " " + std::to_string(v); + cell_vlist_map.emplace(std::make_pair(to_string(edge_cell), vlist)); +#endif + } + + if (configuration.toggle_triangles && sc_map.size() >= 3) + for (const auto& sc_pair: sc_map[2]) { + for (const auto& ei_pair: sc_pair.second->get_boundary()) { + Mesh_element_vertices triangle(1, ci_map[sc_pair.second]); + for (const auto& vi_pair: ei_pair.first->get_boundary()) + triangle.push_back(vi_map[vi_pair.first]); + output.triangles.emplace_back(std::make_pair(triangle, configuration.ref_triangles)); + } + } + + if (configuration.toggle_tetrahedra && sc_map.size() >= 4) + for (const auto& sc_pair: sc_map[3]) { + Eigen::VectorXd barycenter = Eigen::VectorXd::Zero(amb_d); + std::set vertex_indices; + Hasse_cell* cell = sc_pair.second; + for (const auto& ci_pair: cell->get_boundary()) + for (const auto& ei_pair: ci_pair.first->get_boundary()) + for (const auto& vi_pair: ei_pair.first->get_boundary()) + vertex_indices.emplace(vi_map[vi_pair.first]); + for (const std::size_t& v: vertex_indices) + barycenter += output.vertex_points[v-1]; + output.vertex_points.emplace_back((1./vertex_indices.size()) * barycenter); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + std::string vlist = " (" + std::to_string(index) + ")"; + for (const std::size_t& v: vertex_indices) + vlist += " " + std::to_string(v); + cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); +#endif + + for (const auto& ci_pair: cell->get_boundary()) + for (const auto& ei_pair: ci_pair.first->get_boundary()) { + Mesh_element_vertices tetrahedron = {index, ci_map[sc_pair.second]}; + for (const auto& vi_pair: ei_pair.first->get_boundary()) + tetrahedron.push_back(vi_map[vi_pair.first]); + output.tetrahedra.emplace_back(std::make_pair(tetrahedron, configuration.ref_tetrahedra)); + } + index++; + } +} + +template +Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, + Configuration i_configuration = Configuration(), + Configuration b_configuration = Configuration()) { + using Hasse_cell = typename Cell_complex::Hasse_cell; + Mesh_medit output; + std::map vi_map; // one for vertices, other for 2d-cells + std::size_t index = 1; // current size of output.vertex_points + + if (cell_complex.cell_point_map().empty()) + return output; + std::size_t amb_d = std::min((int) cell_complex.cell_point_map().begin()->second.size(), 3); + + for (const auto& cp_pair: cell_complex.cell_point_map()) { +#ifdef GUDHI_COX_OUTPUT_TO_HTML + std::string vlist; + vlist += " " + std::to_string(index); + cell_vlist_map.emplace(std::make_pair(to_string(cp_pair.first), vlist)); +#endif + vi_map.emplace(std::make_pair(cp_pair.first, index++)); + output.vertex_points.push_back(cp_pair.second); + output.vertex_points.back().conservativeResize(amb_d); + } + + + populate_mesh(output, cell_complex.interior_simplex_cell_maps(), i_configuration, amb_d, vi_map); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + for (const auto& sc_map: cell_complex.interior_simplex_cell_maps()) + for (const auto& sc_pair: sc_map) { + std::string simplex = "I" + to_string(sc_pair.first); + std::string cell = to_string(sc_pair.second); + std::string vlist = cell_vlist_map.at(cell).substr(1); + simplex_vlist_map.emplace(std::make_pair(simplex, vlist)); + } +#endif + populate_mesh(output, cell_complex.boundary_simplex_cell_maps(), b_configuration, amb_d, vi_map); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + for (const auto& sc_map: cell_complex.boundary_simplex_cell_maps()) + for (const auto& sc_pair: sc_map) { + std::string simplex = "B" + to_string(sc_pair.first); + std::string cell = to_string(sc_pair.second); + std::string vlist = cell_vlist_map.at(cell).substr(1); + simplex_vlist_map.emplace(std::make_pair(simplex, vlist)); + } +#endif + return output; +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h new file mode 100644 index 00000000..43cca967 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h @@ -0,0 +1,589 @@ +#ifdef GUDHI_DEBUG +#define GUDHI_COX_OUTPUT_TO_HTML + +#include +#include +#include +#include +#include +#include + +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +template +std::ostream& operator<<(std::ostream& os, const std::vector& vector) { + os << "("; + if (vector.empty()) { + os << ")"; + return os; + } + auto v_it = vector.begin(); + os << *v_it++; + for (; v_it != vector.end(); ++v_it) + os << ", " << *v_it; + os << ")"; + return os; +} + +/* A class to make the vector horizontal instead of vertical */ +struct Straighten { + Straighten (const Eigen::VectorXd& vector) : vector_(vector) {} + const Eigen::VectorXd& vector_; +}; + +std::ostream& operator<<(std::ostream& os, const Straighten& str) { + std::size_t size = str.vector_.size(); + os << "(" << str.vector_(0); + if (size == 0) { + os << ")"; + return os; + } + for (std::size_t i = 1; i < size; ++i) + os << ", " << str.vector_(i); + os << ")"; + return os; +} + +std::string id_from_simplex(const std::string& simplex) { + std::regex r("\\s+"), r2("\\(|\\)|\\{|\\}"), r3(","), r4("\\["), r5("\\]"); + std::string output = std::regex_replace(simplex, r, ""); + output = std::regex_replace(output, r2, ":"); + output = std::regex_replace(output, r3, "."); + output = std::regex_replace(output, r4, "_"); + output = std::regex_replace(output, r5, ""); + return output; +} + +template +std::string to_string(const T& t) { + std::ostringstream oss; + oss << t; + return oss.str(); +} + +struct MT_inserted_info { + std::string qr_face_, init_face_, qr_intersection_; + bool qr_success_, is_boundary_; + template + MT_inserted_info(const Query_result& qr, const Simplex_handle& face, bool is_boundary) + : qr_face_(to_string(face)), init_face_(to_string(face)), + qr_intersection_(to_string(qr.intersection)), + qr_success_(qr.success), is_boundary_(is_boundary) {} +}; +std::list mt_seed_inserted_list, mt_inserted_list; + +struct CC_summary_info { + std::string face_, cell_; + template + CC_summary_info(const SC_pair& sc_pair) + : face_(to_string(sc_pair.first)), cell_(to_string(sc_pair.second)) {} +}; +using CC_summary_list = std::list; +std::vector cc_interior_summary_lists, cc_boundary_summary_lists; + +struct CC_detail_info { + enum class Result_type {self, face, coface, inserted, join_single, join_is_face}; + std::string simplex_, trigger_, init_simplex_; + Result_type status_; + bool join_trigger_ = false; + std::list faces_, post_faces_, cofaces_; + template + CC_detail_info(const Simplex_handle& simplex) + : simplex_(to_string(simplex)) {} +}; +using CC_detail_list = std::list; +std::vector cc_interior_detail_lists, cc_boundary_detail_lists; +std::vector cc_interior_insert_detail_lists, cc_boundary_insert_detail_lists; + +struct CC_prejoin_info { + enum class Result_type {join_single, join_is_face, join_different, join_same}; + std::string simplex_, join_; + std::vector faces_; + std::size_t dimension_; + Result_type status_; + template + CC_prejoin_info(const Simplex_handle& simplex) + : simplex_(to_string(simplex)), dimension_(simplex.dimension()) {} +}; +using CC_prejoin_list = std::list; +std::vector cc_interior_prejoin_lists, cc_boundary_prejoin_lists; + + +struct CC_join_info { + enum class Result_type {self, face, coface, inserted, join_single, join_is_face}; + std::string simplex_, join_, trigger_; + Result_type status_; + std::list boundary_faces_; + std::list faces_, post_faces_, cofaces_; + template + CC_join_info(const Simplex_handle& simplex) + : simplex_(to_string(simplex)) {} +}; +bool join_switch = false; +std::vector cc_interior_join_detail_lists, cc_boundary_join_detail_lists; + +std::map cell_vlist_map; +std::map simplex_vlist_map; + +std::ostringstream mt_ostream, vis_ostream; +std::vector cc_summary_ostream, cc_traces_ostream; + +std::string simplex_format(const std::string& simplex, bool is_boundary) { + std::string b_simplex = (is_boundary? "B": "I") + simplex; + std::string tooltiptext; + auto it = simplex_vlist_map.find(b_simplex); + if (it == simplex_vlist_map.end()) + tooltiptext = "deleted"; + else + tooltiptext = simplex_vlist_map.at(b_simplex); + return (std::string)"" + b_simplex + + "" + tooltiptext + ""; +} + +std::string simplex_format(const std::string& b_simplex) { + bool is_boundary = b_simplex[0] == 'B'; + std::string tooltiptext; + auto it = simplex_vlist_map.find(b_simplex); + if (it == simplex_vlist_map.end()) + tooltiptext = "deleted"; + else + tooltiptext = simplex_vlist_map.at(b_simplex); + return (std::string)"" + b_simplex + + "" + tooltiptext + ""; +} + + +void write_head(std::ofstream& ofs) { + ofs << " \n" + << " Cell complex debug trace\n" + << " \n" + << " \n"; +} + +void write_nav(std::ofstream& ofs) { + ofs << "
\n" + << " \n" + << "
\n"; +} + +void write_mt(std::ofstream& ofs) { + ofs << "
\n"; + ofs << "

Manifold debug trace

\n"; + ofs << "

Simplices inserted during the seed phase

\n"; + ofs << "
    \n"; + for (const MT_inserted_info& mt_info: mt_seed_inserted_list) { + if (mt_info.qr_success_) { + ofs << "
  • Inserted " << simplex_format(mt_info.qr_face_, mt_info.is_boundary_); + if (mt_info.qr_face_ != mt_info.init_face_) + ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")"; + ofs << " intersection point is " << mt_info.qr_intersection_ << "
  • \n"; + } + else + ofs << "
  • Failed to insert " << mt_info.init_face_ + << "
  • \n"; + } + ofs << "
\n"; + ofs << "

Simplices inserted during the while loop phase

\n"; + ofs << "
    \n"; + for (const MT_inserted_info& mt_info: mt_inserted_list) { + if (mt_info.qr_success_) { + ofs << "
  • Inserted " << simplex_format(mt_info.qr_face_, mt_info.is_boundary_); + if (mt_info.qr_face_ != mt_info.init_face_) + ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")"; + ofs << " intersection point is " << mt_info.qr_intersection_ << "
  • \n"; + } + else + ofs << "
  • Failed to insert " << mt_info.init_face_ + << ")
  • \n"; + } + ofs << "
\n"; + ofs << "
\n"; +} + +void write_cc(std::ofstream& ofs) { + ofs << "
\n" + << "

Cell complex debug trace

\n" + << "

Go to:

\n" + << "
    \n"; + for (std::size_t i = 0; i < cc_interior_summary_lists.size(); ++i) { + ofs << "
  • Dimension " << i << "
  • \n"; + } + ofs << "
\n"; + for (std::size_t i = 0; i < cc_interior_summary_lists.size(); ++i) { + ofs << "

Dimension " << i << "

\n"; + ofs << "

Summary for interior simplices

\n"; + if (i < cc_boundary_summary_lists.size()) + ofs << "

Go to boundary

\n"; + ofs << "
    \n"; + for (const CC_summary_info& cc_info: cc_interior_summary_lists[i]) + ofs << "
  • " + << simplex_format(cc_info.face_, false) + << " cell =" << cc_info.cell_ << "
  • \n"; + ofs << "
\n"; + ofs << "

Prejoin state of the interior cells of dimension " << i << "

\n"; + auto prejoin_it = cc_interior_prejoin_lists[i].begin(); + while (prejoin_it != cc_interior_prejoin_lists[i].end()) { + std::size_t j = prejoin_it->dimension_; + ofs << "
" << j << "-dimensional ambient simplices
\n"; + ofs << "
    \n"; + for (; prejoin_it->dimension_ == j; ++prejoin_it) { + ofs << "
  • " << simplex_format(prejoin_it->simplex_, false) + << " join = " << simplex_format(prejoin_it->join_, false) + << " boundary:\n" + << "
      \n"; + for (const auto& face: prejoin_it->faces_) + ofs << "
    • " << simplex_format(face) << "
    • "; + ofs << "
    \n"; + switch (prejoin_it->status_) { + case (CC_prejoin_info::Result_type::join_single): + ofs << "

    Deleted " + << simplex_format(prejoin_it->simplex_, false) + << " as it has a single face.

    "; + break; + case (CC_prejoin_info::Result_type::join_is_face): + ofs << "

    Deleted " + << simplex_format(prejoin_it->simplex_, false) + << " as its join " << simplex_format(prejoin_it->join_, false) + << " is one of the faces.

    "; + break; + case (CC_prejoin_info::Result_type::join_different): + ofs << "

    Deleted " << simplex_format(prejoin_it->simplex_, false) + << " and replaced by its join " << simplex_format(prejoin_it->join_, false) + << ".

    "; + break; + case (CC_prejoin_info::Result_type::join_same): + ofs << "

    Kept " << simplex_format(prejoin_it->simplex_, false) + << ".

    "; + } + ofs << "
  • "; + } + ofs << "
\n"; + } + ofs << "

Details for interior simplices

\n"; + ofs << "
    \n"; + for (const CC_detail_info& cc_info: cc_interior_detail_lists[i]) { + if (cc_info.status_ == CC_detail_info::Result_type::join_single) { + ofs << "
  • Simplex " + << simplex_format(cc_info.simplex_, false) << " has only one face (" + << simplex_format(cc_info.trigger_, false) << ") and is deleted."; + continue; + } + if (cc_info.status_ == CC_detail_info::Result_type::join_single) { + ofs << "
  • The join of the simplex " + << simplex_format(cc_info.simplex_, false) << " is one of its faces (" + << simplex_format(cc_info.trigger_, false) << "), hence it is is deleted."; + continue; + } + ofs << "
  • Insert_cell called for " << simplex_format(cc_info.simplex_, false) + << "\n"; + ofs << "
      \n"; + // for (const std::string& cof: cc_info.faces_) + // ofs << "
    • Checking if " << simplex_format(cc_info.simplex_, false) + // << " is a face of " << simplex_format(cof, false) << "\n"; + ofs << "
    \n"; + ofs << "
      \n"; + if (cc_info.status_ == CC_detail_info::Result_type::self) { + ofs << "

      The simplex " + << simplex_format(cc_info.simplex_, false) + << " already exists in the cell complex!

      \n"; + } + if (cc_info.status_ == CC_detail_info::Result_type::face) { + ofs << "

      The simplex " + << simplex_format(cc_info.simplex_, false) << " is a face of the simplex " + << simplex_format(cc_info.trigger_, false) << "!
      \n"; + ofs << "

        \n"; + for (const std::string post_face: cc_info.post_faces_) + ofs << "
      • " + << "Post deleting " << simplex_format(post_face, false) << "
      • \n"; + ofs << "
      \n"; + ofs << "

      \n"; + ofs << "

      " + << "Deleting " << simplex_format(cc_info.trigger_, false) << "

      \n"; + } + // for (const std::string& fac: cc_info.cofaces_) + // ofs << "
    • Checking if " << simplex_format(cc_info.simplex_, false) + // << " is a coface of " << simplex_format(fac, false) << "\n"; + if (cc_info.status_ == CC_detail_info::Result_type::coface) { + ofs << "

      The simplex " + << simplex_format(cc_info.simplex_, false) << " is a coface of the simplex " + << simplex_format(cc_info.trigger_, false) << "!

      \n"; + } + if (cc_info.status_ == CC_detail_info::Result_type::inserted) { + ofs << "

      Successfully inserted " + << simplex_format(cc_info.simplex_, false) << "!

      \n"; + } + ofs << "

    \n"; + ofs << "
  • \n"; + } + ofs << "
\n"; + + if (i < cc_boundary_summary_lists.size()) { + ofs << "

Summary for boundary simplices

\n"; + ofs << "

Go to interior

\n"; + ofs << "
    \n"; + for (const CC_summary_info& cc_info: cc_boundary_summary_lists[i]) + ofs << "
  • " + << simplex_format(cc_info.face_, true) + << " cell =" << cc_info.cell_ << "
  • \n"; + ofs << "
\n"; + ofs << "

Prejoin state of the boundary cells of dimension " << i << "

\n"; + auto prejoin_it = cc_boundary_prejoin_lists[i].begin(); + while (prejoin_it != cc_boundary_prejoin_lists[i].end()) { + std::size_t j = prejoin_it->dimension_; + ofs << "
" << j << "-dimensional ambient simplices
\n"; + ofs << "
    \n"; + for (; prejoin_it->dimension_ == j; ++prejoin_it) { + ofs << "
  • " << simplex_format(prejoin_it->simplex_, true) + << " join = " << simplex_format(prejoin_it->join_, true) + << " boundary:\n" + << "
      \n"; + for (const auto& face: prejoin_it->faces_) + ofs << "
    • " << simplex_format(face) << "
    • "; + ofs << "
    \n"; + switch (prejoin_it->status_) { + case (CC_prejoin_info::Result_type::join_single): + ofs << "

    Deleted " + << simplex_format(prejoin_it->simplex_, true) + << " as it has a single face.

    "; + break; + case (CC_prejoin_info::Result_type::join_is_face): + ofs << "

    Deleted " + << simplex_format(prejoin_it->simplex_, true) + << " as its join " << simplex_format(prejoin_it->join_, true) + << " is one of the faces.

    "; + break; + case (CC_prejoin_info::Result_type::join_different): + ofs << "

    Deleted " << simplex_format(prejoin_it->simplex_, true) + << " and replaced by its join " << simplex_format(prejoin_it->join_, true) + << ".

    "; + break; + case (CC_prejoin_info::Result_type::join_same): + ofs << "

    Kept " << simplex_format(prejoin_it->simplex_, true) + << ".

    "; + } + ofs << "
  • "; + } + ofs << "
\n"; + } + } + if (i < cc_boundary_detail_lists.size()) { + ofs << "

Details for boundary simplices

\n" + << "
    \n"; + for (const CC_detail_info& cc_info: cc_boundary_detail_lists[i]) { + if (cc_info.status_ == CC_detail_info::Result_type::join_single) { + ofs << "
  • Simplex " + << simplex_format(cc_info.simplex_, true) << " has only one face (" + << simplex_format(cc_info.trigger_, true) << ") and is deleted."; + continue; + } + if (cc_info.status_ == CC_detail_info::Result_type::join_single) { + ofs << "
  • The join of the simplex " + << simplex_format(cc_info.simplex_, true) << " is one of its faces (" + << simplex_format(cc_info.trigger_, true) << "), hence it is is deleted."; + continue; + } + ofs << "
  • Insert_simplex called on " << simplex_format(cc_info.simplex_, true); + ofs << "
      \n"; + // for (const std::string& cof: cc_info.faces_) + // ofs << "
    • Checking if " << simplex_format(cc_info.simplex_, true) + // << " is a face of " << simplex_format(cof, true) << "\n"; + ofs << "
    \n"; + ofs << "
      \n"; + if (cc_info.status_ == CC_detail_info::Result_type::self) { + ofs << "

      The simplex " + << simplex_format(cc_info.simplex_, true) + << " already exists in the cell complex!

      \n"; + } + if (cc_info.status_ == CC_detail_info::Result_type::face) { + ofs << "

      The simplex " + << simplex_format(cc_info.simplex_, true) << " is a face of the simplex " + << simplex_format(cc_info.trigger_, true) << "!
      \n"; + ofs << "

        \n"; + for (const std::string post_face: cc_info.post_faces_) + ofs << "
      • Post deleting " << simplex_format(post_face, true) + << "
      • \n"; + ofs << "
      \n"; + ofs << "

      \n"; + ofs << "

      Deleting " << simplex_format(cc_info.trigger_, true) << "

      \n"; + } + // for (const std::string& fac: cc_info.cofaces_) + // ofs << "
    • Checking if " << simplex_format(cc_info.simplex_, true) + // << " is a coface of " << simplex_format(fac, true) << "\n"; + ofs << "
    \n"; + ofs << "
  • \n"; + if (cc_info.status_ == CC_detail_info::Result_type::coface) { + ofs << "

    The simplex " + << simplex_format(cc_info.simplex_, true) << " is a coface of the simplex " + << simplex_format(cc_info.trigger_, true) << "!

    \n"; + } + if (cc_info.status_ == CC_detail_info::Result_type::inserted) { + ofs << "

    Successfully inserted " + << simplex_format(cc_info.simplex_, true) << "!

    \n"; + } + } + ofs << "

\n"; + } + } + ofs << "
\n"; +} + +void write_visu(std::ofstream& ofs) { + ofs << "
\n" + << "

Visualization details debug trace

\n"; + // std::vector > vs_maps(cc_interior_summary_lists.size()); + std::map vs_map; + for (const auto& sv_pair: simplex_vlist_map) + vs_map.emplace(std::make_pair(sv_pair.second, sv_pair.first)); + ofs << "
    \n"; + for (const auto& vs_pair: vs_map) { + std::string w_simplex = vs_pair.second.substr(1); + bool is_boundary = vs_pair.second[0] == 'B'; + ofs << "
  • " << vs_pair.first << ": " + << simplex_format(w_simplex, is_boundary) << "
  • \n"; + } + ofs << "
\n"; + ofs << "
\n"; +} + +void write_to_html(std::string file_name) { + std::ofstream ofs(file_name + ".html", std::ofstream::out); + ofs << "\n" + << "\n"; + write_head(ofs); + ofs << " \n"; + write_nav(ofs); + ofs << "

Debug traces for " << file_name << "

\n"; + write_mt(ofs); + write_cc(ofs); + write_visu(ofs); + ofs << " \n"; + ofs << "\n"; + + ofs.close(); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif + diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h new file mode 100644 index 00000000..fe379242 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h @@ -0,0 +1,181 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef IO_OUTPUT_MESHES_TO_MEDIT_H_ +#define IO_OUTPUT_MESHES_TO_MEDIT_H_ + +#include +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +using Vertex_points = Mesh_medit::Vertex_points; +using Mesh_elements = Mesh_medit::Mesh_elements; +using Scalar_field_range = Mesh_medit::Scalar_field_range; + +template +typename std::enable_if::type +fill_meshes (Vertex_points& vertex_points, + Mesh_elements& edges, + Mesh_elements& triangles, + Mesh_elements& tetrahedra, + Scalar_field_range& triangles_scalar_range, + Scalar_field_range& tetrahedra_scalar_range, + std::size_t index, + const Meshes&... meshes) { +} + +template +typename std::enable_if::type +fill_meshes (Vertex_points& vertex_points, + Mesh_elements& edges, + Mesh_elements& triangles, + Mesh_elements& tetrahedra, + Scalar_field_range& triangles_scalar_range, + Scalar_field_range& tetrahedra_scalar_range, + std::size_t index, + const Meshes&... meshes) { + auto mesh = std::get(std::forward_as_tuple(meshes...)); + for (const auto& v: mesh.vertex_points) + vertex_points.push_back(v); + for (const auto& e: mesh.edges) { + std::vector edge; + for (const auto& v_i: e.first) + edge.push_back(v_i + index); + edges.emplace_back(std::make_pair(edge, e.second)); + } + for (const auto& t: mesh.triangles) { + std::vector triangle; + for (const auto& v_i: t.first) + triangle.push_back(v_i + index); + triangles.emplace_back(std::make_pair(triangle, t.second)); + } + for (const auto& t: mesh.tetrahedra) { + std::vector tetrahedron; + for (const auto& v_i: t.first) + tetrahedron.push_back(v_i + index); + tetrahedra.emplace_back(std::make_pair(tetrahedron, t.second)); + } + for (const auto& b: mesh.triangles_scalar_range) + triangles_scalar_range.push_back(b); + for (const auto& b: mesh.tetrahedra_scalar_range) + tetrahedra_scalar_range.push_back(b); + fill_meshes(vertex_points, + edges, + triangles, + tetrahedra, + triangles_scalar_range, + tetrahedra_scalar_range, + index + mesh.vertex_points.size(), + meshes...); +} + +/** \brief Outputs a text file with specified meshes that can be visualized in Medit. + * + * @param[in] amb_d Ambient dimension. Can be 2 or 3. + * @param[in] file_name The name of the output file. + * @param[in] meshes A pack of meshes to be specified separated by commas. + */ +template +void output_meshes_to_medit(std::size_t amb_d, std::string file_name, const Meshes&... meshes) { + Vertex_points vertex_points; + Mesh_elements edges, triangles, tetrahedra; + Scalar_field_range triangles_scalar_range, tetrahedra_scalar_range; + fill_meshes(vertex_points, + edges, + triangles, + tetrahedra, + triangles_scalar_range, + tetrahedra_scalar_range, + 0, + meshes...); + + std::ofstream ofs (file_name + ".mesh", std::ofstream::out); + std::ofstream ofs_bb (file_name + ".bb", std::ofstream::out); + + if (amb_d == 2) { + ofs << "MeshVersionFormatted 1\nDimension 2\n"; + ofs_bb << "2 1 "; + ofs << "Vertices\n" << vertex_points.size() << "\n"; + for (auto p: vertex_points) { + ofs << p[0] << " " << p[1] << " 2\n"; + } + ofs << "Edges " << edges.size() << "\n"; + for (auto e: edges) { + for (auto v: e.first) + ofs << v << " "; + ofs << e.second << std::endl; + } + ofs << "Triangles " << triangles.size() << "\n"; + for (auto s: triangles) { + for (auto v: s.first) { + ofs << v << " "; + } + ofs << s.second << std::endl; + } + + ofs_bb << triangles_scalar_range.size() << " 1\n"; + for (auto& b: triangles_scalar_range) + ofs_bb << b << "\n"; + + } + else { + ofs << "MeshVersionFormatted 1\nDimension 3\n"; + ofs_bb << "3 1 "; + ofs << "Vertices\n" << vertex_points.size() << "\n"; + for (auto p: vertex_points) { + ofs << p[0] << " " << p[1] << " " << p[2] << " 2\n"; + } + ofs << "Edges " << edges.size() << "\n"; + for (auto e: edges) { + for (auto v: e.first) + ofs << v << " "; + ofs << e.second << std::endl; + } + ofs << "Triangles " << triangles.size() << "\n"; + for (auto s: triangles) { + for (auto v: s.first) { + ofs << v << " "; + } + ofs << s.second << std::endl; + } + ofs << "Tetrahedra " << tetrahedra.size() << "\n"; + for (auto s: tetrahedra) { + for (auto v: s.first) { + ofs << v << " "; + } + ofs << s.second << std::endl; + } + + ofs_bb << triangles_scalar_range.size() + tetrahedra_scalar_range.size() << " 1\n"; + for (auto& b: triangles_scalar_range) + ofs_bb << b << "\n"; + for (auto& b: tetrahedra_scalar_range) + ofs_bb << b << "\n"; + } + + + ofs.close(); + ofs_bb.close(); + +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h new file mode 100644 index 00000000..a522f691 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -0,0 +1,279 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef IMPLICIT_MANIFOLD_INTERSECTION_ORACLE_H_ +#define IMPLICIT_MANIFOLD_INTERSECTION_ORACLE_H_ + +#include + +#include +#include +#include +#include + +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + + + +/** \class Implicit_manifold_intersection_oracle + * \brief An oracle that supports the intersection query on an implicit manifold. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * \tparam Domain_function_ The domain function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template +class Implicit_manifold_intersection_oracle { + + /* Computes the affine coordinates of the intersection point of the implicit manifold + * and the affine hull of the simplex. */ + template + Eigen::VectorXd compute_lambda(const Simplex_handle& simplex, + const Triangulation& triangulation) const { + std::size_t cod_d = this->cod_d(); + Eigen::MatrixXd matrix(cod_d + 1, cod_d + 1); + for (std::size_t i = 0; i < cod_d + 1; ++i) + matrix(0, i) = 1; + std::size_t j = 0; + for (auto v: simplex.vertex_range()) { + Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v)); + for (std::size_t i = 1; i < cod_d + 1; ++i) + matrix(i, j) = v_coords(i-1); + j++; + } + Eigen::VectorXd z(cod_d + 1); + z(0) = 1; + for (std::size_t i = 1; i < cod_d + 1; ++i) + z(i) = 0; + Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z); + return lambda; + } + + /* Computes the affine coordinates of the intersection point of the boundary + * of the implicit manifold and the affine hull of the simplex. */ + template + Eigen::VectorXd compute_boundary_lambda(const Simplex_handle& simplex, + const Triangulation& triangulation) const { + std::size_t cod_d = this->cod_d(); + Eigen::MatrixXd matrix(cod_d + 2, cod_d + 2); + for (std::size_t i = 0; i < cod_d + 2; ++i) + matrix(0, i) = 1; + std::size_t j = 0; + for (auto v: simplex.vertex_range()) { + Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v)); + for (std::size_t i = 1; i < cod_d + 1; ++i) + matrix(i, j) = v_coords(i-1); + Eigen::VectorXd bv_coords = domain_fun_(triangulation.cartesian_coordinates(v)); + matrix(cod_d + 1, j) = bv_coords(0); + j++; + } + Eigen::VectorXd z(cod_d + 2); + z(0) = 1; + for (std::size_t i = 1; i < cod_d + 2; ++i) + z(i) = 0; + Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z); + return lambda; + } + + /* Computes the intersection result for a given simplex in a triangulation. */ + template + Query_result intersection_result(const Eigen::VectorXd& lambda, + const Simplex_handle& simplex, + const Triangulation& triangulation) const { + using QR = Query_result; + std::size_t amb_d = triangulation.dimension(); + std::size_t cod_d = simplex.dimension(); + + for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) + if (lambda(i) < 0 || lambda(i) > 1) + return QR({Eigen::VectorXd(), false}); + + Eigen::MatrixXd vertex_matrix(cod_d + 1, amb_d); + auto v_range = simplex.vertex_range(); + auto v_it = v_range.begin(); + for (std::size_t i = 0; i < cod_d + 1 && v_it != v_range.end(); ++v_it, ++i) { + Eigen::VectorXd v_coords = triangulation.cartesian_coordinates(*v_it); + for (std::size_t j = 0; j < amb_d; ++j) + vertex_matrix(i, j) = v_coords(j); + } + Eigen::VectorXd intersection = lambda.transpose()*vertex_matrix; + return QR({intersection, true}); + } + +public: + + /** \brief Ambient dimension of the implicit manifold. */ + std::size_t amb_d() const { + return fun_.amb_d(); + } + + /** \brief Codimension of the implicit manifold. */ + std::size_t cod_d() const { + return fun_.cod_d(); + } + + /** \brief Intersection query with the relative interior of the manifold. + * + * \details The returned structure Query_result contains the boolean value + * that is true only if the intersection point of the query simplex and + * the relative interior of the manifold exists, the intersection point + * and the face of the query simplex that contains + * the intersection point. + * + * \tparam Simplex_handle The class of the query simplex. + * Needs to be a model of the concept SimplexInCoxeterTriangulation. + * \tparam Triangulation The class of the triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + * + * @param[in] simplex The query simplex. The dimension of the simplex + * should be the same as the codimension of the manifold + * (the codomain dimension of the function). + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold + * (the domain dimension of the function). + */ + template + Query_result intersects(const Simplex_handle& simplex, + const Triangulation& triangulation) const { + Eigen::VectorXd lambda = compute_lambda(simplex, triangulation); + return intersection_result(lambda, simplex, triangulation); + } + + /** \brief Intersection query with the boundary of the manifold. + * + * \details The returned structure Query_result contains the boolean value + * that is true only if the intersection point of the query simplex and + * the boundary of the manifold exists, the intersection point + * and the face of the query simplex that contains + * the intersection point. + * + * \tparam Simplex_handle The class of the query simplex. + * Needs to be a model of the concept SimplexInCoxeterTriangulation. + * \tparam Triangulation The class of the triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + * + * @param[in] simplex The query simplex. The dimension of the simplex + * should be the same as the codimension of the boundary of the manifold + * (the codomain dimension of the function + 1). + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold + * (the domain dimension of the function). + */ + template + Query_result intersects_boundary(const Simplex_handle& simplex, + const Triangulation& triangulation) const { + Eigen::VectorXd lambda = compute_boundary_lambda(simplex, triangulation); + return intersection_result(lambda, simplex, triangulation); + } + + + /** \brief Returns true if the input point lies inside the piecewise-linear + * domain induced by the given ambient triangulation that defines the relative + * interior of the piecewise-linear approximation of the manifold. + * + * @param p The input point. Needs to have the same dimension as the ambient + * dimension of the manifold (the domain dimension of the function). + * @param triangulation The ambient triangulation. Needs to have the same + * dimension as the ambient dimension of the manifold + * (the domain dimension of the function). + */ + template + bool lies_in_domain(const Eigen::VectorXd& p, + const Triangulation& triangulation) const { + Eigen::VectorXd pl_p = make_pl_approximation(domain_fun_, triangulation)(p); + return pl_p(0) < 0; + } + + /** \brief Returns the function that defines the interior of the manifold */ + const Function_& function() const { + return fun_; + } + + /** \brief Constructs an intersection oracle for an implicit manifold potentially + * with boundary from given function and domain. + * + * @param function The input function that represents the implicit manifold + * before the restriction with the domain. + * @param domain_function The input domain function that can be used to define an implicit + * manifold with boundary. + */ + Implicit_manifold_intersection_oracle(const Function_& function, + const Domain_function_& domain_function) + : fun_(function), domain_fun_(domain_function) {} + + /** \brief Constructs an intersection oracle for an implicit manifold + * without boundary from a given function. + * + * \details To use this constructor, the template Domain_function_ needs to be left + * at its default value (Gudhi::coxeter_triangulation::Constant_function). + * + * @param function The input function that represents the implicit manifold + * without boundary. + */ + Implicit_manifold_intersection_oracle(const Function_& function) + : fun_(function), + domain_fun_(function.amb_d(), 1, Eigen::VectorXd::Constant(1,-1)) {} + +private: + Function_ fun_; + Domain_function_ domain_fun_; +}; + +/** \brief Static constructor of an intersection oracle from a function with a domain. + * + * @param function The input function that represents the implicit manifold + * before the restriction with the domain. + * @param domain_function The input domain function that can be used to define an implicit + * manifold with boundary. + * + * \ingroup coxeter_triangulation + */ +template +Implicit_manifold_intersection_oracle +make_oracle(const Function_& function, + const Domain_function_& domain_function){ + return Implicit_manifold_intersection_oracle(function, + domain_function); +} + + +/** \brief Static constructor of an intersection oracle from a function without a domain. + * + * @param function The input function that represents the implicit manifold + * without boundary. + * + * \ingroup coxeter_triangulation + */ +template +Implicit_manifold_intersection_oracle make_oracle(const Function_& function){ + return Implicit_manifold_intersection_oracle(function); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h new file mode 100644 index 00000000..fdb4f630 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -0,0 +1,307 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef MANIFOLD_TRACING_H_ +#define MANIFOLD_TRACING_H_ + +#include + +#include + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \ingroup coxeter_triangulation + */ + +/** \class Manifold_tracing + * \brief A class that assembles methods for manifold tracing algorithm. + * + * \tparam Triangulation_ The type of the ambient triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + */ +template +class Manifold_tracing { + + typedef typename Triangulation_::Simplex_handle Simplex_handle; + + struct Simplex_hash { + typedef Simplex_handle argument_type; + typedef std::size_t result_type; + result_type operator()(const argument_type& s) const noexcept { + return boost::hash()(s.vertex()); + } + }; + +public: + /** \brief Type of the output simplex map with keys of type Triangulation_::Simplex_handle + * and values of type Eigen::VectorXd. + * This type should be used for the output in the method manifold_tracing_algorithm. + */ + typedef std::unordered_map Out_simplex_map; + + /** + * \brief Computes the set of k-simplices that intersect + * a boundaryless implicit manifold given by an intersection oracle, where k + * is the codimension of the manifold. + * The computation is based on the seed propagation --- it starts at the + * given seed points and then propagates along the manifold. + * + * \tparam Point_range Range of points of type Eigen::VectorXd. + * \tparam Intersection_oracle Intersection oracle that represents the manifold. + * Needs to be a model of the concept IntersectionOracle. + * + * \param[in] seed_points The range of points on the manifold from which + * the computation begins. + * \param[in] triangulation The ambient triangulation. + * \param[in] oracle The intersection oracle for the manifold. + * The ambient dimension needs to match the dimension of the + * triangulation. + * \param[out] out_simplex_map The output map, where the keys are k-simplices in + * the input triangulation that intersect the input manifold and the mapped values + * are the intersection points. + */ + template + void manifold_tracing_algorithm(const Point_range& seed_points, + const Triangulation_& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& out_simplex_map) { + std::size_t cod_d = oracle.cod_d(); + std::queue queue; + + for (const auto& p: seed_points) { + Simplex_handle full_simplex = triangulation.locate_point(p); + for (Simplex_handle face: full_simplex.face_range(cod_d)) { + Query_result qr = oracle.intersects(face, triangulation); + if (qr.success && + out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { +#ifdef GUDHI_COX_OUTPUT_TO_HTML + mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); +#endif + queue.emplace(face); + break; + } + } + } + + + while (!queue.empty()) { + Simplex_handle s = queue.front(); + queue.pop(); + for (auto cof: s.coface_range(cod_d+1)) { + for (auto face: cof.face_range(cod_d)) { + Query_result qr = oracle.intersects(face, triangulation); + if (qr.success && + out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) + queue.emplace(face); + } + } + } + } + + /** + * \brief Computes the set of k-simplices that intersect + * the dimensional manifold given by an intersection oracle, where k + * is the codimension of the manifold. + * The computation is based on the seed propagation --- it starts at the + * given seed points and then propagates along the manifold. + * + * \tparam Point_range Range of points of type Eigen::VectorXd. + * \tparam Intersection_oracle Intersection oracle that represents the manifold. + * Needs to be a model of the concept IntersectionOracle. + * + * \param[in] seed_points The range of points on the manifold from which + * the computation begins. + * \param[in] triangulation The ambient triangulation. + * \param[in] oracle The intersection oracle for the manifold. + * The ambient dimension needs to match the dimension of the + * triangulation. + * \param[out] interior_simplex_map The output map, where the keys are k-simplices in + * the input triangulation that intersect the relative interior of the input manifold + * and the mapped values are the intersection points. + * \param[out] boundary_simplex_map The output map, where the keys are k-simplices in + * the input triangulation that intersect the boundary of the input manifold + * and the mapped values are the intersection points. + */ + template + void manifold_tracing_algorithm(const Point_range& seed_points, + const Triangulation_& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& interior_simplex_map, + Out_simplex_map& boundary_simplex_map) { + std::size_t cod_d = oracle.cod_d(); + std::queue queue; + + for (const auto& p: seed_points) { + Simplex_handle full_simplex = triangulation.locate_point(p); + for (Simplex_handle face: full_simplex.face_range(cod_d)) { + auto qr = oracle.intersects(face, triangulation); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); +#endif + if (qr.success) { + if (oracle.lies_in_domain(qr.intersection, triangulation)) { + if (interior_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) + queue.emplace(face); + } + else { + for (Simplex_handle cof: face.coface_range(cod_d+1)) { + auto qrb = oracle.intersects_boundary(cof, triangulation); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + mt_seed_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); +#endif + if (qrb.success) + boundary_simplex_map.emplace(cof, qrb.intersection); + } + } + // break; + } + } + } + + while (!queue.empty()) { + Simplex_handle s = queue.front(); + queue.pop(); + for (auto cof: s.coface_range(cod_d+1)) { + for (auto face: cof.face_range(cod_d)) { + auto qr = oracle.intersects(face, triangulation); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + mt_inserted_list.push_back(MT_inserted_info(qr, face, false)); +#endif + if (qr.success) { + if (oracle.lies_in_domain(qr.intersection, triangulation)) { + if (interior_simplex_map.emplace(face, qr.intersection).second) + queue.emplace(face); + } + else { + auto qrb = oracle.intersects_boundary(cof, triangulation); +#ifdef GUDHI_COX_OUTPUT_TO_HTML + mt_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); +#endif + // assert (qrb.success); // always a success + if (qrb.success) + boundary_simplex_map.emplace(cof, qrb.intersection); + } + } + } + } + } + } + + /** \brief Empty constructor */ + Manifold_tracing() {} + +}; + +/** + * \brief Static method for Manifold_tracing::manifold_tracing_algorithm + * that computes the set of k-simplices that intersect + * a boundaryless implicit manifold given by an intersection oracle, where k + * is the codimension of the manifold. + * The computation is based on the seed propagation --- it starts at the + * given seed points and then propagates along the manifold. + * + * \tparam Point_range Range of points of type Eigen::VectorXd. + * \tparam Triangulation_ The type of the ambient triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + * \tparam Intersection_oracle Intersection oracle that represents the manifold. + * Needs to be a model of the concept IntersectionOracle. + * \tparam Out_simplex_map Needs to be Manifold_tracing::Out_simplex_map. + * + * \param[in] seed_points The range of points on the manifold from which + * the computation begins. + * \param[in] triangulation The ambient triangulation. + * \param[in] oracle The intersection oracle for the manifold. + * The ambient dimension needs to match the dimension of the + * triangulation. + * \param[out] out_simplex_map The output map, where the keys are k-simplices in + * the input triangulation that intersect the input manifold and the mapped values + * are the intersection points. + * + * \ingroup coxeter_triangulation + */ +template +void manifold_tracing_algorithm(const Point_range& seed_points, + const Triangulation& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& out_simplex_map) { + Manifold_tracing mt; + mt.manifold_tracing_algorithm(seed_points, + triangulation, + oracle, + out_simplex_map); +} + +/** + * \brief Static method for Manifold_tracing::manifold_tracing_algorithm + * the dimensional manifold given by an intersection oracle, where k + * is the codimension of the manifold. + * The computation is based on the seed propagation --- it starts at the + * given seed points and then propagates along the manifold. + * + * \tparam Point_range Range of points of type Eigen::VectorXd. + * \tparam Triangulation_ The type of the ambient triangulation. + * Needs to be a model of the concept TriangulationForManifoldTracing. + * \tparam Intersection_oracle Intersection oracle that represents the manifold. + * Needs to be a model of the concept IntersectionOracle. + * \tparam Out_simplex_map Needs to be Manifold_tracing::Out_simplex_map. + * + * \param[in] seed_points The range of points on the manifold from which + * the computation begins. + * \param[in] triangulation The ambient triangulation. + * \param[in] oracle The intersection oracle for the manifold. + * The ambient dimension needs to match the dimension of the + * triangulation. + * \param[out] interior_simplex_map The output map, where the keys are k-simplices in + * the input triangulation that intersect the relative interior of the input manifold + * and the mapped values are the intersection points. + * \param[out] boundary_simplex_map The output map, where the keys are k-simplices in + * the input triangulation that intersect the boundary of the input manifold + * and the mapped values are the intersection points. + * + * \ingroup coxeter_triangulation + */ +template +void manifold_tracing_algorithm(const Point_range& seed_points, + const Triangulation& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& interior_simplex_map, + Out_simplex_map& boundary_simplex_map) { + Manifold_tracing mt; + mt.manifold_tracing_algorithm(seed_points, + triangulation, + oracle, + interior_simplex_map, + boundary_simplex_map); +} + + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h new file mode 100644 index 00000000..a3c2b2c7 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h @@ -0,0 +1,257 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_H_ +#define PERMUTAHEDRAL_REPRESENTATION_H_ + +#include + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Permutahedral_representation + * \brief A class that stores the permutahedral representation of a simplex + * in a Coxeter triangulation or a Freudenthal-Kuhn triangulation. + * + * \ingroup coxeter_triangulation + * + * \details The data structure is a record consisting of a range that + * represents the vertex and a range that represents the ordered set + * partition, both of which identify the simplex in the triangulation. + * + * \tparam Vertex_ needs to be a random-access range. + * \tparam Ordered_set_partition_ needs to be a a random-access range that consists of + * random-access ranges. + */ +template +class Permutahedral_representation { + + typedef Permutahedral_representation Self; + +public: + /** \brief Type of the vertex. */ + typedef Vertex_ Vertex; + + /** \brief Type of the ordered partition. */ + typedef Ordered_set_partition_ OrderedSetPartition; + + + /** \brief Permutahedral_representation constructor from a vertex and an ordered set partition. + * + * @param[in] vertex Vertex. + * @param[in] partition Ordered set partition. + * + * \details If the size of vertex is d, the ranges in partition must consist + * of the integers 0,...,d without repetition or collision between the ranges. + */ + Permutahedral_representation(const Vertex& vertex, const OrderedSetPartition& partition) + : vertex_(vertex), partition_(partition) {} + + /** \brief Constructor for an empty permutahedral representation that does not correspond + * to any simplex. + */ + Permutahedral_representation() {} + + /** \brief Dimension of the simplex. */ + std::size_t dimension() const { + return partition_.size() - 1; + } + + /** \brief Lexicographically-minimal vertex. */ + Vertex& vertex() { + return vertex_; + } + + /** \brief Lexicographically-minimal vertex. */ + const Vertex& vertex() const { + return vertex_; + } + + /** \brief Ordered set partition. */ + OrderedSetPartition& partition() { + return partition_; + } + + /** \brief Identifying vertex. */ + const OrderedSetPartition& partition() const { + return partition_; + } + + /** \brief Equality operator. + * Returns true if an only if both vertex and the ordered set partition coincide. + */ + bool operator==(const Permutahedral_representation& other) const { + if (dimension() != other.dimension()) + return false; + if (vertex_ != other.vertex_) + return false; + for (std::size_t k = 0; k < partition_.size(); ++k) + if (partition_[k] != other.partition_[k]) + return false; + return true; + } + + /** \brief Inequality operator. + * Returns true if an only if either vertex or the ordered set partition are different. + */ + bool operator!=(const Permutahedral_representation& other) const { + return !(*this == other); + } + + typedef Gudhi::coxeter_triangulation::Vertex_iterator Vertex_iterator; + typedef boost::iterator_range Vertex_range; + /** \brief Returns a range of vertices of the simplex. + * The type of vertices is Vertex. + */ + Vertex_range vertex_range() const { + return Vertex_range(Vertex_iterator(*this), + Vertex_iterator()); + } + + typedef Gudhi::coxeter_triangulation::Face_iterator Face_iterator; + typedef boost::iterator_range Face_range; + /** \brief Returns a range of permutahedral representations of faces of the simplex. + * @param[in] value_dim The dimension of the faces. Must be between 0 and the dimension of the simplex. + */ + Face_range face_range(std::size_t value_dim) const { + return Face_range(Face_iterator(*this, value_dim), + Face_iterator()); + } + + /** \brief Returns a range of permutahedral representations of facets of the simplex. + * The dimension of the simplex must be strictly positive. + */ + Face_range facet_range() const { + return Face_range(Face_iterator(*this, dimension()-1), + Face_iterator()); + } + + typedef Gudhi::coxeter_triangulation::Coface_iterator Coface_iterator; + typedef boost::iterator_range Coface_range; + /** \brief Returns a range of permutahedral representations of cofaces of the simplex. + * @param[in] value_dim The dimension of the cofaces. Must be between the dimension of the simplex and the ambient dimension (the size of the vertex). + */ + Coface_range coface_range(std::size_t value_dim) const { + return Coface_range(Coface_iterator(*this, value_dim), + Coface_iterator()); + } + + /** \brief Returns a range of permutahedral representations of cofacets of the simplex. + * The dimension of the simplex must be strictly different from the ambient dimension (the size of the vertex). + */ + Coface_range cofacet_range() const { + return Coface_range(Coface_iterator(*this, dimension()+1), + Coface_iterator()); + } + + /** \brief Returns true, if the simplex is a face of other simplex. + * + * @param[in] other A simplex that is potential a coface of the current simplex. + */ + bool is_face_of(const Permutahedral_representation& other) const { + using Part = typename OrderedSetPartition::value_type; + + if (other.dimension() < dimension()) + return false; + if (other.vertex_.size() != vertex_.size()) + std::cerr << "Error: Permutahedral_representation::is_face_of: incompatible ambient dimensions.\n"; + + Vertex v_self = vertex_, v_other = other.vertex_; + auto self_partition_it = partition_.begin(); + auto other_partition_it = other.partition_.begin(); + while (self_partition_it != partition_.end()) { + while (other_partition_it != other.partition_.end() && v_self != v_other) { + const Part& other_part = *other_partition_it++; + if (other_partition_it == other.partition_.end()) + return false; + for (const auto& k: other_part) + v_other[k]++; + } + if (other_partition_it == other.partition_.end()) + return false; + const Part& self_part = *self_partition_it++; + if (self_partition_it == partition_.end()) + return true; + for (const auto& k: self_part) + v_self[k]++; + } + return true; + } + +private: + Vertex vertex_; + OrderedSetPartition partition_; + +}; + +/** \brief Print a permutahedral representation to a stream. + * \ingroup coxeter_triangulation + * + * @param[in] os The output stream. + * @param[in] simplex A simplex represented by its permutahedral representation. + */ +template +std::ostream& operator<<(std::ostream& os, + const Permutahedral_representation& simplex) { + // vertex part + os << "("; + if (simplex.vertex().empty()) { + os << ")"; + return os; + } + auto v_it = simplex.vertex().begin(); + os << *v_it++; + for (; v_it != simplex.vertex().end(); ++v_it) + os << ", " << *v_it; + os << ")"; + + // ordered partition part + using Part = typename OrderedSetPartition::value_type; + auto print_part = + [&os](const Part& p) { + os << "{"; + if (p.empty()) { + os << "}"; + } + auto p_it = p.begin(); + os << *p_it++; + for (; p_it != p.end(); ++p_it) + os << ", " << *p_it; + os << "}"; + }; + os << " ["; + if (simplex.partition().empty()) { + os << "]"; + return os; + } + auto o_it = simplex.partition().begin(); + print_part(*o_it++); + for (; o_it != simplex.partition().end(); ++o_it) { + os << ", "; + print_part(*o_it); + } + os << "]"; + return os; +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif // PERMUTAHEDRAL_REPRESENTATION_H_ diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h new file mode 100644 index 00000000..20a4a8ff --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h @@ -0,0 +1,101 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_COMBINATION_ITERATOR_H_ +#define PERMUTAHEDRAL_REPRESENTATION_COMBINATION_ITERATOR_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +typedef unsigned uint; + +/** \brief Class that allows the user to generate combinations of + * k elements in a set of n elements. + * Based on the algorithm by Mifsud. +*/ +class Combination_iterator : public boost::iterator_facade< Combination_iterator, + std::vector const, + boost::forward_traversal_tag> { + typedef std::vector value_t; + +protected: + friend class boost::iterator_core_access; + + bool equal(Combination_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void increment() { + if (value_[0] == n_ - k_) { + is_end_ = true; + return; + } + uint j = k_ - 1; + if (value_[j] < n_ - 1) { + value_[j]++; + return; + } + for (; j > 0; --j) + if (value_[j-1] < n_ - k_ + j-1) { + value_[j-1]++; + for (uint s = j; s < k_; s++) + value_[s] = value_[j-1] + s - (j-1); + return; + } + } + +public: + + Combination_iterator(const uint& n, const uint& k) + : + value_(k), + is_end_(n == 0), + n_(n), + k_(k) + { + for (uint i = 0; i < k; ++i) + value_[i] = i; + } + + // Used for the creating an end iterator + Combination_iterator() : is_end_(true), n_(0), k_(0) {} + + void reinitialize() { + if (n_ > 0) { + is_end_ = false; + for (uint i = 0; i < n_; ++i) + value_[i] = i; + } + } + +protected: + value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one + + uint n_; + uint k_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h new file mode 100644 index 00000000..47eb8b98 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h @@ -0,0 +1,128 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_INTEGER_COMBINATION_ITERATOR_H_ +#define PERMUTAHEDRAL_REPRESENTATION_INTEGER_COMBINATION_ITERATOR_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +typedef unsigned uint; + +/** \brief Class that allows the user to generate combinations of + * k elements in a set of n elements. + * Based on the algorithm by Mifsud. +*/ +class Integer_combination_iterator : public boost::iterator_facade< Integer_combination_iterator, + std::vector const, + boost::forward_traversal_tag> { + typedef std::vector value_t; + +protected: + friend class boost::iterator_core_access; + + bool equal(Integer_combination_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void increment() { + uint j1 = 0; + uint s = 0; + while (value_[j1] == 0 && j1 < k_) + j1++; + uint j2 = j1+1; + while (value_[j2] == bounds_[j2]) { + if (bounds_[j2] != 0) { + s += value_[j1]; + value_[j1] = 0; + j1 = j2; + } + j2++; + } + if (j2 >= k_) { + is_end_ = true; + return; + } + s += value_[j1] - 1; + value_[j1] = 0; + value_[j2]++; + uint i = 0; + while (s >= bounds_[i]) { + value_[i] = bounds_[i]; + s -= bounds_[i]; + i++; + } + value_[i++] = s; + } + +public: + + template + Integer_combination_iterator(const uint& n, const uint& k, const Bound_range& bounds) + : + value_(k+2), + is_end_(n == 0 || k == 0), + n_(n), + k_(k) + { + bounds_.reserve(k+2); + uint sum_radices = 0; + for (auto b: bounds) { + bounds_.push_back(b); + sum_radices += b; + } + bounds_.push_back(2); + bounds_.push_back(1); + if (n > sum_radices) { + is_end_ = true; + return; + } + uint i = 0; + uint s = n; + while (s >= bounds_[i]) { + value_[i] = bounds_[i]; + s -= bounds_[i]; + i++; + } + value_[i++] = s; + + while (i < k_) + value_[i++] = 0; + value_[k] = 1; + value_[k+1] = 0; + } + + // Used for the creating an end iterator + Integer_combination_iterator() : is_end_(true), n_(0), k_(0) {} + +protected: + value_t value_; // the dereference value + bool is_end_; // is true when the current integer combination is the final one + + uint n_; + uint k_; + std::vector bounds_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h new file mode 100644 index 00000000..55c32664 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h @@ -0,0 +1,108 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_ORDERED_SET_PARTITION_ITERATOR_H_ +#define PERMUTAHEDRAL_REPRESENTATION_ORDERED_SET_PARTITION_ITERATOR_H_ + +#include +#include +#include +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +typedef unsigned uint; + +/** \brief Class that represents an ordered set partition of a set {0,...,n-1} in k parts as + * a pair of an unordered set partition given in lexicographic order and + * a permutation of the parts. + */ +struct Ordered_set_partition { + Set_partition_iterator s_it_; + Permutation_iterator p_it_; + + // Ordered_set_partition(const Set_partition_iterator& s_it, const Permutation_iterator& p_it) + // : s_it_(s_it), p_it_(p_it) {} + + const std::vector operator[](const uint& i) const { + return (*s_it_)[(*p_it_)[i]]; + } + + std::size_t size() const { + return s_it_->size(); + } + +}; + +/** \brief Class that allows the user to generate set partitions of a set {0,...,n-1} in k parts. + * +*/ +class Ordered_set_partition_iterator : public boost::iterator_facade< Ordered_set_partition_iterator, + Ordered_set_partition const, + boost::forward_traversal_tag> { + typedef Ordered_set_partition value_t; + +protected: + friend class boost::iterator_core_access; + + bool equal(Ordered_set_partition_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void increment() { + if (++value_.p_it_ == p_end_) { + if (++value_.s_it_ == s_end_) { + is_end_ = true; + return; + } + else + value_.p_it_.reinitialize(); + } + } + +public: + + Ordered_set_partition_iterator(const uint& n, const uint& k) + : + value_({Set_partition_iterator(n,k), Permutation_iterator(k)}), + is_end_(n == 0) + { + } + + // Used for the creating an end iterator + Ordered_set_partition_iterator() : is_end_(true) {} + + void reinitialize() { + is_end_ = false; + value_.p_it_.reinitialize(); + value_.s_it_.reinitialize(); + } + +protected: + Set_partition_iterator s_end_; // Set partition iterator and the corresponding end iterator + Permutation_iterator p_end_; // Permutation iterator and the corresponding end iterator + value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h new file mode 100644 index 00000000..4528ef20 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h @@ -0,0 +1,288 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_PERMUTAHEDRAL_REPRESENTATION_ITERATORS_H_ +#define PERMUTAHEDRAL_REPRESENTATION_PERMUTAHEDRAL_REPRESENTATION_ITERATORS_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +/* \addtogroup coxeter_triangulation + * Iterator types for Permutahedral_representation + * @{ + */ + +/* \brief Iterator over the vertices of a simplex + * represented by its permutahedral representation. + * + * Forward iterator, 'value_type' is Permutahedral_representation::Vertex.*/ +template +class Vertex_iterator : public boost::iterator_facade< Vertex_iterator, + typename Permutahedral_representation::Vertex const, + boost::forward_traversal_tag> { +protected: + friend class boost::iterator_core_access; + + using Vertex = typename Permutahedral_representation::Vertex; + using Ordered_partition = typename Permutahedral_representation::OrderedSetPartition; + + typedef Vertex value_t; + + + bool equal(Vertex_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void update_value() { + std::size_t d = value_.size(); + for (auto i: *o_it_) + if (i != d) + value_[i]++; + else + for (std::size_t j = 0; j < d; j++) + value_[j]--; + } + + void increment() { + if (is_end_) + return; + update_value(); + if (++o_it_ == o_end_) + is_end_ = true; + } + +public: + Vertex_iterator(const Permutahedral_representation& simplex) + : + o_it_(simplex.partition().begin()), + o_end_(simplex.partition().end()), + value_(simplex.vertex()), + is_end_(o_it_ == o_end_) + {} + + Vertex_iterator() : is_end_(true) {} + + +protected: + typename Ordered_partition::const_iterator o_it_, o_end_; + value_t value_; + bool is_end_; + +}; // Vertex_iterator + +/*---------------------------------------------------------------------------*/ +/* \brief Iterator over the k-faces of a simplex + * given by its permutahedral representation. + * + * Forward iterator, value_type is Permutahedral_representation. */ +template +class Face_iterator : public boost::iterator_facade< Face_iterator, + Permutahedral_representation const, + boost::forward_traversal_tag> { + typedef Permutahedral_representation value_t; + +protected: + friend class boost::iterator_core_access; + + using Vertex = typename Permutahedral_representation::Vertex; + using Ordered_partition = typename Permutahedral_representation::OrderedSetPartition; + + bool equal(Face_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void increment() { + if (++c_it_ == c_end_) { + is_end_ = true; + return; + } + update_value(); + } + + void update_value() { + // Combination *c_it_ is supposed to be sorted in increasing order + value_ = face_from_indices(simplex_, *c_it_); + } + +public: + + Face_iterator(const Permutahedral_representation& simplex, const uint& k) + : simplex_(simplex), + k_(k), + l_(simplex.dimension()), + c_it_(l_+1, k_+1), + is_end_(k_ > l_), + value_({Vertex(simplex.vertex().size()), Ordered_partition(k+1)}) + { + update_value(); + } + + // Used for the creating an end iterator + Face_iterator() : is_end_(true) {} + +protected: + Permutahedral_representation simplex_; // Input simplex + uint k_; + uint l_; // Dimension of the input simplex + Combination_iterator c_it_, c_end_; // indicates the vertices in the current face + + bool is_end_; // is true when the current permutation is the final one + value_t value_; // the dereference value + +}; // Face_iterator + +/*---------------------------------------------------------------------------*/ +/* \brief Iterator over the k-cofaces of a simplex + * given by its permutahedral representation. + * + * Forward iterator, value_type is Permutahedral_representation. */ +template +class Coface_iterator : public boost::iterator_facade< Coface_iterator, + Permutahedral_representation const, + boost::forward_traversal_tag> { + typedef Permutahedral_representation value_t; + +protected: + friend class boost::iterator_core_access; + + using Vertex = typename Permutahedral_representation::Vertex; + using Ordered_partition = typename Permutahedral_representation::OrderedSetPartition; + + bool equal(Coface_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void increment() { + uint i = 0; + for (; i < k_+1; i++) { + if (++(o_its_[i]) != o_end_) + break; + } + if (i == k_+1) { + if (++i_it_ == i_end_) { + is_end_ = true; + return; + } + o_its_.clear(); + for (uint j = 0; j < k_ + 1; j++) + o_its_.emplace_back(Ordered_set_partition_iterator(simplex_.partition()[j].size(), (*i_it_)[j]+1)); + } + else + for (uint j = 0; j < i; j++) + o_its_[j].reinitialize(); + update_value(); + } + + void update_value() { + value_.vertex() = simplex_.vertex(); + for (auto& p: value_.partition()) + p.clear(); + uint u_ = 0; // the part in o_its_[k_] that contains t_ + for (; u_ <= (*i_it_)[k_]; u_++) { + auto range = (*o_its_[k_])[u_]; + if (std::find(range.begin(), range.end(), t_) != range.end()) + break; + } + uint i = 0; + for (uint j = u_+1; j <= (*i_it_)[k_]; j++, i++) + for (uint b: (*o_its_[k_])[j]) { + uint c = simplex_.partition()[k_][b]; + value_.partition()[i].push_back(c); + value_.vertex()[c]--; + } + for (uint h = 0; h < k_; h++) + for (uint j = 0; j <= (*i_it_)[h]; j++, i++) { + for (uint b: (*o_its_[h])[j]) + value_.partition()[i].push_back(simplex_.partition()[h][b]); + } + for (uint j = 0; j <= u_; j++, i++) + for (uint b: (*o_its_[k_])[j]) + value_.partition()[i].push_back(simplex_.partition()[k_][b]); + // sort the values in each part (probably not needed) + for (auto& part: value_.partition()) + std::sort(part.begin(), part.end()); + } + +public: + + Coface_iterator(const Permutahedral_representation& simplex, const uint& l) + : simplex_(simplex), + d_(simplex.vertex().size()), + l_(l), + k_(simplex.dimension()), + i_it_(l_-k_ , k_+1, Size_range(simplex.partition())), + is_end_(k_ > l_), + value_({Vertex(d_), Ordered_partition(l_+1)}) + { + uint j = 0; + for (; j < simplex_.partition()[k_].size(); j++) + if (simplex_.partition()[k_][j] == d_) { + t_ = j; + break; + } + if (j == simplex_.partition()[k_].size()) { + std::cerr << "Coface iterator: the argument simplex is not a permutahedral representation\n"; + is_end_ = true; + return; + } + for (uint i = 0; i < k_+1; i++) + o_its_.emplace_back(Ordered_set_partition_iterator(simplex_.partition()[i].size(), (*i_it_)[i]+1)); + update_value(); + } + + // Used for the creating an end iterator + Coface_iterator() : is_end_(true) {} + +protected: + Permutahedral_representation simplex_; // Input simplex + uint d_; // Ambient dimension + uint l_; // Dimension of the coface + uint k_; // Dimension of the input simplex + uint t_; // The position of d in simplex_.partition()[k_] + Integer_combination_iterator i_it_, i_end_; // indicates in how many parts each simplex_[i] is subdivided + std::vector o_its_; // indicates subdivision for each simplex_[i] + Ordered_set_partition_iterator o_end_; // one end for all o_its_ + + bool is_end_; // is true when the current permutation is the final one + value_t value_; // the dereference value + +}; // Coface_iterator + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h new file mode 100644 index 00000000..7cf6158b --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h @@ -0,0 +1,137 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_PERMUTATION_ITERATOR_H_ +#define PERMUTAHEDRAL_REPRESENTATION_PERMUTATION_ITERATOR_H_ + +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +typedef unsigned uint; + +/** \brief Class that allows the user to generate permutations. + * Based on the optimization of the Heap's algorithm by Sedgewick. +*/ +class Permutation_iterator : public boost::iterator_facade< Permutation_iterator, + std::vector const, + boost::forward_traversal_tag> { + typedef std::vector value_t; + +protected: + friend class boost::iterator_core_access; + + bool equal(Permutation_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void swap_two_indices(std::size_t i, std::size_t j) { + uint t = value_[i]; + value_[i] = value_[j]; + value_[j] = t; + } + + void elementary_increment() { + uint j = 0; + while (d_[j] == j+1) { + d_[j] = 0; + ++j; + } + if (j == n_ - 1) { + is_end_ = true; + return; + } + uint k = j+1; + uint x = (k%2 ? d_[j] : 0); + swap_two_indices(k, x); + ++d_[j]; + } + + void elementary_increment_optim_3() { + if (ct_ != 0) { + --ct_; + swap_two_indices(1 + (ct_%2), 0); + } + else { + ct_ = 5; + uint j = 2; + while (d_[j] == j+1) { + d_[j] = 0; + ++j; + } + if (j == n_ - 1) { + is_end_ = true; + return; + } + uint k = j+1; + uint x = (k%2 ? d_[j] : 0); + swap_two_indices(k, x); + ++d_[j]; + } + } + + void increment() { + if (optim_3_) + elementary_increment_optim_3(); + else + elementary_increment(); + } + +public: + + Permutation_iterator(const uint& n) + : + value_(n), + is_end_(n == 0), + optim_3_(n >= 3), + n_(n), + d_(n), + ct_(5) + { + for (uint i = 0; i < n; ++i) { + value_[i] = i; + d_[i] = 0; + } + if (n > 0) + d_[n-1] = -1; + } + + // Used for the creating an end iterator + Permutation_iterator() : is_end_(true), n_(0) {} + + void reinitialize() { + if (n_ > 0) + is_end_ = false; + } + +protected: + value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one + bool optim_3_; // true if n>=3. for n >= 3, the algorithm is optimized + + uint n_; + std::vector d_; // mix radix digits with radix [2 3 4 ... n-1 (sentinel=-1)] + uint ct_; // counter with values in {0,...,5} used in the n>=3 optimization. +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h new file mode 100644 index 00000000..46f67752 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h @@ -0,0 +1,137 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_SET_PARTITION_ITERATOR_H_ +#define PERMUTAHEDRAL_REPRESENTATION_SET_PARTITION_ITERATOR_H_ + +#include +#include +#include + +namespace Gudhi { + +namespace coxeter_triangulation { + +typedef unsigned uint; + +/** \brief Class that allows the user to generate set partitions of a set {0,...,n-1} in k parts. + * +*/ +class Set_partition_iterator : public boost::iterator_facade< Set_partition_iterator, + std::vector > const, + boost::forward_traversal_tag> { + typedef std::vector > value_t; + +protected: + friend class boost::iterator_core_access; + + bool equal(Set_partition_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + value_t const& dereference() const { + return value_; + } + + void update_value() { + for (uint i = 0; i < k_; i++) + value_[i].clear(); + for (uint i = 0; i < n_; i++) + value_[rgs_[i]].push_back(i); + } + + void increment() { + if (k_ <= 1) { + is_end_ = true; + return; + } + uint i = n_ - 1; + while (rgs_[i] + 1 > max_[i] || + rgs_[i] + 1 >= k_) + i--; + if (i == 0) { + is_end_ = true; + return; + } + rgs_[i]++; + uint mm = max_[i]; + mm += (rgs_[i] >= mm); + max_[i+1] = mm; + while (++i < n_) { + rgs_[i] = 0; + max_[i+1] = mm; + } + uint p = k_; + if (mm < p) + do { + max_[i] = p; + --i; + --p; + rgs_[i] = p; + } while (max_[i] < p); + update_value(); + } + +public: + + Set_partition_iterator(const uint& n, const uint& k) + : + value_(k), + rgs_(n, 0), + max_(n+1), + is_end_(n == 0), + n_(n), + k_(k) + { + max_[0] = std::numeric_limits::max(); + for (uint i = 0; i <= n-k; ++i) + value_[0].push_back(i); + for (uint i = n-k+1, j = 1; i < n; ++i, ++j) { + rgs_[i] = j; + value_[j].push_back(i); + } + for (uint i = 1; i <= n; i++) + max_[i] = rgs_[i-1] + 1; + update_value(); + } + + // Used for creating an end iterator + Set_partition_iterator() : is_end_(true), n_(0), k_(0) {} + + void reinitialize() { + if (n_ > 0) + is_end_ = false; + for (uint i = 0; i <= n_-k_; ++i) + rgs_[i] = 0; + for (uint i = n_-k_+1, j = 1; i < n_; ++i, ++j) + rgs_[i] = j; + for (uint i = 1; i <= n_; i++) + max_[i] = rgs_[i-1] + 1; + update_value(); + } + +protected: + value_t value_; // the dereference value + std::vector rgs_; // restricted growth string + std::vector max_; // max_[i] = max(rgs_[0],...,rgs[i-1]) + 1 + bool is_end_; // is true when the current permutation is the final one + + uint n_; + uint k_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h new file mode 100644 index 00000000..5b3c29e9 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h @@ -0,0 +1,64 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_SIMPLEX_COMPARATOR_H_ +#define PERMUTAHEDRAL_REPRESENTATION_SIMPLEX_COMPARATOR_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Simplex_comparator + * \brief A comparator class for Permutahedral_representation. + * The comparison is in lexicographic order first on + * vertices and then on ordered partitions with sorted parts. + * The lexicographic order forces that any face is larger than + * a coface. + * + * \tparam Permutahdral_representation_ Needs to be + * Permutahedral_representation + * + * \ingroup coxeter_triangulation + */ +template +struct Simplex_comparator { + + /** \brief Comparison between two permutahedral representations. + * Both permutahedral representations need to be valid and + * the vertices of both permutahedral representations need to be of the same size. + */ + bool operator() (const Permutahedral_representation_& lhs, + const Permutahedral_representation_& rhs) const { + if (lhs.vertex() < rhs.vertex()) + return true; + if (lhs.vertex() > rhs.vertex()) + return false; + + if (lhs.partition().size() > rhs.partition().size()) + return true; + if (lhs.partition().size() < rhs.partition().size()) + return false; + + if (lhs.partition() < rhs.partition()) + return true; + if (lhs.partition() > rhs.partition()) + return false; + + return false; + } +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h new file mode 100644 index 00000000..dd9c20dc --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h @@ -0,0 +1,89 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_SIZE_RANGE_H_ +#define PERMUTAHEDRAL_REPRESENTATION_SIZE_RANGE_H_ + +#include +#include // std::size_t + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief Auxillary iterator class for sizes of parts in an ordered set partition. + */ +template +class Size_iterator : public boost::iterator_facade< Size_iterator, + std::size_t const, + boost::forward_traversal_tag> { + friend class boost::iterator_core_access; + +protected: + bool equal(Size_iterator const& other) const { + return (is_end_ && other.is_end_); + } + + std::size_t const& dereference() const { + return value_; + } + + void increment() { + if (++t_it_ == t_end_) { + is_end_ = true; + return; + } + value_ = t_it_->size()-1; + } + +public: + + Size_iterator(const T_it& t_begin, const T_it& t_end) + : t_it_(t_begin), t_end_(t_end), is_end_(t_begin == t_end) { + if (!is_end_) + value_ = t_it_->size()-1; + } + +protected: + T_it t_it_, t_end_; + bool is_end_; + std::size_t value_; +}; + +template +class Size_range { + const T& t_; + +public: + typedef Size_iterator iterator; + + Size_range(const T& t) : t_(t) {} + + std::size_t operator[](std::size_t i) const { + return t_[i].size()-1; + } + + iterator begin() const { + return iterator(t_.begin(), t_.end()); + } + + iterator end() const { + return iterator(t_.end(), t_.end()); + } + +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h new file mode 100644 index 00000000..461a01e7 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h @@ -0,0 +1,71 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef PERMUTAHEDRAL_REPRESENTATION_FACE_FROM_INDICES_H_ +#define PERMUTAHEDRAL_REPRESENTATION_FACE_FROM_INDICES_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + + /** \brief Computes the permutahedral representation of a face of a given simplex + * and a range of the vertex indices that compose the face. + * + * \tparam Permutahedral_representation has to be Permutahedral_representation + * \tparam Index_range is a range of unsigned integers taking values in 0,...,k, + * where k is the dimension of the simplex simplex. + * + * @param[in] simplex Input simplex. + * @param[in] indices Input range of indices. + */ +template +Permutahedral_representation face_from_indices(const Permutahedral_representation& simplex, + const Index_range& indices) { + using range_index = typename Index_range::value_type; + using Ordered_set_partition = typename Permutahedral_representation::OrderedSetPartition; + using Part = typename Ordered_set_partition::value_type; + using part_index = typename Part::value_type; + Permutahedral_representation value; + std::size_t d = simplex.vertex().size(); + value.vertex() = simplex.vertex(); + std::size_t k = indices.size()-1; + value.partition().resize(k+1); + std::size_t l = simplex.partition().size()-1; + for (std::size_t h = 1; h < k+1; h++) + for (range_index i = indices[h-1]; i < indices[h]; i++) + for (part_index j: simplex.partition()[i]) + value.partition()[h-1].push_back(j); + for (range_index i = indices[k]; i < l+1; i++) + for (part_index j: simplex.partition()[i]) + value.partition()[k].push_back(j); + for (range_index i = 0; i < indices[0]; i++) + for (part_index j: simplex.partition()[i]) { + if (j != d) + value.vertex()[j]++; + else + for (std::size_t l = 0; l < d; l++) + value.vertex()[l]--; + value.partition()[k].push_back(j); + } + // sort the values in each part (probably not needed) + for (auto& part: value.partition()) + std::sort(part.begin(), part.end()); + return value; +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Query_result.h new file mode 100644 index 00000000..c7384c0b --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Query_result.h @@ -0,0 +1,42 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef QUERY_RESULT_H_ +#define QUERY_RESULT_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Query_result + * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. + * + * \tparam Simplex_handle The class of the query simplex. + * + * \ingroup coxeter_triangulation + */ +template +struct Query_result { + /** \brief The potentially lower-dimensional face of the query simplex + * that contains the intersection point. OBSOLETE: as the snapping is removed. */ + // Simplex_handle face; + /** \brief The intersection point. */ + Eigen::VectorXd intersection; + /** \brief True if the query simplex intersects the manifold. */ + bool success; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/test/CMakeLists.txt b/src/Coxeter_triangulation/test/CMakeLists.txt new file mode 100644 index 00000000..663768b1 --- /dev/null +++ b/src/Coxeter_triangulation/test/CMakeLists.txt @@ -0,0 +1,33 @@ +project(Coxeter_triangulation_test) + +include(GUDHI_test_coverage) + + +add_executable ( Coxeter_triangulation_permutahedral_representation_test perm_rep_test.cpp ) +target_link_libraries( Coxeter_triangulation_permutahedral_representation_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ) +gudhi_add_coverage_test(Coxeter_triangulation_permutahedral_representation_test) + +add_executable ( Coxeter_triangulation_freudenthal_triangulation_test freud_triang_test.cpp ) +target_link_libraries( Coxeter_triangulation_freudenthal_triangulation_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +gudhi_add_coverage_test(Coxeter_triangulation_freudenthal_triangulation_test) + +add_executable ( Coxeter_triangulation_functions_test function_test.cpp ) +target_link_libraries( Coxeter_triangulation_functions_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +gudhi_add_coverage_test(Coxeter_triangulation_functions_test) + +add_executable ( Coxeter_triangulation_oracle_test oracle_test.cpp ) +target_link_libraries( Coxeter_triangulation_oracle_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +gudhi_add_coverage_test(Coxeter_triangulation_oracle_test) + +add_executable ( Coxeter_triangulation_manifold_tracing_test manifold_tracing_test.cpp ) +target_link_libraries( Coxeter_triangulation_manifold_tracing_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +gudhi_add_coverage_test(Coxeter_triangulation_manifold_tracing_test) + +add_executable ( Coxeter_triangulation_cell_complex_test cell_complex_test.cpp ) +target_link_libraries( Coxeter_triangulation_cell_complex_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +gudhi_add_coverage_test(Coxeter_triangulation_cell_complex_test) + +if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_cell_complex_test ${TBB_LIBRARIES}) +endif() + diff --git a/src/Coxeter_triangulation/test/cell_complex_test.cpp b/src/Coxeter_triangulation/test/cell_complex_test.cpp new file mode 100644 index 00000000..a48696a6 --- /dev/null +++ b/src/Coxeter_triangulation/test/cell_complex_test.cpp @@ -0,0 +1,62 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "cell_complex" +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +BOOST_AUTO_TEST_CASE(cell_complex) { + + double radius = 1.1111; + Function_torus_in_R3 fun_torus(radius, 3*radius); + Eigen::VectorXd seed = fun_torus.seed(); + Function_Sm_in_Rd fun_bound(2.5*radius, 2, seed); + + auto oracle = make_oracle(fun_torus, fun_bound); + double lambda = 0.2; + Coxeter_triangulation<> cox_tr(oracle.amb_d()); + cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); + cox_tr.change_matrix(lambda * cox_tr.matrix()); + + using MT = Manifold_tracing >; + using Out_simplex_map = typename MT::Out_simplex_map; + std::vector seed_points(1, seed); + Out_simplex_map interior_simplex_map, boundary_simplex_map; + manifold_tracing_algorithm(seed_points, cox_tr, oracle, interior_simplex_map, boundary_simplex_map); + + std::size_t intr_d = oracle.amb_d() - oracle.cod_d(); + Cell_complex cell_complex(intr_d); + cell_complex.construct_complex(interior_simplex_map, boundary_simplex_map); + + std::size_t interior_sc_map_size0 = cell_complex.interior_simplex_cell_map(0).size(); + std::size_t interior_sc_map_size1 = cell_complex.interior_simplex_cell_map(1).size(); + std::size_t interior_sc_map_size2 = cell_complex.interior_simplex_cell_map(2).size(); + std::size_t boundary_sc_map_size0 = cell_complex.boundary_simplex_cell_map(0).size(); + std::size_t boundary_sc_map_size1 = cell_complex.boundary_simplex_cell_map(1).size(); + BOOST_CHECK (interior_simplex_map.size() == interior_sc_map_size0 ); + BOOST_CHECK ( boundary_sc_map_size0 - boundary_sc_map_size1 == 0 ); + BOOST_CHECK ( interior_sc_map_size0 - interior_sc_map_size1 + interior_sc_map_size2 == 0 ); +} diff --git a/src/Coxeter_triangulation/test/freud_triang_test.cpp b/src/Coxeter_triangulation/test/freud_triang_test.cpp new file mode 100644 index 00000000..6e7bf865 --- /dev/null +++ b/src/Coxeter_triangulation/test/freud_triang_test.cpp @@ -0,0 +1,104 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "freudenthal_triangulation" +#include + +#include +#include +#include + +BOOST_AUTO_TEST_CASE(freudenthal_triangulation) { + + // Point location check + typedef std::vector Point; + typedef Gudhi::coxeter_triangulation::Freudenthal_triangulation<> FK_triangulation; + typedef typename FK_triangulation::Simplex_handle Simplex_handle; + typedef typename FK_triangulation::Vertex_handle Vertex_handle; + typedef typename Simplex_handle::OrderedSetPartition Ordered_set_partition; + typedef typename Ordered_set_partition::value_type Part; + + FK_triangulation tr(3); + + // Point location check + { + Point point({3, -1, 0}); + Simplex_handle s = tr.locate_point(point); + BOOST_CHECK( s.vertex() == Vertex_handle({3, -1, 0}) ); + BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0, 1, 2, 3})}) ); + } + + { + Point point({3.5, -1.5, 0.5}); + Simplex_handle s = tr.locate_point(point); + BOOST_CHECK( s.vertex() == Vertex_handle({3, -2, 0}) ); + BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0, 1, 2}), Part({3})}) ); + } + + { + Point point({3.5, -1.8, 0.5}); + Simplex_handle s = tr.locate_point(point); + BOOST_CHECK( s.vertex() == Vertex_handle({3, -2, 0}) ); + BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0, 2}), Part({1}), Part({3})}) ); + } + + { + Point point({3.5, -1.8, 0.3}); + Simplex_handle s = tr.locate_point(point); + BOOST_CHECK( s.vertex() == Vertex_handle({3, -2, 0}) ); + BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0}), Part({2}), Part({1}), Part({3})}) ); + } + + // Dimension check + BOOST_CHECK( tr.dimension() == 3 ); + // Matrix check + Eigen::MatrixXd default_matrix = Eigen::MatrixXd::Identity(3, 3); + BOOST_CHECK( tr.matrix() == default_matrix ); + // Vector check + Eigen::MatrixXd default_offset = Eigen::VectorXd::Zero(3); + BOOST_CHECK( tr.offset() == default_offset ); + + // Barycenter check + Point point({3.5, -1.8, 0.3}); + Simplex_handle s = tr.locate_point(point); + Eigen::Vector3d barycenter_cart = Eigen::Vector3d::Zero(); + for (auto v: s.vertex_range()) + for (std::size_t i = 0; i < v.size(); i++) + barycenter_cart(i) += v[i]; + barycenter_cart /= 4.; // simplex is three-dimensional + Eigen::Vector3d barycenter = tr.barycenter(s); + for (std::size_t i = 0; (long int)i < barycenter.size(); i++) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(barycenter(i), barycenter_cart(i), 1e-7); + + // Barycenter check for twice the scale + s = tr.locate_point(point, 2); + barycenter_cart = Eigen::Vector3d::Zero(); + for (auto v: s.vertex_range()) + for (std::size_t i = 0; i < v.size(); i++) + barycenter_cart(i) += v[i]; + barycenter_cart /= 3.; // simplex is now a two-dimensional face + barycenter_cart /= 2.; // scale + barycenter = tr.barycenter(s, 2); + for (std::size_t i = 0; (long int)i < barycenter.size(); i++) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(barycenter(i), barycenter_cart(i), 1e-7); + + // Matrix and offset change check + Eigen::MatrixXd new_matrix(3,3); + new_matrix << 1, 0, 0, -1, 1, 0, -1, 0, 1; + Eigen::Vector3d new_offset(1.5, 1, 0.5); + tr.change_matrix(new_matrix); + tr.change_offset(new_offset); + + BOOST_CHECK( tr.matrix() == new_matrix ); + BOOST_CHECK( tr.offset() == new_offset ); +} diff --git a/src/Coxeter_triangulation/test/function_test.cpp b/src/Coxeter_triangulation/test/function_test.cpp new file mode 100644 index 00000000..518bef9b --- /dev/null +++ b/src/Coxeter_triangulation/test/function_test.cpp @@ -0,0 +1,177 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +// workaround for the annoying boost message in boost 1.69 +#define BOOST_PENDING_INTEGER_LOG2_HPP +#include +// end workaround + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "function" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +template +void test_function(const Function& fun) { + Eigen::VectorXd seed = fun.seed(); + Eigen::VectorXd res_seed = fun(fun.seed()); + BOOST_CHECK( seed.size() == (long int)fun.amb_d() ); + BOOST_CHECK( res_seed.size() == (long int)fun.cod_d() ); + for (std::size_t i = 0; i < fun.cod_d(); i++) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(res_seed(i), 0., 1e-10); +} + +BOOST_AUTO_TEST_CASE(function) { + + { + // the sphere testing part + std::size_t m = 3, d = 5; + Eigen::VectorXd center(d); center << 2, 1.5, -0.5, 4.5, -1; + double radius = 5; + typedef Function_Sm_in_Rd Function_sphere; + Function_sphere fun_sphere(radius, m, d, center); + test_function(fun_sphere); + } + { + // the affine plane testing part + std::size_t m = 0, d = 5; + Eigen::MatrixXd normal_matrix = Eigen::MatrixXd::Zero(d, d-m); + for (std::size_t i = 0; i < d-m; ++i) + normal_matrix(i,i) = 1; + typedef Function_affine_plane_in_Rd Function_plane; + Function_plane fun_plane(normal_matrix); + test_function(fun_plane); + } + { + // the constant function testing part + std::size_t k = 2, d = 5; + auto x = Eigen::VectorXd::Constant(k, 1); + Constant_function fun_const(d, k, x); + Eigen::VectorXd res_zero = fun_const(Eigen::VectorXd::Zero(d)); + for (std::size_t i = 0; i < k; ++i) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(res_zero(i), x(i), 1e-10); + } + { + // the chair function + Function_chair_in_R3 fun_chair; + test_function(fun_chair); + } + { + // the torus function + Function_torus_in_R3 fun_torus; + test_function(fun_torus); + } + { + // the whitney umbrella function + Function_whitney_umbrella_in_R3 fun_umbrella; + test_function(fun_umbrella); + } + { + // the lemniscate revolution function + Function_lemniscate_revolution_in_R3 fun_lemniscate; + test_function(fun_lemniscate); + } + { + // the iron function + Function_iron_in_R3 fun_iron; + test_function(fun_iron); + } + { + Function_moment_curve_in_Rd fun_moment_curve(3, 5); + test_function(fun_moment_curve); + } + { + // random orthogonal matrix + Eigen::MatrixXd matrix = random_orthogonal_matrix(5); + Eigen::MatrixXd id_matrix = matrix.transpose() * matrix; + for (std::size_t i = 0; i < 5; ++i) + for (std::size_t j = 0; j < 5; ++j) + if (i == j) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i,j), 1.0, 1e-10); + else + GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i,j), 0.0, 1e-10); + } + { + // function embedding + Function_iron_in_R3 fun_iron; + auto fun_embed = make_embedding(fun_iron, 5); + test_function(fun_iron); + + // function translation + Eigen::VectorXd off = Eigen::VectorXd::Random(5); + auto fun_trans = translate(fun_embed, off); + test_function(fun_trans); + + // function linear transformation + Eigen::MatrixXd matrix = Eigen::MatrixXd::Random(5, 5); + BOOST_CHECK( matrix.determinant() != 0. ); + auto fun_lin = make_linear_transformation(fun_trans, matrix); + test_function(fun_lin); + + // function negative + auto fun_neg = negation(fun_lin); + test_function(fun_neg); + + // function product + typedef Function_Sm_in_Rd Function_sphere; + Function_sphere fun_sphere(1, 1); + auto fun_prod = make_product_function(fun_sphere, fun_sphere, fun_sphere); + test_function(fun_prod); + + // function PL approximation + Coxeter_triangulation<> cox_tr(6); + typedef Coxeter_triangulation<>::Vertex_handle Vertex_handle; + auto fun_pl = make_pl_approximation(fun_prod, cox_tr); + Vertex_handle v0 = Vertex_handle(cox_tr.dimension(), 0); + Eigen::VectorXd x0 = cox_tr.cartesian_coordinates(v0); + Eigen::VectorXd value0 = fun_prod(x0); + Eigen::VectorXd pl_value0 = fun_pl(x0); + for (std::size_t i = 0; i < fun_pl.cod_d(); i++) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(value0(i), pl_value0(i), 1e-10); + Vertex_handle v1 = v0; + v1[0] += 1; + Eigen::VectorXd x1 = cox_tr.cartesian_coordinates(v1); + Eigen::VectorXd value1 = fun_prod(x1); + Eigen::VectorXd pl_value1 = fun_pl(x1); + for (std::size_t i = 0; i < fun_pl.cod_d(); i++) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(value1(i), pl_value1(i), 1e-10); + Eigen::VectorXd pl_value_mid = fun_pl(0.5*x0 + 0.5*x1); + for (std::size_t i = 0; i < fun_pl.cod_d(); i++) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(0.5*value0(i) + 0.5*value1(i), pl_value_mid(i), 1e-10); + } +} diff --git a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp new file mode 100644 index 00000000..7bcb11db --- /dev/null +++ b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp @@ -0,0 +1,62 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "manifold_tracing" +#include +#include + +#include + +#include +#include +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +BOOST_AUTO_TEST_CASE(manifold_tracing) { + // manifold without boundary + Function_Sm_in_Rd fun_sph(5.1111, 2); + auto oracle = make_oracle(fun_sph); + Coxeter_triangulation<> cox_tr(oracle.amb_d()); + cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); + + using MT = Manifold_tracing >; + Eigen::VectorXd seed = fun_sph.seed(); + std::vector seed_points(1, seed); + typename MT::Out_simplex_map out_simplex_map; + manifold_tracing_algorithm(seed_points, cox_tr, oracle, out_simplex_map); + + for (auto si_pair: out_simplex_map) { + BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d() ); + BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); + } + BOOST_CHECK ( out_simplex_map.size() == 1054 ); + + // manifold with boundary + Function_Sm_in_Rd fun_boundary(3.0, 2, fun_sph.seed()); + auto oracle_with_boundary = make_oracle(fun_sph, fun_boundary); + typename MT::Out_simplex_map interior_simplex_map, boundary_simplex_map; + manifold_tracing_algorithm(seed_points, cox_tr, oracle_with_boundary, interior_simplex_map, boundary_simplex_map); + for (auto si_pair: interior_simplex_map) { + BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d() ); + BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); + } + BOOST_CHECK ( interior_simplex_map.size() == 89 ); + for (auto si_pair: boundary_simplex_map) { + BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d()+1 ); + BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); + } + BOOST_CHECK ( boundary_simplex_map.size() == 54 ); + +} diff --git a/src/Coxeter_triangulation/test/oracle_test.cpp b/src/Coxeter_triangulation/test/oracle_test.cpp new file mode 100644 index 00000000..8d371656 --- /dev/null +++ b/src/Coxeter_triangulation/test/oracle_test.cpp @@ -0,0 +1,60 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "oracle" +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +BOOST_AUTO_TEST_CASE(oracle) { + + Function_Sm_in_Rd fun_sph(5.1111, 2); + auto oracle = make_oracle(fun_sph); + Coxeter_triangulation<> cox_tr(oracle.amb_d()); + // cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); + + Eigen::VectorXd seed = fun_sph.seed(); + auto s = cox_tr.locate_point(seed); + + std::size_t num_intersected_edges = 0; + for (auto f: s.face_range(oracle.cod_d())) { + auto qr = oracle.intersects(f, cox_tr); + if (qr.success) + num_intersected_edges++; + auto vertex_it = f.vertex_range().begin(); + Eigen::Vector3d p1 = cox_tr.cartesian_coordinates(*vertex_it++); + Eigen::Vector3d p2 = cox_tr.cartesian_coordinates(*vertex_it++); + BOOST_CHECK( vertex_it == f.vertex_range().end() ); + Eigen::MatrixXd m(3,3); + if (qr.success) { + m.col(0) = qr.intersection; + m.col(1) = p1; + m.col(2) = p2; + GUDHI_TEST_FLOAT_EQUALITY_CHECK(m.determinant(), 0.0, 1e-10); + } + } + BOOST_CHECK( num_intersected_edges == 3 || num_intersected_edges == 4 ); +} diff --git a/src/Coxeter_triangulation/test/perm_rep_test.cpp b/src/Coxeter_triangulation/test/perm_rep_test.cpp new file mode 100644 index 00000000..f2cdbce1 --- /dev/null +++ b/src/Coxeter_triangulation/test/perm_rep_test.cpp @@ -0,0 +1,66 @@ +/* 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): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "permutahedral_representation" +#include + +#include + +BOOST_AUTO_TEST_CASE(permutahedral_representation) { + typedef std::vector Vertex; + typedef std::vector Part; + typedef std::vector Partition; + typedef Gudhi::coxeter_triangulation::Permutahedral_representation Simplex_handle; + Vertex v0(10, 0); + Partition omega = {Part({5}), Part({2}), Part({3,7}), Part({4,9}), Part({0,6,8}), Part({1,10})}; + Simplex_handle s(v0, omega); + + // Dimension check + BOOST_CHECK(s.dimension() == 5); + + // Vertex number check + std::vector vertices; + for (auto& v: s.vertex_range()) + vertices.push_back(v); + BOOST_CHECK(vertices.size() == 6); + + // Facet number check + std::vector facets; + for (auto& f: s.facet_range()) + facets.push_back(f); + BOOST_CHECK(facets.size() == 6); + + // Face of dim 3 number check + std::vector faces3; + for (auto& f: s.face_range(3)) + faces3.push_back(f); + BOOST_CHECK(faces3.size() == 15); + + // Cofacet number check + std::vector cofacets; + for (auto& f: s.cofacet_range()) + cofacets.push_back(f); + BOOST_CHECK(cofacets.size() == 12); + + // Is face check + Vertex v1(10, 0); + Partition omega1 = {Part({5}), Part({0,1,2,3,4,6,7,8,9,10})}; + Simplex_handle s1(v1, omega1); + Vertex v2(10, 0); v2[1] = -1; + Partition omega2 = {Part({1}), Part({5}), Part({2}), Part({3,7}), Part({4,9}), Part({0,6,8}), Part({10})}; + Simplex_handle s2(v2, omega2); + BOOST_CHECK(s.is_face_of(s)); + BOOST_CHECK(s1.is_face_of(s)); + BOOST_CHECK(!s2.is_face_of(s)); + BOOST_CHECK(s.is_face_of(s2)); +} -- cgit v1.2.3 From 1dc1efe51e99e526113e6b9ed9d171be1d633813 Mon Sep 17 00:00:00 2001 From: Siargey Kachanovich Date: Thu, 17 Oct 2019 21:51:09 +0200 Subject: Fixed gudhi_patches absence issue --- .../include/gudhi/Functions/random_orthogonal_matrix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h index 8979669e..cf0b00ac 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include namespace Gudhi { -- cgit v1.2.3 From 24f4c81be019d1895027427d6e6c3434dfc80ad7 Mon Sep 17 00:00:00 2001 From: Siargey Kachanovich Date: Fri, 18 Oct 2019 10:12:57 +0200 Subject: Added empty constructor for Configuration --- .../include/gudhi/IO/build_mesh_from_cell_complex.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index 5044660e..71070c05 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -31,6 +31,8 @@ struct Configuration { std::size_t r_edges, std::size_t r_triangles, std::size_t r_tetrahedra) : toggle_edges(t_edges), toggle_triangles(t_triangles), toggle_tetrahedra(t_tetrahedra), ref_edges(r_edges), ref_triangles(r_triangles), ref_tetrahedra(r_tetrahedra) {} + + Configuration() {} }; -- cgit v1.2.3 From a5bed8a177756dd5ffd407e8da45e37f881ed9b2 Mon Sep 17 00:00:00 2001 From: Siargey Kachanovich Date: Wed, 13 Nov 2019 15:50:31 +0300 Subject: Removed the random translation in the manifold tracing test. --- src/Coxeter_triangulation/test/manifold_tracing_test.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp index 7bcb11db..cff6ddfa 100644 --- a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp +++ b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { Function_Sm_in_Rd fun_sph(5.1111, 2); auto oracle = make_oracle(fun_sph); Coxeter_triangulation<> cox_tr(oracle.amb_d()); - cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); + // cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); using MT = Manifold_tracing >; Eigen::VectorXd seed = fun_sph.seed(); @@ -41,7 +41,9 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d() ); BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); } - BOOST_CHECK ( out_simplex_map.size() == 1054 ); + std::cout << "out_simplex_map.size() = " << out_simplex_map.size() << "\n"; + BOOST_CHECK ( out_simplex_map.size() == 1140 ); + // manifold with boundary Function_Sm_in_Rd fun_boundary(3.0, 2, fun_sph.seed()); @@ -52,11 +54,13 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d() ); BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); } - BOOST_CHECK ( interior_simplex_map.size() == 89 ); + std::cout << "interior_simplex_map.size() = " << interior_simplex_map.size() << "\n"; + BOOST_CHECK ( interior_simplex_map.size() == 96 ); for (auto si_pair: boundary_simplex_map) { BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d()+1 ); BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); } - BOOST_CHECK ( boundary_simplex_map.size() == 54 ); + std::cout << "boundary_simplex_map.size() = " << boundary_simplex_map.size() << "\n"; + BOOST_CHECK ( boundary_simplex_map.size() == 55 ); } -- cgit v1.2.3 From 056d560df20de8c83e6f64e4973fb68f54e8dc13 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 21 Sep 2020 14:48:13 +0200 Subject: Merge skachano/master (coxeter triangulation) --- src/Coxeter_triangulation/test/CMakeLists.txt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/test/CMakeLists.txt b/src/Coxeter_triangulation/test/CMakeLists.txt index 663768b1..b1900601 100644 --- a/src/Coxeter_triangulation/test/CMakeLists.txt +++ b/src/Coxeter_triangulation/test/CMakeLists.txt @@ -1,33 +1,30 @@ project(Coxeter_triangulation_test) -include(GUDHI_test_coverage) - +include(GUDHI_boost_test) add_executable ( Coxeter_triangulation_permutahedral_representation_test perm_rep_test.cpp ) target_link_libraries( Coxeter_triangulation_permutahedral_representation_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ) -gudhi_add_coverage_test(Coxeter_triangulation_permutahedral_representation_test) +gudhi_add_boost_test(Coxeter_triangulation_permutahedral_representation_test) add_executable ( Coxeter_triangulation_freudenthal_triangulation_test freud_triang_test.cpp ) target_link_libraries( Coxeter_triangulation_freudenthal_triangulation_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -gudhi_add_coverage_test(Coxeter_triangulation_freudenthal_triangulation_test) +gudhi_add_boost_test(Coxeter_triangulation_freudenthal_triangulation_test) add_executable ( Coxeter_triangulation_functions_test function_test.cpp ) target_link_libraries( Coxeter_triangulation_functions_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -gudhi_add_coverage_test(Coxeter_triangulation_functions_test) +gudhi_add_boost_test(Coxeter_triangulation_functions_test) add_executable ( Coxeter_triangulation_oracle_test oracle_test.cpp ) target_link_libraries( Coxeter_triangulation_oracle_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -gudhi_add_coverage_test(Coxeter_triangulation_oracle_test) +gudhi_add_boost_test(Coxeter_triangulation_oracle_test) add_executable ( Coxeter_triangulation_manifold_tracing_test manifold_tracing_test.cpp ) target_link_libraries( Coxeter_triangulation_manifold_tracing_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -gudhi_add_coverage_test(Coxeter_triangulation_manifold_tracing_test) +gudhi_add_boost_test(Coxeter_triangulation_manifold_tracing_test) add_executable ( Coxeter_triangulation_cell_complex_test cell_complex_test.cpp ) target_link_libraries( Coxeter_triangulation_cell_complex_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -gudhi_add_coverage_test(Coxeter_triangulation_cell_complex_test) - if (TBB_FOUND) target_link_libraries(Coxeter_triangulation_cell_complex_test ${TBB_LIBRARIES}) endif() - +gudhi_add_boost_test(Coxeter_triangulation_cell_complex_test) \ No newline at end of file -- cgit v1.2.3 From 46a2d96fd8230458a799622d027227c1dd5c49ab Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 21 Sep 2020 15:30:44 +0200 Subject: Add examples as tests --- src/Coxeter_triangulation/example/CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/example/CMakeLists.txt b/src/Coxeter_triangulation/example/CMakeLists.txt index 345949ae..cbab2024 100644 --- a/src/Coxeter_triangulation/example/CMakeLists.txt +++ b/src/Coxeter_triangulation/example/CMakeLists.txt @@ -1,10 +1,15 @@ -cmake_minimum_required(VERSION 2.6) project(Coxeter_triangulation_example) add_executable ( Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example manifold_tracing_flat_torus_with_boundary.cpp ) -add_executable ( Coxeter_triangulation_manifold_tracing_custom_function_example manifold_tracing_custom_function.cpp ) - if (TBB_FOUND) target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${TBB_LIBRARIES}) +endif() +add_test(NAME Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example + COMMAND $) + +add_executable ( Coxeter_triangulation_manifold_tracing_custom_function_example manifold_tracing_custom_function.cpp ) +if (TBB_FOUND) target_link_libraries(Coxeter_triangulation_manifold_tracing_custom_function_example ${TBB_LIBRARIES}) endif() +add_test(NAME Coxeter_triangulation_manifold_tracing_custom_function_example + COMMAND $) -- cgit v1.2.3 From 4ebdf2b588017f2ac4a07753c2b1c2a6a569e576 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 21 Sep 2020 16:19:42 +0200 Subject: struct Function should be abstract and virtual functions signatures --- .../example/manifold_tracing_custom_function.cpp | 8 ++++---- .../include/gudhi/Functions/Cartesian_product.h | 8 ++++---- .../include/gudhi/Functions/Constant_function.h | 8 ++++---- .../include/gudhi/Functions/Embed_in_Rd.h | 8 ++++---- src/Coxeter_triangulation/include/gudhi/Functions/Function.h | 10 +++++----- .../include/gudhi/Functions/Function_Sm_in_Rd.h | 8 ++++---- .../include/gudhi/Functions/Function_affine_plane_in_Rd.h | 8 ++++---- .../include/gudhi/Functions/Function_chair_in_R3.h | 8 ++++---- .../include/gudhi/Functions/Function_iron_in_R3.h | 8 ++++---- .../gudhi/Functions/Function_lemniscate_revolution_in_R3.h | 8 ++++---- .../include/gudhi/Functions/Function_moment_curve_in_Rd.h | 8 ++++---- .../include/gudhi/Functions/Function_torus_in_R3.h | 8 ++++---- .../include/gudhi/Functions/Function_whitney_umbrella_in_R3.h | 8 ++++---- .../include/gudhi/Functions/Linear_transformation.h | 8 ++++---- src/Coxeter_triangulation/include/gudhi/Functions/Negation.h | 8 ++++---- .../include/gudhi/Functions/PL_approximation.h | 8 ++++---- src/Coxeter_triangulation/include/gudhi/Functions/Translate.h | 8 ++++---- 17 files changed, 69 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp index 7a89a32f..95f63b4f 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp @@ -21,7 +21,7 @@ using namespace Gudhi::coxeter_triangulation; */ struct Function_surface_on_CP2_in_R4 : public Function { - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { // The real and imaginary parts of the variables x and y double xr = p(0), xi = p(1), yr = p(2), yi = p(3); Eigen::VectorXd result(cod_d()); @@ -42,10 +42,10 @@ struct Function_surface_on_CP2_in_R4 : public Function { return result; } - std::size_t amb_d() const {return 4;}; - std::size_t cod_d() const {return 2;}; + virtual std::size_t amb_d() const override {return 4;}; + virtual std::size_t cod_d() const override {return 2;}; - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = Eigen::VectorXd::Zero(4); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h index 43198b89..9fd0d69b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -110,20 +110,20 @@ struct Cartesian_product : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result(cod_d_); get_value(function_tuple_, p, result, 0, 0); return result; } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return amb_d_;} + virtual std::size_t amb_d() const override {return amb_d_;} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return cod_d_;} + virtual std::size_t cod_d() const override {return cod_d_;} /** \brief Returns a point on the zero-set. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result(amb_d_); get_seed(function_tuple_, result, 0); return result; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index ea354fac..b0c7a167 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -32,19 +32,19 @@ struct Constant_function : public Function { /** \brief Value of the function at a specified point. The value is constant. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result = value_; return result; } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - std::size_t amb_d() const {return d_;}; + virtual std::size_t amb_d() const override {return d_;}; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - std::size_t cod_d() const {return k_;}; + virtual std::size_t cod_d() const override {return k_;}; /** \brief No seed point is available. Throws an exception on evocation. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { throw "Seed invoked on a constant function.\n"; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index 9476944b..c2419783 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -40,7 +40,7 @@ struct Embed_in_Rd : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd x = p; Eigen::VectorXd x_k(fun_.amb_d()), x_rest(d_ - fun_.amb_d()); for (std::size_t i = 0; i < fun_.amb_d(); ++i) @@ -55,13 +55,13 @@ struct Embed_in_Rd : public Function { } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return d_;} + virtual std::size_t amb_d() const override {return d_;} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return d_-(fun_.amb_d() - fun_.cod_d());} + virtual std::size_t cod_d() const override {return d_-(fun_.amb_d() - fun_.cod_d());} /** \brief Returns a point on the zero-set of the embedded function. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = fun_.seed(); result.conservativeResize(d_); for (std::size_t l = fun_.amb_d(); l < d_; ++l) diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h index dbcb0142..afafbb2f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h @@ -31,16 +31,16 @@ struct Function { /** \brief Virtual method for the value of the function at a specified point. * @param[in] p The input point. */ - virtual Eigen::VectorXd evaluate(const Eigen::VectorXd& p) const {return Eigen::VectorXd(0);} - + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const = 0; + /** \brief Virtual method for the domain dimension. */ - virtual std::size_t amb_d() const {return 0;}; + virtual std::size_t amb_d() const = 0; /** \brief Virtual method for the codomain dimension. */ - virtual std::size_t cod_d() const {return 0;}; + virtual std::size_t cod_d() const = 0; /** \brief Virtual method for the seed point. */ - virtual Eigen::VectorXd seed() const {return Eigen::VectorXd(0);} + virtual Eigen::VectorXd seed() const = 0; /** \brief Virtual destructor. */ virtual ~Function() {} diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h index a7d4a965..d8b3a780 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -32,7 +32,7 @@ struct Function_Sm_in_Rd: public Function { /** \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd x = p; for (std::size_t i = 0; i < d_; ++i) x(i) -= center_[i]; @@ -46,13 +46,13 @@ struct Function_Sm_in_Rd: public Function { } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - std::size_t amb_d() const {return d_;}; + virtual std::size_t amb_d() const override {return d_;}; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - std::size_t cod_d() const {return k_;}; + virtual std::size_t cod_d() const override {return k_;}; /** \brief Returns a point on the sphere. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); result(0) += r_; for (std::size_t i = 0; i < d_; ++i) diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h index cb3af848..3af0b14c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -33,19 +33,19 @@ struct Function_affine_plane_in_Rd : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result = normal_matrix_.transpose() * (p - off_); return result; } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - std::size_t amb_d() const {return d_;}; + virtual std::size_t amb_d() const override {return d_;}; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - std::size_t cod_d() const {return k_;}; + virtual std::size_t cod_d() const override {return k_;}; /** \brief Returns a point on the affine plane. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = off_; return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h index 2a76e631..26b62731 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -35,7 +35,7 @@ struct Function_chair_in_R3 : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; Eigen::VectorXd result(cod_d()); result(0) = std::pow(x*x + y*y + z*z - a_*k_*k_, 2) - b_*((z-k_)*(z-k_) - 2*x*x)*((z+k_)*(z+k_) - 2*y*y); @@ -43,13 +43,13 @@ struct Function_chair_in_R3 : public Function { } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return 3;} + virtual std::size_t amb_d() const override {return 3;} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return 1;} + virtual std::size_t cod_d() const override {return 1;} /** \brief Returns a point on the surface. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { double t1 = a_-b_; double discr = t1*t1 - (1.0 - b_)*(a_*a_ - b_); double z0 = k_*std::sqrt((t1+std::sqrt(discr))/(1-b_)); diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h index af323c94..ad12a29f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -33,7 +33,7 @@ struct Function_iron_in_R3 : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { double x = p(0), y = p(1), z = p(2); Eigen::VectorXd result(cod_d()); result(0) = - std::pow(x,6)/300. - std::pow(y,6)/300. - std::pow(z,6)/300. + x*y*y*z/2.1 + y*y + std::pow(z-2, 4) - 1; @@ -41,13 +41,13 @@ struct Function_iron_in_R3 : public Function { } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return 3;}; + virtual std::size_t amb_d() const override {return 3;}; /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return 1;}; + virtual std::size_t cod_d() const override {return 1;}; /** \brief Returns a point on the surface. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::Vector3d result(std::pow(4500, 1./6), 0, 0); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h index cd03a0a5..67dcf0b1 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -33,7 +33,7 @@ struct Function_lemniscate_revolution_in_R3 : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; Eigen::VectorXd result(cod_d()); double x2 = x*x, y2 = y*y, z2 = z*z, a2 = a_*a_; @@ -43,16 +43,16 @@ struct Function_lemniscate_revolution_in_R3 : public Function { } /** \brief Returns the (ambient) domain dimension.*/ - std::size_t amb_d() const {return 3;}; + virtual std::size_t amb_d() const override {return 3;}; /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return 1;}; + virtual std::size_t cod_d() const override {return 1;}; /** \brief Returns a point on the surface. This seed point is only one of * two necessary seed points for the manifold tracing algorithm. * See the method seed2() for the other point. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::Vector3d result(sqrt(2*a_)+off_[0], off_[1], off_[2]); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h index 91eb016b..e27d35ae 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -32,7 +32,7 @@ struct Function_moment_curve_in_Rd : public Function { /** \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result(k_); for (std::size_t i = 1; i < d_; ++i) result(i-1) = p(i) - p(0) * p(i-1); @@ -40,13 +40,13 @@ struct Function_moment_curve_in_Rd : public Function { } /** \brief Returns the domain (ambient) dimension.. */ - std::size_t amb_d() const {return d_;}; + virtual std::size_t amb_d() const override {return d_;}; /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return k_;}; + virtual std::size_t cod_d() const override {return k_;}; /** \brief Returns a point on the moment curve. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h index 3cda2518..8fd93a2a 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -33,7 +33,7 @@ struct Function_torus_in_R3 : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; Eigen::VectorXd result(cod_d()); result(0) = (z*z + (std::sqrt(x*x + y*y) - r_)*(std::sqrt(x*x + y*y) - r_) - R_*R_); @@ -41,13 +41,13 @@ struct Function_torus_in_R3 : public Function { } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return 3;}; + virtual std::size_t amb_d() const override {return 3;}; /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return 1;}; + virtual std::size_t cod_d() const override {return 1;}; /** \brief Returns a point on the surface. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::Vector3d result(R_ + r_ +off_[0], off_[1], off_[2]); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h index 3d825f8f..10ff53f3 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -33,7 +33,7 @@ struct Function_whitney_umbrella_in_R3 : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; Eigen::VectorXd result(cod_d()); result(0) = x*x - y*y*z; @@ -41,16 +41,16 @@ struct Function_whitney_umbrella_in_R3 : public Function { } /** \brief Returns the (ambient) domain dimension.*/ - std::size_t amb_d() const {return 3;}; + virtual std::size_t amb_d() const override {return 3;}; /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return 1;}; + virtual std::size_t cod_d() const override {return 1;}; /** \brief Returns a point on the surface. This seed point is only one of * two necessary seed points for the manifold tracing algorithm. * See the method seed2() for the other point. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::Vector3d result(1+off_[0], 1+off_[1], 1+off_[2]); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index 4cb5ca84..5f7485e7 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -38,19 +38,19 @@ struct Linear_transformation : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result = fun_(matrix_.householderQr().solve(p)); return result; } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return fun_.amb_d();} + virtual std::size_t amb_d() const override {return fun_.amb_d();} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return fun_.cod_d();} + virtual std::size_t cod_d() const override {return fun_.cod_d();} /** \brief Returns a point on the zero-set. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = fun_.seed(); result = matrix_ * result; return result; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index 6b7feff5..e28d9ddb 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -39,19 +39,19 @@ struct Negation : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result = -fun_(p); return result; } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return fun_.amb_d();} + virtual std::size_t amb_d() const override {return fun_.amb_d();} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return fun_.cod_d();} + virtual std::size_t cod_d() const override {return fun_.cod_d();} /** \brief Returns a point on the zero-set. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = fun_.seed(); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index 25c8a139..e161f697 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -42,7 +42,7 @@ struct PL_approximation : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { std::size_t cod_d = this->cod_d(); std::size_t amb_d = this->amb_d(); auto s = tr_.locate_point(p); @@ -71,13 +71,13 @@ struct PL_approximation : public Function { } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return fun_.amb_d();} + virtual std::size_t amb_d() const override {return fun_.amb_d();} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return fun_.cod_d();} + virtual std::size_t cod_d() const override {return fun_.cod_d();} /** \brief Returns a point on the zero-set. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { // TODO: not finished. Should use an oracle. return Eigen::VectorXd(amb_d()); } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index 6edac28c..2236ea31 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -39,19 +39,19 @@ struct Translate : public Function { * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result = fun_(p - off_); return result; } /** \brief Returns the domain (ambient) dimension. */ - std::size_t amb_d() const {return fun_.amb_d();} + virtual std::size_t amb_d() const override {return fun_.amb_d();} /** \brief Returns the codomain dimension. */ - std::size_t cod_d() const {return fun_.cod_d();} + virtual std::size_t cod_d() const override {return fun_.cod_d();} /** \brief Returns a point on the zero-set. */ - Eigen::VectorXd seed() const { + virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = fun_.seed(); result += off_; return result; -- cgit v1.2.3 From f559a463ba531f22b5e47369325e7a2fa22e3f59 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 21 Sep 2020 17:58:46 +0200 Subject: Fix doxygen warnings --- biblio/bibliography.bib | 15 ++ .../doc/intro_coxeter_triangulation.h | 217 ++++++++++++++------- .../gudhi/Functions/Linear_transformation.h | 2 + .../include/gudhi/Functions/Negation.h | 1 - 4 files changed, 166 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index 16fa29d0..579fa85e 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -1324,3 +1324,18 @@ year = "2011" doi = {10.4230/LIPIcs.SoCG.2020.19}, annote = {Keywords: Computational Topology, Topological Data Analysis, Edge Collapse, Simple Collapse, Persistent homology} } + +@phdthesis{KachanovichThesis, + TITLE = {{Meshing submanifolds using Coxeter triangulations}}, + AUTHOR = {Kachanovich, Siargey}, + URL = {https://hal.inria.fr/tel-02419148}, + NUMBER = {2019AZUR4072}, + SCHOOL = {{COMUE Universit{\'e} C{\^o}te d'Azur (2015 - 2019)}}, + YEAR = {2019}, + MONTH = Oct, + KEYWORDS = {Mesh generation ; Coxeter triangulations ; Simplex quality ; Triangulations of the Euclidean space ; Freudenthal-Kuhn triangulations ; G{\'e}n{\'e}ration de maillages ; Triangulations de Coxeter ; Qualit{\'e} des simplexes ; Triangulations de l'espace euclidien ; Triangulations de Freudenthal-Kuhn}, + TYPE = {Theses}, + PDF = {https://hal.inria.fr/tel-02419148v2/file/2019AZUR4072.pdf}, + HAL_ID = {tel-02419148}, + HAL_VERSION = {v2}, +} \ No newline at end of file diff --git a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h index 80ca5b37..c883d904 100644 --- a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h +++ b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria @@ -10,8 +8,8 @@ * - YYYY/MM Author: Description of the modification */ -#ifndef DOC_TANGENTIAL_COMPLEX_INTRO_COXETER_TRIANGULATION_H_ -#define DOC_TANGENTIAL_COMPLEX_INTRO_COXETER_TRIANGULATION_H_ +#ifndef DOC_COXETER_TRIANGULATION_INTRO_COXETER_TRIANGULATION_H_ +#define DOC_COXETER_TRIANGULATION_INTRO_COXETER_TRIANGULATION_H_ // needs namespaces for Doxygen to link on classes namespace Gudhi { @@ -25,101 +23,184 @@ namespace tangential_complex { \section overview Module overview -Coxeter triangulation module is designed to provide tools for constructing a piecewise-linear approximation of an \f$m\f$-dimensional smooth manifold embedded in \f$ \mathbb{R}^d \f$ using an ambient triangulation. +Coxeter triangulation module is designed to provide tools for constructing a piecewise-linear approximation of an +\f$m\f$-dimensional smooth manifold embedded in \f$ \mathbb{R}^d \f$ using an ambient triangulation. For a more detailed description of the module see \cite KachanovichThesis. \section manifoldtracing Manifold tracing algorithm -The central piece of the module is the manifold tracing algorithm represented by the class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing". -The manifold tracing algorithm takes as input a manifold of some dimension \f$m\f$ embedded in \f$\mathbb{R}^d\f$ represented by an intersection oracle (see Section \ref intersectionoracle "Intersection oracle"), a point on the manifold and an ambient triangulation (see Section \ref ambienttriangulations "Ambient triangulations"). -The output consists of one map (or two maps in the case of manifolds with boundary) from the \f$(d-m)\f$-dimensional (and \f$(d-m+1)\f$-dimensional in the case of manifolds with boundary) simplices in the ambient triangulation that intersect the manifold to their intersection points. -From this output, it is possible to construct the cell complex of the piecewise-linear approximation of the input manifold. - -There are two methods that execute the manifold tracing algorithm: the method \ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" for manifolds without boundary and \ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" for manifolds with boundary. +The central piece of the module is the manifold tracing algorithm represented by the class +\ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing". +The manifold tracing algorithm takes as input a manifold of some dimension \f$m\f$ embedded in \f$\mathbb{R}^d\f$ +represented by an intersection oracle (see Section \ref intersectionoracle "Intersection oracle"), a point on the +manifold and an ambient triangulation (see Section \ref ambienttriangulations "Ambient triangulations"). +The output consists of one map (or two maps in the case of manifolds with boundary) from the \f$(d-m)\f$-dimensional +(and \f$(d-m+1)\f$-dimensional in the case of manifolds with boundary) simplices in the ambient triangulation that +intersect the manifold to their intersection points. +From this output, it is possible to construct the cell complex of the piecewise-linear approximation of the input +manifold. + +There are two methods that execute the manifold tracing algorithm: the method +\ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" +for manifolds without boundary and +\ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" +for manifolds with boundary. The algorithm functions as follows. -It starts at the specified seed points and inserts a \f$(d-m)\f$-dimensional simplices nearby each seed point that intersect the manifold into the output. -Starting from this simplex, the algorithm propagates the search for other \f$(d-m)\f$-dimensional simplices that intersect the manifold by marching from a simplex to neighbouring simplices via their common cofaces. - -This class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing" has one template parameter Triangulation_ which specifies the ambient triangulation which is used by the algorithm. -The template type Triangulation_ has to be a model of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". - -The module also provides two static methods: \ref Gudhi::coxeter_triangulation::manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" for manifolds without boundary and \ref manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" for manifolds with boundary. +It starts at the specified seed points and inserts a \f$(d-m)\f$-dimensional simplices nearby each seed point that +intersect the manifold into the output. +Starting from this simplex, the algorithm propagates the search for other \f$(d-m)\f$-dimensional simplices that +intersect the manifold by marching from a simplex to neighbouring simplices via their common cofaces. + +This class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing" has one template parameter +`Triangulation_` which specifies the ambient triangulation which is used by the algorithm. +The template type `Triangulation_` has to be a model of the concept +\ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". + +The module also provides two static methods: +\ref Gudhi::coxeter_triangulation::manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" +for manifolds without boundary and +\ref manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" +for manifolds with boundary. For these static methods it is not necessary to specify any template arguments. \section ambienttriangulations Ambient triangulations -The ambient triangulations supported by the manifold tracing algorithm have to be models of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". -This module offers two such models: the class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and the derived class \ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation". +The ambient triangulations supported by the manifold tracing algorithm have to be models of the concept +\ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". +This module offers two such models: the class +\ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and the derived class +\ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation". Both these classes encode affine transformations of the so-called Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. -The Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ is defined as the simplicial subdivision of the unit cubic partition of \f$\mathbb{R}^d\f$. -Each simplex is encoded using the permutahedral representation, which consists of an integer-valued vector \f$y\f$ that positions the simplex in a specific cube in the cubical partition and an ordered partition \f$\omega\f$ of the set \f$\{1,\ldots,d+1\}\f$, which positions the simplex in the simplicial subdivision of the cube. -The default constructor \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation::Freudenthal_triangulation(std::size_t) "Freudenthal_triangulation(d)" the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. -The class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" can also encode any affine transformation of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ using an invertible matrix \f$\Lambda\f$ and an offset vector \f$b\f$ that can be specified in the constructor and which can be changed using the methods change_matrix and change_offset. -The class \ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation" is derived from \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and its default constructor \ref Gudhi::coxeter_triangulation::Coxeter_triangulation::Coxeter_triangulation(std::size_t) "Coxeter_triangulation(d)" builds a Coxeter triangulation of type \f$\tilde{A}_d\f$, which has the best simplex quality of all linear transformations of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. - -\image html two_triangulations.png "On the left: Coxeter triangulation of type \f$\tilde{A}_2\f$. On the right: Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$." +The Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ is defined as the simplicial subdivision of the unit cubic +partition of \f$\mathbb{R}^d\f$. +Each simplex is encoded using the permutahedral representation, which consists of an integer-valued vector \f$y\f$ that +positions the simplex in a specific cube in the cubical partition and an ordered partition \f$\omega\f$ of the set +\f$\{1,\ldots,d+1\}\f$, which positions the simplex in the simplicial subdivision of the cube. +The default constructor +\ref Gudhi::coxeter_triangulation::Freudenthal_triangulation::Freudenthal_triangulation(std::size_t) "Freudenthal_triangulation(d)" +the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. +The class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" can also encode any +affine transformation of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ using an invertible matrix +\f$\Lambda\f$ and an offset vector \f$b\f$ that can be specified in the constructor and which can be changed using the +methods change_matrix and change_offset. +The class \ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation" is derived from +\ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and its default constructor +\ref Gudhi::coxeter_triangulation::Coxeter_triangulation::Coxeter_triangulation(std::size_t) "Coxeter_triangulation(d)" +builds a Coxeter triangulation of type \f$\tilde{A}_d\f$, which has the best simplex quality of all linear +transformations of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. + +\image html two_triangulations.png "Coxeter (on the left) and Freudenthal-Kuhn triangulation (on the right)" \section intersectionoracle Intersection oracle -The input \f$m\f$-dimensional manifold in \f$\mathbb{R}^d\f$ needs to be given via the intersection oracle that answers the following query: given a \f$(d-m)\f$-dimensional simplex, does it intersect the manifold? -The concept \ref Gudhi::coxeter_triangulation::IntersectionOracle "IntersectionOracle" describes all requirements for an intersection oracle class to be compatible with the class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing". -This module offers one model of the concept \ref Gudhi::coxeter_triangulation::IntersectionOracle "IntersectionOracle", which is the class \ref Gudhi::coxeter_triangulation::Implicit_manifold_intersection_oracle "Implicit_manifold_intersection_oracle". -This class represents a manifold given as the zero-set of a specified function \f$F: \mathbb{R}^d \rightarrow \mathbb{R}^{d-m}\f$. -The function \f$F\f$ is given by a class which is a model of the concept \ref Gudhi::coxeter_triangulation::FunctionForImplicitManifold "FunctionForImplicitManifold". +The input \f$m\f$-dimensional manifold in \f$\mathbb{R}^d\f$ needs to be given via the intersection oracle that answers +the following query: given a \f$(d-m)\f$-dimensional simplex, does it intersect the manifold? +The concept \ref Gudhi::coxeter_triangulation::IntersectionOracle "IntersectionOracle" describes all requirements for +an intersection oracle class to be compatible with the class +\ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing". +This module offers one model of the concept +\ref Gudhi::coxeter_triangulation::IntersectionOracle "IntersectionOracle", which is the class +\ref Gudhi::coxeter_triangulation::Implicit_manifold_intersection_oracle "Implicit_manifold_intersection_oracle". +This class represents a manifold given as the zero-set of a specified function +\f$F: \mathbb{R}^d \rightarrow \mathbb{R}^{d-m}\f$. +The function \f$F\f$ is given by a class which is a model of the concept +\ref Gudhi::coxeter_triangulation::FunctionForImplicitManifold "FunctionForImplicitManifold". There are multiple function classes that are already implemented in this module. -\li \ref Gudhi::coxeter_triangulation::Constant_function(std::size_t, std::size_t, Eigen::VectorXd) "Constant_function(d,k,v)" defines a constant function \f$F\f$ such that for all \f$x \in \mathbb{R}^d\f$, we have \f$F(x) = v \in \mathbb{R}^k\f$. - The class Constant_function does not define an implicit manifold, but is useful as the domain function when defining boundaryless implicit manifolds. -\li \ref Gudhi::coxeter_triangulation::Function_affine_plane_in_Rd(N,b) "Function_affine_plane_in_Rd(N,b)" defines an \f$m\f$-dimensional implicit affine plane in the \f$d\f$-dimensional Euclidean space given by a normal matrix \f$N\f$ and an offset vector \f$b\f$. -\li \ref Gudhi::coxeter_triangulation::Function_Sm_in_Rd(r,m,d,center) "Function_Sm_in_Rd(r,m,d,center)" defines an \f$m\f$-dimensional implicit sphere embedded in the \f$d\f$-dimensional Euclidean space of radius \f$r\f$ centered at the point 'center'. -\li \ref Gudhi::coxeter_triangulation::Function_moment_curve_in_Rd(r,d) "Function_moment_curve(r,d)" defines the moment curve in the \f$d\f$-dimensional Euclidean space of radius \f$r\f$ given as the parameterized curve (but implemented as an implicit curve): +\li \ref Gudhi::coxeter_triangulation::Constant_function(std::size_t, std::size_t, Eigen::VectorXd) "Constant_function(d,k,v)" + defines a constant function \f$F\f$ such that for all \f$x \in \mathbb{R}^d\f$, we have + \f$F(x) = v \in \mathbb{R}^k\f$. + The class Constant_function does not define an implicit manifold, but is useful as the domain function when defining + boundaryless implicit manifolds. +\li \ref Gudhi::coxeter_triangulation::Function_affine_plane_in_Rd(N,b) "Function_affine_plane_in_Rd(N,b)" defines an + \f$m\f$-dimensional implicit affine plane in the \f$d\f$-dimensional Euclidean space given by a normal matrix \f$N\f$ + and an offset vector \f$b\f$. +\li \ref Gudhi::coxeter_triangulation::Function_Sm_in_Rd(r,m,d,center) "Function_Sm_in_Rd(r,m,d,center)" defines an + \f$m\f$-dimensional implicit sphere embedded in the \f$d\f$-dimensional Euclidean space of radius \f$r\f$ centered at + the point 'center'. +\li \ref Gudhi::coxeter_triangulation::Function_moment_curve_in_Rd(r,d) "Function_moment_curve(r,d)" defines the moment + curve in the \f$d\f$-dimensional Euclidean space of radius \f$r\f$ given as the parameterized curve (but implemented + as an implicit curve): \f[ (r, rt, \ldots, rt^{d-1}) \in \mathbb{R}^d,\text{ for $t \in \mathbb{R}$.} \f] -\li \ref Gudhi::coxeter_triangulation::Function_torus_in_R3(R, r) "Function_torus_in_R3(R, r)" defines a torus in \f$\mathbb{R}^3\f$ with the outer radius \f$R\f$ and the inner radius, given by the equation: +\li \ref Gudhi::coxeter_triangulation::Function_torus_in_R3(R, r) "Function_torus_in_R3(R, r)" defines a torus in + \f$\mathbb{R}^3\f$ with the outer radius \f$R\f$ and the inner radius, given by the equation: \f[ z^2 + (\sqrt{x^2 + y^2} - r)^2 - R^2 = 0. \f] -\li \ref Gudhi::coxeter_triangulation::Function_chair_in_R3(a, b, k) "Function_chair_in_R3(a, b, k)" defines the ``Chair'' surface in \f$\mathbb{R}^3\f$ defined by the equation: +\li \ref Gudhi::coxeter_triangulation::Function_chair_in_R3(a, b, k) "Function_chair_in_R3(a, b, k)" defines the + \"Chair\" surface in \f$\mathbb{R}^3\f$ defined by the equation: \f[ (x^2 + y^2 + z^2 - ak^2)^2 - b((z-k)^2 - 2x^2)((z+k)^2 - 2y^2) = 0. \f] -\li \ref Gudhi::coxeter_triangulation::Function_iron_in_R3() "Function_iron_in_R3()" defines the ``Iron'' surface in \f$\mathbb{R}^3\f$ defined by the equation: +\li \ref Gudhi::coxeter_triangulation::Function_iron_in_R3() "Function_iron_in_R3()" defines the \"Iron\" surface in + \f$\mathbb{R}^3\f$ defined by the equation: \f[ \frac{-x^6-y^6-z^6}{300} + \frac{xy^2z}{2.1} + y^2 + (z-2)^2 = 1. \f] -\li \ref Gudhi::coxeter_triangulation::Function_lemniscate_revolution_in_R3(a) "Function_lemniscate_revolution_in_R3(a)" defines a revolution surface in \f$\mathbb{R}^3\f$ obtained from the lemniscate of Bernoulli defined by the equation: +\li \ref Gudhi::coxeter_triangulation::Function_lemniscate_revolution_in_R3(a) "Function_lemniscate_revolution_in_R3(a)" + defines a revolution surface in \f$\mathbb{R}^3\f$ obtained from the lemniscate of Bernoulli defined by the equation: \f[ (x^2 + y^2 + z^2)^2 - 2a^2(x^2 - y^2 - z^2) = 0. \f] -\li \ref Gudhi::coxeter_triangulation::Function_whitney_umbrella_in_R3() "Function_whitney_umbrella_in_R3()" defines the Whitney umbrella surface in \f$\mathbb{R}^3\f$ defined by the equation: +\li \ref Gudhi::coxeter_triangulation::Function_whitney_umbrella_in_R3() "Function_whitney_umbrella_in_R3()" defines + the Whitney umbrella surface in \f$\mathbb{R}^3\f$ defined by the equation: \f[ x^2 - y^2z = 0. \f] The base function classes above can be composed or modified into new functions using the following classes and methods: -\li \ref Gudhi::coxeter_triangulation::Cartesian_product "Cartesian_product(functions...)" expresses the Cartesian product \f$F_1^{-1}(0) \times \ldots \times F_k^{-1}(0)\f$ of multiple implicit manifolds as an implicit manifold. - For convenience, a static function \ref Gudhi::coxeter_triangulation::make_product_function() "make_product_function(functions...)" is provided that takes a pack of function-typed objects as the argument. -\li \ref Gudhi::coxeter_triangulation::Embed_in_Rd "Embed_in_Rd(F, d)" expresses an implicit manifold given as the zero-set of a function \f$F\f$ embedded in a higher-dimensional Euclidean space \f$\mathbb{R}^d\f$. - For convenience, a static function \ref Gudhi::coxeter_triangulation::make_embedding() "make_embedding(F, d)" is provided. -\li \ref Gudhi::coxeter_triangulation::Linear_transformation "Linear_transformation(F, M)" applies a linear transformation given by a matrix \f$M\f$ on an implicit manifold given as the zero-set of the function \f$F\f$. - For convenience, a static function \ref Gudhi::coxeter_triangulation::linear_transformation() "linear_transformation(F, M)" is provided. -\li \ref Gudhi::coxeter_triangulation::Translate "Translate(F, v)" translates an implicit manifold given as the zero-set of ththe function \f$F\f$ by a vector \f$v\f$. - For convenience, a static function \ref Gudhi::coxeter_triangulation::translate(F, v) "translate(F, v)" is provided. +\li \ref Gudhi::coxeter_triangulation::Cartesian_product "Cartesian_product(functions...)" expresses the Cartesian + product \f$F_1^{-1}(0) \times \ldots \times F_k^{-1}(0)\f$ of multiple implicit manifolds as an implicit manifold. + For convenience, a static function + \ref Gudhi::coxeter_triangulation::make_product_function() "make_product_function(functions...)" is provided that + takes a pack of function-typed objects as the argument. +\li \ref Gudhi::coxeter_triangulation::Embed_in_Rd "Embed_in_Rd(F, d)" expresses an implicit manifold given as the + zero-set of a function \f$F\f$ embedded in a higher-dimensional Euclidean space \f$\mathbb{R}^d\f$. + For convenience, a static function \ref Gudhi::coxeter_triangulation::make_embedding() "make_embedding(F, d)" is + provided. +\li \ref Gudhi::coxeter_triangulation::Linear_transformation "Linear_transformation(F, M)" applies a linear + transformation given by a matrix \f$M\f$ on an implicit manifold given as the zero-set of the function \f$F\f$. + For convenience, a static function + \ref Gudhi::coxeter_triangulation::make_linear_transformation() "make_linear_transformation(F, M)" is provided. +\li \ref Gudhi::coxeter_triangulation::Translate "Translate(F, v)" translates an implicit manifold given as the + zero-set of ththe function \f$F\f$ by a vector \f$v\f$. + For convenience, a static function \ref Gudhi::coxeter_triangulation::translate() "translate(F, v)" is provided. \li \ref Gudhi::coxeter_triangulation::Negation() "Negation(F)" defines the negative of the given function \f$F\f$. This class is useful to define the complementary of a given domain, when defining a manifold with boundary. For convenience, a static function \ref Gudhi::coxeter_triangulation::negation() "negation(F)" is provided. -\li \ref Gudhi::coxeter_triangulation::PL_approximation "PL_approximation(F, T)" defines a piecewise-linear approximation of a given function \f$F\f$ induced by an ambient triangulation \f$T\f$. - The purpose of this class is to define a piecewise-linear function that is compatible with the requirements for the domain function \f$D\f$ when defining a manifold with boundary. - For convenience, a static function \ref Gudhi::coxeter_triangulation::make_pl_approximation() "make_pl_approximation(F, T)" is provided. - The type of \f$T\f$ is required to be a model of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". +\li \ref Gudhi::coxeter_triangulation::PL_approximation "PL_approximation(F, T)" defines a piecewise-linear + approximation of a given function \f$F\f$ induced by an ambient triangulation \f$T\f$. + The purpose of this class is to define a piecewise-linear function that is compatible with the requirements for the + domain function \f$D\f$ when defining a manifold with boundary. + For convenience, a static function + \ref Gudhi::coxeter_triangulation::make_pl_approximation() "make_pl_approximation(F, T)" is provided. + The type of \f$T\f$ is required to be a model of the concept + \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". \section cellcomplex Cell complex construction -The output of the manifold tracing algorithm can be transformed into the Hasse diagram of a cell complex that approximates the input manifold using the class \ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex". -The type of the cells in the Hasse diagram is \ref Gudhi::Hasse_diagram::Hasse_diagram_cell "Hasse_cell" provided by the module Hasse diagram. -The cells in the cell complex given by an object of the class \ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex" are accessed through several maps that are accessed through the following methods. - -\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::interior_simplex_cell_maps() "interior_simplex_cell_maps()" returns a vector of maps from the cells of various dimensions in the interior of the cell complex to the permutahedral representations of the corresponding simplices in the ambient triangulation. -Each individual map for cells of a specific dimension \f$l\f$ can be accessed using the method \ref Gudhi::coxeter_triangulation::Cell_complex::interior_simplex_cell_map() "interior_simplex_cell_map(l)". -\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::boundary_simplex_cell_maps() "boundary_simplex_cell_maps()" returns a vector of maps from the cells of various dimensions on the boundary of the cell complex to the permutahedral representations of the corresponding simplices in the ambient triangulation. -Each individual map for cells of a specific dimension \f$l\f$ can be accessed using the method \ref Gudhi::coxeter_triangulation::Cell_complex::boundary_simplex_cell_map() "boundary_simplex_cell_map(l)". -\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_simplex_map() "cell_simplex_map()" returns a map from the cells in the cell complex to the permutahedral representations of the corresponding simplices in the ambient triangulation. -\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_point_map() "cell_point_map()" returns a map from the vertex cells in the cell complex to their Cartesian coordinates. +The output of the manifold tracing algorithm can be transformed into the Hasse diagram of a cell complex that +approximates the input manifold using the class \ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex". +The type of the cells in the Hasse diagram is +\ref Gudhi::Hasse_diagram::Hasse_diagram_cell "Hasse_cell" provided by the module Hasse diagram. +The cells in the cell complex given by an object of the class +\ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex" are accessed through several maps that are accessed +through the following methods. + +\li The method +\ref Gudhi::coxeter_triangulation::Cell_complex::interior_simplex_cell_maps() "interior_simplex_cell_maps()" +returns a vector of maps from the cells of various dimensions in the interior of the cell complex to the permutahedral +representations of the corresponding simplices in the ambient triangulation. +Each individual map for cells of a specific dimension \f$l\f$ can be accessed using the method +\ref Gudhi::coxeter_triangulation::Cell_complex::interior_simplex_cell_map() "interior_simplex_cell_map(l)". +\li The method +\ref Gudhi::coxeter_triangulation::Cell_complex::boundary_simplex_cell_maps() "boundary_simplex_cell_maps()" +returns a vector of maps from the cells of various dimensions on the boundary of the cell complex to the permutahedral +representations of the corresponding simplices in the ambient triangulation. +Each individual map for cells of a specific dimension \f$l\f$ can be accessed using the method +\ref Gudhi::coxeter_triangulation::Cell_complex::boundary_simplex_cell_map() "boundary_simplex_cell_map(l)". +\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_simplex_map() "cell_simplex_map()" returns a map +from the cells in the cell complex to the permutahedral representations of the corresponding simplices in the ambient +triangulation. +\li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_point_map() "cell_point_map()" returns a map from +the vertex cells in the cell complex to their Cartesian coordinates. \section example Examples -Here is an example of constructing a piecewise-linear approximation of a flat torus embedded in \f$\mathbb{R}^4\f$, rotated by a random rotation in \f$\mathbb{R}^4\f$ and cut by a hyperplane. +Here is an example of constructing a piecewise-linear approximation of a flat torus embedded in \f$\mathbb{R}^4\f$, +rotated by a random rotation in \f$\mathbb{R}^4\f$ and cut by a hyperplane. \include Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp @@ -143,4 +224,4 @@ The output in medit looks as follows: } // namespace Gudhi -#endif // DOC_TANGENTIAL_COMPLEX_INTRO_TANGENTIAL_COMPLEX_H_ +#endif // DOC_COXETER_TRIANGULATION_INTRO_COXETER_TRIANGULATION_H_ diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index 5f7485e7..89bef379 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -82,6 +82,8 @@ private: * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation */ template Linear_transformation make_linear_transformation(const Function_& function, diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index e28d9ddb..6752ec3f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -72,7 +72,6 @@ struct Negation : public Function { * \brief Static constructor of the negative function. * * @param[in] function The function to be translated. - * @param[in] off The offset vector. The dimension should correspond to the * domain (ambient) dimension of 'function'. * * \tparam Function_ The function template parameter. Should be a model of -- cgit v1.2.3 From cba4b7047cc8665a3f20e2334358a4ca28bf021a Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 21 Sep 2020 18:00:40 +0200 Subject: Fix copyright --- src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h | 6 ++---- src/Coxeter_triangulation/concept/IntersectionOracle.h | 6 ++---- src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h | 6 ++---- src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Cell_complex.h | 6 ++---- .../include/gudhi/Cell_complex/Hasse_diagram_cell.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h | 6 ++---- .../include/gudhi/Functions/Cartesian_product.h | 6 ++---- .../include/gudhi/Functions/Constant_function.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Functions/Function.h | 6 ++---- .../include/gudhi/Functions/Function_Sm_in_Rd.h | 6 ++---- .../include/gudhi/Functions/Function_affine_plane_in_Rd.h | 6 ++---- .../include/gudhi/Functions/Function_chair_in_R3.h | 6 ++---- .../include/gudhi/Functions/Function_iron_in_R3.h | 6 ++---- .../include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h | 6 ++---- .../include/gudhi/Functions/Function_moment_curve_in_Rd.h | 6 ++---- .../include/gudhi/Functions/Function_torus_in_R3.h | 6 ++---- .../include/gudhi/Functions/Function_whitney_umbrella_in_R3.h | 6 ++---- .../include/gudhi/Functions/Linear_transformation.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Functions/Negation.h | 6 ++---- .../include/gudhi/Functions/PL_approximation.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Functions/Translate.h | 6 ++---- .../include/gudhi/Functions/random_orthogonal_matrix.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h | 6 ++---- .../include/gudhi/IO/build_mesh_from_cell_complex.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h | 6 ++---- .../include/gudhi/Implicit_manifold_intersection_oracle.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h | 6 ++---- .../include/gudhi/Permutahedral_representation.h | 6 ++---- .../gudhi/Permutahedral_representation/Combination_iterator.h | 6 ++---- .../Permutahedral_representation/Integer_combination_iterator.h | 6 ++---- .../Permutahedral_representation/Ordered_set_partition_iterator.h | 6 ++---- .../Permutahedral_representation_iterators.h | 6 ++---- .../gudhi/Permutahedral_representation/Permutation_iterator.h | 6 ++---- .../gudhi/Permutahedral_representation/Set_partition_iterator.h | 6 ++---- .../include/gudhi/Permutahedral_representation/Simplex_comparator.h | 6 ++---- .../include/gudhi/Permutahedral_representation/Size_range.h | 6 ++---- .../include/gudhi/Permutahedral_representation/face_from_indices.h | 6 ++---- src/Coxeter_triangulation/include/gudhi/Query_result.h | 6 ++---- src/Coxeter_triangulation/test/cell_complex_test.cpp | 6 ++---- src/Coxeter_triangulation/test/freud_triang_test.cpp | 6 ++---- src/Coxeter_triangulation/test/function_test.cpp | 6 ++---- src/Coxeter_triangulation/test/manifold_tracing_test.cpp | 6 ++---- src/Coxeter_triangulation/test/oracle_test.cpp | 6 ++---- src/Coxeter_triangulation/test/perm_rep_test.cpp | 6 ++---- 47 files changed, 94 insertions(+), 188 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h b/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h index 2339817e..15d74860 100644 --- a/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h +++ b/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/concept/IntersectionOracle.h b/src/Coxeter_triangulation/concept/IntersectionOracle.h index 642317f2..8c0dbf19 100644 --- a/src/Coxeter_triangulation/concept/IntersectionOracle.h +++ b/src/Coxeter_triangulation/concept/IntersectionOracle.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h b/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h index c1562066..bb2451ff 100644 --- a/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h +++ b/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h b/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h index e64d3b97..4f3d4411 100644 --- a/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h +++ b/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index 51109bcb..03d5b288 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h index bd730368..e751f002 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Pawel Dlotko * * Copyright (C) 2017 Swansea University UK diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h index bc59ac12..1110c850 100644 --- a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h index be5d275c..99fe81d2 100644 --- a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h index 9fd0d69b..cda966f8 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index b0c7a167..e5b78b04 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index c2419783..230c89d8 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h index afafbb2f..29fadcbf 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h index d8b3a780..f3ae577a 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h index 3af0b14c..75fb9322 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h index 26b62731..1649ef9c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h index ad12a29f..8a438bf4 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h index 67dcf0b1..4f08614f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h index e27d35ae..f7588225 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h index 8fd93a2a..af0675b0 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h index 10ff53f3..3c729878 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index 89bef379..7d36cf84 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index 6752ec3f..e3ddecdb 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index e161f697..abfad697 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index 2236ea31..90f09a0b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h index cf0b00ac..e1bbaea3 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h index b1cc0fe5..2cceeac1 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index 71070c05..a96d12ba 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h index fe379242..b40593ba 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index a522f691..d3f371a6 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index fdb4f630..bbd86eb9 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h index a3c2b2c7..303011a2 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h index 20a4a8ff..36bf4b55 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h index 47eb8b98..8bf75711 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h index 55c32664..73b98337 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h index 4528ef20..e892b73b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h index 7cf6158b..ed1fb337 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h index 46f67752..26bbc1ef 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h index 5b3c29e9..b8925d96 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h index dd9c20dc..262915fb 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h index 461a01e7..c658a06d 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/include/gudhi/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Query_result.h index c7384c0b..ecc40c25 100644 --- a/src/Coxeter_triangulation/include/gudhi/Query_result.h +++ b/src/Coxeter_triangulation/include/gudhi/Query_result.h @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/test/cell_complex_test.cpp b/src/Coxeter_triangulation/test/cell_complex_test.cpp index a48696a6..486c4981 100644 --- a/src/Coxeter_triangulation/test/cell_complex_test.cpp +++ b/src/Coxeter_triangulation/test/cell_complex_test.cpp @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/test/freud_triang_test.cpp b/src/Coxeter_triangulation/test/freud_triang_test.cpp index 6e7bf865..69729975 100644 --- a/src/Coxeter_triangulation/test/freud_triang_test.cpp +++ b/src/Coxeter_triangulation/test/freud_triang_test.cpp @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/test/function_test.cpp b/src/Coxeter_triangulation/test/function_test.cpp index 518bef9b..c9c3f55b 100644 --- a/src/Coxeter_triangulation/test/function_test.cpp +++ b/src/Coxeter_triangulation/test/function_test.cpp @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp index cff6ddfa..0113f8b5 100644 --- a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp +++ b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/test/oracle_test.cpp b/src/Coxeter_triangulation/test/oracle_test.cpp index 8d371656..dfa19293 100644 --- a/src/Coxeter_triangulation/test/oracle_test.cpp +++ b/src/Coxeter_triangulation/test/oracle_test.cpp @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria diff --git a/src/Coxeter_triangulation/test/perm_rep_test.cpp b/src/Coxeter_triangulation/test/perm_rep_test.cpp index f2cdbce1..2376c88a 100644 --- a/src/Coxeter_triangulation/test/perm_rep_test.cpp +++ b/src/Coxeter_triangulation/test/perm_rep_test.cpp @@ -1,7 +1,5 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. * Author(s): Siargey Kachanovich * * Copyright (C) 2019 Inria -- cgit v1.2.3 From e0041b766b647f3906b52f861e97edba1f089312 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 22 Sep 2020 16:43:54 +0200 Subject: include what you use --- .../concept/IntersectionOracle.h | 10 +- .../include/gudhi/Cell_complex.h | 85 ++++++----- .../gudhi/Cell_complex/Hasse_diagram_cell.h | 17 +-- .../include/gudhi/Coxeter_triangulation.h | 25 ++-- .../include/gudhi/Freudenthal_triangulation.h | 52 +++---- .../include/gudhi/Functions/Cartesian_product.h | 6 +- .../include/gudhi/Functions/Constant_function.h | 6 +- .../include/gudhi/Functions/Embed_in_Rd.h | 6 +- .../include/gudhi/Functions/Function_Sm_in_Rd.h | 5 +- .../gudhi/Functions/Function_affine_plane_in_Rd.h | 5 +- .../include/gudhi/Functions/Function_chair_in_R3.h | 4 +- .../include/gudhi/Functions/Function_iron_in_R3.h | 6 +- .../Function_lemniscate_revolution_in_R3.h | 10 +- .../gudhi/Functions/Function_moment_curve_in_Rd.h | 5 +- .../include/gudhi/Functions/Function_torus_in_R3.h | 6 +- .../Functions/Function_whitney_umbrella_in_R3.h | 5 + .../gudhi/Functions/Linear_transformation.h | 5 +- .../include/gudhi/Functions/Negation.h | 7 +- .../include/gudhi/Functions/PL_approximation.h | 5 +- .../include/gudhi/Functions/Translate.h | 5 +- .../gudhi/Functions/random_orthogonal_matrix.h | 17 ++- .../include/gudhi/IO/Mesh_medit.h | 5 + .../gudhi/IO/build_mesh_from_cell_complex.h | 83 ++++++----- .../include/gudhi/IO/output_meshes_to_medit.h | 9 +- .../gudhi/Implicit_manifold_intersection_oracle.h | 42 +++--- .../include/gudhi/Manifold_tracing.h | 160 ++++++++++----------- .../include/gudhi/Permutahedral_representation.h | 41 +++--- .../Combination_iterator.h | 2 +- .../Integer_combination_iterator.h | 13 +- .../Ordered_set_partition_iterator.h | 25 ++-- .../Permutahedral_representation_iterators.h | 81 +++++------ .../Permutation_iterator.h | 22 +-- .../Set_partition_iterator.h | 29 ++-- .../Permutahedral_representation/Size_range.h | 16 +-- .../face_from_indices.h | 8 +- 35 files changed, 441 insertions(+), 387 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/concept/IntersectionOracle.h b/src/Coxeter_triangulation/concept/IntersectionOracle.h index 8c0dbf19..1427460b 100644 --- a/src/Coxeter_triangulation/concept/IntersectionOracle.h +++ b/src/Coxeter_triangulation/concept/IntersectionOracle.h @@ -48,9 +48,9 @@ struct IntersectionOracle { * (the domain dimension of the function). */ template + class Triangulation> Query_result intersects(const Simplex_handle& simplex, - const Triangulation& triangulation) const; + const Triangulation& triangulation) const; /** \brief Intersection query with the boundary of the manifold. * @@ -73,9 +73,9 @@ struct IntersectionOracle { * (the domain dimension of the function). */ template + class Triangulation> Query_result intersects_boundary(const Simplex_handle& simplex, - const Triangulation& triangulation) const; + const Triangulation& triangulation) const; /** \brief Returns true if the input point lies inside the piecewise-linear * domain induced by the given ambient triangulation that defines the relative @@ -89,7 +89,7 @@ struct IntersectionOracle { */ template bool lies_in_domain(const Eigen::VectorXd& p, - const Triangulation& triangulation) const { + const Triangulation& triangulation) const { Eigen::VectorXd pl_p = make_pl_approximation(domain_fun_, triangulation)(p); return pl_p(0) < 0; } diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index 03d5b288..3bc60a50 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -13,10 +13,11 @@ #include -#include -#include -#include // for Hasse_diagram_persistence.h +#include +#include +#include // for std::make_pair +#include #include // for Hasse_cell namespace Gudhi { @@ -43,40 +44,36 @@ public: /** \brief Type of a simplex in the ambient triangulation. * Is a model of the concept SimplexInCoxeterTriangulation. */ - typedef typename Out_simplex_map_::key_type Simplex_handle; + using Simplex_handle = typename Out_simplex_map_::key_type; /** \brief Type of a cell in the cell complex. * Always is Gudhi::Hasse_cell from the Hasse diagram module. * The additional information is the boolean that is true if and only if the cell lies * on the boundary. */ - typedef Gudhi::Hasse_diagram::Hasse_diagram_cell Hasse_cell; + using Hasse_cell = Gudhi::Hasse_diagram::Hasse_diagram_cell; /** \brief Type of a map from permutahedral representations of simplices in the * ambient triangulation to the corresponding cells in the cell complex of some * specific dimension. */ - typedef std::map > Simplex_cell_map; + using Simplex_cell_map = std::map >; /** \brief Type of a vector of maps from permutahedral representations of simplices in the * ambient triangulation to the corresponding cells in the cell complex of various dimensions. */ - typedef std::vector Simplex_cell_maps; + using Simplex_cell_maps = std::vector; /** \brief Type of a map from cells in the cell complex to the permutahedral representations * of the corresponding simplices in the ambient triangulation. */ - typedef std::map Cell_simplex_map; + using Cell_simplex_map = std::map; /** \brief Type of a map from vertex cells in the cell complex to the permutahedral representations * of their Cartesian coordinates. */ - typedef std::map Cell_point_map; + using Cell_point_map = std::map; private: - Hasse_cell* insert_cell(const Simplex_handle& simplex, - std::size_t cell_d, - bool is_boundary) { + Hasse_cell* insert_cell(const Simplex_handle& simplex, std::size_t cell_d, bool is_boundary) { Simplex_cell_maps& simplex_cell_maps = (is_boundary? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); #ifdef GUDHI_COX_OUTPUT_TO_HTML @@ -110,27 +107,27 @@ private: const Simplex_handle& simplex = sc_pair.first; Hasse_cell* cell = sc_pair.second; for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d)) { - Hasse_cell* new_cell = insert_cell(coface, cell_d, false); - new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + Hasse_cell* new_cell = insert_cell(coface, cell_d, false); + new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); } } if (is_manifold_with_boundary) { for (auto& sc_pair: boundary_simplex_cell_maps_[cell_d - 1]) { - const Simplex_handle& simplex = sc_pair.first; - Hasse_cell* cell = sc_pair.second; - if (cell_d != intr_d_) - for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d + 1)) { - Hasse_cell* new_cell = insert_cell(coface, cell_d, true); - new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); - } - auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex); - if (map_it == interior_simplex_cell_maps_[cell_d].end()) - std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n"; - else { - Hasse_cell* i_cell = map_it->second; - i_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); - } + const Simplex_handle& simplex = sc_pair.first; + Hasse_cell* cell = sc_pair.second; + if (cell_d != intr_d_) + for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d + 1)) { + Hasse_cell* new_cell = insert_cell(coface, cell_d, true); + new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + } + auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex); + if (map_it == interior_simplex_cell_maps_[cell_d].end()) + std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n"; + else { + Hasse_cell* i_cell = map_it->second; + i_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + } } } } @@ -148,15 +145,15 @@ private: cell_point_map_.emplace(std::make_pair(new_cell, point)); } for (std::size_t cell_d = 1; - cell_d < interior_simplex_cell_maps_.size() && - !interior_simplex_cell_maps_[cell_d - 1].empty(); - ++cell_d) { + cell_d < interior_simplex_cell_maps_.size() && + !interior_simplex_cell_maps_[cell_d - 1].empty(); + ++cell_d) { expand_level(cell_d); } } void construct_complex_(const Out_simplex_map_& interior_simplex_map, - const Out_simplex_map_& boundary_simplex_map) { + const Out_simplex_map_& boundary_simplex_map) { #ifdef GUDHI_COX_OUTPUT_TO_HTML cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); @@ -185,17 +182,17 @@ private: #endif for (std::size_t cell_d = 1; - cell_d < interior_simplex_cell_maps_.size() && - !interior_simplex_cell_maps_[cell_d - 1].empty(); - ++cell_d) { + cell_d < interior_simplex_cell_maps_.size() && + !interior_simplex_cell_maps_[cell_d - 1].empty(); + ++cell_d) { expand_level(cell_d); #ifdef GUDHI_COX_OUTPUT_TO_HTML for (const auto& sc_pair: interior_simplex_cell_maps_[cell_d]) - cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); + cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); if (cell_d < boundary_simplex_cell_maps_.size()) - for (const auto& sc_pair: boundary_simplex_cell_maps_[cell_d]) - cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); + for (const auto& sc_pair: boundary_simplex_cell_maps_[cell_d]) + cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); #endif } } @@ -230,7 +227,7 @@ public: * \param[in] limit_dimension The dimension of the constructed skeleton. */ void construct_complex(const Out_simplex_map_& out_simplex_map, - std::size_t limit_dimension) { + std::size_t limit_dimension) { interior_simplex_cell_maps_.resize(limit_dimension + 1); if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); @@ -250,7 +247,7 @@ public: * to the intersection points. */ void construct_complex(const Out_simplex_map_& interior_simplex_map, - const Out_simplex_map_& boundary_simplex_map) { + const Out_simplex_map_& boundary_simplex_map) { interior_simplex_cell_maps_.resize(intr_d_ + 1); boundary_simplex_cell_maps_.resize(intr_d_); if (!interior_simplex_map.empty()) @@ -273,8 +270,8 @@ public: * \param[in] limit_dimension The dimension of the constructed skeleton. */ void construct_complex(const Out_simplex_map_& interior_simplex_map, - const Out_simplex_map_& boundary_simplex_map, - std::size_t limit_dimension) { + const Out_simplex_map_& boundary_simplex_map, + std::size_t limit_dimension) { interior_simplex_cell_maps_.resize(limit_dimension + 1); boundary_simplex_cell_maps_.resize(limit_dimension); if (!interior_simplex_map.empty()) diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h index e751f002..a59026fa 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -8,21 +8,14 @@ * - YYYY/MM Author: Description of the modification */ -#include -#include -#include -#include -#include -#include -#include -#include - - - - #ifndef HASSE_DIAGRAM_CELL_H #define HASSE_DIAGRAM_CELL_H +#include +#include // for std::pair +#include +#include +#include // for std::is_same namespace Gudhi { namespace Hasse_diagram { diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h index 1110c850..19ceb007 100644 --- a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h @@ -11,9 +11,8 @@ #ifndef COXETER_TRIANGULATION_H_ #define COXETER_TRIANGULATION_H_ -#include -#include -#include //iota +#include +#include // for std::sqrt #include #include @@ -42,10 +41,9 @@ namespace coxeter_triangulation { * Needs to be a model of SimplexInCoxeterTriangulation. */ template , std::vector > > > + = Permutahedral_representation, std::vector > > > class Coxeter_triangulation : public Freudenthal_triangulation { - - typedef Eigen::MatrixXd Matrix; + using Matrix = Eigen::MatrixXd; Matrix root_matrix(unsigned d) { Matrix cartan(d,d); @@ -58,8 +56,8 @@ class Coxeter_triangulation : public Freudenthal_triangulation i+1) - cartan(i,j) = 0; + if (j+1 < i || j > i+1) + cartan(i,j) = 0; Eigen::SelfAdjointEigenSolver saes(cartan); Eigen::VectorXd sqrt_diag(d); for (unsigned i = 0; i < d; ++i) @@ -68,16 +66,15 @@ class Coxeter_triangulation : public Freudenthal_triangulation -#include -#include //iota +#include +#include // for std::sort +#include // for std::floor +#include // for std::iota +#include // for std::size_t #include #include @@ -40,21 +42,19 @@ namespace coxeter_triangulation { * Needs to be a model of SimplexInCoxeterTriangulation. */ template , std::vector > > > + = Permutahedral_representation, std::vector > > > class Freudenthal_triangulation { - - typedef Eigen::MatrixXd Matrix; - typedef Eigen::VectorXd Vector; - typedef Eigen::SparseMatrix SparseMatrix; - typedef Eigen::Triplet Triplet; + using Matrix = Eigen::MatrixXd; + using Vector = Eigen::VectorXd; + using SparseMatrix = Eigen::SparseMatrix; + using Triplet = Eigen::Triplet; -public: - + public: /** \brief Type of the simplices in the triangulation. */ - typedef Permutahedral_representation_ Simplex_handle; + using Simplex_handle = Permutahedral_representation_; /** \brief Type of the vertices in the triangulation. */ - typedef typename Permutahedral_representation_::Vertex Vertex_handle; + using Vertex_handle = typename Permutahedral_representation_::Vertex; /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension. @@ -155,37 +155,37 @@ public: std::vector z; if (is_freudenthal) { for (std::size_t i = 0; i < d; i++) { - double x_i = scale * point[i]; - int y_i = std::floor(x_i); - output.vertex().push_back(y_i); - z.push_back(x_i - y_i); + double x_i = scale * point[i]; + int y_i = std::floor(x_i); + output.vertex().push_back(y_i); + z.push_back(x_i - y_i); } } else { Eigen::VectorXd p_vect(d); for (std::size_t i = 0; i < d; i++) - p_vect(i) = point[i]; + p_vect(i) = point[i]; Eigen::VectorXd x_vect = colpivhouseholderqr_.solve(p_vect - offset_); for (std::size_t i = 0; i < d; i++) { - double x_i = scale * x_vect(i); - int y_i = std::floor(x_i); - output.vertex().push_back(y_i); - z.push_back(x_i - y_i); + double x_i = scale * x_vect(i); + int y_i = std::floor(x_i); + output.vertex().push_back(y_i); + z.push_back(x_i - y_i); } } z.push_back(0); Part indices(d+1); std::iota(indices.begin(), indices.end(), 0); std::sort(indices.begin(), - indices.end(), - [&z](std::size_t i1, std::size_t i2) {return z[i1] > z[i2];}); + indices.end(), + [&z](std::size_t i1, std::size_t i2) {return z[i1] > z[i2];}); output.partition().push_back(Part(1, indices[0])); for (std::size_t i = 1; i <= d; ++i) if (z[indices[i-1]] > z[indices[i]] + error) - output.partition().push_back(Part(1, indices[i])); + output.partition().push_back(Part(1, indices[i])); else - output.partition().back().push_back(indices[i]); + output.partition().back().push_back(indices[i]); return output; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h index cda966f8..0a6f264d 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -13,9 +13,11 @@ #include #include -#include +#include // for std::enable_if +#include // for std::size_t #include + #include namespace Gudhi { @@ -139,7 +141,7 @@ struct Cartesian_product : public Function { cod_d_ = get_cod_d(function_tuple_); } -private: + private: std::tuple function_tuple_; std::size_t amb_d_, cod_d_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index e5b78b04..c03a2a24 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -11,7 +11,10 @@ #ifndef FUNCTIONS_CONSTANT_FUNCTION_H_ #define FUNCTIONS_CONSTANT_FUNCTION_H_ +#include // for std::size_t + #include + #include namespace Gudhi { @@ -57,7 +60,8 @@ struct Constant_function : public Function { */ Constant_function(std::size_t d, std::size_t k, const Eigen::VectorXd& value) : d_(d), k_(k), value_(value) {} - + + private: std::size_t d_, k_; Eigen::VectorXd value_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index 230c89d8..5ebeac75 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -11,10 +11,10 @@ #ifndef FUNCTIONS_EMBED_IN_RD_H_ #define FUNCTIONS_EMBED_IN_RD_H_ -#include -#include +#include // for std::size_t #include + #include @@ -76,6 +76,8 @@ struct Embed_in_Rd : public Function { Embed_in_Rd(const Function_& function, std::size_t d) : fun_(function), d_(d) { } + + private: Function_ fun_; std::size_t d_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h index f3ae577a..7ebb7fc8 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -11,7 +11,10 @@ #ifndef FUNCTIONS_FUNCTION_SM_IN_RD_H_ #define FUNCTIONS_FUNCTION_SM_IN_RD_H_ +#include // for std::size_t + #include + #include namespace Gudhi { @@ -115,7 +118,7 @@ struct Function_Sm_in_Rd: public Function { : Function_Sm_in_Rd(rhs.r_, rhs.m_, rhs.d_, rhs.center_) {} -protected: + private: std::size_t m_, k_, d_; double r_; Eigen::VectorXd center_; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h index 75fb9322..1e950d4e 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -11,7 +11,10 @@ #ifndef FUNCTIONS_FUNCTION_AFFINE_PLANE_IN_RD_H_ #define FUNCTIONS_FUNCTION_AFFINE_PLANE_IN_RD_H_ +#include // for std::size_t + #include + #include namespace Gudhi { @@ -85,7 +88,7 @@ struct Function_affine_plane_in_Rd : public Function { normal_matrix_.colwise().normalize(); } -protected: +private: Eigen::MatrixXd normal_matrix_; std::size_t d_, k_, m_; Eigen::VectorXd off_; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h index 1649ef9c..fe16d37b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -11,9 +11,11 @@ #ifndef FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ #define FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ -#include +#include // for std::size_t +#include // for std::pow #include + #include namespace Gudhi { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h index 8a438bf4..fa5e4e66 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -11,7 +11,11 @@ #ifndef FUNCTIONS_FUNCTION_IRON_IN_R3_H_ #define FUNCTIONS_FUNCTION_IRON_IN_R3_H_ +#include // for std::size_t +#include // for std::pow + #include + #include namespace Gudhi { @@ -59,7 +63,7 @@ struct Function_iron_in_R3 : public Function { Function_iron_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : off_(off) {} -protected: + private: Eigen::Vector3d off_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h index 4f08614f..b715932b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -11,7 +11,11 @@ #ifndef FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ #define FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ +#include // for std::size_t +#include // for std::sqrt + #include + #include namespace Gudhi { @@ -51,7 +55,7 @@ struct Function_lemniscate_revolution_in_R3 : public Function { * See the method seed2() for the other point. */ virtual Eigen::VectorXd seed() const override { - Eigen::Vector3d result(sqrt(2*a_)+off_[0], off_[1], off_[2]); + Eigen::Vector3d result(std::sqrt(2*a_)+off_[0], off_[1], off_[2]); return result; } @@ -60,7 +64,7 @@ struct Function_lemniscate_revolution_in_R3 : public Function { * See the method seed() for the other point. */ Eigen::VectorXd seed2() const { - Eigen::Vector3d result(-sqrt(2*a_)+off_[0], off_[1], off_[2]); + Eigen::Vector3d result(-std::sqrt(2*a_)+off_[0], off_[1], off_[2]); return result; } @@ -75,7 +79,7 @@ struct Function_lemniscate_revolution_in_R3 : public Function { Eigen::Vector3d off = Eigen::Vector3d::Zero()) : a_(a), off_(off) {} -protected: + private: double a_; Eigen::Vector3d off_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h index f7588225..eecbc914 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -11,7 +11,10 @@ #ifndef FUNCTIONS_FUNCTION_MOMENT_CURVE_IN_RD_H_ #define FUNCTIONS_FUNCTION_MOMENT_CURVE_IN_RD_H_ +#include // for std::size_t + #include + #include namespace Gudhi { @@ -73,7 +76,7 @@ struct Function_moment_curve_in_Rd : public Function { Eigen::VectorXd& offset) : m_(1), k_(d-1), d_(d), r_(r), off_(offset) {} -protected: + private: std::size_t m_, k_, d_; double r_; Eigen::VectorXd off_; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h index af0675b0..c756c1a6 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -11,7 +11,11 @@ #ifndef FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ #define FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ +#include // for std::size_t +#include // for std::sqrt + #include + #include namespace Gudhi { @@ -62,7 +66,7 @@ struct Function_torus_in_R3 : public Function { Eigen::Vector3d off = Eigen::Vector3d::Zero()) : R_(R), r_(r), off_(off) {} -protected: + private: double R_, r_; Eigen::Vector3d off_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h index 3c729878..09306561 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -11,7 +11,10 @@ #ifndef FUNCTIONS_FUNCTION_WHITNEY_UMBRELLA_IN_R3_H_ #define FUNCTIONS_FUNCTION_WHITNEY_UMBRELLA_IN_R3_H_ +#include // for std::size_t + #include + #include namespace Gudhi { @@ -69,6 +72,8 @@ struct Function_whitney_umbrella_in_R3 : public Function { */ Function_whitney_umbrella_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : off_(off) {} + + private: Eigen::Vector3d off_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index 7d36cf84..a5d17fe0 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -11,9 +11,10 @@ #ifndef FUNCTIONS_LINEAR_TRANSFORMATION_H_ #define FUNCTIONS_LINEAR_TRANSFORMATION_H_ -#include +#include // for std::size_t #include + #include namespace Gudhi { @@ -65,7 +66,7 @@ struct Linear_transformation : public Function { fun_(function), matrix_(matrix) { } -private: + private: Function_ fun_; Eigen::MatrixXd matrix_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index e3ddecdb..3439dbad 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -11,9 +11,10 @@ #ifndef FUNCTIONS_NEGATION_H_ #define FUNCTIONS_NEGATION_H_ -#include +#include // for std::size_t #include + #include namespace Gudhi { @@ -62,6 +63,8 @@ struct Negation : public Function { Negation(const Function_& function) : fun_(function) { } + + private: Function_ fun_; }; @@ -78,7 +81,7 @@ struct Negation : public Function { * \ingroup coxeter_triangulation */ template -Negation negation(const Function_& function) { +Negation negation(const Function_& function) { return Negation(function); } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index abfad697..ab2b9294 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -11,9 +11,10 @@ #ifndef FUNCTIONS_PL_APPROXIMATION_H_ #define FUNCTIONS_PL_APPROXIMATION_H_ -#include +#include // for std::size_t #include + #include namespace Gudhi { @@ -90,7 +91,7 @@ struct PL_approximation : public Function { PL_approximation(const Function_& function, const Triangulation_& triangulation) : fun_(function), tr_(triangulation) {} -private: + private: Function_ fun_; Triangulation_ tr_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index 90f09a0b..b3f53fe0 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -11,9 +11,10 @@ #ifndef FUNCTIONS_TRANSLATE_H_ #define FUNCTIONS_TRANSLATE_H_ -#include +#include // for std::size_t #include + #include namespace Gudhi { @@ -65,6 +66,8 @@ struct Translate : public Function { Translate(const Function_& function, const Eigen::VectorXd& off) : fun_(function), off_(off) { } + + private: Function_ fun_; Eigen::VectorXd off_; }; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h index e1bbaea3..34fc1a67 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -11,8 +11,11 @@ #ifndef FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ #define FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ -#include -#include +#include // for std::size_t +#include // for std::cos, std::sin +#include // for std::uniform_real_distribution, std::random_device + +#include #include #include @@ -41,10 +44,14 @@ Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) { if (d == 1) return Eigen::VectorXd::Constant(1, 1.0); if (d == 2) { - double X = 2 * 3.14159265358; - double alpha = static_cast (rand()) / (static_cast (RAND_MAX/X)); + // 0. < alpha < 2 Pi + std::uniform_real_distribution unif(0., 2 * Gudhi::PI); + std::random_device rand_dev; + std::mt19937 rand_engine(rand_dev()); + double alpha = unif(rand_engine); + Eigen::Matrix2d rot; - rot << cos(alpha), -sin(alpha), sin(alpha), cos(alpha); + rot << std::cos(alpha), -std::sin(alpha), std::sin(alpha), cos(alpha); return rot; } Eigen::MatrixXd low_dim_rot = random_orthogonal_matrix(d-1); diff --git a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h index 2cceeac1..28276bf7 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h @@ -15,6 +15,11 @@ namespace Gudhi { namespace coxeter_triangulation { +#include + +#include +#include // for std::pair + /* \class Mesh_medit * \brief Structure to store a mesh that can be output in Medit .mesh file format * using the output_meshes_to_medit method. diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index a96d12ba..abe6cdbf 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -13,34 +13,42 @@ #include +#include + +#include // for std::size_t +#include +#include +#include +#include // for std::make_pair +#include // for std::min + namespace Gudhi { namespace coxeter_triangulation { struct Configuration { + Configuration(bool t_edges, bool t_triangles, bool t_tetrahedra, + std::size_t r_edges, std::size_t r_triangles, std::size_t r_tetrahedra) + : toggle_edges(t_edges), toggle_triangles(t_triangles), toggle_tetrahedra(t_tetrahedra), + ref_edges(r_edges), ref_triangles(r_triangles), ref_tetrahedra(r_tetrahedra) {} + + Configuration() {} + bool toggle_edges = true, toggle_triangles = true, toggle_tetrahedra = true; std::size_t ref_edges = 1, ref_triangles = 1, ref_tetrahedra = 1; - - Configuration(bool t_edges, bool t_triangles, bool t_tetrahedra, - std::size_t r_edges, std::size_t r_triangles, std::size_t r_tetrahedra) - : toggle_edges(t_edges), toggle_triangles(t_triangles), toggle_tetrahedra(t_tetrahedra), - ref_edges(r_edges), ref_triangles(r_triangles), ref_tetrahedra(r_tetrahedra) {} - - Configuration() {} }; -template +template void populate_mesh(Mesh_medit& output, - Simplex_cell_map& sc_map, - Configuration configuration, - std::size_t amb_d, - std::map vi_map) { + Simplex_cell_map& sc_map, + Configuration configuration, + std::size_t amb_d, + std::map vi_map) { using Mesh_element_vertices = Mesh_medit::Mesh_elements::value_type::first_type; std::map ci_map; std::size_t index = vi_map.size() + 1; // current size of output.vertex_points @@ -50,16 +58,16 @@ void populate_mesh(Mesh_medit& output, std::set vertex_indices; Hasse_cell* cell = sc_pair.second; for (const auto& ei_pair: cell->get_boundary()) - for (const auto& vi_pair: ei_pair.first->get_boundary()) - vertex_indices.emplace(vi_map[vi_pair.first]); + for (const auto& vi_pair: ei_pair.first->get_boundary()) + vertex_indices.emplace(vi_map[vi_pair.first]); for (const std::size_t& v: vertex_indices) - barycenter += output.vertex_points[v-1]; + barycenter += output.vertex_points[v-1]; ci_map.emplace(std::make_pair(cell, index++)); output.vertex_points.emplace_back((1./vertex_indices.size()) * barycenter); #ifdef GUDHI_COX_OUTPUT_TO_HTML std::string vlist = " (" + std::to_string(index-1) + ")"; for (const std::size_t& v: vertex_indices) - vlist += " " + std::to_string(v); + vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); #endif } @@ -69,12 +77,12 @@ void populate_mesh(Mesh_medit& output, Hasse_cell* edge_cell = sc_map.second; Mesh_element_vertices edge; for (const auto& vi_pair: edge_cell->get_boundary()) - edge.push_back(vi_map[vi_pair.first]); + edge.push_back(vi_map[vi_pair.first]); output.edges.emplace_back(std::make_pair(edge, configuration.ref_edges)); #ifdef GUDHI_COX_OUTPUT_TO_HTML std::string vlist; for (const std::size_t& v: edge) - vlist += " " + std::to_string(v); + vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(edge_cell), vlist)); #endif } @@ -82,10 +90,10 @@ void populate_mesh(Mesh_medit& output, if (configuration.toggle_triangles && sc_map.size() >= 3) for (const auto& sc_pair: sc_map[2]) { for (const auto& ei_pair: sc_pair.second->get_boundary()) { - Mesh_element_vertices triangle(1, ci_map[sc_pair.second]); - for (const auto& vi_pair: ei_pair.first->get_boundary()) - triangle.push_back(vi_map[vi_pair.first]); - output.triangles.emplace_back(std::make_pair(triangle, configuration.ref_triangles)); + Mesh_element_vertices triangle(1, ci_map[sc_pair.second]); + for (const auto& vi_pair: ei_pair.first->get_boundary()) + triangle.push_back(vi_map[vi_pair.first]); + output.triangles.emplace_back(std::make_pair(triangle, configuration.ref_triangles)); } } @@ -95,34 +103,34 @@ void populate_mesh(Mesh_medit& output, std::set vertex_indices; Hasse_cell* cell = sc_pair.second; for (const auto& ci_pair: cell->get_boundary()) - for (const auto& ei_pair: ci_pair.first->get_boundary()) - for (const auto& vi_pair: ei_pair.first->get_boundary()) - vertex_indices.emplace(vi_map[vi_pair.first]); - for (const std::size_t& v: vertex_indices) - barycenter += output.vertex_points[v-1]; + for (const auto& ei_pair: ci_pair.first->get_boundary()) + for (const auto& vi_pair: ei_pair.first->get_boundary()) + vertex_indices.emplace(vi_map[vi_pair.first]); + for (const std::size_t& v: vertex_indices) + barycenter += output.vertex_points[v-1]; output.vertex_points.emplace_back((1./vertex_indices.size()) * barycenter); #ifdef GUDHI_COX_OUTPUT_TO_HTML std::string vlist = " (" + std::to_string(index) + ")"; for (const std::size_t& v: vertex_indices) - vlist += " " + std::to_string(v); + vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); #endif for (const auto& ci_pair: cell->get_boundary()) - for (const auto& ei_pair: ci_pair.first->get_boundary()) { - Mesh_element_vertices tetrahedron = {index, ci_map[sc_pair.second]}; - for (const auto& vi_pair: ei_pair.first->get_boundary()) - tetrahedron.push_back(vi_map[vi_pair.first]); - output.tetrahedra.emplace_back(std::make_pair(tetrahedron, configuration.ref_tetrahedra)); - } + for (const auto& ei_pair: ci_pair.first->get_boundary()) { + Mesh_element_vertices tetrahedron = {index, ci_map[sc_pair.second]}; + for (const auto& vi_pair: ei_pair.first->get_boundary()) + tetrahedron.push_back(vi_map[vi_pair.first]); + output.tetrahedra.emplace_back(std::make_pair(tetrahedron, configuration.ref_tetrahedra)); + } index++; } } template Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, - Configuration i_configuration = Configuration(), - Configuration b_configuration = Configuration()) { + Configuration i_configuration = Configuration(), + Configuration b_configuration = Configuration()) { using Hasse_cell = typename Cell_complex::Hasse_cell; Mesh_medit output; std::map vi_map; // one for vertices, other for 2d-cells @@ -142,7 +150,6 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, output.vertex_points.push_back(cp_pair.second); output.vertex_points.back().conservativeResize(amb_d); } - populate_mesh(output, cell_complex.interior_simplex_cell_maps(), i_configuration, amb_d, vi_map); #ifdef GUDHI_COX_OUTPUT_TO_HTML diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h index b40593ba..850736e9 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h @@ -12,8 +12,15 @@ #define IO_OUTPUT_MESHES_TO_MEDIT_H_ #include + #include -#include + +#include // for std::size_t +#include // for std::ofstream +#include +#include // for std::enable_if +#include // for std::get +#include // for std::make_pair namespace Gudhi { diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index d3f371a6..51d84274 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -37,15 +37,15 @@ namespace coxeter_triangulation { * \ingroup coxeter_triangulation */ template + class Domain_function_ = Constant_function> class Implicit_manifold_intersection_oracle { /* Computes the affine coordinates of the intersection point of the implicit manifold * and the affine hull of the simplex. */ template + class Triangulation> Eigen::VectorXd compute_lambda(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + const Triangulation& triangulation) const { std::size_t cod_d = this->cod_d(); Eigen::MatrixXd matrix(cod_d + 1, cod_d + 1); for (std::size_t i = 0; i < cod_d + 1; ++i) @@ -54,7 +54,7 @@ class Implicit_manifold_intersection_oracle { for (auto v: simplex.vertex_range()) { Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v)); for (std::size_t i = 1; i < cod_d + 1; ++i) - matrix(i, j) = v_coords(i-1); + matrix(i, j) = v_coords(i-1); j++; } Eigen::VectorXd z(cod_d + 1); @@ -68,9 +68,9 @@ class Implicit_manifold_intersection_oracle { /* Computes the affine coordinates of the intersection point of the boundary * of the implicit manifold and the affine hull of the simplex. */ template + class Triangulation> Eigen::VectorXd compute_boundary_lambda(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + const Triangulation& triangulation) const { std::size_t cod_d = this->cod_d(); Eigen::MatrixXd matrix(cod_d + 2, cod_d + 2); for (std::size_t i = 0; i < cod_d + 2; ++i) @@ -79,7 +79,7 @@ class Implicit_manifold_intersection_oracle { for (auto v: simplex.vertex_range()) { Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v)); for (std::size_t i = 1; i < cod_d + 1; ++i) - matrix(i, j) = v_coords(i-1); + matrix(i, j) = v_coords(i-1); Eigen::VectorXd bv_coords = domain_fun_(triangulation.cartesian_coordinates(v)); matrix(cod_d + 1, j) = bv_coords(0); j++; @@ -94,17 +94,17 @@ class Implicit_manifold_intersection_oracle { /* Computes the intersection result for a given simplex in a triangulation. */ template + class Triangulation> Query_result intersection_result(const Eigen::VectorXd& lambda, - const Simplex_handle& simplex, - const Triangulation& triangulation) const { + const Simplex_handle& simplex, + const Triangulation& triangulation) const { using QR = Query_result; std::size_t amb_d = triangulation.dimension(); std::size_t cod_d = simplex.dimension(); for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) if (lambda(i) < 0 || lambda(i) > 1) - return QR({Eigen::VectorXd(), false}); + return QR({Eigen::VectorXd(), false}); Eigen::MatrixXd vertex_matrix(cod_d + 1, amb_d); auto v_range = simplex.vertex_range(); @@ -112,7 +112,7 @@ class Implicit_manifold_intersection_oracle { for (std::size_t i = 0; i < cod_d + 1 && v_it != v_range.end(); ++v_it, ++i) { Eigen::VectorXd v_coords = triangulation.cartesian_coordinates(*v_it); for (std::size_t j = 0; j < amb_d; ++j) - vertex_matrix(i, j) = v_coords(j); + vertex_matrix(i, j) = v_coords(j); } Eigen::VectorXd intersection = lambda.transpose()*vertex_matrix; return QR({intersection, true}); @@ -151,9 +151,9 @@ public: * (the domain dimension of the function). */ template + class Triangulation> Query_result intersects(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + const Triangulation& triangulation) const { Eigen::VectorXd lambda = compute_lambda(simplex, triangulation); return intersection_result(lambda, simplex, triangulation); } @@ -179,9 +179,9 @@ public: * (the domain dimension of the function). */ template + class Triangulation> Query_result intersects_boundary(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + const Triangulation& triangulation) const { Eigen::VectorXd lambda = compute_boundary_lambda(simplex, triangulation); return intersection_result(lambda, simplex, triangulation); } @@ -199,7 +199,7 @@ public: */ template bool lies_in_domain(const Eigen::VectorXd& p, - const Triangulation& triangulation) const { + const Triangulation& triangulation) const { Eigen::VectorXd pl_p = make_pl_approximation(domain_fun_, triangulation)(p); return pl_p(0) < 0; } @@ -218,7 +218,7 @@ public: * manifold with boundary. */ Implicit_manifold_intersection_oracle(const Function_& function, - const Domain_function_& domain_function) + const Domain_function_& domain_function) : fun_(function), domain_fun_(domain_function) {} /** \brief Constructs an intersection oracle for an implicit manifold @@ -249,12 +249,12 @@ private: * \ingroup coxeter_triangulation */ template + class Domain_function_> Implicit_manifold_intersection_oracle make_oracle(const Function_& function, - const Domain_function_& domain_function){ + const Domain_function_& domain_function){ return Implicit_manifold_intersection_oracle(function, - domain_function); + domain_function); } diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index bbd86eb9..25b664eb 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -76,26 +76,26 @@ public: * are the intersection points. */ template + class Intersection_oracle> void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation_& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& out_simplex_map) { + const Triangulation_& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& out_simplex_map) { std::size_t cod_d = oracle.cod_d(); std::queue queue; for (const auto& p: seed_points) { Simplex_handle full_simplex = triangulation.locate_point(p); for (Simplex_handle face: full_simplex.face_range(cod_d)) { - Query_result qr = oracle.intersects(face, triangulation); - if (qr.success && - out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { + Query_result qr = oracle.intersects(face, triangulation); + if (qr.success && + out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { #ifdef GUDHI_COX_OUTPUT_TO_HTML - mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); + mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); #endif - queue.emplace(face); - break; - } + queue.emplace(face); + break; + } } } @@ -104,12 +104,12 @@ public: Simplex_handle s = queue.front(); queue.pop(); for (auto cof: s.coface_range(cod_d+1)) { - for (auto face: cof.face_range(cod_d)) { - Query_result qr = oracle.intersects(face, triangulation); - if (qr.success && - out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) - queue.emplace(face); - } + for (auto face: cof.face_range(cod_d)) { + Query_result qr = oracle.intersects(face, triangulation); + if (qr.success && + out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) + queue.emplace(face); + } } } } @@ -139,39 +139,39 @@ public: * and the mapped values are the intersection points. */ template + class Intersection_oracle> void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation_& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& interior_simplex_map, - Out_simplex_map& boundary_simplex_map) { + const Triangulation_& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& interior_simplex_map, + Out_simplex_map& boundary_simplex_map) { std::size_t cod_d = oracle.cod_d(); std::queue queue; for (const auto& p: seed_points) { Simplex_handle full_simplex = triangulation.locate_point(p); for (Simplex_handle face: full_simplex.face_range(cod_d)) { - auto qr = oracle.intersects(face, triangulation); + auto qr = oracle.intersects(face, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML - mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); -#endif - if (qr.success) { - if (oracle.lies_in_domain(qr.intersection, triangulation)) { - if (interior_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) - queue.emplace(face); - } - else { - for (Simplex_handle cof: face.coface_range(cod_d+1)) { - auto qrb = oracle.intersects_boundary(cof, triangulation); + mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); +#endif + if (qr.success) { + if (oracle.lies_in_domain(qr.intersection, triangulation)) { + if (interior_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) + queue.emplace(face); + } + else { + for (Simplex_handle cof: face.coface_range(cod_d+1)) { + auto qrb = oracle.intersects_boundary(cof, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML - mt_seed_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); -#endif - if (qrb.success) - boundary_simplex_map.emplace(cof, qrb.intersection); - } - } - // break; - } + mt_seed_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); +#endif + if (qrb.success) + boundary_simplex_map.emplace(cof, qrb.intersection); + } + } + // break; + } } } @@ -179,27 +179,27 @@ public: Simplex_handle s = queue.front(); queue.pop(); for (auto cof: s.coface_range(cod_d+1)) { - for (auto face: cof.face_range(cod_d)) { - auto qr = oracle.intersects(face, triangulation); + for (auto face: cof.face_range(cod_d)) { + auto qr = oracle.intersects(face, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML - mt_inserted_list.push_back(MT_inserted_info(qr, face, false)); -#endif - if (qr.success) { - if (oracle.lies_in_domain(qr.intersection, triangulation)) { - if (interior_simplex_map.emplace(face, qr.intersection).second) - queue.emplace(face); - } - else { - auto qrb = oracle.intersects_boundary(cof, triangulation); + mt_inserted_list.push_back(MT_inserted_info(qr, face, false)); +#endif + if (qr.success) { + if (oracle.lies_in_domain(qr.intersection, triangulation)) { + if (interior_simplex_map.emplace(face, qr.intersection).second) + queue.emplace(face); + } + else { + auto qrb = oracle.intersects_boundary(cof, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML - mt_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); -#endif - // assert (qrb.success); // always a success - if (qrb.success) - boundary_simplex_map.emplace(cof, qrb.intersection); - } - } - } + mt_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); +#endif + // assert (qrb.success); // always a success + if (qrb.success) + boundary_simplex_map.emplace(cof, qrb.intersection); + } + } + } } } } @@ -237,18 +237,18 @@ public: * \ingroup coxeter_triangulation */ template + class Triangulation, + class Intersection_oracle, + class Out_simplex_map> void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& out_simplex_map) { + const Triangulation& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& out_simplex_map) { Manifold_tracing mt; mt.manifold_tracing_algorithm(seed_points, - triangulation, - oracle, - out_simplex_map); + triangulation, + oracle, + out_simplex_map); } /** @@ -281,20 +281,20 @@ void manifold_tracing_algorithm(const Point_range& seed_points, * \ingroup coxeter_triangulation */ template + class Triangulation, + class Intersection_oracle, + class Out_simplex_map> void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& interior_simplex_map, - Out_simplex_map& boundary_simplex_map) { + const Triangulation& triangulation, + const Intersection_oracle& oracle, + Out_simplex_map& interior_simplex_map, + Out_simplex_map& boundary_simplex_map) { Manifold_tracing mt; mt.manifold_tracing_algorithm(seed_points, - triangulation, - oracle, - interior_simplex_map, - boundary_simplex_map); + triangulation, + oracle, + interior_simplex_map, + boundary_simplex_map); } diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h index 303011a2..b1f57b08 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h @@ -13,8 +13,7 @@ #include -#include -#include +#include // for std::make_pair namespace Gudhi { @@ -36,7 +35,7 @@ namespace coxeter_triangulation { * random-access ranges. */ template + class Ordered_set_partition_> class Permutahedral_representation { typedef Permutahedral_representation Self; @@ -100,7 +99,7 @@ public: return false; for (std::size_t k = 0; k < partition_.size(); ++k) if (partition_[k] != other.partition_[k]) - return false; + return false; return true; } @@ -118,7 +117,7 @@ public: */ Vertex_range vertex_range() const { return Vertex_range(Vertex_iterator(*this), - Vertex_iterator()); + Vertex_iterator()); } typedef Gudhi::coxeter_triangulation::Face_iterator Face_iterator; @@ -128,7 +127,7 @@ public: */ Face_range face_range(std::size_t value_dim) const { return Face_range(Face_iterator(*this, value_dim), - Face_iterator()); + Face_iterator()); } /** \brief Returns a range of permutahedral representations of facets of the simplex. @@ -136,7 +135,7 @@ public: */ Face_range facet_range() const { return Face_range(Face_iterator(*this, dimension()-1), - Face_iterator()); + Face_iterator()); } typedef Gudhi::coxeter_triangulation::Coface_iterator Coface_iterator; @@ -146,7 +145,7 @@ public: */ Coface_range coface_range(std::size_t value_dim) const { return Coface_range(Coface_iterator(*this, value_dim), - Coface_iterator()); + Coface_iterator()); } /** \brief Returns a range of permutahedral representations of cofacets of the simplex. @@ -154,7 +153,7 @@ public: */ Coface_range cofacet_range() const { return Coface_range(Coface_iterator(*this, dimension()+1), - Coface_iterator()); + Coface_iterator()); } /** \brief Returns true, if the simplex is a face of other simplex. @@ -174,19 +173,19 @@ public: auto other_partition_it = other.partition_.begin(); while (self_partition_it != partition_.end()) { while (other_partition_it != other.partition_.end() && v_self != v_other) { - const Part& other_part = *other_partition_it++; - if (other_partition_it == other.partition_.end()) - return false; - for (const auto& k: other_part) - v_other[k]++; + const Part& other_part = *other_partition_it++; + if (other_partition_it == other.partition_.end()) + return false; + for (const auto& k: other_part) + v_other[k]++; } if (other_partition_it == other.partition_.end()) - return false; + return false; const Part& self_part = *self_partition_it++; if (self_partition_it == partition_.end()) - return true; + return true; for (const auto& k: self_part) - v_self[k]++; + v_self[k]++; } return true; } @@ -204,9 +203,9 @@ private: * @param[in] simplex A simplex represented by its permutahedral representation. */ template + class OrderedSetPartition> std::ostream& operator<<(std::ostream& os, - const Permutahedral_representation& simplex) { + const Permutahedral_representation& simplex) { // vertex part os << "("; if (simplex.vertex().empty()) { @@ -225,12 +224,12 @@ std::ostream& operator<<(std::ostream& os, [&os](const Part& p) { os << "{"; if (p.empty()) { - os << "}"; + os << "}"; } auto p_it = p.begin(); os << *p_it++; for (; p_it != p.end(); ++p_it) - os << ", " << *p_it; + os << ", " << *p_it; os << "}"; }; os << " ["; diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h index 36bf4b55..ce6a34ec 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h @@ -83,7 +83,7 @@ public: } } -protected: + private: value_t value_; // the dereference value bool is_end_; // is true when the current permutation is the final one diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h index 8bf75711..c4e86a36 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h @@ -25,11 +25,11 @@ typedef unsigned uint; * Based on the algorithm by Mifsud. */ class Integer_combination_iterator : public boost::iterator_facade< Integer_combination_iterator, - std::vector const, - boost::forward_traversal_tag> { - typedef std::vector value_t; + std::vector const, + boost::forward_traversal_tag> { + using value_t = std::vector; -protected: + private: friend class boost::iterator_core_access; bool equal(Integer_combination_iterator const& other) const { @@ -71,7 +71,6 @@ protected: } public: - template Integer_combination_iterator(const uint& n, const uint& k, const Bound_range& bounds) : @@ -109,8 +108,8 @@ public: // Used for the creating an end iterator Integer_combination_iterator() : is_end_(true), n_(0), k_(0) {} - -protected: + + private: value_t value_; // the dereference value bool is_end_; // is true when the current integer combination is the final one diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h index 73b98337..d6f9f121 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h @@ -13,8 +13,10 @@ #include #include + #include #include + #include namespace Gudhi { @@ -48,11 +50,11 @@ struct Ordered_set_partition { * */ class Ordered_set_partition_iterator : public boost::iterator_facade< Ordered_set_partition_iterator, - Ordered_set_partition const, - boost::forward_traversal_tag> { - typedef Ordered_set_partition value_t; + Ordered_set_partition const, + boost::forward_traversal_tag> { + using value_t = Ordered_set_partition; -protected: + private: friend class boost::iterator_core_access; bool equal(Ordered_set_partition_iterator const& other) const { @@ -66,22 +68,19 @@ protected: void increment() { if (++value_.p_it_ == p_end_) { if (++value_.s_it_ == s_end_) { - is_end_ = true; - return; + is_end_ = true; + return; } else - value_.p_it_.reinitialize(); + value_.p_it_.reinitialize(); } } -public: - + public: Ordered_set_partition_iterator(const uint& n, const uint& k) : value_({Set_partition_iterator(n,k), Permutation_iterator(k)}), - is_end_(n == 0) - { - } + is_end_(n == 0) {} // Used for the creating an end iterator Ordered_set_partition_iterator() : is_end_(true) {} @@ -92,7 +91,7 @@ public: value_.s_it_.reinitialize(); } -protected: + private: Set_partition_iterator s_end_; // Set partition iterator and the corresponding end iterator Permutation_iterator p_end_; // Permutation iterator and the corresponding end iterator value_t value_; // the dereference value diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h index e892b73b..d42e892a 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h @@ -20,7 +20,7 @@ #include #include -#include +#include // for std::find namespace Gudhi { @@ -37,15 +37,15 @@ namespace coxeter_triangulation { * Forward iterator, 'value_type' is Permutahedral_representation::Vertex.*/ template class Vertex_iterator : public boost::iterator_facade< Vertex_iterator, - typename Permutahedral_representation::Vertex const, - boost::forward_traversal_tag> { -protected: + typename Permutahedral_representation::Vertex const, + boost::forward_traversal_tag> { + private: friend class boost::iterator_core_access; using Vertex = typename Permutahedral_representation::Vertex; using Ordered_partition = typename Permutahedral_representation::OrderedSetPartition; - typedef Vertex value_t; + using value_t = Vertex; bool equal(Vertex_iterator const& other) const { @@ -60,12 +60,12 @@ protected: std::size_t d = value_.size(); for (auto i: *o_it_) if (i != d) - value_[i]++; + value_[i]++; else - for (std::size_t j = 0; j < d; j++) - value_[j]--; + for (std::size_t j = 0; j < d; j++) + value_[j]--; } - + void increment() { if (is_end_) return; @@ -84,9 +84,8 @@ public: {} Vertex_iterator() : is_end_(true) {} - - -protected: + + private: typename Ordered_partition::const_iterator o_it_, o_end_; value_t value_; bool is_end_; @@ -100,11 +99,11 @@ protected: * Forward iterator, value_type is Permutahedral_representation. */ template class Face_iterator : public boost::iterator_facade< Face_iterator, - Permutahedral_representation const, - boost::forward_traversal_tag> { - typedef Permutahedral_representation value_t; + Permutahedral_representation const, + boost::forward_traversal_tag> { + using value_t = Permutahedral_representation; -protected: + private: friend class boost::iterator_core_access; using Vertex = typename Permutahedral_representation::Vertex; @@ -130,9 +129,8 @@ protected: // Combination *c_it_ is supposed to be sorted in increasing order value_ = face_from_indices(simplex_, *c_it_); } - + public: - Face_iterator(const Permutahedral_representation& simplex, const uint& k) : simplex_(simplex), k_(k), @@ -147,7 +145,7 @@ public: // Used for the creating an end iterator Face_iterator() : is_end_(true) {} -protected: + private: Permutahedral_representation simplex_; // Input simplex uint k_; uint l_; // Dimension of the input simplex @@ -165,11 +163,11 @@ protected: * Forward iterator, value_type is Permutahedral_representation. */ template class Coface_iterator : public boost::iterator_facade< Coface_iterator, - Permutahedral_representation const, - boost::forward_traversal_tag> { - typedef Permutahedral_representation value_t; - -protected: + Permutahedral_representation const, + boost::forward_traversal_tag> { + using value_t = Permutahedral_representation; + + private: friend class boost::iterator_core_access; using Vertex = typename Permutahedral_representation::Vertex; @@ -187,20 +185,20 @@ protected: uint i = 0; for (; i < k_+1; i++) { if (++(o_its_[i]) != o_end_) - break; + break; } if (i == k_+1) { if (++i_it_ == i_end_) { - is_end_ = true; - return; + is_end_ = true; + return; } o_its_.clear(); for (uint j = 0; j < k_ + 1; j++) - o_its_.emplace_back(Ordered_set_partition_iterator(simplex_.partition()[j].size(), (*i_it_)[j]+1)); + o_its_.emplace_back(Ordered_set_partition_iterator(simplex_.partition()[j].size(), (*i_it_)[j]+1)); } else for (uint j = 0; j < i; j++) - o_its_[j].reinitialize(); + o_its_[j].reinitialize(); update_value(); } @@ -212,30 +210,29 @@ protected: for (; u_ <= (*i_it_)[k_]; u_++) { auto range = (*o_its_[k_])[u_]; if (std::find(range.begin(), range.end(), t_) != range.end()) - break; + break; } uint i = 0; for (uint j = u_+1; j <= (*i_it_)[k_]; j++, i++) for (uint b: (*o_its_[k_])[j]) { - uint c = simplex_.partition()[k_][b]; + uint c = simplex_.partition()[k_][b]; value_.partition()[i].push_back(c); - value_.vertex()[c]--; + value_.vertex()[c]--; } for (uint h = 0; h < k_; h++) for (uint j = 0; j <= (*i_it_)[h]; j++, i++) { - for (uint b: (*o_its_[h])[j]) - value_.partition()[i].push_back(simplex_.partition()[h][b]); + for (uint b: (*o_its_[h])[j]) + value_.partition()[i].push_back(simplex_.partition()[h][b]); } for (uint j = 0; j <= u_; j++, i++) for (uint b: (*o_its_[k_])[j]) - value_.partition()[i].push_back(simplex_.partition()[k_][b]); + value_.partition()[i].push_back(simplex_.partition()[k_][b]); // sort the values in each part (probably not needed) for (auto& part: value_.partition()) std::sort(part.begin(), part.end()); } - -public: - + + public: Coface_iterator(const Permutahedral_representation& simplex, const uint& l) : simplex_(simplex), d_(simplex.vertex().size()), @@ -248,8 +245,8 @@ public: uint j = 0; for (; j < simplex_.partition()[k_].size(); j++) if (simplex_.partition()[k_][j] == d_) { - t_ = j; - break; + t_ = j; + break; } if (j == simplex_.partition()[k_].size()) { std::cerr << "Coface iterator: the argument simplex is not a permutahedral representation\n"; @@ -263,8 +260,8 @@ public: // Used for the creating an end iterator Coface_iterator() : is_end_(true) {} - -protected: + + private: Permutahedral_representation simplex_; // Input simplex uint d_; // Ambient dimension uint l_; // Dimension of the coface diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h index ed1fb337..e0142bf4 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h @@ -11,7 +11,9 @@ #ifndef PERMUTAHEDRAL_REPRESENTATION_PERMUTATION_ITERATOR_H_ #define PERMUTAHEDRAL_REPRESENTATION_PERMUTATION_ITERATOR_H_ +#include // for std::size_t #include + #include namespace Gudhi { @@ -24,11 +26,11 @@ typedef unsigned uint; * Based on the optimization of the Heap's algorithm by Sedgewick. */ class Permutation_iterator : public boost::iterator_facade< Permutation_iterator, - std::vector const, - boost::forward_traversal_tag> { - typedef std::vector value_t; + std::vector const, + boost::forward_traversal_tag> { + using value_t = std::vector; -protected: + private: friend class boost::iterator_core_access; bool equal(Permutation_iterator const& other) const { @@ -70,12 +72,12 @@ protected: ct_ = 5; uint j = 2; while (d_[j] == j+1) { - d_[j] = 0; - ++j; + d_[j] = 0; + ++j; } if (j == n_ - 1) { - is_end_ = true; - return; + is_end_ = true; + return; } uint k = j+1; uint x = (k%2 ? d_[j] : 0); @@ -117,8 +119,8 @@ public: if (n_ > 0) is_end_ = false; } - -protected: + + private: value_t value_; // the dereference value bool is_end_; // is true when the current permutation is the final one bool optim_3_; // true if n>=3. for n >= 3, the algorithm is optimized diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h index 26bbc1ef..bd1770bc 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h @@ -25,11 +25,11 @@ typedef unsigned uint; * */ class Set_partition_iterator : public boost::iterator_facade< Set_partition_iterator, - std::vector > const, - boost::forward_traversal_tag> { - typedef std::vector > value_t; - -protected: + std::vector > const, + boost::forward_traversal_tag> { + using value_t = std::vector>; + + private: friend class boost::iterator_core_access; bool equal(Set_partition_iterator const& other) const { @@ -54,7 +54,7 @@ protected: } uint i = n_ - 1; while (rgs_[i] + 1 > max_[i] || - rgs_[i] + 1 >= k_) + rgs_[i] + 1 >= k_) i--; if (i == 0) { is_end_ = true; @@ -71,16 +71,15 @@ protected: uint p = k_; if (mm < p) do { - max_[i] = p; - --i; - --p; - rgs_[i] = p; + max_[i] = p; + --i; + --p; + rgs_[i] = p; } while (max_[i] < p); update_value(); } -public: - + public: Set_partition_iterator(const uint& n, const uint& k) : value_(k), @@ -116,12 +115,12 @@ public: max_[i] = rgs_[i-1] + 1; update_value(); } - -protected: + + private: value_t value_; // the dereference value std::vector rgs_; // restricted growth string std::vector max_; // max_[i] = max(rgs_[0],...,rgs[i-1]) + 1 - bool is_end_; // is true when the current permutation is the final one + bool is_end_; // is true when the current permutation is the final one uint n_; uint k_; diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h index 262915fb..f41335e9 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h @@ -11,8 +11,9 @@ #ifndef PERMUTAHEDRAL_REPRESENTATION_SIZE_RANGE_H_ #define PERMUTAHEDRAL_REPRESENTATION_SIZE_RANGE_H_ +#include // for std::size_t + #include -#include // std::size_t namespace Gudhi { @@ -22,11 +23,11 @@ namespace coxeter_triangulation { */ template class Size_iterator : public boost::iterator_facade< Size_iterator, - std::size_t const, - boost::forward_traversal_tag> { + std::size_t const, + boost::forward_traversal_tag> { friend class boost::iterator_core_access; -protected: + private: bool equal(Size_iterator const& other) const { return (is_end_ && other.is_end_); } @@ -43,15 +44,14 @@ protected: value_ = t_it_->size()-1; } -public: - + public: Size_iterator(const T_it& t_begin, const T_it& t_end) : t_it_(t_begin), t_end_(t_end), is_end_(t_begin == t_end) { if (!is_end_) value_ = t_it_->size()-1; } -protected: + private: T_it t_it_, t_end_; bool is_end_; std::size_t value_; @@ -61,7 +61,7 @@ template class Size_range { const T& t_; -public: + public: typedef Size_iterator iterator; Size_range(const T& t) : t_(t) {} diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h index c658a06d..21ee3c8b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h @@ -15,6 +15,9 @@ namespace Gudhi { namespace coxeter_triangulation { +#include // for std::size_t +#include + /** \brief Computes the permutahedral representation of a face of a given simplex * and a range of the vertex indices that compose the face. * @@ -25,10 +28,9 @@ namespace coxeter_triangulation { * @param[in] simplex Input simplex. * @param[in] indices Input range of indices. */ -template +template Permutahedral_representation face_from_indices(const Permutahedral_representation& simplex, - const Index_range& indices) { + const Index_range& indices) { using range_index = typename Index_range::value_type; using Ordered_set_partition = typename Permutahedral_representation::OrderedSetPartition; using Part = typename Ordered_set_partition::value_type; -- cgit v1.2.3 From be7555abfb97f02c37de96736f7a0993d4d47f03 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 22 Sep 2020 18:12:31 +0200 Subject: clang-format files --- .../concept/FunctionForImplicitManifold.h | 12 +- .../concept/IntersectionOracle.h | 49 +- .../concept/SimplexInCoxeterTriangulation.h | 21 +- .../concept/TriangulationForManifoldTracing.h | 17 +- .../doc/intro_coxeter_triangulation.h | 39 +- .../example/manifold_tracing_custom_function.cpp | 35 +- .../manifold_tracing_flat_torus_with_boundary.cpp | 25 +- .../include/gudhi/Cell_complex.h | 178 +++---- .../gudhi/Cell_complex/Hasse_diagram_cell.h | 509 ++++++++++----------- .../include/gudhi/Coxeter_triangulation.h | 38 +- .../include/gudhi/Freudenthal_triangulation.h | 129 +++--- .../include/gudhi/Functions/Cartesian_product.h | 82 ++-- .../include/gudhi/Functions/Constant_function.h | 26 +- .../include/gudhi/Functions/Embed_in_Rd.h | 37 +- .../include/gudhi/Functions/Function.h | 8 +- .../include/gudhi/Functions/Function_Sm_in_Rd.h | 78 ++-- .../gudhi/Functions/Function_affine_plane_in_Rd.h | 57 +-- .../include/gudhi/Functions/Function_chair_in_R3.h | 43 +- .../include/gudhi/Functions/Function_iron_in_R3.h | 32 +- .../Function_lemniscate_revolution_in_R3.h | 47 +- .../gudhi/Functions/Function_moment_curve_in_Rd.h | 43 +- .../include/gudhi/Functions/Function_torus_in_R3.h | 36 +- .../Functions/Function_whitney_umbrella_in_R3.h | 41 +- .../gudhi/Functions/Linear_transformation.h | 29 +- .../include/gudhi/Functions/Negation.h | 26 +- .../include/gudhi/Functions/PL_approximation.h | 59 +-- .../include/gudhi/Functions/Translate.h | 30 +- .../gudhi/Functions/random_orthogonal_matrix.h | 35 +- .../include/gudhi/IO/Mesh_medit.h | 12 +- .../gudhi/IO/build_mesh_from_cell_complex.h | 127 +++-- .../include/gudhi/IO/output_debug_traces_to_html.h | 390 +++++++--------- .../include/gudhi/IO/output_meshes_to_medit.h | 147 +++--- .../gudhi/Implicit_manifold_intersection_oracle.h | 152 +++--- .../include/gudhi/Manifold_tracing.h | 148 +++--- .../include/gudhi/Permutahedral_representation.h | 138 ++---- .../Combination_iterator.h | 60 +-- .../Integer_combination_iterator.h | 61 +-- .../Ordered_set_partition_iterator.h | 56 +-- .../Permutahedral_representation_iterators.h | 185 ++++---- .../Permutation_iterator.h | 73 ++- .../Set_partition_iterator.h | 81 ++-- .../Simplex_comparator.h | 36 +- .../Permutahedral_representation/Size_range.h | 40 +- .../face_from_indices.h | 59 ++- .../include/gudhi/Query_result.h | 6 +- .../test/cell_complex_test.cpp | 19 +- .../test/freud_triang_test.cpp | 55 ++- src/Coxeter_triangulation/test/function_test.cpp | 43 +- .../test/manifold_tracing_test.cpp | 28 +- src/Coxeter_triangulation/test/oracle_test.cpp | 16 +- src/Coxeter_triangulation/test/perm_rep_test.cpp | 23 +- 51 files changed, 1593 insertions(+), 2123 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h b/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h index 15d74860..210d804e 100644 --- a/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h +++ b/src/Coxeter_triangulation/concept/FunctionForImplicitManifold.h @@ -11,16 +11,19 @@ #ifndef CONCEPT_COXETER_TRIANGULATION_FUNCTION_FOR_IMPLICIT_MANIFOLD_H_ #define CONCEPT_COXETER_TRIANGULATION_FUNCTION_FOR_IMPLICIT_MANIFOLD_H_ +#include // for std::size_t + +#include + namespace Gudhi { namespace coxeter_triangulation { -/** \brief The concept FunctionForImplicitManifold describes the requirements +/** \brief The concept FunctionForImplicitManifold describes the requirements * for a type to implement an implicit function class used for example in Manifold_tracing. */ struct FunctionForImplicitManifold { - - /** \brief Value of the function at a specified point 'p'. + /** \brief Value of the function at a specified point 'p'. * @param[in] p The input point given by its Cartesian coordinates. * Its size needs to be equal to amb_d(). */ @@ -28,7 +31,7 @@ struct FunctionForImplicitManifold { /** \brief Returns the domain (ambient) dimension. */ std::size_t amb_d() const; - + /** \brief Returns the codomain dimension. */ std::size_t cod_d() const; @@ -40,5 +43,4 @@ struct FunctionForImplicitManifold { } // namespace Gudhi - #endif diff --git a/src/Coxeter_triangulation/concept/IntersectionOracle.h b/src/Coxeter_triangulation/concept/IntersectionOracle.h index 1427460b..e4e397fa 100644 --- a/src/Coxeter_triangulation/concept/IntersectionOracle.h +++ b/src/Coxeter_triangulation/concept/IntersectionOracle.h @@ -11,19 +11,22 @@ #ifndef CONCEPT_COXETER_TRIANGULATION_INTERSECTION_ORACLE_H_ #define CONCEPT_COXETER_TRIANGULATION_INTERSECTION_ORACLE_H_ +#include // for std::size_t + +#include + namespace Gudhi { namespace coxeter_triangulation { -/** \brief The concept IntersectionOracle describes the requirements +/** \brief The concept IntersectionOracle describes the requirements * for a type to implement an intersection oracle class used for example in Manifold_tracing. * */ struct IntersectionOracle { - /** \brief Returns the domain (ambient) dimension of the underlying manifold. */ std::size_t amb_d() const; - + /** \brief Returns the codomain dimension of the underlying manifold. */ std::size_t cod_d() const; @@ -32,48 +35,45 @@ struct IntersectionOracle { * \details The returned structure Query_result contains the boolean value * that is true only if the intersection point of the query simplex and * the relative interior of the manifold exists, the intersection point - * and the face of the query simplex that contains + * and the face of the query simplex that contains * the intersection point. - * + * * \tparam Simplex_handle The class of the query simplex. * Needs to be a model of the concept SimplexInCoxeterTriangulation. * \tparam Triangulation The class of the triangulation. * Needs to be a model of the concept TriangulationForManifoldTracing. - * + * * @param[in] simplex The query simplex. The dimension of the simplex - * should be the same as the codimension of the manifold + * should be the same as the codimension of the manifold * (the codomain dimension of the function). - * @param[in] triangulation The ambient triangulation. The dimension of - * the triangulation should be the same as the ambient dimension of the manifold + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold * (the domain dimension of the function). */ - template - Query_result intersects(const Simplex_handle& simplex, - const Triangulation& triangulation) const; + template + Query_result intersects(const Simplex_handle& simplex, const Triangulation& triangulation) const; /** \brief Intersection query with the boundary of the manifold. - * + * * \details The returned structure Query_result contains the boolean value * that is true only if the intersection point of the query simplex and * the boundary of the manifold exists, the intersection point - * and the face of the query simplex that contains + * and the face of the query simplex that contains * the intersection point. - * + * * \tparam Simplex_handle The class of the query simplex. * Needs to be a model of the concept SimplexInCoxeterTriangulation. * \tparam Triangulation The class of the triangulation. * Needs to be a model of the concept TriangulationForManifoldTracing. * * @param[in] simplex The query simplex. The dimension of the simplex - * should be the same as the codimension of the boundary of the manifold + * should be the same as the codimension of the boundary of the manifold * (the codomain dimension of the function + 1). - * @param[in] triangulation The ambient triangulation. The dimension of - * the triangulation should be the same as the ambient dimension of the manifold + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold * (the domain dimension of the function). */ - template + template Query_result intersects_boundary(const Simplex_handle& simplex, const Triangulation& triangulation) const; @@ -84,24 +84,21 @@ struct IntersectionOracle { * @param p The input point. Needs to have the same dimension as the ambient * dimension of the manifold (the domain dimension of the function). * @param triangulation The ambient triangulation. Needs to have the same - * dimension as the ambient dimension of the manifold + * dimension as the ambient dimension of the manifold * (the domain dimension of the function). */ template - bool lies_in_domain(const Eigen::VectorXd& p, - const Triangulation& triangulation) const { + bool lies_in_domain(const Eigen::VectorXd& p, const Triangulation& triangulation) const { Eigen::VectorXd pl_p = make_pl_approximation(domain_fun_, triangulation)(p); return pl_p(0) < 0; } /** \brief Returns the function that defines the interior of the manifold */ const Function_& function() const; - }; } // namespace coxeter_triangulation } // namespace Gudhi - #endif diff --git a/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h b/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h index bb2451ff..dac8e66d 100644 --- a/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h +++ b/src/Coxeter_triangulation/concept/SimplexInCoxeterTriangulation.h @@ -11,19 +11,22 @@ #ifndef CONCEPT_COXETER_TRIANGULATION_SIMPLEX_IN_COXETER_TRIANGULATION_H_ #define CONCEPT_COXETER_TRIANGULATION_SIMPLEX_IN_COXETER_TRIANGULATION_H_ +#include // for std::size_t + +#include + namespace Gudhi { namespace coxeter_triangulation { -/** \brief The concept SimplexInCoxeterTriangulation describes the requirements +/** \brief The concept SimplexInCoxeterTriangulation describes the requirements * for a type to implement a representation of simplices in Freudenthal_triangulation * or in Coxeter_triangulation. */ struct SimplexInCoxeterTriangulation { - /** \brief Type of the vertex. */ typedef Vertex_ Vertex; - + /** \brief Type of the ordered partition. */ typedef Ordered_set_partition_ OrderedSetPartition; @@ -32,13 +35,13 @@ struct SimplexInCoxeterTriangulation { /** \brief Type of a range of vertices, each of type Vertex. */ typedef Vertex_range; - + /** \brief Returns a range of vertices of the simplex. */ Vertex_range vertex_range() const; - /** \brief Type of a range of faces, each of type that - * is a model of the concept SimplexInCoxeterTriangulation. + /** \brief Type of a range of faces, each of type that + * is a model of the concept SimplexInCoxeterTriangulation. */ typedef Face_range; @@ -52,8 +55,8 @@ struct SimplexInCoxeterTriangulation { */ Face_range facet_range() const; - /** \brief Type of a range of cofaces, each of type that - * is a model of the concept SimplexInCoxeterTriangulation. + /** \brief Type of a range of cofaces, each of type that + * is a model of the concept SimplexInCoxeterTriangulation. */ typedef Coface_range; @@ -69,12 +72,10 @@ struct SimplexInCoxeterTriangulation { /** \brief Returns true, if the simplex is a face of other simplex. */ bool is_face_of(const Permutahedral_representation& other) const; - }; } // namespace coxeter_triangulation } // namespace Gudhi - #endif diff --git a/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h b/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h index 4f3d4411..2b5d568c 100644 --- a/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h +++ b/src/Coxeter_triangulation/concept/TriangulationForManifoldTracing.h @@ -11,23 +11,24 @@ #ifndef CONCEPT_COXETER_TRIANGULATION_TRIANGULATION_FOR_MANIFOLD_TRACING_H_ #define CONCEPT_COXETER_TRIANGULATION_TRIANGULATION_FOR_MANIFOLD_TRACING_H_ +#include + namespace Gudhi { namespace coxeter_triangulation { -/** \brief The concept TriangulationForManifoldTracing describes the requirements +/** \brief The concept TriangulationForManifoldTracing describes the requirements * for a type to implement a triangulation class used for example in Manifold_tracing. */ struct TriangulationForManifoldTracing { - - /** \brief Type of the simplices in the triangulation. + /** \brief Type of the simplices in the triangulation. * Needs to be a model of the concept SimplexInCoxeterTriangulation. */ typedef Simplex_handle; - /** \brief Type of the vertices in the triangulation. + /** \brief Type of the vertices in the triangulation. * Needs to be a random-access range of integer values. */ typedef Vertex_handle; - + /** \brief Returns the permutahedral representation of the simplex in the * triangulation that contains a given query point 'p'. * \tparam Point_d A class that represents a point in d-dimensional Euclidean space. @@ -37,21 +38,19 @@ struct TriangulationForManifoldTracing { template Simplex_handle locate_point(const Point_d& point) const; - /** \brief Returns the Cartesian coordinates of the given vertex 'v'. + /** \brief Returns the Cartesian coordinates of the given vertex 'v'. * @param[in] v The input vertex. */ Eigen::VectorXd cartesian_coordinates(const Vertex_handle& v) const; - /** \brief Returns the Cartesian coordinates of the barycenter of a given simplex 's'. + /** \brief Returns the Cartesian coordinates of the barycenter of a given simplex 's'. * @param[in] s The input simplex given by permutahedral representation. */ Eigen::VectorXd barycenter(const Simplex_handle& s) const; - }; } // namespace coxeter_triangulation } // namespace Gudhi - #endif diff --git a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h index c883d904..5eb0cb22 100644 --- a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h +++ b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h @@ -13,7 +13,7 @@ // needs namespaces for Doxygen to link on classes namespace Gudhi { -namespace tangential_complex { +namespace coxeter_triangulation { /** \defgroup coxeter_triangulation Coxeter triangulation @@ -42,13 +42,11 @@ manifold. There are two methods that execute the manifold tracing algorithm: the method \ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" for manifolds without boundary and -\ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" -for manifolds with boundary. -The algorithm functions as follows. -It starts at the specified seed points and inserts a \f$(d-m)\f$-dimensional simplices nearby each seed point that -intersect the manifold into the output. -Starting from this simplex, the algorithm propagates the search for other \f$(d-m)\f$-dimensional simplices that -intersect the manifold by marching from a simplex to neighbouring simplices via their common cofaces. +\ref Gudhi::coxeter_triangulation::Manifold_tracing::manifold_tracing_algorithm() "Manifold_tracing::manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map,boundary_simplex_map)" +for manifolds with boundary. The algorithm functions as follows. It starts at the specified seed points and inserts a +\f$(d-m)\f$-dimensional simplices nearby each seed point that intersect the manifold into the output. Starting from +this simplex, the algorithm propagates the search for other \f$(d-m)\f$-dimensional simplices that intersect the +manifold by marching from a simplex to neighbouring simplices via their common cofaces. This class \ref Gudhi::coxeter_triangulation::Manifold_tracing "Manifold_tracing" has one template parameter `Triangulation_` which specifies the ambient triangulation which is used by the algorithm. @@ -59,16 +57,15 @@ The module also provides two static methods: \ref Gudhi::coxeter_triangulation::manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map)" for manifolds without boundary and \ref manifold_tracing_algorithm() "manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map)" -for manifolds with boundary. -For these static methods it is not necessary to specify any template arguments. +for manifolds with boundary. For these static methods it is not necessary to specify any template arguments. \section ambienttriangulations Ambient triangulations The ambient triangulations supported by the manifold tracing algorithm have to be models of the concept -\ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". +\ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". This module offers two such models: the class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and the derived class -\ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation". +\ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation". Both these classes encode affine transformations of the so-called Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. The Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ is defined as the simplicial subdivision of the unit cubic @@ -77,13 +74,13 @@ Each simplex is encoded using the permutahedral representation, which consists o positions the simplex in a specific cube in the cubical partition and an ordered partition \f$\omega\f$ of the set \f$\{1,\ldots,d+1\}\f$, which positions the simplex in the simplicial subdivision of the cube. The default constructor -\ref Gudhi::coxeter_triangulation::Freudenthal_triangulation::Freudenthal_triangulation(std::size_t) "Freudenthal_triangulation(d)" -the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. -The class \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" can also encode any -affine transformation of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ using an invertible matrix -\f$\Lambda\f$ and an offset vector \f$b\f$ that can be specified in the constructor and which can be changed using the -methods change_matrix and change_offset. -The class \ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation" is derived from +\ref Gudhi::coxeter_triangulation::Freudenthal_triangulation::Freudenthal_triangulation(std::size_t) +"Freudenthal_triangulation(d)" the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$. The class +\ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" can also encode any affine +transformation of the Freudenthal-Kuhn triangulation of \f$\mathbb{R}^d\f$ using an invertible matrix \f$\Lambda\f$ and +an offset vector \f$b\f$ that can be specified in the constructor and which can be changed using the methods +change_matrix and change_offset. The class +\ref Gudhi::coxeter_triangulation::Coxeter_triangulation "Coxeter_triangulation" is derived from \ref Gudhi::coxeter_triangulation::Freudenthal_triangulation "Freudenthal_triangulation" and its default constructor \ref Gudhi::coxeter_triangulation::Coxeter_triangulation::Coxeter_triangulation(std::size_t) "Coxeter_triangulation(d)" builds a Coxeter triangulation of type \f$\tilde{A}_d\f$, which has the best simplex quality of all linear @@ -108,8 +105,8 @@ The function \f$F\f$ is given by a class which is a model of the concept \ref Gudhi::coxeter_triangulation::FunctionForImplicitManifold "FunctionForImplicitManifold". There are multiple function classes that are already implemented in this module. -\li \ref Gudhi::coxeter_triangulation::Constant_function(std::size_t, std::size_t, Eigen::VectorXd) "Constant_function(d,k,v)" - defines a constant function \f$F\f$ such that for all \f$x \in \mathbb{R}^d\f$, we have +\li \ref Gudhi::coxeter_triangulation::Constant_function(std::size_t, std::size_t, Eigen::VectorXd) +"Constant_function(d,k,v)" defines a constant function \f$F\f$ such that for all \f$x \in \mathbb{R}^d\f$, we have \f$F(x) = v \in \mathbb{R}^k\f$. The class Constant_function does not define an implicit manifold, but is useful as the domain function when defining boundaryless implicit manifolds. diff --git a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp index 95f63b4f..7e3d95a4 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp @@ -20,41 +20,34 @@ using namespace Gudhi::coxeter_triangulation; * The embedding consists of restricting the manifold to the affine subspace z = 1. */ struct Function_surface_on_CP2_in_R4 : public Function { - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { // The real and imaginary parts of the variables x and y double xr = p(0), xi = p(1), yr = p(2), yi = p(3); Eigen::VectorXd result(cod_d()); - + // Squares and cubes of real and imaginary parts used in the computations - double - xr2 = xr*xr, xi2 = xi*xi, yr2 = yr*yr, yi2 = yi*yi, - xr3 = xr2*xr, xi3 = xi2*xi, yr3 = yr2*yr, yi3 = yi2*yi; + double xr2 = xr * xr, xi2 = xi * xi, yr2 = yr * yr, yi2 = yi * yi, xr3 = xr2 * xr, xi3 = xi2 * xi, yr3 = yr2 * yr, + yi3 = yi2 * yi; // The first coordinate of the output is Re(x^3*y + y^3 + x) - result(0) = - xr3*yr - 3*xr*xi2*yr - 3*xr2*xi*yi + xi3*yi - + yr3 - 3*yr*yi2 + xr; + result(0) = xr3 * yr - 3 * xr * xi2 * yr - 3 * xr2 * xi * yi + xi3 * yi + yr3 - 3 * yr * yi2 + xr; // The second coordinate of the output is Im(x^3*y + y^3 + x) - result(1) = - 3*xr2*xi*yr + xr3*yi - 3*xr*xi2*yi - xi3*yr - + 3*yr2*yi - yi3 + xi; + result(1) = 3 * xr2 * xi * yr + xr3 * yi - 3 * xr * xi2 * yi - xi3 * yr + 3 * yr2 * yi - yi3 + xi; return result; } - virtual std::size_t amb_d() const override {return 4;}; - virtual std::size_t cod_d() const override {return 2;}; + virtual std::size_t amb_d() const override { return 4; }; + virtual std::size_t cod_d() const override { return 2; }; virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = Eigen::VectorXd::Zero(4); return result; } - Function_surface_on_CP2_in_R4() {} + Function_surface_on_CP2_in_R4() {} }; int main(int argc, char** argv) { - // The function for the (non-compact) manifold Function_surface_on_CP2_in_R4 fun; @@ -74,24 +67,22 @@ int main(int argc, char** argv) { Coxeter_triangulation<> cox_tr(oracle.amb_d()); cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); cox_tr.change_matrix(lambda * cox_tr.matrix()); - + // Manifold tracing algorithm using MT = Manifold_tracing >; using Out_simplex_map = typename MT::Out_simplex_map; std::vector seed_points(1, seed); Out_simplex_map interior_simplex_map, boundary_simplex_map; manifold_tracing_algorithm(seed_points, cox_tr, oracle, interior_simplex_map, boundary_simplex_map); - + // Constructing the cell complex std::size_t intr_d = oracle.amb_d() - oracle.cod_d(); Cell_complex cell_complex(intr_d); cell_complex.construct_complex(interior_simplex_map, boundary_simplex_map); // Output the cell complex to a file readable by medit - output_meshes_to_medit(3, - "manifold_on_CP2_with_boundary", - build_mesh_from_cell_complex(cell_complex, - Configuration(true, true, true, 1, 5, 3), - Configuration(true, true, true, 2, 13, 14))); + output_meshes_to_medit(3, "manifold_on_CP2_with_boundary", + build_mesh_from_cell_complex(cell_complex, Configuration(true, true, true, 1, 5, 3), + Configuration(true, true, true, 2, 13, 14))); return 0; } diff --git a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp index c83fdd5d..2260e692 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp @@ -1,7 +1,7 @@ // workaround for the annoying boost message in boost 1.69 #define BOOST_PENDING_INTEGER_LOG2_HPP #include -// end workaround +// end workaround #include @@ -21,7 +21,6 @@ using namespace Gudhi::coxeter_triangulation; int main(int argc, char** argv) { - // Creating a circle S1 in R2 of specified radius double radius = 1.0; Function_Sm_in_Rd fun_circle(radius, 1); @@ -34,14 +33,14 @@ int main(int argc, char** argv) { auto fun_flat_torus_rotated = make_linear_transformation(fun_flat_torus, matrix); // Computing the seed of the function fun_flat_torus - Eigen::VectorXd seed = fun_flat_torus_rotated.seed(); - - // Defining a domain function that defines the boundary, which is a hyperplane passing by the origin and orthogonal to x. + Eigen::VectorXd seed = fun_flat_torus_rotated.seed(); + + // Defining a domain function that defines the boundary, which is a hyperplane passing by the origin and orthogonal to + // x. Eigen::MatrixXd normal_matrix = Eigen::MatrixXd::Zero(4, 1); - for (std::size_t i = 0; i < 4; i++) - normal_matrix(i,0) = -seed(i); - Function_affine_plane_in_Rd fun_bound(normal_matrix, -seed/2); - + for (std::size_t i = 0; i < 4; i++) normal_matrix(i, 0) = -seed(i); + Function_affine_plane_in_Rd fun_bound(normal_matrix, -seed / 2); + // Defining the intersection oracle auto oracle = make_oracle(fun_flat_torus_rotated, fun_bound); @@ -65,11 +64,9 @@ int main(int argc, char** argv) { cell_complex.construct_complex(interior_simplex_map, boundary_simplex_map); // Output the cell complex to a file readable by medit - output_meshes_to_medit(3, - "flat_torus_with_boundary", - build_mesh_from_cell_complex(cell_complex, - Configuration(true, true, true, 1, 5, 3), - Configuration(true, true, true, 2, 13, 14))); + output_meshes_to_medit(3, "flat_torus_with_boundary", + build_mesh_from_cell_complex(cell_complex, Configuration(true, true, true, 1, 5, 3), + Configuration(true, true, true, 2, 13, 14))); return 0; } diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index 3bc60a50..9cac58d9 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -11,14 +11,14 @@ #ifndef CELL_COMPLEX_H_ #define CELL_COMPLEX_H_ -#include +#include #include #include #include // for std::make_pair #include -#include // for Hasse_cell +#include // for Hasse_cell namespace Gudhi { @@ -28,8 +28,8 @@ namespace coxeter_triangulation { * \ingroup coxeter_triangulation */ -/** \class Cell_complex - * \brief A class that constructs the cell complex from the output provided by the class +/** \class Cell_complex + * \brief A class that constructs the cell complex from the output provided by the class * Gudhi::Manifold_tracing. * * \tparam Out_simplex_map_ The type of a map from a simplex type that is a @@ -39,13 +39,12 @@ namespace coxeter_triangulation { */ template class Cell_complex { -public: - + public: /** \brief Type of a simplex in the ambient triangulation. * Is a model of the concept SimplexInCoxeterTriangulation. */ using Simplex_handle = typename Out_simplex_map_::key_type; - /** \brief Type of a cell in the cell complex. + /** \brief Type of a cell in the cell complex. * Always is Gudhi::Hasse_cell from the Hasse diagram module. * The additional information is the boolean that is true if and only if the cell lies * on the boundary. @@ -60,7 +59,7 @@ public: * ambient triangulation to the corresponding cells in the cell complex of various dimensions. */ using Simplex_cell_maps = std::vector; - + /** \brief Type of a map from cells in the cell complex to the permutahedral representations * of the corresponding simplices in the ambient triangulation. */ @@ -71,21 +70,19 @@ public: */ using Cell_point_map = std::map; -private: - + private: Hasse_cell* insert_cell(const Simplex_handle& simplex, std::size_t cell_d, bool is_boundary) { - Simplex_cell_maps& simplex_cell_maps - = (is_boundary? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); + Simplex_cell_maps& simplex_cell_maps = (is_boundary ? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); #ifdef GUDHI_COX_OUTPUT_TO_HTML CC_detail_list& cc_detail_list = - (is_boundary? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); + (is_boundary ? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); cc_detail_list.emplace_back(CC_detail_info(simplex)); #endif Simplex_cell_map& simplex_cell_map = simplex_cell_maps[cell_d]; auto map_it = simplex_cell_map.find(simplex); if (map_it == simplex_cell_map.end()) { hasse_cells_.push_back(new Hasse_cell(is_boundary, cell_d)); - Hasse_cell* new_cell = hasse_cells_.back(); + Hasse_cell* new_cell = hasse_cells_.back(); simplex_cell_map.emplace(std::make_pair(simplex, new_cell)); cell_simplex_map_.emplace(std::make_pair(new_cell, simplex)); #ifdef GUDHI_COX_OUTPUT_TO_HTML @@ -103,21 +100,21 @@ private: void expand_level(std::size_t cell_d) { bool is_manifold_with_boundary = boundary_simplex_cell_maps_.size() > 0; - for (auto& sc_pair: interior_simplex_cell_maps_[cell_d - 1]) { + for (auto& sc_pair : interior_simplex_cell_maps_[cell_d - 1]) { const Simplex_handle& simplex = sc_pair.first; Hasse_cell* cell = sc_pair.second; - for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d)) { + for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d)) { Hasse_cell* new_cell = insert_cell(coface, cell_d, false); new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); } } - + if (is_manifold_with_boundary) { - for (auto& sc_pair: boundary_simplex_cell_maps_[cell_d - 1]) { + for (auto& sc_pair : boundary_simplex_cell_maps_[cell_d - 1]) { const Simplex_handle& simplex = sc_pair.first; Hasse_cell* cell = sc_pair.second; if (cell_d != intr_d_) - for (Simplex_handle coface: simplex.coface_range(cod_d_ + cell_d + 1)) { + for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d + 1)) { Hasse_cell* new_cell = insert_cell(coface, cell_d, true); new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); } @@ -131,29 +128,26 @@ private: } } } - + void construct_complex_(const Out_simplex_map_& out_simplex_map) { #ifdef GUDHI_COX_OUTPUT_TO_HTML cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); -#endif - for (auto& os_pair: out_simplex_map) { +#endif + for (auto& os_pair : out_simplex_map) { const Simplex_handle& simplex = os_pair.first; const Eigen::VectorXd& point = os_pair.second; Hasse_cell* new_cell = insert_cell(simplex, 0, false); cell_point_map_.emplace(std::make_pair(new_cell, point)); } for (std::size_t cell_d = 1; - cell_d < interior_simplex_cell_maps_.size() && - !interior_simplex_cell_maps_[cell_d - 1].empty(); - ++cell_d) { + cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { expand_level(cell_d); } } - - void construct_complex_(const Out_simplex_map_& interior_simplex_map, - const Out_simplex_map_& boundary_simplex_map) { + + void construct_complex_(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { #ifdef GUDHI_COX_OUTPUT_TO_HTML cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); @@ -161,76 +155,70 @@ private: cc_boundary_summary_lists.resize(boundary_simplex_cell_maps_.size()); cc_boundary_prejoin_lists.resize(boundary_simplex_cell_maps_.size()); cc_boundary_detail_lists.resize(boundary_simplex_cell_maps_.size()); -#endif - for (auto& os_pair: boundary_simplex_map) { +#endif + for (auto& os_pair : boundary_simplex_map) { const Simplex_handle& simplex = os_pair.first; const Eigen::VectorXd& point = os_pair.second; Hasse_cell* new_cell = insert_cell(simplex, 0, true); cell_point_map_.emplace(std::make_pair(new_cell, point)); } - for (auto& os_pair: interior_simplex_map) { + for (auto& os_pair : interior_simplex_map) { const Simplex_handle& simplex = os_pair.first; const Eigen::VectorXd& point = os_pair.second; Hasse_cell* new_cell = insert_cell(simplex, 0, false); cell_point_map_.emplace(std::make_pair(new_cell, point)); } #ifdef GUDHI_COX_OUTPUT_TO_HTML - for (const auto& sc_pair: interior_simplex_cell_maps_[0]) + for (const auto& sc_pair : interior_simplex_cell_maps_[0]) cc_interior_summary_lists[0].push_back(CC_summary_info(sc_pair)); - for (const auto& sc_pair: boundary_simplex_cell_maps_[0]) + for (const auto& sc_pair : boundary_simplex_cell_maps_[0]) cc_boundary_summary_lists[0].push_back(CC_summary_info(sc_pair)); -#endif +#endif for (std::size_t cell_d = 1; - cell_d < interior_simplex_cell_maps_.size() && - !interior_simplex_cell_maps_[cell_d - 1].empty(); - ++cell_d) { + cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { expand_level(cell_d); - + #ifdef GUDHI_COX_OUTPUT_TO_HTML - for (const auto& sc_pair: interior_simplex_cell_maps_[cell_d]) + for (const auto& sc_pair : interior_simplex_cell_maps_[cell_d]) cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); if (cell_d < boundary_simplex_cell_maps_.size()) - for (const auto& sc_pair: boundary_simplex_cell_maps_[cell_d]) + for (const auto& sc_pair : boundary_simplex_cell_maps_[cell_d]) cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); #endif } } - -public: - + + public: /** * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold * without boundary embedded in the \f$ d \f$-dimensional Euclidean space * from the output of the class Gudhi::Manifold_tracing. * - * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold + * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold * to the intersection points. */ void construct_complex(const Out_simplex_map_& out_simplex_map) { interior_simplex_cell_maps_.resize(intr_d_ + 1); - if (!out_simplex_map.empty()) - cod_d_ = out_simplex_map.begin()->first.dimension(); + if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); construct_complex_(out_simplex_map); } - + /** * \brief Constructs the skeleton of the cell complex that approximates - * an \f$m\f$-dimensional manifold without boundary embedded + * an \f$m\f$-dimensional manifold without boundary embedded * in the \f$d\f$-dimensional Euclidean space * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. * - * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold + * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold * to the intersection points. * \param[in] limit_dimension The dimension of the constructed skeleton. */ - void construct_complex(const Out_simplex_map_& out_simplex_map, - std::size_t limit_dimension) { + void construct_complex(const Out_simplex_map_& out_simplex_map, std::size_t limit_dimension) { interior_simplex_cell_maps_.resize(limit_dimension + 1); - if (!out_simplex_map.empty()) - cod_d_ = out_simplex_map.begin()->first.dimension(); + if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); construct_complex_(out_simplex_map); } @@ -239,74 +227,64 @@ public: * with boundary embedded in the \f$ d \f$-dimensional Euclidean space * from the output of the class Gudhi::Manifold_tracing. * - * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold + * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold * to the intersection points. - * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ - * in the ambient triangulation that intersect the boundary of the manifold + * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ + * in the ambient triangulation that intersect the boundary of the manifold * to the intersection points. */ - void construct_complex(const Out_simplex_map_& interior_simplex_map, - const Out_simplex_map_& boundary_simplex_map) { + void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { interior_simplex_cell_maps_.resize(intr_d_ + 1); boundary_simplex_cell_maps_.resize(intr_d_); - if (!interior_simplex_map.empty()) - cod_d_ = interior_simplex_map.begin()->first.dimension(); + if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension(); construct_complex_(interior_simplex_map, boundary_simplex_map); } /** * \brief Constructs the skeleton of the cell complex that approximates - * an \f$m\f$-dimensional manifold with boundary embedded + * an \f$m\f$-dimensional manifold with boundary embedded * in the \f$d\f$-dimensional Euclidean space * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. * - * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold + * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold * to the intersection points. - * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ - * in the ambient triangulation that intersect the boundary of the manifold + * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ + * in the ambient triangulation that intersect the boundary of the manifold * to the intersection points. * \param[in] limit_dimension The dimension of the constructed skeleton. */ - void construct_complex(const Out_simplex_map_& interior_simplex_map, - const Out_simplex_map_& boundary_simplex_map, + void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map, std::size_t limit_dimension) { interior_simplex_cell_maps_.resize(limit_dimension + 1); boundary_simplex_cell_maps_.resize(limit_dimension); - if (!interior_simplex_map.empty()) - cod_d_ = interior_simplex_map.begin()->first.dimension(); + if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension(); construct_complex_(interior_simplex_map, boundary_simplex_map); } /** * \brief Returns the dimension of the cell complex. */ - std::size_t intrinsic_dimension() const { - return intr_d_; - } + std::size_t intrinsic_dimension() const { return intr_d_; } /** * \brief Returns a vector of maps from the cells of various dimensions in the interior - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations * of the corresponding simplices in the ambient triangulation. */ - const Simplex_cell_maps& interior_simplex_cell_maps() const { - return interior_simplex_cell_maps_; - } + const Simplex_cell_maps& interior_simplex_cell_maps() const { return interior_simplex_cell_maps_; } /** * \brief Returns a vector of maps from the cells of various dimensions on the boundary - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations * of the corresponding simplices in the ambient triangulation. */ - const Simplex_cell_maps& boundary_simplex_cell_maps() const { - return boundary_simplex_cell_maps_; - } - + const Simplex_cell_maps& boundary_simplex_cell_maps() const { return boundary_simplex_cell_maps_; } + /** - * \brief Returns a map from the cells of a given dimension in the interior - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * \brief Returns a map from the cells of a given dimension in the interior + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations * of the corresponding simplices in the ambient triangulation. * * \param[in] cell_d The dimension of the cells. @@ -316,8 +294,8 @@ public: } /** - * \brief Returns a map from the cells of a given dimension on the boundary - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * \brief Returns a map from the cells of a given dimension on the boundary + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations * of the corresponding simplices in the ambient triangulation. * * \param[in] cell_d The dimension of the cells. @@ -328,35 +306,29 @@ public: /** * \brief Returns a map from the cells in the cell complex of type Gudhi::Hasse_cell - * to the permutahedral representations of the corresponding simplices in the + * to the permutahedral representations of the corresponding simplices in the * ambient triangulation. */ - const Cell_simplex_map& cell_simplex_map() const { - return cell_simplex_map_; - } + const Cell_simplex_map& cell_simplex_map() const { return cell_simplex_map_; } /** * \brief Returns a map from the vertex cells in the cell complex of type Gudhi::Hasse_cell * to their Cartesian coordinates. */ - const Cell_point_map& cell_point_map() const { - return cell_point_map_; - } + const Cell_point_map& cell_point_map() const { return cell_point_map_; } /** * \brief Conxtructor for the class Cell_complex. * * \param[in] intrinsic_dimension The dimension of the cell complex. */ - Cell_complex(std::size_t intrinsic_dimension) - : intr_d_(intrinsic_dimension) {} + Cell_complex(std::size_t intrinsic_dimension) : intr_d_(intrinsic_dimension) {} ~Cell_complex() { - for (Hasse_cell* hs_ptr: hasse_cells_) - delete hs_ptr; + for (Hasse_cell* hs_ptr : hasse_cells_) delete hs_ptr; } - -private: + + private: std::size_t intr_d_, cod_d_; Simplex_cell_maps interior_simplex_cell_maps_, boundary_simplex_cell_maps_; Cell_simplex_map cell_simplex_map_; @@ -364,8 +336,8 @@ private: std::vector hasse_cells_; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h index a59026fa..9847a6d3 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -20,10 +20,8 @@ namespace Gudhi { namespace Hasse_diagram { - -template < typename Cell_type > class Hasse_diagram; - - +template +class Hasse_diagram; /** * \class Hasse_diagram_cell @@ -32,270 +30,255 @@ template < typename Cell_type > class Hasse_diagram; * \ingroup Hasse_diagram * * \details - * This is a data structure to store a cell in a general Hasse diagram data structure. It store the following information about the cell: - * References to boundary and coBoundary elements, dimension of a cell and its filtration. It also allow to store any additional - * information of a type Additional_information which is a template parameter of the class (set by default to void). + * This is a data structure to store a cell in a general Hasse diagram data structure. It store the following + * information about the cell: References to boundary and coBoundary elements, dimension of a cell and its filtration. + * It also allow to store any additional information of a type Additional_information which is a template parameter of + * the class (set by default to void). * * Please refer to \ref Hasse_diagram for examples. * * The complex is a template class requiring the following parameters: - * Incidence_type_ - determine the type of incidence coefficients. Use integers in most general case. + * Incidence_type_ - determine the type of incidence coefficients. Use integers in most general case. * Filtration_type_ - type of filtration of cells. - * Additional_information_ (set by default to void) - allows to store any + * Additional_information_ (set by default to void) - allows to store any * additional information in the cells of Hasse diagrams. * */ -template -class Hasse_diagram_cell -{ -public: - typedef Incidence_type_ Incidence_type; - typedef Filtration_type_ Filtration_type; - typedef Additional_information_ Additional_information; - using Cell_range = std::vector< std::pair >; - - /** - * Default constructor. - **/ - Hasse_diagram_cell():dimension(0),position(0),deleted_(false){} - - /** - * Constructor of a cell of dimension dim. - **/ - Hasse_diagram_cell( int dim ):dimension(dim),position(0),deleted_(false){} - - /** - * Constructor of a cell of dimension dim. - **/ - Hasse_diagram_cell( int dim , Filtration_type filt_ ):dimension(dim),position(0),deleted_(false),filtration(filt_){} - - /** - * Constructor of a cell of dimension dim with a given boundary. - **/ - Hasse_diagram_cell( const Cell_range& boundary_ , int dim ): - dimension(dim),boundary(boundary_),position(0),deleted_(false){} - - /** - * Constructor of a cell of dimension dim with a given boundary and coboundary. - **/ - Hasse_diagram_cell( const Cell_range& boundary_ , const Cell_range& coboundary_, - int dim ):dimension(dim),boundary(boundary_),coBoundary(coboundary_), - position(0),deleted_(false){} - - /** - * Constructor of a cell of dimension dim with a given boundary, coboundary and - * additional information. - **/ - Hasse_diagram_cell( const Cell_range& boundary_ , const Cell_range& coboundary_, - const Additional_information& ai, int dim ): - dimension(dim),boundary(boundary_),coBoundary(coboundary_),additional_info(ai), - position(0),deleted_(false){} - - /** - * Construcor of a cell of dimension dim having given additional information. - **/ - Hasse_diagram_cell(Additional_information ai, int dim ): - dimension(dim),additional_info(ai),position(0),deleted_(false){} - - /** - * Procedure to get the boundary of a fiven cell. The output format - * is a vector of pairs of pointers to boundary elements and incidence - * coefficients. - **/ - inline Cell_range& get_boundary(){return this->boundary;} - - /** - * Procedure to get the coboundary of a fiven cell. The output format - * is a vector of pairs of pointers to coboundary elements and incidence - * coefficients. - **/ - inline Cell_range& get_coBoundary(){return this->coBoundary;} - - /** - * Procedure to get the dimension of a cell. - **/ - inline int& get_dimension(){return this->dimension;} - - /** - * Procedure to get additional information about the cell.s - **/ - inline Additional_information& get_additional_information(){return this->additional_info;} - - /** - * Procedure to retrive position of the cell in the structure. It is used in - * the implementation of Hasse diagram and set by it. Note that removal of - * cell and subsequent call of clean_up_the_structure will change those - * positions. - **/ - inline unsigned& get_position(){return this->position;} - - /** - * Accessing the filtration of the cell. - **/ - inline Filtration_type& get_filtration() - { - //std::cout << "Accessing the filtration of a cell : " << *this << std::endl; - return this->filtration; - } - - /** - * A procedure used to check if the cell is deleted. It is used by the - * subsequent implementation of Hasse diagram that is absed on lazy - * delete. - **/ - inline bool deleted(){return this->deleted_;} - - template < typename Cell_type > - friend class Hasse_diagram; - - template < typename Cell_type > - friend class is_before_in_filtration; - - - template - friend std::vector convert_to_vector_of_Cell_type( Complex_type& cmplx ); - - /** - * Procedure to remove deleted boundary and coboundary elements from the - * vectors of boundary and coboundary elements of this cell. - **/ - void remove_deleted_elements_from_boundary_and_coboundary() - { - Cell_range new_boundary; - new_boundary.reserve( this->boundary.size() ); - for ( size_t bd = 0 ; bd != this->boundary.size() ; ++bd ) - { - if ( !this->boundary[bd].first->deleted() ) - { - new_boundary.push_back( this->boundary[bd] ); - } - } - this->boundary.swap( new_boundary ); - - Cell_range new_coBoundary; - new_coBoundary.reserve( this->coBoundary.size() ); - for ( size_t cbd = 0 ; cbd != this->coBoundary.size() ; ++cbd ) - { - if ( !this->coBoundary[cbd].first->deleted() ) - { - new_coBoundary.push_back( this->coBoundary[cbd] ); - } - } - this->coBoundary.swap( new_coBoundary ); - } - - /** - * Writing to a stream operator. - **/ - friend std::ostream& operator<<( std::ostream& out, const Hasse_diagram_cell& c ) - { - //cout << "position : " << c.position << ", dimension : " << c.dimension << ", filtration: " << c.filtration << ", size of boudary : " << c.boundary.size() << "\n"; - out << c.position << " " << c.dimension << " " << c.filtration << std::endl; - for ( size_t bd = 0 ; bd != c.boundary.size() ; ++bd ) - { - //do not write out the cells that has been deleted - if ( c.boundary[bd].first->deleted() )continue; - out << c.boundary[bd].first->position << " " << c.boundary[bd].second << " "; - } - out << std::endl; - return out; - } - - - /** - * Procedure that return vector of pointers to boundary elements of a given cell. - **/ - inline std::vector< Hasse_diagram_cell* > get_list_of_boundary_elements() - { - std::vector< Hasse_diagram_cell* > result; - size_t size_of_boundary = this->boundary.size(); - result.reserve( size_of_boundary ); - for ( size_t bd = 0 ; bd != size_of_boundary ; ++bd ) - { - result.push_back( this->boundary[bd].first ); - } - return result; - } - - /** - * Procedure that return vector of positios of boundary elements of a given cell. - **/ - inline std::vector< unsigned > get_list_of_positions_of_boundary_elements() - { - std::vector< unsigned > result; - size_t size_of_boundary = this->boundary.size(); - result.reserve( size_of_boundary ); - for ( size_t bd = 0 ; bd != size_of_boundary ; ++bd ) - { - result.push_back( this->boundary[bd].first->position ); - } - return result; - } - - /** - * Function that display a string being a signature of a structure. - * Used mainly for debugging purposes. - **/ - std::string full_signature_of_the_structure() - { - std::string result; - result += "dimension: "; - result += std::to_string(this->dimension); - result += " filtration: "; - result += std::to_string(this->filtration); - result += " position: "; - result += std::to_string(this->position); - result += " deleted_: "; - result += std::to_string(this->deleted_); - - //if the Additional_information is not void, add them to - //the signature as well. - if ( std::is_same::value ) - { - result += " Additional_information: "; - result += std::to_string(this->additional_info); - } - result += " boundary "; - for ( size_t bd = 0 ; bd != this->boundary.size() ; ++bd ) - { - result += "( " + std::to_string(this->boundary[bd].first->position); - result += " " + std::to_string(this->boundary[bd].second); - result += ") "; - } - - result += " coBoundary "; - for ( size_t cbd = 0 ; cbd != this->coBoundary.size() ; ++cbd ) - { - result += "( " + std::to_string(this->coBoundary[cbd].first->position); - result += " " + std::to_string(this->coBoundary[cbd].second); - result += ") "; - } - - return result; - } - - -protected: - Cell_range boundary; - Cell_range coBoundary; - int dimension; - Additional_information additional_info; - unsigned position; - bool deleted_; - Filtration_type filtration; - - /** - * A procedure to delete a cell. It is a private function of the Hasse_diagram_cell - * class, since in the Hasse_diagram class I want to have a control - * of removal of cells. Therefore, to remove cell please use - * remove_cell in the Hasse_diagram structure. - **/ - void delete_cell(){ this->deleted_ = true; } -};//Hasse_diagram_cell - - - -}//namespace Hasse_diagram -}//namespace Gudhi - -#endif //CELL_H +template +class Hasse_diagram_cell { + public: + typedef Incidence_type_ Incidence_type; + typedef Filtration_type_ Filtration_type; + typedef Additional_information_ Additional_information; + using Cell_range = std::vector >; + + /** + * Default constructor. + **/ + Hasse_diagram_cell() : dimension(0), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim. + **/ + Hasse_diagram_cell(int dim) : dimension(dim), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim. + **/ + Hasse_diagram_cell(int dim, Filtration_type filt_) + : dimension(dim), position(0), deleted_(false), filtration(filt_) {} + + /** + * Constructor of a cell of dimension dim with a given boundary. + **/ + Hasse_diagram_cell(const Cell_range& boundary_, int dim) + : dimension(dim), boundary(boundary_), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim with a given boundary and coboundary. + **/ + Hasse_diagram_cell(const Cell_range& boundary_, const Cell_range& coboundary_, int dim) + : dimension(dim), boundary(boundary_), coBoundary(coboundary_), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim with a given boundary, coboundary and + * additional information. + **/ + Hasse_diagram_cell(const Cell_range& boundary_, const Cell_range& coboundary_, const Additional_information& ai, + int dim) + : dimension(dim), + boundary(boundary_), + coBoundary(coboundary_), + additional_info(ai), + position(0), + deleted_(false) {} + + /** + * Construcor of a cell of dimension dim having given additional information. + **/ + Hasse_diagram_cell(Additional_information ai, int dim) + : dimension(dim), additional_info(ai), position(0), deleted_(false) {} + + /** + * Procedure to get the boundary of a fiven cell. The output format + * is a vector of pairs of pointers to boundary elements and incidence + * coefficients. + **/ + inline Cell_range& get_boundary() { return this->boundary; } + + /** + * Procedure to get the coboundary of a fiven cell. The output format + * is a vector of pairs of pointers to coboundary elements and incidence + * coefficients. + **/ + inline Cell_range& get_coBoundary() { return this->coBoundary; } + + /** + * Procedure to get the dimension of a cell. + **/ + inline int& get_dimension() { return this->dimension; } + + /** + * Procedure to get additional information about the cell.s + **/ + inline Additional_information& get_additional_information() { return this->additional_info; } + + /** + * Procedure to retrive position of the cell in the structure. It is used in + * the implementation of Hasse diagram and set by it. Note that removal of + * cell and subsequent call of clean_up_the_structure will change those + * positions. + **/ + inline unsigned& get_position() { return this->position; } + + /** + * Accessing the filtration of the cell. + **/ + inline Filtration_type& get_filtration() { + // std::cout << "Accessing the filtration of a cell : " << *this << std::endl; + return this->filtration; + } + + /** + * A procedure used to check if the cell is deleted. It is used by the + * subsequent implementation of Hasse diagram that is absed on lazy + * delete. + **/ + inline bool deleted() { return this->deleted_; } + + template + friend class Hasse_diagram; + + template + friend class is_before_in_filtration; + + template + friend std::vector convert_to_vector_of_Cell_type(Complex_type& cmplx); + + /** + * Procedure to remove deleted boundary and coboundary elements from the + * vectors of boundary and coboundary elements of this cell. + **/ + void remove_deleted_elements_from_boundary_and_coboundary() { + Cell_range new_boundary; + new_boundary.reserve(this->boundary.size()); + for (size_t bd = 0; bd != this->boundary.size(); ++bd) { + if (!this->boundary[bd].first->deleted()) { + new_boundary.push_back(this->boundary[bd]); + } + } + this->boundary.swap(new_boundary); + + Cell_range new_coBoundary; + new_coBoundary.reserve(this->coBoundary.size()); + for (size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { + if (!this->coBoundary[cbd].first->deleted()) { + new_coBoundary.push_back(this->coBoundary[cbd]); + } + } + this->coBoundary.swap(new_coBoundary); + } + + /** + * Writing to a stream operator. + **/ + friend std::ostream& operator<<( + std::ostream& out, const Hasse_diagram_cell& c) { + // cout << "position : " << c.position << ", dimension : " << c.dimension << ", filtration: " << c.filtration << ", + // size of boudary : " << c.boundary.size() << "\n"; + out << c.position << " " << c.dimension << " " << c.filtration << std::endl; + for (size_t bd = 0; bd != c.boundary.size(); ++bd) { + // do not write out the cells that has been deleted + if (c.boundary[bd].first->deleted()) continue; + out << c.boundary[bd].first->position << " " << c.boundary[bd].second << " "; + } + out << std::endl; + return out; + } + + /** + * Procedure that return vector of pointers to boundary elements of a given cell. + **/ + inline std::vector get_list_of_boundary_elements() { + std::vector result; + size_t size_of_boundary = this->boundary.size(); + result.reserve(size_of_boundary); + for (size_t bd = 0; bd != size_of_boundary; ++bd) { + result.push_back(this->boundary[bd].first); + } + return result; + } + + /** + * Procedure that return vector of positios of boundary elements of a given cell. + **/ + inline std::vector get_list_of_positions_of_boundary_elements() { + std::vector result; + size_t size_of_boundary = this->boundary.size(); + result.reserve(size_of_boundary); + for (size_t bd = 0; bd != size_of_boundary; ++bd) { + result.push_back(this->boundary[bd].first->position); + } + return result; + } + + /** + * Function that display a string being a signature of a structure. + * Used mainly for debugging purposes. + **/ + std::string full_signature_of_the_structure() { + std::string result; + result += "dimension: "; + result += std::to_string(this->dimension); + result += " filtration: "; + result += std::to_string(this->filtration); + result += " position: "; + result += std::to_string(this->position); + result += " deleted_: "; + result += std::to_string(this->deleted_); + + // if the Additional_information is not void, add them to + // the signature as well. + if (std::is_same::value) { + result += " Additional_information: "; + result += std::to_string(this->additional_info); + } + result += " boundary "; + for (size_t bd = 0; bd != this->boundary.size(); ++bd) { + result += "( " + std::to_string(this->boundary[bd].first->position); + result += " " + std::to_string(this->boundary[bd].second); + result += ") "; + } + + result += " coBoundary "; + for (size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { + result += "( " + std::to_string(this->coBoundary[cbd].first->position); + result += " " + std::to_string(this->coBoundary[cbd].second); + result += ") "; + } + + return result; + } + + protected: + Cell_range boundary; + Cell_range coBoundary; + int dimension; + Additional_information additional_info; + unsigned position; + bool deleted_; + Filtration_type filtration; + + /** + * A procedure to delete a cell. It is a private function of the Hasse_diagram_cell + * class, since in the Hasse_diagram class I want to have a control + * of removal of cells. Therefore, to remove cell please use + * remove_cell in the Hasse_diagram structure. + **/ + void delete_cell() { this->deleted_ = true; } +}; // Hasse_diagram_cell + +} // namespace Hasse_diagram +} // namespace Gudhi + +#endif // CELL_H diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h index 19ceb007..2a57666d 100644 --- a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h @@ -26,10 +26,10 @@ #include namespace Gudhi { - + namespace coxeter_triangulation { -/** +/** * \class Coxeter_triangulation * \brief A class that stores Coxeter triangulation of type \f$\tilde{A}_d\f$. * This triangulation has the greatest simplex quality out of all linear transformations @@ -40,50 +40,48 @@ namespace coxeter_triangulation { * \tparam Permutahedral_representation_ Type of a simplex given by a permutahedral representation. * Needs to be a model of SimplexInCoxeterTriangulation. */ -template , std::vector > > > +template , std::vector > > > class Coxeter_triangulation : public Freudenthal_triangulation { using Matrix = Eigen::MatrixXd; Matrix root_matrix(unsigned d) { - Matrix cartan(d,d); + Matrix cartan(d, d); for (unsigned i = 0; i < d; i++) { - cartan(i,i) = 1.0; + cartan(i, i) = 1.0; } for (unsigned i = 1; i < d; i++) { - cartan(i-1,i) = -0.5; - cartan(i,i-1) = -0.5; + cartan(i - 1, i) = -0.5; + cartan(i, i - 1) = -0.5; } for (unsigned i = 0; i < d; i++) for (unsigned j = 0; j < d; j++) - if (j+1 < i || j > i+1) - cartan(i,j) = 0; + if (j + 1 < i || j > i + 1) cartan(i, j) = 0; Eigen::SelfAdjointEigenSolver saes(cartan); Eigen::VectorXd sqrt_diag(d); - for (unsigned i = 0; i < d; ++i) - sqrt_diag(i) = std::sqrt(saes.eigenvalues()[i]); + for (unsigned i = 0; i < d; ++i) sqrt_diag(i) = std::sqrt(saes.eigenvalues()[i]); - Matrix lower(d,d); + Matrix lower(d, d); for (unsigned i = 0; i < d; i++) for (unsigned j = 0; j < d; j++) if (i < j) - lower(i,j) = 0; + lower(i, j) = 0; else - lower(i,j) = 1; - Matrix result = (lower * saes.eigenvectors()*sqrt_diag.asDiagonal()).inverse(); + lower(i, j) = 1; + Matrix result = (lower * saes.eigenvectors() * sqrt_diag.asDiagonal()).inverse(); return result; } public: - /** \brief Constructor of Coxeter triangulation of a given dimension. + /** \brief Constructor of Coxeter triangulation of a given dimension. * @param[in] dimension The dimension of the triangulation. */ Coxeter_triangulation(std::size_t dimension) - : Freudenthal_triangulation(dimension, root_matrix(dimension)) {} + : Freudenthal_triangulation(dimension, root_matrix(dimension)) {} }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h index 6b33a00c..43b33d1f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -13,9 +13,9 @@ #include #include // for std::sort -#include // for std::floor -#include // for std::iota -#include // for std::size_t +#include // for std::floor +#include // for std::iota +#include // for std::size_t #include #include @@ -27,7 +27,7 @@ namespace Gudhi { namespace coxeter_triangulation { -/** +/** * \class Freudenthal_triangulation * \brief A class that stores any affine transformation of the Freudenthal-Kuhn * triangulation. @@ -41,32 +41,30 @@ namespace coxeter_triangulation { * \tparam Permutahedral_representation_ Type of a simplex given by a permutahedral representation. * Needs to be a model of SimplexInCoxeterTriangulation. */ -template , std::vector > > > +template , std::vector > > > class Freudenthal_triangulation { using Matrix = Eigen::MatrixXd; using Vector = Eigen::VectorXd; using SparseMatrix = Eigen::SparseMatrix; using Triplet = Eigen::Triplet; - + public: /** \brief Type of the simplices in the triangulation. */ using Simplex_handle = Permutahedral_representation_; /** \brief Type of the vertices in the triangulation. */ using Vertex_handle = typename Permutahedral_representation_::Vertex; - - - /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension. + + /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension. * @param[in] dimension The dimension of the triangulation. */ Freudenthal_triangulation(std::size_t dimension) - : dimension_(dimension), - matrix_(Matrix::Identity(dimension, dimension)), - offset_(Vector::Zero(dimension)), - colpivhouseholderqr_(matrix_.colPivHouseholderQr()), - is_freudenthal(true) { - } + : dimension_(dimension), + matrix_(Matrix::Identity(dimension, dimension)), + offset_(Vector::Zero(dimension)), + colpivhouseholderqr_(matrix_.colPivHouseholderQr()), + is_freudenthal(true) {} /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension under * a linear transformation by a given matrix. @@ -75,12 +73,11 @@ class Freudenthal_triangulation { * Needs to be invertible. */ Freudenthal_triangulation(std::size_t dimension, const Matrix& matrix) - : dimension_(dimension), - matrix_(matrix), - offset_(Vector::Zero(dimension)), - colpivhouseholderqr_(matrix_.colPivHouseholderQr()), - is_freudenthal(false) { - } + : dimension_(dimension), + matrix_(matrix), + offset_(Vector::Zero(dimension)), + colpivhouseholderqr_(matrix_.colPivHouseholderQr()), + is_freudenthal(false) {} /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension under * an affine transformation by a given matrix and a translation vector. @@ -90,64 +87,56 @@ class Freudenthal_triangulation { * @param[in] offset The offset vector. */ Freudenthal_triangulation(unsigned dimension, const Matrix& matrix, const Vector& offset) - : dimension_(dimension), - matrix_(matrix), - offset_(offset), - colpivhouseholderqr_(matrix_.colPivHouseholderQr()), - is_freudenthal(false) { - } - + : dimension_(dimension), + matrix_(matrix), + offset_(offset), + colpivhouseholderqr_(matrix_.colPivHouseholderQr()), + is_freudenthal(false) {} /** \brief Dimension of the triangulation. */ - unsigned dimension() const { - return dimension_; - } + unsigned dimension() const { return dimension_; } /** \brief Matrix that defines the linear transformation of the triangulation. */ - const Matrix& matrix() const { - return matrix_; - } + const Matrix& matrix() const { return matrix_; } /** \brief Vector that defines the offset of the triangulation. */ - const Vector& offset() const { - return offset_; - } + const Vector& offset() const { return offset_; } - /** \brief Change the linear transformation matrix to a given value. + /** \brief Change the linear transformation matrix to a given value. * @param[in] matrix New value of the linear transformation matrix. */ void change_matrix(const Eigen::MatrixXd& matrix) { matrix_ = matrix; colpivhouseholderqr_ = matrix.colPivHouseholderQr(); is_freudenthal = false; - } + } - /** \brief Change the offset vector to a given value. + /** \brief Change the offset vector to a given value. * @param[in] offset New value of the offset vector. */ void change_offset(const Eigen::VectorXd& offset) { offset_ = offset; is_freudenthal = false; } - + /** \brief Returns the permutahedral representation of the simplex in the * triangulation that contains a given query point. - * \details Using the additional parameter scale, the search can be done in a + * \details Using the additional parameter scale, the search can be done in a * triangulation that shares the origin, but is scaled by a given factor. * This parameter can be useful to simulate the point location in a subdivided * triangulation. * The returned simplex is always minimal by inclusion. - * + * * \tparam Point_d A class that represents a point in d-dimensional Euclidean space. * The coordinates should be random-accessible. Needs to provide the method size(). * * @param[in] point The query point. - * @param[in] scale The scale of the triangulation. + * @param[in] scale The scale of the triangulation. */ template - Simplex_handle locate_point(const Point_d& point, double scale=1) const { - using Ordered_set_partition = typename Simplex_handle::OrderedSetPartition; - using Part = typename Ordered_set_partition::value_type; + Simplex_handle locate_point(const Point_d& point, double scale = 1) const { + using Ordered_set_partition = typename Simplex_handle::OrderedSetPartition; + using Part = typename Ordered_set_partition::value_type; unsigned d = point.size(); assert(d == dimension_); double error = 1e-9; @@ -160,11 +149,9 @@ class Freudenthal_triangulation { output.vertex().push_back(y_i); z.push_back(x_i - y_i); } - } - else { + } else { Eigen::VectorXd p_vect(d); - for (std::size_t i = 0; i < d; i++) - p_vect(i) = point[i]; + for (std::size_t i = 0; i < d; i++) p_vect(i) = point[i]; Eigen::VectorXd x_vect = colpivhouseholderqr_.solve(p_vect - offset_); for (std::size_t i = 0; i < d; i++) { double x_i = scale * x_vect(i); @@ -174,15 +161,13 @@ class Freudenthal_triangulation { } } z.push_back(0); - Part indices(d+1); + Part indices(d + 1); std::iota(indices.begin(), indices.end(), 0); - std::sort(indices.begin(), - indices.end(), - [&z](std::size_t i1, std::size_t i2) {return z[i1] > z[i2];}); + std::sort(indices.begin(), indices.end(), [&z](std::size_t i1, std::size_t i2) { return z[i1] > z[i2]; }); output.partition().push_back(Part(1, indices[0])); for (std::size_t i = 1; i <= d; ++i) - if (z[indices[i-1]] > z[indices[i]] + error) + if (z[indices[i - 1]] > z[indices[i]] + error) output.partition().push_back(Part(1, indices[i])); else output.partition().back().push_back(indices[i]); @@ -190,39 +175,37 @@ class Freudenthal_triangulation { } /** \brief Returns the Cartesian coordinates of the given vertex. - * \details Using the additional parameter scale, the search can be done in a + * \details Using the additional parameter scale, the search can be done in a * triangulation that shares the origin, but is scaled by a given factor. - * This parameter can be useful to simulate the computation of Cartesian coordinates + * This parameter can be useful to simulate the computation of Cartesian coordinates * of a vertex in a subdivided triangulation. * @param[in] vertex The query vertex. - * @param[in] scale The scale of the triangulation. + * @param[in] scale The scale of the triangulation. */ Eigen::VectorXd cartesian_coordinates(const Vertex_handle& vertex, double scale = 1) const { Eigen::VectorXd v_vect(dimension_); - for (std::size_t j = 0; j < dimension_; j++) - v_vect(j) = vertex[j] / scale; + for (std::size_t j = 0; j < dimension_; j++) v_vect(j) = vertex[j] / scale; return matrix_ * v_vect + offset_; } /** \brief Returns the Cartesian coordinates of the barycenter of a given simplex. - * \details Using the additional parameter scale, the search can be done in a + * \details Using the additional parameter scale, the search can be done in a * triangulation that shares the origin, but is scaled by a given factor. - * This parameter can be useful to simulate the computation of Cartesian coordinates + * This parameter can be useful to simulate the computation of Cartesian coordinates * of the barycenter of a simplex in a subdivided triangulation. * @param[in] simplex The query simplex. - * @param[in] scale The scale of the triangulation. + * @param[in] scale The scale of the triangulation. */ Eigen::VectorXd barycenter(const Simplex_handle& simplex, double scale = 1) const { Eigen::VectorXd res_vector(dimension_); - for (size_t i = 0; i < dimension_; ++i) - res_vector(i) = 0; - for (auto v: simplex.vertex_range()) { + for (size_t i = 0; i < dimension_; ++i) res_vector(i) = 0; + for (auto v : simplex.vertex_range()) { res_vector += cartesian_coordinates(v, scale); } - return (1./(simplex.dimension()+1)) * res_vector; + return (1. / (simplex.dimension() + 1)) * res_vector; } - -protected: + + protected: unsigned dimension_; Matrix matrix_; Vector offset_; @@ -230,8 +213,8 @@ protected: bool is_freudenthal; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h index 0a6f264d..c0d6aec4 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -14,7 +14,7 @@ #include #include #include // for std::enable_if -#include // for std::size_t +#include // for std::size_t #include @@ -27,86 +27,79 @@ namespace coxeter_triangulation { /* Get the domain dimension of the tuple of functions. */ template -inline typename std::enable_if::type -get_amb_d (const std::tuple& tuple) { +inline typename std::enable_if::type get_amb_d(const std::tuple& tuple) { return 0; } template -inline typename std::enable_if::type -get_amb_d (const std::tuple& tuple) { - return std::get(tuple).amb_d() + get_amb_d(tuple); +inline typename std::enable_if::type get_amb_d(const std::tuple& tuple) { + return std::get(tuple).amb_d() + get_amb_d(tuple); } /* Get the codomain dimension of the tuple of functions. */ template -inline typename std::enable_if::type -get_cod_d (const std::tuple& tuple) { +inline typename std::enable_if::type get_cod_d(const std::tuple& tuple) { return 0; } template -inline typename std::enable_if::type -get_cod_d (const std::tuple& tuple) { - return std::get(tuple).cod_d() + get_cod_d(tuple); +inline typename std::enable_if::type get_cod_d(const std::tuple& tuple) { + return std::get(tuple).cod_d() + get_cod_d(tuple); } /* Get the seed of the tuple of functions. */ template -inline typename std::enable_if::type -get_seed (const std::tuple& tuple, Eigen::VectorXd& point, std::size_t i = 0) { -} +inline typename std::enable_if::type get_seed(const std::tuple& tuple, + Eigen::VectorXd& point, std::size_t i = 0) {} template -inline typename std::enable_if::type -get_seed (const std::tuple& tuple, Eigen::VectorXd& point, std::size_t i = 0) { +inline typename std::enable_if::type get_seed(const std::tuple& tuple, + Eigen::VectorXd& point, std::size_t i = 0) { const auto& f = std::get(tuple); std::size_t n = f.amb_d(); Eigen::VectorXd seed = f.seed(); - for (std::size_t j = 0; j < n; ++j) - point(i+j) = seed(j); - get_seed(tuple, point, i+n); + for (std::size_t j = 0; j < n; ++j) point(i + j) = seed(j); + get_seed(tuple, point, i + n); } /* Get the seed of the tuple of functions. */ template -inline typename std::enable_if::type -get_value (const std::tuple& tuple, const Eigen::VectorXd& x, Eigen::VectorXd& point, std::size_t i = 0, std::size_t j = 0) { -} +inline typename std::enable_if::type get_value(const std::tuple& tuple, + const Eigen::VectorXd& x, + Eigen::VectorXd& point, std::size_t i = 0, + std::size_t j = 0) {} template -inline typename std::enable_if::type -get_value (const std::tuple& tuple, const Eigen::VectorXd& x, Eigen::VectorXd& point, std::size_t i = 0, std::size_t j = 0) { +inline typename std::enable_if::type get_value(const std::tuple& tuple, + const Eigen::VectorXd& x, + Eigen::VectorXd& point, std::size_t i = 0, + std::size_t j = 0) { const auto& f = std::get(tuple); std::size_t n = f.amb_d(); std::size_t k = f.cod_d(); Eigen::VectorXd x_i(n); - for (std::size_t l = 0; l < n; ++l) - x_i(l) = x(i+l); + for (std::size_t l = 0; l < n; ++l) x_i(l) = x(i + l); Eigen::VectorXd res = f(x_i); - for (std::size_t l = 0; l < k; ++l) - point(j+l) = res(l); - get_value(tuple, x, point, i+n, j+k); + for (std::size_t l = 0; l < k; ++l) point(j + l) = res(l); + get_value(tuple, x, point, i + n, j + k); } - -/** +/** * \class Cartesian_product * \brief Constructs the function the zero-set of which is the Cartesian product * of the zero-sets of some given functions. * - * \tparam Functions A pack template parameter for functions. All functions should be models of + * \tparam Functions A pack template parameter for functions. All functions should be models of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ template struct Cartesian_product : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -117,10 +110,10 @@ struct Cartesian_product : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return amb_d_;} + virtual std::size_t amb_d() const override { return amb_d_; } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return cod_d_;} + virtual std::size_t cod_d() const override { return cod_d_; } /** \brief Returns a point on the zero-set. */ virtual Eigen::VectorXd seed() const override { @@ -128,15 +121,14 @@ struct Cartesian_product : public Function { get_seed(function_tuple_, result, 0); return result; } - - /** + + /** * \brief Constructor of the Cartesian product function. * * @param[in] functions The functions the zero-sets of which are factors in the * Cartesian product of the resulting function. */ - Cartesian_product(const Functions&... functions) - : function_tuple_(std::make_tuple(functions...)) { + Cartesian_product(const Functions&... functions) : function_tuple_(std::make_tuple(functions...)) { amb_d_ = get_amb_d(function_tuple_); cod_d_ = get_cod_d(function_tuple_); } @@ -146,14 +138,13 @@ struct Cartesian_product : public Function { std::size_t amb_d_, cod_d_; }; - -/** +/** * \brief Static constructor of a Cartesian product function. * * @param[in] functions The functions the zero-sets of which are factors in the * Cartesian product of the resulting function. * - * \tparam Functions A pack template parameter for functions. All functions should be models of + * \tparam Functions A pack template parameter for functions. All functions should be models of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation @@ -163,9 +154,8 @@ Cartesian_product make_product_function(const Functions&... functi return Cartesian_product(functions...); } +} // namespace coxeter_triangulation -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index c03a2a24..424bcbff 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -21,15 +21,14 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Constant_function +/** + * \class Constant_function * \brief A class that encodes a constant function from R^d to R^k. * This class does not have any implicit manifold in correspondence. * * \ingroup coxeter_triangulation */ struct Constant_function : public Function { - /** \brief Value of the function at a specified point. The value is constant. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -37,37 +36,34 @@ struct Constant_function : public Function { Eigen::VectorXd result = value_; return result; } - + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - virtual std::size_t amb_d() const override {return d_;}; + virtual std::size_t amb_d() const override { return d_; }; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - virtual std::size_t cod_d() const override {return k_;}; + virtual std::size_t cod_d() const override { return k_; }; /** \brief No seed point is available. Throws an exception on evocation. */ - virtual Eigen::VectorXd seed() const override { - throw "Seed invoked on a constant function.\n"; - } + virtual Eigen::VectorXd seed() const override { throw "Seed invoked on a constant function.\n"; } Constant_function() {} - - /** + + /** * \brief Constructor of a constant function from R^d to R^m. * * @param[in] d The domain dimension. * @param[in] k The codomain dimension. * @param[in] value The constant value of the function. */ - Constant_function(std::size_t d, std::size_t k, const Eigen::VectorXd& value) - : d_(d), k_(k), value_(value) {} + Constant_function(std::size_t d, std::size_t k, const Eigen::VectorXd& value) : d_(d), k_(k), value_(value) {} private: std::size_t d_, k_; Eigen::VectorXd value_; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index 5ebeac75..69bd269a 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -17,7 +17,6 @@ #include - namespace Gudhi { namespace coxeter_triangulation { @@ -26,70 +25,62 @@ namespace coxeter_triangulation { * \class Embed_in_Rd * \brief Embedding of an implicit manifold in a higher dimension. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ template struct Embed_in_Rd : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd x = p; Eigen::VectorXd x_k(fun_.amb_d()), x_rest(d_ - fun_.amb_d()); - for (std::size_t i = 0; i < fun_.amb_d(); ++i) - x_k(i) = x(i); - for (std::size_t i = fun_.amb_d(); i < d_; ++i) - x_rest(i - fun_.amb_d()) = x(i); + for (std::size_t i = 0; i < fun_.amb_d(); ++i) x_k(i) = x(i); + for (std::size_t i = fun_.amb_d(); i < d_; ++i) x_rest(i - fun_.amb_d()) = x(i); Eigen::VectorXd result = fun_(x_k); result.conservativeResize(this->cod_d()); - for (std::size_t i = fun_.cod_d(); i < this->cod_d(); ++i) - result(i) = x_rest(i - fun_.cod_d()); + for (std::size_t i = fun_.cod_d(); i < this->cod_d(); ++i) result(i) = x_rest(i - fun_.cod_d()); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return d_;} + virtual std::size_t amb_d() const override { return d_; } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return d_-(fun_.amb_d() - fun_.cod_d());} + virtual std::size_t cod_d() const override { return d_ - (fun_.amb_d() - fun_.cod_d()); } /** \brief Returns a point on the zero-set of the embedded function. */ virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = fun_.seed(); result.conservativeResize(d_); - for (std::size_t l = fun_.amb_d(); l < d_; ++l) - result(l) = 0; + for (std::size_t l = fun_.amb_d(); l < d_; ++l) result(l) = 0; return result; } - /** + /** * \brief Constructor of the embedding function. * * @param[in] function The function to be embedded in higher dimension. * @param[in] d Embedding dimension. */ - Embed_in_Rd(const Function_& function, std::size_t d) : - fun_(function), d_(d) { - } + Embed_in_Rd(const Function_& function, std::size_t d) : fun_(function), d_(d) {} private: Function_ fun_; std::size_t d_; }; - -/** +/** * \brief Static constructor of an embedding function. * * @param[in] function The function to be embedded in higher dimension. * @param[in] d Embedding dimension. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation @@ -99,8 +90,8 @@ Embed_in_Rd make_embedding(const Function_& function, std::size_t d) return Embed_in_Rd(function, d); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h index 29fadcbf..eddfedf5 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h @@ -17,7 +17,7 @@ namespace Gudhi { namespace coxeter_triangulation { -/** +/** * \class Function * \brief The parent class for all functions implemented in the module. * Contains virtual methods needed to be a model of the concept FunctionForImplicitManifold. @@ -25,7 +25,6 @@ namespace coxeter_triangulation { * \ingroup coxeter_triangulation */ struct Function { - /** \brief Virtual method for the value of the function at a specified point. * @param[in] p The input point. */ @@ -44,9 +43,8 @@ struct Function { virtual ~Function() {} }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h index 7ebb7fc8..25b9b5fc 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -21,47 +21,42 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_Sm_in_Rd +/** + * \class Function_Sm_in_Rd * \brief A class for the function that defines an m-dimensional implicit sphere embedded * in the d-dimensional Euclidean space. * * \ingroup coxeter_triangulation */ -struct Function_Sm_in_Rd: public Function { - -/** \brief Value of the function at a specified point. - * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. - */ +struct Function_Sm_in_Rd : public Function { + /** \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd x = p; - for (std::size_t i = 0; i < d_; ++i) - x(i) -= center_[i]; - Eigen::VectorXd result = Eigen::VectorXd::Zero(k_); - for (std::size_t i = 0; i < m_+1; ++i) - result(0) += x(i)*x(i); - result(0) -= r_*r_; - for (std::size_t j = 1; j < k_; ++j) - result(j) = x(m_+j); + for (std::size_t i = 0; i < d_; ++i) x(i) -= center_[i]; + Eigen::VectorXd result = Eigen::VectorXd::Zero(k_); + for (std::size_t i = 0; i < m_ + 1; ++i) result(0) += x(i) * x(i); + result(0) -= r_ * r_; + for (std::size_t j = 1; j < k_; ++j) result(j) = x(m_ + j); return result; } - + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - virtual std::size_t amb_d() const override {return d_;}; + virtual std::size_t amb_d() const override { return d_; }; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - virtual std::size_t cod_d() const override {return k_;}; + virtual std::size_t cod_d() const override { return k_; }; /** \brief Returns a point on the sphere. */ virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); result(0) += r_; - for (std::size_t i = 0; i < d_; ++i) - result(i) += center_[i]; + for (std::size_t i = 0; i < d_; ++i) result(i) += center_[i]; return result; } - - /** + + /** * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded * in the d-dimensional Euclidean space. * @@ -70,13 +65,10 @@ struct Function_Sm_in_Rd: public Function { * @param[in] d The ambient dimension of the sphere. * @param[in] center The center of the sphere. */ - Function_Sm_in_Rd(double r, - std::size_t m, - std::size_t d, - Eigen::VectorXd center) - : m_(m), k_(d-m), d_(d), r_(r), center_(center) {} + Function_Sm_in_Rd(double r, std::size_t m, std::size_t d, Eigen::VectorXd center) + : m_(m), k_(d - m), d_(d), r_(r), center_(center) {} - /** + /** * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded * in the d-dimensional Euclidean space centered at the origin. * @@ -84,13 +76,10 @@ struct Function_Sm_in_Rd: public Function { * @param[in] m The dimension of the sphere. * @param[in] d The ambient dimension of the sphere. */ - Function_Sm_in_Rd(double r, - std::size_t m, - std::size_t d) - : m_(m), k_(d-m), d_(d), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} + Function_Sm_in_Rd(double r, std::size_t m, std::size_t d) + : m_(m), k_(d - m), d_(d), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} - - /** + /** * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded * in the (m+1)-dimensional Euclidean space. * @@ -98,35 +87,28 @@ struct Function_Sm_in_Rd: public Function { * @param[in] m The dimension of the sphere. * @param[in] center The center of the sphere. */ - Function_Sm_in_Rd(double r, - std::size_t m, - Eigen::VectorXd center) - : m_(m), k_(1), d_(m_+1), r_(r), center_(center) {} + Function_Sm_in_Rd(double r, std::size_t m, Eigen::VectorXd center) + : m_(m), k_(1), d_(m_ + 1), r_(r), center_(center) {} - /** + /** * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded * in the (m+1)-dimensional Euclidean space centered at the origin. * * @param[in] r The radius of the sphere. * @param[in] m The dimension of the sphere. */ - Function_Sm_in_Rd(double r, - std::size_t m) - : m_(m), k_(1), d_(m_+1), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} + Function_Sm_in_Rd(double r, std::size_t m) : m_(m), k_(1), d_(m_ + 1), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} - Function_Sm_in_Rd(const Function_Sm_in_Rd& rhs) - : Function_Sm_in_Rd(rhs.r_, rhs.m_, rhs.d_, rhs.center_) {} + Function_Sm_in_Rd(const Function_Sm_in_Rd& rhs) : Function_Sm_in_Rd(rhs.r_, rhs.m_, rhs.d_, rhs.center_) {} - private: std::size_t m_, k_, d_; double r_; Eigen::VectorXd center_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h index 1e950d4e..d0089149 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -21,16 +21,15 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_affine_plane_in_Rd - * \brief A class for the function that defines an m-dimensional implicit affine plane +/** + * \class Function_affine_plane_in_Rd + * \brief A class for the function that defines an m-dimensional implicit affine plane * embedded in d-dimensional Euclidean space. * * \ingroup coxeter_triangulation */ struct Function_affine_plane_in_Rd : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -38,65 +37,59 @@ struct Function_affine_plane_in_Rd : public Function { Eigen::VectorXd result = normal_matrix_.transpose() * (p - off_); return result; } - + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - virtual std::size_t amb_d() const override {return d_;}; + virtual std::size_t amb_d() const override { return d_; }; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - virtual std::size_t cod_d() const override {return k_;}; + virtual std::size_t cod_d() const override { return k_; }; /** \brief Returns a point on the affine plane. */ virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = off_; return result; } - - /** + + /** * \brief Constructor of the function that defines an m-dimensional implicit affine * plane in the d-dimensional Euclidean space. * * @param[in] normal_matrix A normal matrix of the affine plane. The number of rows should - * correspond to the ambient dimension, the number of columns should corespond to - * the size of the normal basis (codimension). + * correspond to the ambient dimension, the number of columns should corespond to + * the size of the normal basis (codimension). * @param[in] offset The offset vector of the affine plane. * The dimension of the vector should be the ambient dimension of the manifold. */ - Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix, - const Eigen::VectorXd& offset) - : normal_matrix_(normal_matrix), - d_(normal_matrix.rows()), - k_(normal_matrix.cols()), - m_(d_ - k_), - off_(offset) { + Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix, const Eigen::VectorXd& offset) + : normal_matrix_(normal_matrix), d_(normal_matrix.rows()), k_(normal_matrix.cols()), m_(d_ - k_), off_(offset) { normal_matrix_.colwise().normalize(); } - /** + /** * \brief Constructor of the function that defines an m-dimensional implicit affine * plane in the d-dimensional Euclidean space that passes through origin. * * @param[in] normal_matrix A normal matrix of the affine plane. The number of rows should - * correspond to the ambient dimension, the number of columns should corespond to - * the size of the normal basis (codimension). + * correspond to the ambient dimension, the number of columns should corespond to + * the size of the normal basis (codimension). */ Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix) - : normal_matrix_(normal_matrix), - d_(normal_matrix.rows()), - k_(normal_matrix.cols()), - m_(d_ - k_), - off_(Eigen::VectorXd::Zero(d_)) { + : normal_matrix_(normal_matrix), + d_(normal_matrix.rows()), + k_(normal_matrix.cols()), + m_(d_ - k_), + off_(Eigen::VectorXd::Zero(d_)) { normal_matrix_.colwise().normalize(); } -private: + private: Eigen::MatrixXd normal_matrix_; std::size_t d_, k_, m_; - Eigen::VectorXd off_; + Eigen::VectorXd off_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h index fe16d37b..e2f65144 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -12,7 +12,7 @@ #define FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ #include // for std::size_t -#include // for std::pow +#include // for std::pow #include @@ -22,42 +22,42 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_chair_in_R3 +/** + * \class Function_chair_in_R3 * \brief A class that encodes the function, the zero-set of which is a so-called * "chair" surface embedded in R^3. * * \ingroup coxeter_triangulation */ struct Function_chair_in_R3 : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { - double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); - result(0) = std::pow(x*x + y*y + z*z - a_*k_*k_, 2) - b_*((z-k_)*(z-k_) - 2*x*x)*((z+k_)*(z+k_) - 2*y*y); + result(0) = std::pow(x * x + y * y + z * z - a_ * k_ * k_, 2) - + b_ * ((z - k_) * (z - k_) - 2 * x * x) * ((z + k_) * (z + k_) - 2 * y * y); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return 3;} + virtual std::size_t amb_d() const override { return 3; } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return 1;} + virtual std::size_t cod_d() const override { return 1; } /** \brief Returns a point on the surface. */ virtual Eigen::VectorXd seed() const override { - double t1 = a_-b_; - double discr = t1*t1 - (1.0 - b_)*(a_*a_ - b_); - double z0 = k_*std::sqrt((t1+std::sqrt(discr))/(1-b_)); - Eigen::Vector3d result(off_[0], off_[1], z0+off_[2]); + double t1 = a_ - b_; + double discr = t1 * t1 - (1.0 - b_) * (a_ * a_ - b_); + double z0 = k_ * std::sqrt((t1 + std::sqrt(discr)) / (1 - b_)); + Eigen::Vector3d result(off_[0], off_[1], z0 + off_[2]); return result; } - /** + /** * \brief Constructor of the function that defines the 'chair' surface * embedded in R^3. * @@ -66,20 +66,17 @@ struct Function_chair_in_R3 : public Function { * @param[in] k A numerical parameter. * @param[in] off Offset vector. */ - Function_chair_in_R3(double a = 0.8, - double b = 0.4, - double k = 1.0, - Eigen::Vector3d off = Eigen::Vector3d::Zero()) : - a_(a), b_(b), k_(k), off_(off) {} - -protected: + Function_chair_in_R3(double a = 0.8, double b = 0.4, double k = 1.0, Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : a_(a), b_(b), k_(k), off_(off) {} + + protected: double a_, b_, k_; Eigen::Vector3d off_; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h index fa5e4e66..5842c58f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -12,7 +12,7 @@ #define FUNCTIONS_FUNCTION_IRON_IN_R3_H_ #include // for std::size_t -#include // for std::pow +#include // for std::pow #include @@ -22,54 +22,52 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_iron_in_R3 +/** + * \class Function_iron_in_R3 * \brief A class that encodes the function, the zero-set of which is a surface * embedded in R^3 that ressembles an iron. * * \ingroup coxeter_triangulation */ struct Function_iron_in_R3 : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { double x = p(0), y = p(1), z = p(2); Eigen::VectorXd result(cod_d()); - result(0) = - std::pow(x,6)/300. - std::pow(y,6)/300. - std::pow(z,6)/300. + x*y*y*z/2.1 + y*y + std::pow(z-2, 4) - 1; + result(0) = -std::pow(x, 6) / 300. - std::pow(y, 6) / 300. - std::pow(z, 6) / 300. + x * y * y * z / 2.1 + y * y + + std::pow(z - 2, 4) - 1; return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return 3;}; + virtual std::size_t amb_d() const override { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return 1;}; + virtual std::size_t cod_d() const override { return 1; }; /** \brief Returns a point on the surface. */ virtual Eigen::VectorXd seed() const override { - Eigen::Vector3d result(std::pow(4500, 1./6), 0, 0); + Eigen::Vector3d result(std::pow(4500, 1. / 6), 0, 0); return result; } - - /** + + /** * \brief Constructor of the function that defines a surface embedded in R^3 * that ressembles an iron. * * @param[in] off Offset vector. */ - Function_iron_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : - off_(off) {} - + Function_iron_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : off_(off) {} + private: Eigen::Vector3d off_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h index b715932b..b5d54b24 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -12,7 +12,7 @@ #define FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ #include // for std::size_t -#include // for std::sqrt +#include // for std::sqrt #include @@ -22,71 +22,68 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_lemniscate_revolution_in_R3 +/** + * \class Function_lemniscate_revolution_in_R3 * \brief A class that encodes the function, the zero-set of which is a surface of revolution * around the x axis based on the lemniscate of Bernoulli embedded in R^3. * * \ingroup coxeter_triangulation */ struct Function_lemniscate_revolution_in_R3 : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { - double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); - double x2 = x*x, y2 = y*y, z2 = z*z, a2 = a_*a_; + double x2 = x * x, y2 = y * y, z2 = z * z, a2 = a_ * a_; double t1 = x2 + y2 + z2; - result(0) = t1*t1 - 2*a2*(x2 - y2 - z2); + result(0) = t1 * t1 - 2 * a2 * (x2 - y2 - z2); return result; } /** \brief Returns the (ambient) domain dimension.*/ - virtual std::size_t amb_d() const override {return 3;}; + virtual std::size_t amb_d() const override { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return 1;}; + virtual std::size_t cod_d() const override { return 1; }; - /** \brief Returns a point on the surface. This seed point is only one of + /** \brief Returns a point on the surface. This seed point is only one of * two necessary seed points for the manifold tracing algorithm. - * See the method seed2() for the other point. + * See the method seed2() for the other point. */ virtual Eigen::VectorXd seed() const override { - Eigen::Vector3d result(std::sqrt(2*a_)+off_[0], off_[1], off_[2]); + Eigen::Vector3d result(std::sqrt(2 * a_) + off_[0], off_[1], off_[2]); return result; } - /** \brief Returns a point on the surface. This seed point is only one of - * two necessary seed points for the manifold tracing algorithm. - * See the method seed() for the other point. + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed() for the other point. */ Eigen::VectorXd seed2() const { - Eigen::Vector3d result(-std::sqrt(2*a_)+off_[0], off_[1], off_[2]); + Eigen::Vector3d result(-std::sqrt(2 * a_) + off_[0], off_[1], off_[2]); return result; } - - /** + + /** * \brief Constructor of the function that defines a surface of revolution * around the x axis based on the lemniscate of Bernoulli embedded in R^3. * * @param[in] a A numerical parameter. * @param[in] off Offset vector. */ - Function_lemniscate_revolution_in_R3(double a = 1, - Eigen::Vector3d off = Eigen::Vector3d::Zero()) - : a_(a), off_(off) {} + Function_lemniscate_revolution_in_R3(double a = 1, Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : a_(a), off_(off) {} private: double a_; Eigen::Vector3d off_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h index eecbc914..3ea5cf12 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -21,49 +21,45 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_moment_curve_in_Rd +/** + * \class Function_moment_curve_in_Rd * \brief A class for the function that defines an implicit moment curve * in the d-dimensional Euclidean space. * * \ingroup coxeter_triangulation */ struct Function_moment_curve_in_Rd : public Function { - -/** \brief Value of the function at a specified point. - * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. - */ + /** \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { Eigen::VectorXd result(k_); - for (std::size_t i = 1; i < d_; ++i) - result(i-1) = p(i) - p(0) * p(i-1); + for (std::size_t i = 1; i < d_; ++i) result(i - 1) = p(i) - p(0) * p(i - 1); return result; } - + /** \brief Returns the domain (ambient) dimension.. */ - virtual std::size_t amb_d() const override {return d_;}; + virtual std::size_t amb_d() const override { return d_; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return k_;}; + virtual std::size_t cod_d() const override { return k_; }; /** \brief Returns a point on the moment curve. */ virtual Eigen::VectorXd seed() const override { Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); return result; } - - /** + + /** * \brief Constructor of the function that defines an implicit moment curve * in the d-dimensional Euclidean space. * * @param[in] r Numerical parameter. * @param[in] d The ambient dimension. */ - Function_moment_curve_in_Rd(double r, - std::size_t d) - : m_(1), k_(d-1), d_(d), r_(r) {} + Function_moment_curve_in_Rd(double r, std::size_t d) : m_(1), k_(d - 1), d_(d), r_(r) {} - /** + /** * \brief Constructor of the function that defines an implicit moment curve * in the d-dimensional Euclidean space. * @@ -71,20 +67,17 @@ struct Function_moment_curve_in_Rd : public Function { * @param[in] d The ambient dimension. * @param[in] offset The offset of the moment curve. */ - Function_moment_curve_in_Rd(double r, - std::size_t d, - Eigen::VectorXd& offset) - : m_(1), k_(d-1), d_(d), r_(r), off_(offset) {} - + Function_moment_curve_in_Rd(double r, std::size_t d, Eigen::VectorXd& offset) + : m_(1), k_(d - 1), d_(d), r_(r), off_(offset) {} + private: std::size_t m_, k_, d_; double r_; Eigen::VectorXd off_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h index c756c1a6..cdc39199 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -12,7 +12,7 @@ #define FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ #include // for std::size_t -#include // for std::sqrt +#include // for std::sqrt #include @@ -22,58 +22,54 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_torus_in_R3 +/** + * \class Function_torus_in_R3 * \brief A class that encodes the function, the zero-set of which is a torus * surface embedded in R^3. * * \ingroup coxeter_triangulation */ struct Function_torus_in_R3 : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { - double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); - result(0) = (z*z + (std::sqrt(x*x + y*y) - r_)*(std::sqrt(x*x + y*y) - r_) - R_*R_); + result(0) = (z * z + (std::sqrt(x * x + y * y) - r_) * (std::sqrt(x * x + y * y) - r_) - R_ * R_); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return 3;}; + virtual std::size_t amb_d() const override { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return 1;}; + virtual std::size_t cod_d() const override { return 1; }; /** \brief Returns a point on the surface. */ virtual Eigen::VectorXd seed() const override { - Eigen::Vector3d result(R_ + r_ +off_[0], off_[1], off_[2]); + Eigen::Vector3d result(R_ + r_ + off_[0], off_[1], off_[2]); return result; } - - /** + + /** * \brief Constructor of the function that defines a torus embedded in R^3. * * @param[in] R The outer radius of the torus. * @param[in] r The inner radius of the torus. * @param[in] off Offset vector. */ - Function_torus_in_R3(double R = 1, - double r = 0.5, - Eigen::Vector3d off = Eigen::Vector3d::Zero()) : - R_(R), r_(r), off_(off) {} - + Function_torus_in_R3(double R = 1, double r = 0.5, Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : R_(R), r_(r), off_(off) {} + private: double R_, r_; Eigen::Vector3d off_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h index 09306561..4415ab87 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -21,65 +21,62 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \class Function_whitney_umbrella_in_R3 +/** + * \class Function_whitney_umbrella_in_R3 * \brief A class that encodes the function, the zero-set of which is the Whitney umbrella * surface embedded in R^3. * * \ingroup coxeter_triangulation */ struct Function_whitney_umbrella_in_R3 : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { - double x = p(0)-off_[0], y = p(1)-off_[1], z = p(2)-off_[2]; + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); - result(0) = x*x - y*y*z; + result(0) = x * x - y * y * z; return result; } /** \brief Returns the (ambient) domain dimension.*/ - virtual std::size_t amb_d() const override {return 3;}; + virtual std::size_t amb_d() const override { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return 1;}; + virtual std::size_t cod_d() const override { return 1; }; - /** \brief Returns a point on the surface. This seed point is only one of + /** \brief Returns a point on the surface. This seed point is only one of * two necessary seed points for the manifold tracing algorithm. - * See the method seed2() for the other point. + * See the method seed2() for the other point. */ virtual Eigen::VectorXd seed() const override { - Eigen::Vector3d result(1+off_[0], 1+off_[1], 1+off_[2]); + Eigen::Vector3d result(1 + off_[0], 1 + off_[1], 1 + off_[2]); return result; } - /** \brief Returns a point on the surface. This seed point is only one of - * two necessary seed points for the manifold tracing algorithm. - * See the method seed() for the other point. + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed() for the other point. */ Eigen::VectorXd seed2() const { - Eigen::Vector3d result(-1+off_[0], -1+off_[1], 1+off_[2]); + Eigen::Vector3d result(-1 + off_[0], -1 + off_[1], 1 + off_[2]); return result; } - - /** + + /** * \brief Constructor of the function that defines the Whitney umbrella in R^3. * * @param[in] off Offset vector. */ - Function_whitney_umbrella_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) - : off_(off) {} + Function_whitney_umbrella_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : off_(off) {} private: Eigen::Vector3d off_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index a5d17fe0..1a82984b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -25,15 +25,14 @@ namespace coxeter_triangulation { * \brief Transforms the zero-set of the function by a given linear transformation. * The underlying function corresponds to f(M*x), where M is the transformation matrix. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ template struct Linear_transformation : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -43,10 +42,10 @@ struct Linear_transformation : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return fun_.amb_d();} + virtual std::size_t amb_d() const override { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return fun_.cod_d();} + virtual std::size_t cod_d() const override { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ virtual Eigen::VectorXd seed() const override { @@ -55,43 +54,39 @@ struct Linear_transformation : public Function { return result; } - /** + /** * \brief Constructor of a linearly transformed function. * * @param[in] function The function to be linearly transformed. * @param[in] matrix The transformation matrix. Its dimension should be d*d, * where d is the domain (ambient) dimension of 'function'. */ - Linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) : - fun_(function), matrix_(matrix) { - } + Linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) : fun_(function), matrix_(matrix) {} private: Function_ fun_; Eigen::MatrixXd matrix_; }; - -/** +/** * \brief Static constructor of a linearly transformed function. * * @param[in] function The function to be linearly transformed. * @param[in] matrix The transformation matrix. Its dimension should be d*d, * where d is the domain (ambient) dimension of 'function'. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ template -Linear_transformation make_linear_transformation(const Function_& function, - const Eigen::MatrixXd& matrix) { - return Linear_transformation(function, matrix); +Linear_transformation make_linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) { + return Linear_transformation(function, matrix); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index 3439dbad..58d8ebe0 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -21,20 +21,19 @@ namespace Gudhi { namespace coxeter_triangulation { -/** +/** *\class Negation * \brief Constructs the "minus" function. The zero-set is the same, but * the values at other points are the negative of their original value. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ template struct Negation : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -44,10 +43,10 @@ struct Negation : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return fun_.amb_d();} + virtual std::size_t amb_d() const override { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return fun_.cod_d();} + virtual std::size_t cod_d() const override { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ virtual Eigen::VectorXd seed() const override { @@ -55,27 +54,24 @@ struct Negation : public Function { return result; } - /** + /** * \brief Constructor of the negative function. * * @param[in] function The function to be negated. */ - Negation(const Function_& function) : - fun_(function) { - } + Negation(const Function_& function) : fun_(function) {} private: Function_ fun_; }; - -/** +/** * \brief Static constructor of the negative function. * * @param[in] function The function to be translated. * domain (ambient) dimension of 'function'. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation @@ -85,8 +81,8 @@ Negation negation(const Function_& function) { return Negation(function); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index ab2b9294..3d1f3564 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -21,23 +21,21 @@ namespace Gudhi { namespace coxeter_triangulation { -/** +/** * \class PL_approximation * \brief Constructs a piecewise-linear approximation of a function induced by * an ambient triangulation. * - * \tparam Function The function template parameter. Should be a model of + * \tparam Function The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * \tparam Triangulation The triangulation template parameter. Should be a model of * the concept TriangulationForManifoldTracing. * * \ingroup coxeter_triangulation */ -template +template struct PL_approximation : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -47,33 +45,29 @@ struct PL_approximation : public Function { auto s = tr_.locate_point(p); Eigen::MatrixXd matrix(cod_d, s.dimension() + 1); Eigen::MatrixXd vertex_matrix(amb_d + 1, s.dimension() + 1); - for (std::size_t i = 0; i < s.dimension() + 1; ++i) - vertex_matrix(0, i) = 1; + for (std::size_t i = 0; i < s.dimension() + 1; ++i) vertex_matrix(0, i) = 1; std::size_t j = 0; - for (auto v: s.vertex_range()) { + for (auto v : s.vertex_range()) { Eigen::VectorXd pt_v = tr_.cartesian_coordinates(v); Eigen::VectorXd fun_v = fun_(pt_v); - for (std::size_t i = 1; i < amb_d + 1; ++i) - vertex_matrix(i, j) = pt_v(i-1); - for (std::size_t i = 0; i < cod_d; ++i) - matrix(i, j) = fun_v(i); + for (std::size_t i = 1; i < amb_d + 1; ++i) vertex_matrix(i, j) = pt_v(i - 1); + for (std::size_t i = 0; i < cod_d; ++i) matrix(i, j) = fun_v(i); j++; } - assert(j == s.dimension()+1); + assert(j == s.dimension() + 1); Eigen::VectorXd z(amb_d + 1); z(0) = 1; - for (std::size_t i = 1; i < amb_d + 1; ++i) - z(i) = p(i-1); - Eigen::VectorXd lambda = vertex_matrix.colPivHouseholderQr().solve(z); + for (std::size_t i = 1; i < amb_d + 1; ++i) z(i) = p(i - 1); + Eigen::VectorXd lambda = vertex_matrix.colPivHouseholderQr().solve(z); Eigen::VectorXd result = matrix * lambda; return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return fun_.amb_d();} + virtual std::size_t amb_d() const override { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return fun_.cod_d();} + virtual std::size_t cod_d() const override { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ virtual Eigen::VectorXd seed() const override { @@ -81,44 +75,41 @@ struct PL_approximation : public Function { return Eigen::VectorXd(amb_d()); } - /** - * \brief Constructor of the piecewise-linear approximation of a function + /** + * \brief Constructor of the piecewise-linear approximation of a function * induced by an ambient triangulation. * * @param[in] function The function. * @param[in] triangulation The ambient triangulation. */ PL_approximation(const Function_& function, const Triangulation_& triangulation) - : fun_(function), tr_(triangulation) {} + : fun_(function), tr_(triangulation) {} - private: + private: Function_ fun_; Triangulation_ tr_; }; - -/** - * \brief Static constructor of the piecewise-linear approximation of a function +/** + * \brief Static constructor of the piecewise-linear approximation of a function * induced by an ambient triangulation. * * @param[in] function The function. * @param[in] triangulation The ambient triangulation. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ -template -PL_approximation -make_pl_approximation(const Function_& function, - const Triangulation_& triangulation) { +template +PL_approximation make_pl_approximation(const Function_& function, + const Triangulation_& triangulation) { return PL_approximation(function, triangulation); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index b3f53fe0..bd91c707 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -21,20 +21,19 @@ namespace Gudhi { namespace coxeter_triangulation { -/** +/** * \class Translate * \brief Translates the zero-set of the function by a vector. * The underlying function corresponds to f(x-off), where off is the offset vector. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ template struct Translate : public Function { - - /** + /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ @@ -44,10 +43,10 @@ struct Translate : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override {return fun_.amb_d();} + virtual std::size_t amb_d() const override { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override {return fun_.cod_d();} + virtual std::size_t cod_d() const override { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ virtual Eigen::VectorXd seed() const override { @@ -56,31 +55,28 @@ struct Translate : public Function { return result; } - /** + /** * \brief Constructor of the translated function. * * @param[in] function The function to be translated. - * @param[in] off The offset vector. The dimension should correspond to the + * @param[in] off The offset vector. The dimension should correspond to the * domain (ambient) dimension of 'function'. */ - Translate(const Function_& function, const Eigen::VectorXd& off) : - fun_(function), off_(off) { - } + Translate(const Function_& function, const Eigen::VectorXd& off) : fun_(function), off_(off) {} private: Function_ fun_; Eigen::VectorXd off_; }; - -/** +/** * \brief Static constructor of a translated function. * * @param[in] function The function to be translated. - * @param[in] off The offset vector. The dimension should correspond to the + * @param[in] off The offset vector. The dimension should correspond to the * domain (ambient) dimension of 'function'. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation @@ -90,8 +86,8 @@ Translate translate(const Function_& function, Eigen::VectorXd off) { return Translate(function, off); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h index 34fc1a67..fbc1c895 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -12,8 +12,8 @@ #define FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ #include // for std::size_t -#include // for std::cos, std::sin -#include // for std::uniform_real_distribution, std::random_device +#include // for std::cos, std::sin +#include // for std::uniform_real_distribution, std::random_device #include @@ -28,10 +28,10 @@ namespace Gudhi { namespace coxeter_triangulation { -/** \brief Generates a uniform random orthogonal matrix using the "subgroup algorithm" by - * Diaconis & Shashahani. +/** \brief Generates a uniform random orthogonal matrix using the "subgroup algorithm" by + * Diaconis & Shashahani. * \details Taken from https://en.wikipedia.org/wiki/Rotation_matrix#Uniform_random_rotation_matrices. - * The idea: take a random rotation matrix of dimension d-1, embed it + * The idea: take a random rotation matrix of dimension d-1, embed it * as a d*d matrix M with the last column (0,...,0,1). * Pick a random vector v on a sphere S^d. rotate the matrix M so that its last column is v. * The determinant of the matrix can be either 1 or -1 @@ -41,8 +41,7 @@ namespace coxeter_triangulation { Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) { typedef CGAL::Epick_d Kernel; typedef typename Kernel::Point_d Point_d; - if (d == 1) - return Eigen::VectorXd::Constant(1, 1.0); + if (d == 1) return Eigen::VectorXd::Constant(1, 1.0); if (d == 2) { // 0. < alpha < 2 Pi std::uniform_real_distribution unif(0., 2 * Gudhi::PI); @@ -54,22 +53,20 @@ Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) { rot << std::cos(alpha), -std::sin(alpha), std::sin(alpha), cos(alpha); return rot; } - Eigen::MatrixXd low_dim_rot = random_orthogonal_matrix(d-1); - Eigen::MatrixXd rot(d,d); + Eigen::MatrixXd low_dim_rot = random_orthogonal_matrix(d - 1); + Eigen::MatrixXd rot(d, d); Point_d v = *CGAL::Random_points_on_sphere_d(d, 1); - for (std::size_t i = 0; i < d; ++i) - rot(i,0) = v[i]; - for (std::size_t i = 0; i < d-1; ++i) - for (std::size_t j = 1; j < d-1; ++j) - rot(i,j) = low_dim_rot(i,j-1); - for (std::size_t j = 1; j < d; ++j) - rot(d-1,j) = 0; - rot = rot.householderQr().householderQ(); // a way to do Gram-Schmidt, see https://forum.kde.org/viewtopic.php?f=74&t=118568#p297246 + for (std::size_t i = 0; i < d; ++i) rot(i, 0) = v[i]; + for (std::size_t i = 0; i < d - 1; ++i) + for (std::size_t j = 1; j < d - 1; ++j) rot(i, j) = low_dim_rot(i, j - 1); + for (std::size_t j = 1; j < d; ++j) rot(d - 1, j) = 0; + rot = rot.householderQr() + .householderQ(); // a way to do Gram-Schmidt, see https://forum.kde.org/viewtopic.php?f=74&t=118568#p297246 return rot; } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h index 28276bf7..203ed6c5 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h @@ -11,15 +11,15 @@ #ifndef IO_MESH_MEDIT_H_ #define IO_MESH_MEDIT_H_ -namespace Gudhi { - -namespace coxeter_triangulation { - #include #include #include // for std::pair +namespace Gudhi { + +namespace coxeter_triangulation { + /* \class Mesh_medit * \brief Structure to store a mesh that can be output in Medit .mesh file format * using the output_meshes_to_medit method. @@ -53,8 +53,8 @@ struct Mesh_medit { Scalar_field_range tetrahedra_scalar_range; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index abe6cdbf..0dc98f95 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -19,7 +19,7 @@ #include #include #include -#include // for std::make_pair +#include // for std::make_pair #include // for std::min namespace Gudhi { @@ -27,104 +27,90 @@ namespace Gudhi { namespace coxeter_triangulation { struct Configuration { - Configuration(bool t_edges, bool t_triangles, bool t_tetrahedra, - std::size_t r_edges, std::size_t r_triangles, std::size_t r_tetrahedra) - : toggle_edges(t_edges), toggle_triangles(t_triangles), toggle_tetrahedra(t_tetrahedra), - ref_edges(r_edges), ref_triangles(r_triangles), ref_tetrahedra(r_tetrahedra) {} + Configuration(bool t_edges, bool t_triangles, bool t_tetrahedra, std::size_t r_edges, std::size_t r_triangles, + std::size_t r_tetrahedra) + : toggle_edges(t_edges), + toggle_triangles(t_triangles), + toggle_tetrahedra(t_tetrahedra), + ref_edges(r_edges), + ref_triangles(r_triangles), + ref_tetrahedra(r_tetrahedra) {} Configuration() {} - bool toggle_edges = true, - toggle_triangles = true, - toggle_tetrahedra = true; - std::size_t ref_edges = 1, - ref_triangles = 1, - ref_tetrahedra = 1; + bool toggle_edges = true, toggle_triangles = true, toggle_tetrahedra = true; + std::size_t ref_edges = 1, ref_triangles = 1, ref_tetrahedra = 1; }; - template -void populate_mesh(Mesh_medit& output, - Simplex_cell_map& sc_map, - Configuration configuration, - std::size_t amb_d, +void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration configuration, std::size_t amb_d, std::map vi_map) { using Mesh_element_vertices = Mesh_medit::Mesh_elements::value_type::first_type; std::map ci_map; - std::size_t index = vi_map.size() + 1; // current size of output.vertex_points - if (sc_map.size() >= 3) - for (const auto& sc_pair: sc_map[2]) { + std::size_t index = vi_map.size() + 1; // current size of output.vertex_points + if (sc_map.size() >= 3) + for (const auto& sc_pair : sc_map[2]) { Eigen::VectorXd barycenter = Eigen::VectorXd::Zero(amb_d); std::set vertex_indices; Hasse_cell* cell = sc_pair.second; - for (const auto& ei_pair: cell->get_boundary()) - for (const auto& vi_pair: ei_pair.first->get_boundary()) - vertex_indices.emplace(vi_map[vi_pair.first]); - for (const std::size_t& v: vertex_indices) - barycenter += output.vertex_points[v-1]; + for (const auto& ei_pair : cell->get_boundary()) + for (const auto& vi_pair : ei_pair.first->get_boundary()) vertex_indices.emplace(vi_map[vi_pair.first]); + for (const std::size_t& v : vertex_indices) barycenter += output.vertex_points[v - 1]; ci_map.emplace(std::make_pair(cell, index++)); - output.vertex_points.emplace_back((1./vertex_indices.size()) * barycenter); + output.vertex_points.emplace_back((1. / vertex_indices.size()) * barycenter); #ifdef GUDHI_COX_OUTPUT_TO_HTML - std::string vlist = " (" + std::to_string(index-1) + ")"; - for (const std::size_t& v: vertex_indices) - vlist += " " + std::to_string(v); + std::string vlist = " (" + std::to_string(index - 1) + ")"; + for (const std::size_t& v : vertex_indices) vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); #endif } if (configuration.toggle_edges && sc_map.size() >= 2) - for (const auto& sc_map: sc_map[1]) { + for (const auto& sc_map : sc_map[1]) { Hasse_cell* edge_cell = sc_map.second; Mesh_element_vertices edge; - for (const auto& vi_pair: edge_cell->get_boundary()) - edge.push_back(vi_map[vi_pair.first]); + for (const auto& vi_pair : edge_cell->get_boundary()) edge.push_back(vi_map[vi_pair.first]); output.edges.emplace_back(std::make_pair(edge, configuration.ref_edges)); #ifdef GUDHI_COX_OUTPUT_TO_HTML std::string vlist; - for (const std::size_t& v: edge) - vlist += " " + std::to_string(v); + for (const std::size_t& v : edge) vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(edge_cell), vlist)); #endif } - + if (configuration.toggle_triangles && sc_map.size() >= 3) - for (const auto& sc_pair: sc_map[2]) { - for (const auto& ei_pair: sc_pair.second->get_boundary()) { + for (const auto& sc_pair : sc_map[2]) { + for (const auto& ei_pair : sc_pair.second->get_boundary()) { Mesh_element_vertices triangle(1, ci_map[sc_pair.second]); - for (const auto& vi_pair: ei_pair.first->get_boundary()) - triangle.push_back(vi_map[vi_pair.first]); + for (const auto& vi_pair : ei_pair.first->get_boundary()) triangle.push_back(vi_map[vi_pair.first]); output.triangles.emplace_back(std::make_pair(triangle, configuration.ref_triangles)); } } - + if (configuration.toggle_tetrahedra && sc_map.size() >= 4) - for (const auto& sc_pair: sc_map[3]) { + for (const auto& sc_pair : sc_map[3]) { Eigen::VectorXd barycenter = Eigen::VectorXd::Zero(amb_d); std::set vertex_indices; Hasse_cell* cell = sc_pair.second; - for (const auto& ci_pair: cell->get_boundary()) - for (const auto& ei_pair: ci_pair.first->get_boundary()) - for (const auto& vi_pair: ei_pair.first->get_boundary()) - vertex_indices.emplace(vi_map[vi_pair.first]); - for (const std::size_t& v: vertex_indices) - barycenter += output.vertex_points[v-1]; - output.vertex_points.emplace_back((1./vertex_indices.size()) * barycenter); + for (const auto& ci_pair : cell->get_boundary()) + for (const auto& ei_pair : ci_pair.first->get_boundary()) + for (const auto& vi_pair : ei_pair.first->get_boundary()) vertex_indices.emplace(vi_map[vi_pair.first]); + for (const std::size_t& v : vertex_indices) barycenter += output.vertex_points[v - 1]; + output.vertex_points.emplace_back((1. / vertex_indices.size()) * barycenter); #ifdef GUDHI_COX_OUTPUT_TO_HTML std::string vlist = " (" + std::to_string(index) + ")"; - for (const std::size_t& v: vertex_indices) - vlist += " " + std::to_string(v); + for (const std::size_t& v : vertex_indices) vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); #endif - for (const auto& ci_pair: cell->get_boundary()) - for (const auto& ei_pair: ci_pair.first->get_boundary()) { + for (const auto& ci_pair : cell->get_boundary()) + for (const auto& ei_pair : ci_pair.first->get_boundary()) { Mesh_element_vertices tetrahedron = {index, ci_map[sc_pair.second]}; - for (const auto& vi_pair: ei_pair.first->get_boundary()) - tetrahedron.push_back(vi_map[vi_pair.first]); + for (const auto& vi_pair : ei_pair.first->get_boundary()) tetrahedron.push_back(vi_map[vi_pair.first]); output.tetrahedra.emplace_back(std::make_pair(tetrahedron, configuration.ref_tetrahedra)); } index++; - } + } } template @@ -133,14 +119,13 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, Configuration b_configuration = Configuration()) { using Hasse_cell = typename Cell_complex::Hasse_cell; Mesh_medit output; - std::map vi_map; // one for vertices, other for 2d-cells - std::size_t index = 1; // current size of output.vertex_points - - if (cell_complex.cell_point_map().empty()) - return output; - std::size_t amb_d = std::min((int) cell_complex.cell_point_map().begin()->second.size(), 3); - - for (const auto& cp_pair: cell_complex.cell_point_map()) { + std::map vi_map; // one for vertices, other for 2d-cells + std::size_t index = 1; // current size of output.vertex_points + + if (cell_complex.cell_point_map().empty()) return output; + std::size_t amb_d = std::min((int)cell_complex.cell_point_map().begin()->second.size(), 3); + + for (const auto& cp_pair : cell_complex.cell_point_map()) { #ifdef GUDHI_COX_OUTPUT_TO_HTML std::string vlist; vlist += " " + std::to_string(index); @@ -153,29 +138,29 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, populate_mesh(output, cell_complex.interior_simplex_cell_maps(), i_configuration, amb_d, vi_map); #ifdef GUDHI_COX_OUTPUT_TO_HTML - for (const auto& sc_map: cell_complex.interior_simplex_cell_maps()) - for (const auto& sc_pair: sc_map) { + for (const auto& sc_map : cell_complex.interior_simplex_cell_maps()) + for (const auto& sc_pair : sc_map) { std::string simplex = "I" + to_string(sc_pair.first); std::string cell = to_string(sc_pair.second); std::string vlist = cell_vlist_map.at(cell).substr(1); simplex_vlist_map.emplace(std::make_pair(simplex, vlist)); } -#endif - populate_mesh(output, cell_complex.boundary_simplex_cell_maps(), b_configuration, amb_d, vi_map); +#endif + populate_mesh(output, cell_complex.boundary_simplex_cell_maps(), b_configuration, amb_d, vi_map); #ifdef GUDHI_COX_OUTPUT_TO_HTML - for (const auto& sc_map: cell_complex.boundary_simplex_cell_maps()) - for (const auto& sc_pair: sc_map) { + for (const auto& sc_map : cell_complex.boundary_simplex_cell_maps()) + for (const auto& sc_pair : sc_map) { std::string simplex = "B" + to_string(sc_pair.first); std::string cell = to_string(sc_pair.second); std::string vlist = cell_vlist_map.at(cell).substr(1); simplex_vlist_map.emplace(std::make_pair(simplex, vlist)); } -#endif +#endif return output; } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h index 43cca967..147ab908 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h @@ -16,22 +16,21 @@ namespace coxeter_triangulation { template std::ostream& operator<<(std::ostream& os, const std::vector& vector) { - os << "("; + os << "("; if (vector.empty()) { os << ")"; return os; } auto v_it = vector.begin(); os << *v_it++; - for (; v_it != vector.end(); ++v_it) - os << ", " << *v_it; + for (; v_it != vector.end(); ++v_it) os << ", " << *v_it; os << ")"; return os; } /* A class to make the vector horizontal instead of vertical */ struct Straighten { - Straighten (const Eigen::VectorXd& vector) : vector_(vector) {} + Straighten(const Eigen::VectorXd& vector) : vector_(vector) {} const Eigen::VectorXd& vector_; }; @@ -42,8 +41,7 @@ std::ostream& operator<<(std::ostream& os, const Straighten& str) { os << ")"; return os; } - for (std::size_t i = 1; i < size; ++i) - os << ", " << str.vector_(i); + for (std::size_t i = 1; i < size; ++i) os << ", " << str.vector_(i); os << ")"; return os; } @@ -68,61 +66,57 @@ std::string to_string(const T& t) { struct MT_inserted_info { std::string qr_face_, init_face_, qr_intersection_; bool qr_success_, is_boundary_; - template + template MT_inserted_info(const Query_result& qr, const Simplex_handle& face, bool is_boundary) - : qr_face_(to_string(face)), init_face_(to_string(face)), - qr_intersection_(to_string(qr.intersection)), - qr_success_(qr.success), is_boundary_(is_boundary) {} + : qr_face_(to_string(face)), + init_face_(to_string(face)), + qr_intersection_(to_string(qr.intersection)), + qr_success_(qr.success), + is_boundary_(is_boundary) {} }; std::list mt_seed_inserted_list, mt_inserted_list; struct CC_summary_info { std::string face_, cell_; template - CC_summary_info(const SC_pair& sc_pair) - : face_(to_string(sc_pair.first)), cell_(to_string(sc_pair.second)) {} + CC_summary_info(const SC_pair& sc_pair) : face_(to_string(sc_pair.first)), cell_(to_string(sc_pair.second)) {} }; using CC_summary_list = std::list; std::vector cc_interior_summary_lists, cc_boundary_summary_lists; struct CC_detail_info { - enum class Result_type {self, face, coface, inserted, join_single, join_is_face}; + enum class Result_type { self, face, coface, inserted, join_single, join_is_face }; std::string simplex_, trigger_, init_simplex_; Result_type status_; bool join_trigger_ = false; std::list faces_, post_faces_, cofaces_; template - CC_detail_info(const Simplex_handle& simplex) - : simplex_(to_string(simplex)) {} + CC_detail_info(const Simplex_handle& simplex) : simplex_(to_string(simplex)) {} }; using CC_detail_list = std::list; std::vector cc_interior_detail_lists, cc_boundary_detail_lists; std::vector cc_interior_insert_detail_lists, cc_boundary_insert_detail_lists; struct CC_prejoin_info { - enum class Result_type {join_single, join_is_face, join_different, join_same}; + enum class Result_type { join_single, join_is_face, join_different, join_same }; std::string simplex_, join_; std::vector faces_; std::size_t dimension_; Result_type status_; template - CC_prejoin_info(const Simplex_handle& simplex) - : simplex_(to_string(simplex)), dimension_(simplex.dimension()) {} + CC_prejoin_info(const Simplex_handle& simplex) : simplex_(to_string(simplex)), dimension_(simplex.dimension()) {} }; using CC_prejoin_list = std::list; std::vector cc_interior_prejoin_lists, cc_boundary_prejoin_lists; - struct CC_join_info { - enum class Result_type {self, face, coface, inserted, join_single, join_is_face}; + enum class Result_type { self, face, coface, inserted, join_single, join_is_face }; std::string simplex_, join_, trigger_; Result_type status_; std::list boundary_faces_; std::list faces_, post_faces_, cofaces_; template - CC_join_info(const Simplex_handle& simplex) - : simplex_(to_string(simplex)) {} + CC_join_info(const Simplex_handle& simplex) : simplex_(to_string(simplex)) {} }; bool join_switch = false; std::vector cc_interior_join_detail_lists, cc_boundary_join_detail_lists; @@ -134,16 +128,15 @@ std::ostringstream mt_ostream, vis_ostream; std::vector cc_summary_ostream, cc_traces_ostream; std::string simplex_format(const std::string& simplex, bool is_boundary) { - std::string b_simplex = (is_boundary? "B": "I") + simplex; + std::string b_simplex = (is_boundary ? "B" : "I") + simplex; std::string tooltiptext; auto it = simplex_vlist_map.find(b_simplex); if (it == simplex_vlist_map.end()) tooltiptext = "deleted"; else tooltiptext = simplex_vlist_map.at(b_simplex); - return (std::string)"" + b_simplex - + "" + tooltiptext + ""; + return (std::string) "" + b_simplex + "" + tooltiptext + ""; } std::string simplex_format(const std::string& b_simplex) { @@ -154,12 +147,10 @@ std::string simplex_format(const std::string& b_simplex) { tooltiptext = "deleted"; else tooltiptext = simplex_vlist_map.at(b_simplex); - return (std::string)"" + b_simplex - + "" + tooltiptext + ""; + return (std::string) "" + b_simplex + "" + tooltiptext + ""; } - void write_head(std::ofstream& ofs) { ofs << " \n" << " Cell complex debug trace\n" @@ -215,11 +206,11 @@ void write_head(std::ofstream& ofs) { << " .boundary:hover .tooltiptext {\n" << " visibility: visible;\n" << " opacity: 1;\n" - << " }\n" + << " }\n" << " .interior:hover .tooltiptext {\n" << " visibility: visible;\n" << " opacity: 1;\n" - << " }\n" + << " }\n" << " ul.nav {\n" << " list-style-type: none;\n" << " margin: 0;\n" @@ -284,30 +275,26 @@ void write_mt(std::ofstream& ofs) { ofs << "

Manifold debug trace

\n"; ofs << "

Simplices inserted during the seed phase

\n"; ofs << "
    \n"; - for (const MT_inserted_info& mt_info: mt_seed_inserted_list) { + for (const MT_inserted_info& mt_info : mt_seed_inserted_list) { if (mt_info.qr_success_) { ofs << "
  • Inserted " << simplex_format(mt_info.qr_face_, mt_info.is_boundary_); if (mt_info.qr_face_ != mt_info.init_face_) - ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")"; + ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")"; ofs << " intersection point is " << mt_info.qr_intersection_ << "
  • \n"; - } - else - ofs << "
  • Failed to insert " << mt_info.init_face_ - << "
  • \n"; + } else + ofs << "
  • Failed to insert " << mt_info.init_face_ << "
  • \n"; } ofs << "
\n"; ofs << "

Simplices inserted during the while loop phase

\n"; ofs << "
    \n"; - for (const MT_inserted_info& mt_info: mt_inserted_list) { + for (const MT_inserted_info& mt_info : mt_inserted_list) { if (mt_info.qr_success_) { ofs << "
  • Inserted " << simplex_format(mt_info.qr_face_, mt_info.is_boundary_); if (mt_info.qr_face_ != mt_info.init_face_) - ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")"; + ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")"; ofs << " intersection point is " << mt_info.qr_intersection_ << "
  • \n"; - } - else - ofs << "
  • Failed to insert " << mt_info.init_face_ - << ")
  • \n"; + } else + ofs << "
  • Failed to insert " << mt_info.init_face_ << ")
  • \n"; } ofs << "
\n"; ofs << " \n"; @@ -325,13 +312,11 @@ void write_cc(std::ofstream& ofs) { for (std::size_t i = 0; i < cc_interior_summary_lists.size(); ++i) { ofs << "

Dimension " << i << "

\n"; ofs << "

Summary for interior simplices

\n"; - if (i < cc_boundary_summary_lists.size()) - ofs << "

Go to boundary

\n"; + if (i < cc_boundary_summary_lists.size()) ofs << "

Go to boundary

\n"; ofs << "
    \n"; - for (const CC_summary_info& cc_info: cc_interior_summary_lists[i]) + for (const CC_summary_info& cc_info : cc_interior_summary_lists[i]) ofs << "
  • " - << simplex_format(cc_info.face_, false) - << " cell =" << cc_info.cell_ << "
  • \n"; + << simplex_format(cc_info.face_, false) << " cell =" << cc_info.cell_ << "\n"; ofs << "
\n"; ofs << "

Prejoin state of the interior cells of dimension " << i << "

\n"; auto prejoin_it = cc_interior_prejoin_lists[i].begin(); @@ -340,57 +325,48 @@ void write_cc(std::ofstream& ofs) { ofs << "
" << j << "-dimensional ambient simplices
\n"; ofs << "
    \n"; for (; prejoin_it->dimension_ == j; ++prejoin_it) { - ofs << "
  • " << simplex_format(prejoin_it->simplex_, false) - << " join = " << simplex_format(prejoin_it->join_, false) - << " boundary:\n" - << "
      \n"; - for (const auto& face: prejoin_it->faces_) - ofs << "
    • " << simplex_format(face) << "
    • "; - ofs << "
    \n"; - switch (prejoin_it->status_) { - case (CC_prejoin_info::Result_type::join_single): - ofs << "

    Deleted " - << simplex_format(prejoin_it->simplex_, false) - << " as it has a single face.

    "; - break; - case (CC_prejoin_info::Result_type::join_is_face): - ofs << "

    Deleted " - << simplex_format(prejoin_it->simplex_, false) - << " as its join " << simplex_format(prejoin_it->join_, false) - << " is one of the faces.

    "; - break; - case (CC_prejoin_info::Result_type::join_different): - ofs << "

    Deleted " << simplex_format(prejoin_it->simplex_, false) - << " and replaced by its join " << simplex_format(prejoin_it->join_, false) - << ".

    "; - break; - case (CC_prejoin_info::Result_type::join_same): - ofs << "

    Kept " << simplex_format(prejoin_it->simplex_, false) - << ".

    "; - } - ofs << "
  • "; + ofs << "
  • " << simplex_format(prejoin_it->simplex_, false) + << " join = " << simplex_format(prejoin_it->join_, false) << " boundary:\n" + << "
      \n"; + for (const auto& face : prejoin_it->faces_) ofs << "
    • " << simplex_format(face) << "
    • "; + ofs << "
    \n"; + switch (prejoin_it->status_) { + case (CC_prejoin_info::Result_type::join_single): + ofs << "

    Deleted " << simplex_format(prejoin_it->simplex_, false) + << " as it has a single face.

    "; + break; + case (CC_prejoin_info::Result_type::join_is_face): + ofs << "

    Deleted " << simplex_format(prejoin_it->simplex_, false) + << " as its join " << simplex_format(prejoin_it->join_, false) << " is one of the faces.

    "; + break; + case (CC_prejoin_info::Result_type::join_different): + ofs << "

    Deleted " << simplex_format(prejoin_it->simplex_, false) + << " and replaced by its join " << simplex_format(prejoin_it->join_, false) << ".

    "; + break; + case (CC_prejoin_info::Result_type::join_same): + ofs << "

    Kept " << simplex_format(prejoin_it->simplex_, false) + << ".

    "; + } + ofs << "
  • "; } ofs << "
\n"; } ofs << "

Details for interior simplices

\n"; ofs << "
    \n"; - for (const CC_detail_info& cc_info: cc_interior_detail_lists[i]) { + for (const CC_detail_info& cc_info : cc_interior_detail_lists[i]) { if (cc_info.status_ == CC_detail_info::Result_type::join_single) { - ofs << "
  • Simplex " - << simplex_format(cc_info.simplex_, false) << " has only one face (" - << simplex_format(cc_info.trigger_, false) << ") and is deleted."; - continue; + ofs << "
  • Simplex " << simplex_format(cc_info.simplex_, false) << " has only one face (" + << simplex_format(cc_info.trigger_, false) << ") and is deleted."; + continue; } if (cc_info.status_ == CC_detail_info::Result_type::join_single) { - ofs << "
  • The join of the simplex " - << simplex_format(cc_info.simplex_, false) << " is one of its faces (" - << simplex_format(cc_info.trigger_, false) << "), hence it is is deleted."; - continue; + ofs << "
  • The join of the simplex " << simplex_format(cc_info.simplex_, false) << " is one of its faces (" + << simplex_format(cc_info.trigger_, false) << "), hence it is is deleted."; + continue; } - ofs << "
  • Insert_cell called for " << simplex_format(cc_info.simplex_, false) - << "\n"; + ofs << "
  • Insert_cell called for " << simplex_format(cc_info.simplex_, false) << "\n"; ofs << "
      \n"; // for (const std::string& cof: cc_info.faces_) // ofs << "
    • Checking if " << simplex_format(cc_info.simplex_, false) @@ -398,34 +374,31 @@ void write_cc(std::ofstream& ofs) { ofs << "
    \n"; ofs << "
      \n"; if (cc_info.status_ == CC_detail_info::Result_type::self) { - ofs << "

      The simplex " - << simplex_format(cc_info.simplex_, false) - << " already exists in the cell complex!

      \n"; + ofs << "

      The simplex " << simplex_format(cc_info.simplex_, false) + << " already exists in the cell complex!

      \n"; } if (cc_info.status_ == CC_detail_info::Result_type::face) { - ofs << "

      The simplex " - << simplex_format(cc_info.simplex_, false) << " is a face of the simplex " - << simplex_format(cc_info.trigger_, false) << "!
      \n"; - ofs << "

        \n"; - for (const std::string post_face: cc_info.post_faces_) - ofs << "
      • " - << "Post deleting " << simplex_format(post_face, false) << "
      • \n"; - ofs << "
      \n"; - ofs << "

      \n"; - ofs << "

      " - << "Deleting " << simplex_format(cc_info.trigger_, false) << "

      \n"; + ofs << "

      The simplex " << simplex_format(cc_info.simplex_, false) + << " is a face of the simplex " << simplex_format(cc_info.trigger_, false) << "!
      \n"; + ofs << "

        \n"; + for (const std::string post_face : cc_info.post_faces_) + ofs << "
      • " + << "Post deleting " << simplex_format(post_face, false) << "
      • \n"; + ofs << "
      \n"; + ofs << "

      \n"; + ofs << "

      " + << "Deleting " << simplex_format(cc_info.trigger_, false) << "

      \n"; } // for (const std::string& fac: cc_info.cofaces_) // ofs << "
    • Checking if " << simplex_format(cc_info.simplex_, false) // << " is a coface of " << simplex_format(fac, false) << "\n"; if (cc_info.status_ == CC_detail_info::Result_type::coface) { - ofs << "

      The simplex " - << simplex_format(cc_info.simplex_, false) << " is a coface of the simplex " - << simplex_format(cc_info.trigger_, false) << "!

      \n"; + ofs << "

      The simplex " << simplex_format(cc_info.simplex_, false) + << " is a coface of the simplex " << simplex_format(cc_info.trigger_, false) << "!

      \n"; } if (cc_info.status_ == CC_detail_info::Result_type::inserted) { - ofs << "

      Successfully inserted " - << simplex_format(cc_info.simplex_, false) << "!

      \n"; + ofs << "

      Successfully inserted " + << simplex_format(cc_info.simplex_, false) << "!

      \n"; } ofs << "

    \n"; ofs << "
  • \n"; @@ -436,113 +409,101 @@ void write_cc(std::ofstream& ofs) { ofs << "

    Summary for boundary simplices

    \n"; ofs << "

    Go to interior

    \n"; ofs << "
      \n"; - for (const CC_summary_info& cc_info: cc_boundary_summary_lists[i]) - ofs << "
    • " - << simplex_format(cc_info.face_, true) - << " cell =" << cc_info.cell_ << "
    • \n"; + for (const CC_summary_info& cc_info : cc_boundary_summary_lists[i]) + ofs << "
    • " + << simplex_format(cc_info.face_, true) << " cell =" << cc_info.cell_ << "
    • \n"; ofs << "
    \n"; ofs << "

    Prejoin state of the boundary cells of dimension " << i << "

    \n"; auto prejoin_it = cc_boundary_prejoin_lists[i].begin(); while (prejoin_it != cc_boundary_prejoin_lists[i].end()) { - std::size_t j = prejoin_it->dimension_; - ofs << "
    " << j << "-dimensional ambient simplices
    \n"; - ofs << "
      \n"; - for (; prejoin_it->dimension_ == j; ++prejoin_it) { - ofs << "
    • " << simplex_format(prejoin_it->simplex_, true) - << " join = " << simplex_format(prejoin_it->join_, true) - << " boundary:\n" - << "
        \n"; - for (const auto& face: prejoin_it->faces_) - ofs << "
      • " << simplex_format(face) << "
      • "; - ofs << "
      \n"; - switch (prejoin_it->status_) { - case (CC_prejoin_info::Result_type::join_single): - ofs << "

      Deleted " - << simplex_format(prejoin_it->simplex_, true) - << " as it has a single face.

      "; - break; - case (CC_prejoin_info::Result_type::join_is_face): - ofs << "

      Deleted " - << simplex_format(prejoin_it->simplex_, true) - << " as its join " << simplex_format(prejoin_it->join_, true) - << " is one of the faces.

      "; - break; - case (CC_prejoin_info::Result_type::join_different): - ofs << "

      Deleted " << simplex_format(prejoin_it->simplex_, true) - << " and replaced by its join " << simplex_format(prejoin_it->join_, true) - << ".

      "; - break; - case (CC_prejoin_info::Result_type::join_same): - ofs << "

      Kept " << simplex_format(prejoin_it->simplex_, true) - << ".

      "; - } - ofs << "
    • "; - } - ofs << "
    \n"; + std::size_t j = prejoin_it->dimension_; + ofs << "
    " << j << "-dimensional ambient simplices
    \n"; + ofs << "
      \n"; + for (; prejoin_it->dimension_ == j; ++prejoin_it) { + ofs << "
    • " << simplex_format(prejoin_it->simplex_, true) + << " join = " << simplex_format(prejoin_it->join_, true) << " boundary:\n" + << "
        \n"; + for (const auto& face : prejoin_it->faces_) ofs << "
      • " << simplex_format(face) << "
      • "; + ofs << "
      \n"; + switch (prejoin_it->status_) { + case (CC_prejoin_info::Result_type::join_single): + ofs << "

      Deleted " << simplex_format(prejoin_it->simplex_, true) + << " as it has a single face.

      "; + break; + case (CC_prejoin_info::Result_type::join_is_face): + ofs << "

      Deleted " << simplex_format(prejoin_it->simplex_, true) + << " as its join " << simplex_format(prejoin_it->join_, true) << " is one of the faces.

      "; + break; + case (CC_prejoin_info::Result_type::join_different): + ofs << "

      Deleted " << simplex_format(prejoin_it->simplex_, true) + << " and replaced by its join " << simplex_format(prejoin_it->join_, true) << ".

      "; + break; + case (CC_prejoin_info::Result_type::join_same): + ofs << "

      Kept " << simplex_format(prejoin_it->simplex_, true) + << ".

      "; + } + ofs << "
    • "; + } + ofs << "
    \n"; } } if (i < cc_boundary_detail_lists.size()) { ofs << "

    Details for boundary simplices

    \n" - << "
      \n"; - for (const CC_detail_info& cc_info: cc_boundary_detail_lists[i]) { - if (cc_info.status_ == CC_detail_info::Result_type::join_single) { - ofs << "
    • Simplex " - << simplex_format(cc_info.simplex_, true) << " has only one face (" - << simplex_format(cc_info.trigger_, true) << ") and is deleted."; - continue; - } - if (cc_info.status_ == CC_detail_info::Result_type::join_single) { - ofs << "
    • The join of the simplex " - << simplex_format(cc_info.simplex_, true) << " is one of its faces (" - << simplex_format(cc_info.trigger_, true) << "), hence it is is deleted."; - continue; - } - ofs << "
    • Insert_simplex called on " << simplex_format(cc_info.simplex_, true); - ofs << "
        \n"; - // for (const std::string& cof: cc_info.faces_) - // ofs << "
      • Checking if " << simplex_format(cc_info.simplex_, true) - // << " is a face of " << simplex_format(cof, true) << "\n"; - ofs << "
      \n"; - ofs << "
        \n"; - if (cc_info.status_ == CC_detail_info::Result_type::self) { - ofs << "

        The simplex " - << simplex_format(cc_info.simplex_, true) - << " already exists in the cell complex!

        \n"; - } - if (cc_info.status_ == CC_detail_info::Result_type::face) { - ofs << "

        The simplex " - << simplex_format(cc_info.simplex_, true) << " is a face of the simplex " - << simplex_format(cc_info.trigger_, true) << "!
        \n"; - ofs << "

          \n"; - for (const std::string post_face: cc_info.post_faces_) - ofs << "
        • Post deleting " << simplex_format(post_face, true) - << "
        • \n"; - ofs << "
        \n"; - ofs << "

        \n"; - ofs << "

        Deleting " << simplex_format(cc_info.trigger_, true) << "

        \n"; - } - // for (const std::string& fac: cc_info.cofaces_) - // ofs << "
      • Checking if " << simplex_format(cc_info.simplex_, true) - // << " is a coface of " << simplex_format(fac, true) << "\n"; - ofs << "
      \n"; - ofs << "
    • \n"; - if (cc_info.status_ == CC_detail_info::Result_type::coface) { - ofs << "

      The simplex " - << simplex_format(cc_info.simplex_, true) << " is a coface of the simplex " - << simplex_format(cc_info.trigger_, true) << "!

      \n"; - } - if (cc_info.status_ == CC_detail_info::Result_type::inserted) { - ofs << "

      Successfully inserted " - << simplex_format(cc_info.simplex_, true) << "!

      \n"; - } + << "

        \n"; + for (const CC_detail_info& cc_info : cc_boundary_detail_lists[i]) { + if (cc_info.status_ == CC_detail_info::Result_type::join_single) { + ofs << "
      • Simplex " << simplex_format(cc_info.simplex_, true) << " has only one face (" + << simplex_format(cc_info.trigger_, true) << ") and is deleted."; + continue; + } + if (cc_info.status_ == CC_detail_info::Result_type::join_single) { + ofs << "
      • The join of the simplex " << simplex_format(cc_info.simplex_, true) << " is one of its faces (" + << simplex_format(cc_info.trigger_, true) << "), hence it is is deleted."; + continue; + } + ofs << "
      • Insert_simplex called on " << simplex_format(cc_info.simplex_, true); + ofs << "
          \n"; + // for (const std::string& cof: cc_info.faces_) + // ofs << "
        • Checking if " << simplex_format(cc_info.simplex_, true) + // << " is a face of " << simplex_format(cof, true) << "\n"; + ofs << "
        \n"; + ofs << "
          \n"; + if (cc_info.status_ == CC_detail_info::Result_type::self) { + ofs << "

          The simplex " << simplex_format(cc_info.simplex_, true) + << " already exists in the cell complex!

          \n"; + } + if (cc_info.status_ == CC_detail_info::Result_type::face) { + ofs << "

          The simplex " << simplex_format(cc_info.simplex_, true) + << " is a face of the simplex " << simplex_format(cc_info.trigger_, true) << "!
          \n"; + ofs << "

            \n"; + for (const std::string post_face : cc_info.post_faces_) + ofs << "
          • Post deleting " + << simplex_format(post_face, true) << "
          • \n"; + ofs << "
          \n"; + ofs << "

          \n"; + ofs << "

          Deleting " + << simplex_format(cc_info.trigger_, true) << "

          \n"; + } + // for (const std::string& fac: cc_info.cofaces_) + // ofs << "
        • Checking if " << simplex_format(cc_info.simplex_, true) + // << " is a coface of " << simplex_format(fac, true) << "\n"; + ofs << "
        \n"; + ofs << "
      • \n"; + if (cc_info.status_ == CC_detail_info::Result_type::coface) { + ofs << "

        The simplex " + << simplex_format(cc_info.simplex_, true) << " is a coface of the simplex " + << simplex_format(cc_info.trigger_, true) << "!

        \n"; + } + if (cc_info.status_ == CC_detail_info::Result_type::inserted) { + ofs << "

        Successfully inserted " + << simplex_format(cc_info.simplex_, true) << "!

        \n"; + } } ofs << "

      \n"; } - } + } ofs << " \n"; } @@ -551,14 +512,12 @@ void write_visu(std::ofstream& ofs) { << "

      Visualization details debug trace

      \n"; // std::vector > vs_maps(cc_interior_summary_lists.size()); std::map vs_map; - for (const auto& sv_pair: simplex_vlist_map) - vs_map.emplace(std::make_pair(sv_pair.second, sv_pair.first)); + for (const auto& sv_pair : simplex_vlist_map) vs_map.emplace(std::make_pair(sv_pair.second, sv_pair.first)); ofs << "
        \n"; - for (const auto& vs_pair: vs_map) { + for (const auto& vs_pair : vs_map) { std::string w_simplex = vs_pair.second.substr(1); bool is_boundary = vs_pair.second[0] == 'B'; - ofs << "
      • " << vs_pair.first << ": " - << simplex_format(w_simplex, is_boundary) << "
      • \n"; + ofs << "
      • " << vs_pair.first << ": " << simplex_format(w_simplex, is_boundary) << "
      • \n"; } ofs << "
      \n"; ofs << " \n"; @@ -574,16 +533,15 @@ void write_to_html(std::string file_name) { ofs << "

      Debug traces for " << file_name << "

      \n"; write_mt(ofs); write_cc(ofs); - write_visu(ofs); + write_visu(ofs); ofs << " \n"; ofs << "\n"; ofs.close(); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif - diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h index 850736e9..4b454373 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h @@ -19,8 +19,8 @@ #include // for std::ofstream #include #include // for std::enable_if -#include // for std::get -#include // for std::make_pair +#include // for std::get +#include // for std::make_pair namespace Gudhi { @@ -30,67 +30,46 @@ using Vertex_points = Mesh_medit::Vertex_points; using Mesh_elements = Mesh_medit::Mesh_elements; using Scalar_field_range = Mesh_medit::Scalar_field_range; -template -typename std::enable_if::type -fill_meshes (Vertex_points& vertex_points, - Mesh_elements& edges, - Mesh_elements& triangles, - Mesh_elements& tetrahedra, - Scalar_field_range& triangles_scalar_range, - Scalar_field_range& tetrahedra_scalar_range, - std::size_t index, - const Meshes&... meshes) { -} - -template -typename std::enable_if::type -fill_meshes (Vertex_points& vertex_points, - Mesh_elements& edges, - Mesh_elements& triangles, - Mesh_elements& tetrahedra, - Scalar_field_range& triangles_scalar_range, - Scalar_field_range& tetrahedra_scalar_range, - std::size_t index, - const Meshes&... meshes) { +template +typename std::enable_if::type fill_meshes(Vertex_points& vertex_points, + Mesh_elements& edges, Mesh_elements& triangles, + Mesh_elements& tetrahedra, + Scalar_field_range& triangles_scalar_range, + Scalar_field_range& tetrahedra_scalar_range, + std::size_t index, const Meshes&... meshes) {} + +template +typename std::enable_if::type fill_meshes(Vertex_points& vertex_points, + Mesh_elements& edges, Mesh_elements& triangles, + Mesh_elements& tetrahedra, + Scalar_field_range& triangles_scalar_range, + Scalar_field_range& tetrahedra_scalar_range, + std::size_t index, const Meshes&... meshes) { auto mesh = std::get(std::forward_as_tuple(meshes...)); - for (const auto& v: mesh.vertex_points) - vertex_points.push_back(v); - for (const auto& e: mesh.edges) { + for (const auto& v : mesh.vertex_points) vertex_points.push_back(v); + for (const auto& e : mesh.edges) { std::vector edge; - for (const auto& v_i: e.first) - edge.push_back(v_i + index); + for (const auto& v_i : e.first) edge.push_back(v_i + index); edges.emplace_back(std::make_pair(edge, e.second)); } - for (const auto& t: mesh.triangles) { + for (const auto& t : mesh.triangles) { std::vector triangle; - for (const auto& v_i: t.first) - triangle.push_back(v_i + index); + for (const auto& v_i : t.first) triangle.push_back(v_i + index); triangles.emplace_back(std::make_pair(triangle, t.second)); } - for (const auto& t: mesh.tetrahedra) { + for (const auto& t : mesh.tetrahedra) { std::vector tetrahedron; - for (const auto& v_i: t.first) - tetrahedron.push_back(v_i + index); + for (const auto& v_i : t.first) tetrahedron.push_back(v_i + index); tetrahedra.emplace_back(std::make_pair(tetrahedron, t.second)); } - for (const auto& b: mesh.triangles_scalar_range) - triangles_scalar_range.push_back(b); - for (const auto& b: mesh.tetrahedra_scalar_range) - tetrahedra_scalar_range.push_back(b); - fill_meshes(vertex_points, - edges, - triangles, - tetrahedra, - triangles_scalar_range, - tetrahedra_scalar_range, - index + mesh.vertex_points.size(), - meshes...); + for (const auto& b : mesh.triangles_scalar_range) triangles_scalar_range.push_back(b); + for (const auto& b : mesh.tetrahedra_scalar_range) tetrahedra_scalar_range.push_back(b); + fill_meshes(vertex_points, edges, triangles, tetrahedra, triangles_scalar_range, + tetrahedra_scalar_range, index + mesh.vertex_points.size(), meshes...); } /** \brief Outputs a text file with specified meshes that can be visualized in Medit. - * + * * @param[in] amb_d Ambient dimension. Can be 2 or 3. * @param[in] file_name The name of the output file. * @param[in] meshes A pack of meshes to be specified separated by commas. @@ -100,87 +79,73 @@ void output_meshes_to_medit(std::size_t amb_d, std::string file_name, const Mesh Vertex_points vertex_points; Mesh_elements edges, triangles, tetrahedra; Scalar_field_range triangles_scalar_range, tetrahedra_scalar_range; - fill_meshes(vertex_points, - edges, - triangles, - tetrahedra, - triangles_scalar_range, - tetrahedra_scalar_range, - 0, - meshes...); - - std::ofstream ofs (file_name + ".mesh", std::ofstream::out); - std::ofstream ofs_bb (file_name + ".bb", std::ofstream::out); - + fill_meshes(vertex_points, edges, triangles, tetrahedra, triangles_scalar_range, tetrahedra_scalar_range, 0, + meshes...); + + std::ofstream ofs(file_name + ".mesh", std::ofstream::out); + std::ofstream ofs_bb(file_name + ".bb", std::ofstream::out); + if (amb_d == 2) { ofs << "MeshVersionFormatted 1\nDimension 2\n"; ofs_bb << "2 1 "; ofs << "Vertices\n" << vertex_points.size() << "\n"; - for (auto p: vertex_points) { + for (auto p : vertex_points) { ofs << p[0] << " " << p[1] << " 2\n"; } ofs << "Edges " << edges.size() << "\n"; - for (auto e: edges) { - for (auto v: e.first) - ofs << v << " "; + for (auto e : edges) { + for (auto v : e.first) ofs << v << " "; ofs << e.second << std::endl; } ofs << "Triangles " << triangles.size() << "\n"; - for (auto s: triangles) { - for (auto v: s.first) { - ofs << v << " "; + for (auto s : triangles) { + for (auto v : s.first) { + ofs << v << " "; } ofs << s.second << std::endl; } ofs_bb << triangles_scalar_range.size() << " 1\n"; - for (auto& b: triangles_scalar_range) - ofs_bb << b << "\n"; + for (auto& b : triangles_scalar_range) ofs_bb << b << "\n"; - } - else { + } else { ofs << "MeshVersionFormatted 1\nDimension 3\n"; ofs_bb << "3 1 "; ofs << "Vertices\n" << vertex_points.size() << "\n"; - for (auto p: vertex_points) { + for (auto p : vertex_points) { ofs << p[0] << " " << p[1] << " " << p[2] << " 2\n"; } ofs << "Edges " << edges.size() << "\n"; - for (auto e: edges) { - for (auto v: e.first) - ofs << v << " "; + for (auto e : edges) { + for (auto v : e.first) ofs << v << " "; ofs << e.second << std::endl; } ofs << "Triangles " << triangles.size() << "\n"; - for (auto s: triangles) { - for (auto v: s.first) { - ofs << v << " "; + for (auto s : triangles) { + for (auto v : s.first) { + ofs << v << " "; } ofs << s.second << std::endl; } ofs << "Tetrahedra " << tetrahedra.size() << "\n"; - for (auto s: tetrahedra) { - for (auto v: s.first) { - ofs << v << " "; + for (auto s : tetrahedra) { + for (auto v : s.first) { + ofs << v << " "; } ofs << s.second << std::endl; } ofs_bb << triangles_scalar_range.size() + tetrahedra_scalar_range.size() << " 1\n"; - for (auto& b: triangles_scalar_range) - ofs_bb << b << "\n"; - for (auto& b: tetrahedra_scalar_range) - ofs_bb << b << "\n"; + for (auto& b : triangles_scalar_range) ofs_bb << b << "\n"; + for (auto& b : tetrahedra_scalar_range) ofs_bb << b << "\n"; } - ofs.close(); ofs_bb.close(); - } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index 51d84274..4f44df7c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -24,169 +24,142 @@ namespace Gudhi { namespace coxeter_triangulation { - - /** \class Implicit_manifold_intersection_oracle * \brief An oracle that supports the intersection query on an implicit manifold. * - * \tparam Function_ The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * \tparam Domain_function_ The domain function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * * \ingroup coxeter_triangulation */ -template +template class Implicit_manifold_intersection_oracle { - /* Computes the affine coordinates of the intersection point of the implicit manifold * and the affine hull of the simplex. */ - template - Eigen::VectorXd compute_lambda(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + template + Eigen::VectorXd compute_lambda(const Simplex_handle& simplex, const Triangulation& triangulation) const { std::size_t cod_d = this->cod_d(); Eigen::MatrixXd matrix(cod_d + 1, cod_d + 1); - for (std::size_t i = 0; i < cod_d + 1; ++i) - matrix(0, i) = 1; + for (std::size_t i = 0; i < cod_d + 1; ++i) matrix(0, i) = 1; std::size_t j = 0; - for (auto v: simplex.vertex_range()) { + for (auto v : simplex.vertex_range()) { Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v)); - for (std::size_t i = 1; i < cod_d + 1; ++i) - matrix(i, j) = v_coords(i-1); + for (std::size_t i = 1; i < cod_d + 1; ++i) matrix(i, j) = v_coords(i - 1); j++; } Eigen::VectorXd z(cod_d + 1); z(0) = 1; - for (std::size_t i = 1; i < cod_d + 1; ++i) - z(i) = 0; + for (std::size_t i = 1; i < cod_d + 1; ++i) z(i) = 0; Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z); return lambda; } /* Computes the affine coordinates of the intersection point of the boundary * of the implicit manifold and the affine hull of the simplex. */ - template - Eigen::VectorXd compute_boundary_lambda(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + template + Eigen::VectorXd compute_boundary_lambda(const Simplex_handle& simplex, const Triangulation& triangulation) const { std::size_t cod_d = this->cod_d(); Eigen::MatrixXd matrix(cod_d + 2, cod_d + 2); - for (std::size_t i = 0; i < cod_d + 2; ++i) - matrix(0, i) = 1; + for (std::size_t i = 0; i < cod_d + 2; ++i) matrix(0, i) = 1; std::size_t j = 0; - for (auto v: simplex.vertex_range()) { + for (auto v : simplex.vertex_range()) { Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v)); - for (std::size_t i = 1; i < cod_d + 1; ++i) - matrix(i, j) = v_coords(i-1); + for (std::size_t i = 1; i < cod_d + 1; ++i) matrix(i, j) = v_coords(i - 1); Eigen::VectorXd bv_coords = domain_fun_(triangulation.cartesian_coordinates(v)); matrix(cod_d + 1, j) = bv_coords(0); j++; } Eigen::VectorXd z(cod_d + 2); z(0) = 1; - for (std::size_t i = 1; i < cod_d + 2; ++i) - z(i) = 0; + for (std::size_t i = 1; i < cod_d + 2; ++i) z(i) = 0; Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z); return lambda; } /* Computes the intersection result for a given simplex in a triangulation. */ - template - Query_result intersection_result(const Eigen::VectorXd& lambda, - const Simplex_handle& simplex, + template + Query_result intersection_result(const Eigen::VectorXd& lambda, const Simplex_handle& simplex, const Triangulation& triangulation) const { using QR = Query_result; std::size_t amb_d = triangulation.dimension(); std::size_t cod_d = simplex.dimension(); for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) - if (lambda(i) < 0 || lambda(i) > 1) - return QR({Eigen::VectorXd(), false}); + if (lambda(i) < 0 || lambda(i) > 1) return QR({Eigen::VectorXd(), false}); Eigen::MatrixXd vertex_matrix(cod_d + 1, amb_d); auto v_range = simplex.vertex_range(); auto v_it = v_range.begin(); for (std::size_t i = 0; i < cod_d + 1 && v_it != v_range.end(); ++v_it, ++i) { Eigen::VectorXd v_coords = triangulation.cartesian_coordinates(*v_it); - for (std::size_t j = 0; j < amb_d; ++j) - vertex_matrix(i, j) = v_coords(j); + for (std::size_t j = 0; j < amb_d; ++j) vertex_matrix(i, j) = v_coords(j); } - Eigen::VectorXd intersection = lambda.transpose()*vertex_matrix; + Eigen::VectorXd intersection = lambda.transpose() * vertex_matrix; return QR({intersection, true}); } - -public: + public: /** \brief Ambient dimension of the implicit manifold. */ - std::size_t amb_d() const { - return fun_.amb_d(); - } - + std::size_t amb_d() const { return fun_.amb_d(); } + /** \brief Codimension of the implicit manifold. */ - std::size_t cod_d() const { - return fun_.cod_d(); - } + std::size_t cod_d() const { return fun_.cod_d(); } /** \brief Intersection query with the relative interior of the manifold. - * + * * \details The returned structure Query_result contains the boolean value * that is true only if the intersection point of the query simplex and * the relative interior of the manifold exists, the intersection point - * and the face of the query simplex that contains + * and the face of the query simplex that contains * the intersection point. - * + * * \tparam Simplex_handle The class of the query simplex. * Needs to be a model of the concept SimplexInCoxeterTriangulation. * \tparam Triangulation The class of the triangulation. * Needs to be a model of the concept TriangulationForManifoldTracing. * * @param[in] simplex The query simplex. The dimension of the simplex - * should be the same as the codimension of the manifold + * should be the same as the codimension of the manifold * (the codomain dimension of the function). - * @param[in] triangulation The ambient triangulation. The dimension of - * the triangulation should be the same as the ambient dimension of the manifold + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold * (the domain dimension of the function). */ - template - Query_result intersects(const Simplex_handle& simplex, - const Triangulation& triangulation) const { + template + Query_result intersects(const Simplex_handle& simplex, const Triangulation& triangulation) const { Eigen::VectorXd lambda = compute_lambda(simplex, triangulation); return intersection_result(lambda, simplex, triangulation); } /** \brief Intersection query with the boundary of the manifold. - * + * * \details The returned structure Query_result contains the boolean value * that is true only if the intersection point of the query simplex and * the boundary of the manifold exists, the intersection point - * and the face of the query simplex that contains + * and the face of the query simplex that contains * the intersection point. - * + * * \tparam Simplex_handle The class of the query simplex. * Needs to be a model of the concept SimplexInCoxeterTriangulation. * \tparam Triangulation The class of the triangulation. * Needs to be a model of the concept TriangulationForManifoldTracing. * * @param[in] simplex The query simplex. The dimension of the simplex - * should be the same as the codimension of the boundary of the manifold + * should be the same as the codimension of the boundary of the manifold * (the codomain dimension of the function + 1). - * @param[in] triangulation The ambient triangulation. The dimension of - * the triangulation should be the same as the ambient dimension of the manifold + * @param[in] triangulation The ambient triangulation. The dimension of + * the triangulation should be the same as the ambient dimension of the manifold * (the domain dimension of the function). */ - template + template Query_result intersects_boundary(const Simplex_handle& simplex, const Triangulation& triangulation) const { Eigen::VectorXd lambda = compute_boundary_lambda(simplex, triangulation); return intersection_result(lambda, simplex, triangulation); } - /** \brief Returns true if the input point lies inside the piecewise-linear * domain induced by the given ambient triangulation that defines the relative * interior of the piecewise-linear approximation of the manifold. @@ -194,22 +167,19 @@ public: * @param p The input point. Needs to have the same dimension as the ambient * dimension of the manifold (the domain dimension of the function). * @param triangulation The ambient triangulation. Needs to have the same - * dimension as the ambient dimension of the manifold + * dimension as the ambient dimension of the manifold * (the domain dimension of the function). */ template - bool lies_in_domain(const Eigen::VectorXd& p, - const Triangulation& triangulation) const { + bool lies_in_domain(const Eigen::VectorXd& p, const Triangulation& triangulation) const { Eigen::VectorXd pl_p = make_pl_approximation(domain_fun_, triangulation)(p); return pl_p(0) < 0; } /** \brief Returns the function that defines the interior of the manifold */ - const Function_& function() const { - return fun_; - } - - /** \brief Constructs an intersection oracle for an implicit manifold potentially + const Function_& function() const { return fun_; } + + /** \brief Constructs an intersection oracle for an implicit manifold potentially * with boundary from given function and domain. * * @param function The input function that represents the implicit manifold @@ -217,24 +187,22 @@ public: * @param domain_function The input domain function that can be used to define an implicit * manifold with boundary. */ - Implicit_manifold_intersection_oracle(const Function_& function, - const Domain_function_& domain_function) - : fun_(function), domain_fun_(domain_function) {} + Implicit_manifold_intersection_oracle(const Function_& function, const Domain_function_& domain_function) + : fun_(function), domain_fun_(domain_function) {} - /** \brief Constructs an intersection oracle for an implicit manifold + /** \brief Constructs an intersection oracle for an implicit manifold * without boundary from a given function. * - * \details To use this constructor, the template Domain_function_ needs to be left + * \details To use this constructor, the template Domain_function_ needs to be left * at its default value (Gudhi::coxeter_triangulation::Constant_function). * * @param function The input function that represents the implicit manifold * without boundary. */ Implicit_manifold_intersection_oracle(const Function_& function) - : fun_(function), - domain_fun_(function.amb_d(), 1, Eigen::VectorXd::Constant(1,-1)) {} - -private: + : fun_(function), domain_fun_(function.amb_d(), 1, Eigen::VectorXd::Constant(1, -1)) {} + + private: Function_ fun_; Domain_function_ domain_fun_; }; @@ -248,16 +216,12 @@ private: * * \ingroup coxeter_triangulation */ -template -Implicit_manifold_intersection_oracle -make_oracle(const Function_& function, - const Domain_function_& domain_function){ - return Implicit_manifold_intersection_oracle(function, - domain_function); +template +Implicit_manifold_intersection_oracle make_oracle( + const Function_& function, const Domain_function_& domain_function) { + return Implicit_manifold_intersection_oracle(function, domain_function); } - /** \brief Static constructor of an intersection oracle from a function without a domain. * * @param function The input function that represents the implicit manifold @@ -265,13 +229,13 @@ make_oracle(const Function_& function, * * \ingroup coxeter_triangulation */ -template -Implicit_manifold_intersection_oracle make_oracle(const Function_& function){ +template +Implicit_manifold_intersection_oracle make_oracle(const Function_& function) { return Implicit_manifold_intersection_oracle(function); } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index 25b664eb..b678566a 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -28,7 +28,7 @@ namespace coxeter_triangulation { * \ingroup coxeter_triangulation */ -/** \class Manifold_tracing +/** \class Manifold_tracing * \brief A class that assembles methods for manifold tracing algorithm. * * \tparam Triangulation_ The type of the ambient triangulation. @@ -36,9 +36,8 @@ namespace coxeter_triangulation { */ template class Manifold_tracing { - typedef typename Triangulation_::Simplex_handle Simplex_handle; - + struct Simplex_hash { typedef Simplex_handle argument_type; typedef std::size_t result_type; @@ -46,8 +45,8 @@ class Manifold_tracing { return boost::hash()(s.vertex()); } }; - -public: + + public: /** \brief Type of the output simplex map with keys of type Triangulation_::Simplex_handle * and values of type Eigen::VectorXd. * This type should be used for the output in the method manifold_tracing_algorithm. @@ -58,38 +57,34 @@ public: * \brief Computes the set of k-simplices that intersect * a boundaryless implicit manifold given by an intersection oracle, where k * is the codimension of the manifold. - * The computation is based on the seed propagation --- it starts at the + * The computation is based on the seed propagation --- it starts at the * given seed points and then propagates along the manifold. * * \tparam Point_range Range of points of type Eigen::VectorXd. * \tparam Intersection_oracle Intersection oracle that represents the manifold. * Needs to be a model of the concept IntersectionOracle. * - * \param[in] seed_points The range of points on the manifold from which + * \param[in] seed_points The range of points on the manifold from which * the computation begins. * \param[in] triangulation The ambient triangulation. * \param[in] oracle The intersection oracle for the manifold. * The ambient dimension needs to match the dimension of the * triangulation. * \param[out] out_simplex_map The output map, where the keys are k-simplices in - * the input triangulation that intersect the input manifold and the mapped values + * the input triangulation that intersect the input manifold and the mapped values * are the intersection points. */ - template - void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation_& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& out_simplex_map) { + template + void manifold_tracing_algorithm(const Point_range& seed_points, const Triangulation_& triangulation, + const Intersection_oracle& oracle, Out_simplex_map& out_simplex_map) { std::size_t cod_d = oracle.cod_d(); std::queue queue; - for (const auto& p: seed_points) { + for (const auto& p : seed_points) { Simplex_handle full_simplex = triangulation.locate_point(p); - for (Simplex_handle face: full_simplex.face_range(cod_d)) { + for (Simplex_handle face : full_simplex.face_range(cod_d)) { Query_result qr = oracle.intersects(face, triangulation); - if (qr.success && - out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { + if (qr.success && out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { #ifdef GUDHI_COX_OUTPUT_TO_HTML mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); #endif @@ -98,17 +93,14 @@ public: } } } - while (!queue.empty()) { Simplex_handle s = queue.front(); queue.pop(); - for (auto cof: s.coface_range(cod_d+1)) { - for (auto face: cof.face_range(cod_d)) { + for (auto cof : s.coface_range(cod_d + 1)) { + for (auto face : cof.face_range(cod_d)) { Query_result qr = oracle.intersects(face, triangulation); - if (qr.success && - out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) - queue.emplace(face); + if (qr.success && out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) queue.emplace(face); } } } @@ -118,85 +110,76 @@ public: * \brief Computes the set of k-simplices that intersect * the dimensional manifold given by an intersection oracle, where k * is the codimension of the manifold. - * The computation is based on the seed propagation --- it starts at the + * The computation is based on the seed propagation --- it starts at the * given seed points and then propagates along the manifold. * * \tparam Point_range Range of points of type Eigen::VectorXd. * \tparam Intersection_oracle Intersection oracle that represents the manifold. * Needs to be a model of the concept IntersectionOracle. * - * \param[in] seed_points The range of points on the manifold from which + * \param[in] seed_points The range of points on the manifold from which * the computation begins. * \param[in] triangulation The ambient triangulation. * \param[in] oracle The intersection oracle for the manifold. * The ambient dimension needs to match the dimension of the * triangulation. * \param[out] interior_simplex_map The output map, where the keys are k-simplices in - * the input triangulation that intersect the relative interior of the input manifold + * the input triangulation that intersect the relative interior of the input manifold * and the mapped values are the intersection points. * \param[out] boundary_simplex_map The output map, where the keys are k-simplices in - * the input triangulation that intersect the boundary of the input manifold + * the input triangulation that intersect the boundary of the input manifold * and the mapped values are the intersection points. */ - template - void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation_& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& interior_simplex_map, + template + void manifold_tracing_algorithm(const Point_range& seed_points, const Triangulation_& triangulation, + const Intersection_oracle& oracle, Out_simplex_map& interior_simplex_map, Out_simplex_map& boundary_simplex_map) { std::size_t cod_d = oracle.cod_d(); std::queue queue; - for (const auto& p: seed_points) { + for (const auto& p : seed_points) { Simplex_handle full_simplex = triangulation.locate_point(p); - for (Simplex_handle face: full_simplex.face_range(cod_d)) { + for (Simplex_handle face : full_simplex.face_range(cod_d)) { auto qr = oracle.intersects(face, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); -#endif +#endif if (qr.success) { if (oracle.lies_in_domain(qr.intersection, triangulation)) { - if (interior_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) - queue.emplace(face); - } - else { - for (Simplex_handle cof: face.coface_range(cod_d+1)) { + if (interior_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) queue.emplace(face); + } else { + for (Simplex_handle cof : face.coface_range(cod_d + 1)) { auto qrb = oracle.intersects_boundary(cof, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML mt_seed_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); -#endif - if (qrb.success) - boundary_simplex_map.emplace(cof, qrb.intersection); +#endif + if (qrb.success) boundary_simplex_map.emplace(cof, qrb.intersection); } } // break; } } } - + while (!queue.empty()) { Simplex_handle s = queue.front(); queue.pop(); - for (auto cof: s.coface_range(cod_d+1)) { - for (auto face: cof.face_range(cod_d)) { + for (auto cof : s.coface_range(cod_d + 1)) { + for (auto face : cof.face_range(cod_d)) { auto qr = oracle.intersects(face, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML mt_inserted_list.push_back(MT_inserted_info(qr, face, false)); -#endif +#endif if (qr.success) { if (oracle.lies_in_domain(qr.intersection, triangulation)) { - if (interior_simplex_map.emplace(face, qr.intersection).second) - queue.emplace(face); - } - else { + if (interior_simplex_map.emplace(face, qr.intersection).second) queue.emplace(face); + } else { auto qrb = oracle.intersects_boundary(cof, triangulation); #ifdef GUDHI_COX_OUTPUT_TO_HTML mt_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); -#endif +#endif // assert (qrb.success); // always a success - if (qrb.success) - boundary_simplex_map.emplace(cof, qrb.intersection); + if (qrb.success) boundary_simplex_map.emplace(cof, qrb.intersection); } } } @@ -206,7 +189,6 @@ public: /** \brief Empty constructor */ Manifold_tracing() {} - }; /** @@ -214,7 +196,7 @@ public: * that computes the set of k-simplices that intersect * a boundaryless implicit manifold given by an intersection oracle, where k * is the codimension of the manifold. - * The computation is based on the seed propagation --- it starts at the + * The computation is based on the seed propagation --- it starts at the * given seed points and then propagates along the manifold. * * \tparam Point_range Range of points of type Eigen::VectorXd. @@ -224,38 +206,30 @@ public: * Needs to be a model of the concept IntersectionOracle. * \tparam Out_simplex_map Needs to be Manifold_tracing::Out_simplex_map. * - * \param[in] seed_points The range of points on the manifold from which + * \param[in] seed_points The range of points on the manifold from which * the computation begins. * \param[in] triangulation The ambient triangulation. * \param[in] oracle The intersection oracle for the manifold. * The ambient dimension needs to match the dimension of the * triangulation. * \param[out] out_simplex_map The output map, where the keys are k-simplices in - * the input triangulation that intersect the input manifold and the mapped values + * the input triangulation that intersect the input manifold and the mapped values * are the intersection points. * * \ingroup coxeter_triangulation */ -template -void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& out_simplex_map) { +template +void manifold_tracing_algorithm(const Point_range& seed_points, const Triangulation& triangulation, + const Intersection_oracle& oracle, Out_simplex_map& out_simplex_map) { Manifold_tracing mt; - mt.manifold_tracing_algorithm(seed_points, - triangulation, - oracle, - out_simplex_map); + mt.manifold_tracing_algorithm(seed_points, triangulation, oracle, out_simplex_map); } /** * \brief Static method for Manifold_tracing::manifold_tracing_algorithm * the dimensional manifold given by an intersection oracle, where k * is the codimension of the manifold. - * The computation is based on the seed propagation --- it starts at the + * The computation is based on the seed propagation --- it starts at the * given seed points and then propagates along the manifold. * * \tparam Point_range Range of points of type Eigen::VectorXd. @@ -265,41 +239,31 @@ void manifold_tracing_algorithm(const Point_range& seed_points, * Needs to be a model of the concept IntersectionOracle. * \tparam Out_simplex_map Needs to be Manifold_tracing::Out_simplex_map. * - * \param[in] seed_points The range of points on the manifold from which + * \param[in] seed_points The range of points on the manifold from which * the computation begins. * \param[in] triangulation The ambient triangulation. * \param[in] oracle The intersection oracle for the manifold. * The ambient dimension needs to match the dimension of the * triangulation. * \param[out] interior_simplex_map The output map, where the keys are k-simplices in - * the input triangulation that intersect the relative interior of the input manifold + * the input triangulation that intersect the relative interior of the input manifold * and the mapped values are the intersection points. * \param[out] boundary_simplex_map The output map, where the keys are k-simplices in - * the input triangulation that intersect the boundary of the input manifold + * the input triangulation that intersect the boundary of the input manifold * and the mapped values are the intersection points. * * \ingroup coxeter_triangulation */ -template -void manifold_tracing_algorithm(const Point_range& seed_points, - const Triangulation& triangulation, - const Intersection_oracle& oracle, - Out_simplex_map& interior_simplex_map, +template +void manifold_tracing_algorithm(const Point_range& seed_points, const Triangulation& triangulation, + const Intersection_oracle& oracle, Out_simplex_map& interior_simplex_map, Out_simplex_map& boundary_simplex_map) { Manifold_tracing mt; - mt.manifold_tracing_algorithm(seed_points, - triangulation, - oracle, - interior_simplex_map, - boundary_simplex_map); + mt.manifold_tracing_algorithm(seed_points, triangulation, oracle, interior_simplex_map, boundary_simplex_map); } +} // namespace coxeter_triangulation -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h index b1f57b08..76438c91 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation.h @@ -19,7 +19,7 @@ namespace Gudhi { namespace coxeter_triangulation { -/** +/** * \class Permutahedral_representation * \brief A class that stores the permutahedral representation of a simplex * in a Coxeter triangulation or a Freudenthal-Kuhn triangulation. @@ -32,93 +32,72 @@ namespace coxeter_triangulation { * * \tparam Vertex_ needs to be a random-access range. * \tparam Ordered_set_partition_ needs to be a a random-access range that consists of - * random-access ranges. + * random-access ranges. */ -template +template class Permutahedral_representation { - typedef Permutahedral_representation Self; -public: + public: /** \brief Type of the vertex. */ typedef Vertex_ Vertex; - + /** \brief Type of the ordered partition. */ typedef Ordered_set_partition_ OrderedSetPartition; - /** \brief Permutahedral_representation constructor from a vertex and an ordered set partition. * * @param[in] vertex Vertex. * @param[in] partition Ordered set partition. - * + * * \details If the size of vertex is d, the ranges in partition must consist * of the integers 0,...,d without repetition or collision between the ranges. */ Permutahedral_representation(const Vertex& vertex, const OrderedSetPartition& partition) - : vertex_(vertex), partition_(partition) {} + : vertex_(vertex), partition_(partition) {} /** \brief Constructor for an empty permutahedral representation that does not correspond * to any simplex. */ Permutahedral_representation() {} - + /** \brief Dimension of the simplex. */ - std::size_t dimension() const { - return partition_.size() - 1; - } + std::size_t dimension() const { return partition_.size() - 1; } /** \brief Lexicographically-minimal vertex. */ - Vertex& vertex() { - return vertex_; - } + Vertex& vertex() { return vertex_; } /** \brief Lexicographically-minimal vertex. */ - const Vertex& vertex() const { - return vertex_; - } + const Vertex& vertex() const { return vertex_; } /** \brief Ordered set partition. */ - OrderedSetPartition& partition() { - return partition_; - } + OrderedSetPartition& partition() { return partition_; } /** \brief Identifying vertex. */ - const OrderedSetPartition& partition() const { - return partition_; - } + const OrderedSetPartition& partition() const { return partition_; } /** \brief Equality operator. * Returns true if an only if both vertex and the ordered set partition coincide. */ bool operator==(const Permutahedral_representation& other) const { - if (dimension() != other.dimension()) - return false; - if (vertex_ != other.vertex_) - return false; + if (dimension() != other.dimension()) return false; + if (vertex_ != other.vertex_) return false; for (std::size_t k = 0; k < partition_.size(); ++k) - if (partition_[k] != other.partition_[k]) - return false; + if (partition_[k] != other.partition_[k]) return false; return true; } /** \brief Inequality operator. * Returns true if an only if either vertex or the ordered set partition are different. */ - bool operator!=(const Permutahedral_representation& other) const { - return !(*this == other); - } + bool operator!=(const Permutahedral_representation& other) const { return !(*this == other); } typedef Gudhi::coxeter_triangulation::Vertex_iterator Vertex_iterator; typedef boost::iterator_range Vertex_range; /** \brief Returns a range of vertices of the simplex. * The type of vertices is Vertex. */ - Vertex_range vertex_range() const { - return Vertex_range(Vertex_iterator(*this), - Vertex_iterator()); - } + Vertex_range vertex_range() const { return Vertex_range(Vertex_iterator(*this), Vertex_iterator()); } typedef Gudhi::coxeter_triangulation::Face_iterator Face_iterator; typedef boost::iterator_range Face_range; @@ -126,34 +105,29 @@ public: * @param[in] value_dim The dimension of the faces. Must be between 0 and the dimension of the simplex. */ Face_range face_range(std::size_t value_dim) const { - return Face_range(Face_iterator(*this, value_dim), - Face_iterator()); + return Face_range(Face_iterator(*this, value_dim), Face_iterator()); } /** \brief Returns a range of permutahedral representations of facets of the simplex. * The dimension of the simplex must be strictly positive. */ - Face_range facet_range() const { - return Face_range(Face_iterator(*this, dimension()-1), - Face_iterator()); - } - + Face_range facet_range() const { return Face_range(Face_iterator(*this, dimension() - 1), Face_iterator()); } + typedef Gudhi::coxeter_triangulation::Coface_iterator Coface_iterator; typedef boost::iterator_range Coface_range; /** \brief Returns a range of permutahedral representations of cofaces of the simplex. - * @param[in] value_dim The dimension of the cofaces. Must be between the dimension of the simplex and the ambient dimension (the size of the vertex). + * @param[in] value_dim The dimension of the cofaces. Must be between the dimension of the simplex and the ambient + * dimension (the size of the vertex). */ Coface_range coface_range(std::size_t value_dim) const { - return Coface_range(Coface_iterator(*this, value_dim), - Coface_iterator()); + return Coface_range(Coface_iterator(*this, value_dim), Coface_iterator()); } /** \brief Returns a range of permutahedral representations of cofacets of the simplex. * The dimension of the simplex must be strictly different from the ambient dimension (the size of the vertex). */ Coface_range cofacet_range() const { - return Coface_range(Coface_iterator(*this, dimension()+1), - Coface_iterator()); + return Coface_range(Coface_iterator(*this, dimension() + 1), Coface_iterator()); } /** \brief Returns true, if the simplex is a face of other simplex. @@ -162,38 +136,31 @@ public: */ bool is_face_of(const Permutahedral_representation& other) const { using Part = typename OrderedSetPartition::value_type; - - if (other.dimension() < dimension()) - return false; + + if (other.dimension() < dimension()) return false; if (other.vertex_.size() != vertex_.size()) std::cerr << "Error: Permutahedral_representation::is_face_of: incompatible ambient dimensions.\n"; - + Vertex v_self = vertex_, v_other = other.vertex_; auto self_partition_it = partition_.begin(); auto other_partition_it = other.partition_.begin(); while (self_partition_it != partition_.end()) { while (other_partition_it != other.partition_.end() && v_self != v_other) { const Part& other_part = *other_partition_it++; - if (other_partition_it == other.partition_.end()) - return false; - for (const auto& k: other_part) - v_other[k]++; + if (other_partition_it == other.partition_.end()) return false; + for (const auto& k : other_part) v_other[k]++; } - if (other_partition_it == other.partition_.end()) - return false; + if (other_partition_it == other.partition_.end()) return false; const Part& self_part = *self_partition_it++; - if (self_partition_it == partition_.end()) - return true; - for (const auto& k: self_part) - v_self[k]++; + if (self_partition_it == partition_.end()) return true; + for (const auto& k : self_part) v_self[k]++; } return true; } -private: + private: Vertex vertex_; OrderedSetPartition partition_; - }; /** \brief Print a permutahedral representation to a stream. @@ -202,10 +169,8 @@ private: * @param[in] os The output stream. * @param[in] simplex A simplex represented by its permutahedral representation. */ -template -std::ostream& operator<<(std::ostream& os, - const Permutahedral_representation& simplex) { +template +std::ostream& operator<<(std::ostream& os, const Permutahedral_representation& simplex) { // vertex part os << "("; if (simplex.vertex().empty()) { @@ -214,24 +179,21 @@ std::ostream& operator<<(std::ostream& os, } auto v_it = simplex.vertex().begin(); os << *v_it++; - for (; v_it != simplex.vertex().end(); ++v_it) - os << ", " << *v_it; + for (; v_it != simplex.vertex().end(); ++v_it) os << ", " << *v_it; os << ")"; - + // ordered partition part using Part = typename OrderedSetPartition::value_type; - auto print_part = - [&os](const Part& p) { - os << "{"; - if (p.empty()) { - os << "}"; - } - auto p_it = p.begin(); - os << *p_it++; - for (; p_it != p.end(); ++p_it) - os << ", " << *p_it; + auto print_part = [&os](const Part& p) { + os << "{"; + if (p.empty()) { os << "}"; - }; + } + auto p_it = p.begin(); + os << *p_it++; + for (; p_it != p.end(); ++p_it) os << ", " << *p_it; + os << "}"; + }; os << " ["; if (simplex.partition().empty()) { os << "]"; @@ -247,8 +209,8 @@ std::ostream& operator<<(std::ostream& os, return os; } -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi -#endif // PERMUTAHEDRAL_REPRESENTATION_H_ +#endif // PERMUTAHEDRAL_REPRESENTATION_H_ diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h index ce6a34ec..5f382e31 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Combination_iterator.h @@ -20,25 +20,20 @@ namespace coxeter_triangulation { typedef unsigned uint; -/** \brief Class that allows the user to generate combinations of +/** \brief Class that allows the user to generate combinations of * k elements in a set of n elements. * Based on the algorithm by Mifsud. -*/ -class Combination_iterator : public boost::iterator_facade< Combination_iterator, - std::vector const, - boost::forward_traversal_tag> { + */ +class Combination_iterator + : public boost::iterator_facade const, boost::forward_traversal_tag> { typedef std::vector value_t; - -protected: + + protected: friend class boost::iterator_core_access; - - bool equal(Combination_iterator const& other) const { - return (is_end_ && other.is_end_); - } - value_t const& dereference() const { - return value_; - } + bool equal(Combination_iterator const& other) const { return (is_end_ && other.is_end_); } + + value_t const& dereference() const { return value_; } void increment() { if (value_[0] == n_ - k_) { @@ -51,25 +46,16 @@ protected: return; } for (; j > 0; --j) - if (value_[j-1] < n_ - k_ + j-1) { - value_[j-1]++; - for (uint s = j; s < k_; s++) - value_[s] = value_[j-1] + s - (j-1); - return; + if (value_[j - 1] < n_ - k_ + j - 1) { + value_[j - 1]++; + for (uint s = j; s < k_; s++) value_[s] = value_[j - 1] + s - (j - 1); + return; } } -public: - - Combination_iterator(const uint& n, const uint& k) - : - value_(k), - is_end_(n == 0), - n_(n), - k_(k) - { - for (uint i = 0; i < k; ++i) - value_[i] = i; + public: + Combination_iterator(const uint& n, const uint& k) : value_(k), is_end_(n == 0), n_(n), k_(k) { + for (uint i = 0; i < k; ++i) value_[i] = i; } // Used for the creating an end iterator @@ -78,22 +64,20 @@ public: void reinitialize() { if (n_ > 0) { is_end_ = false; - for (uint i = 0; i < n_; ++i) - value_[i] = i; + for (uint i = 0; i < n_; ++i) value_[i] = i; } } - + private: - value_t value_; // the dereference value - bool is_end_; // is true when the current permutation is the final one + value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one uint n_; uint k_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h index c4e86a36..3ee73754 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Integer_combination_iterator.h @@ -20,37 +20,32 @@ namespace coxeter_triangulation { typedef unsigned uint; -/** \brief Class that allows the user to generate combinations of +/** \brief Class that allows the user to generate combinations of * k elements in a set of n elements. * Based on the algorithm by Mifsud. -*/ -class Integer_combination_iterator : public boost::iterator_facade< Integer_combination_iterator, - std::vector const, - boost::forward_traversal_tag> { + */ +class Integer_combination_iterator + : public boost::iterator_facade const, + boost::forward_traversal_tag> { using value_t = std::vector; - + private: friend class boost::iterator_core_access; - - bool equal(Integer_combination_iterator const& other) const { - return (is_end_ && other.is_end_); - } - value_t const& dereference() const { - return value_; - } + bool equal(Integer_combination_iterator const& other) const { return (is_end_ && other.is_end_); } + + value_t const& dereference() const { return value_; } void increment() { uint j1 = 0; uint s = 0; - while (value_[j1] == 0 && j1 < k_) - j1++; - uint j2 = j1+1; + while (value_[j1] == 0 && j1 < k_) j1++; + uint j2 = j1 + 1; while (value_[j2] == bounds_[j2]) { if (bounds_[j2] != 0) { - s += value_[j1]; - value_[j1] = 0; - j1 = j2; + s += value_[j1]; + value_[j1] = 0; + j1 = j2; } j2++; } @@ -70,20 +65,15 @@ class Integer_combination_iterator : public boost::iterator_facade< Integer_comb value_[i++] = s; } -public: + public: template Integer_combination_iterator(const uint& n, const uint& k, const Bound_range& bounds) - : - value_(k+2), - is_end_(n == 0 || k == 0), - n_(n), - k_(k) - { - bounds_.reserve(k+2); + : value_(k + 2), is_end_(n == 0 || k == 0), n_(n), k_(k) { + bounds_.reserve(k + 2); uint sum_radices = 0; - for (auto b: bounds) { + for (auto b : bounds) { bounds_.push_back(b); - sum_radices += b; + sum_radices += b; } bounds_.push_back(2); bounds_.push_back(1); @@ -100,26 +90,25 @@ public: } value_[i++] = s; - while (i < k_) - value_[i++] = 0; + while (i < k_) value_[i++] = 0; value_[k] = 1; - value_[k+1] = 0; + value_[k + 1] = 0; } // Used for the creating an end iterator Integer_combination_iterator() : is_end_(true), n_(0), k_(0) {} private: - value_t value_; // the dereference value - bool is_end_; // is true when the current integer combination is the final one + value_t value_; // the dereference value + bool is_end_; // is true when the current integer combination is the final one uint n_; uint k_; std::vector bounds_; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h index d6f9f121..866079fa 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Ordered_set_partition_iterator.h @@ -35,52 +35,40 @@ struct Ordered_set_partition { // Ordered_set_partition(const Set_partition_iterator& s_it, const Permutation_iterator& p_it) // : s_it_(s_it), p_it_(p_it) {} - - const std::vector operator[](const uint& i) const { - return (*s_it_)[(*p_it_)[i]]; - } - - std::size_t size() const { - return s_it_->size(); - } - + + const std::vector operator[](const uint& i) const { return (*s_it_)[(*p_it_)[i]]; } + + std::size_t size() const { return s_it_->size(); } }; /** \brief Class that allows the user to generate set partitions of a set {0,...,n-1} in k parts. - * -*/ -class Ordered_set_partition_iterator : public boost::iterator_facade< Ordered_set_partition_iterator, - Ordered_set_partition const, - boost::forward_traversal_tag> { + * + */ +class Ordered_set_partition_iterator + : public boost::iterator_facade { using value_t = Ordered_set_partition; - + private: friend class boost::iterator_core_access; - bool equal(Ordered_set_partition_iterator const& other) const { - return (is_end_ && other.is_end_); - } + bool equal(Ordered_set_partition_iterator const& other) const { return (is_end_ && other.is_end_); } - value_t const& dereference() const { - return value_; - } + value_t const& dereference() const { return value_; } void increment() { if (++value_.p_it_ == p_end_) { if (++value_.s_it_ == s_end_) { is_end_ = true; return; - } - else + } else value_.p_it_.reinitialize(); } } - + public: Ordered_set_partition_iterator(const uint& n, const uint& k) - : - value_({Set_partition_iterator(n,k), Permutation_iterator(k)}), - is_end_(n == 0) {} + : value_({Set_partition_iterator(n, k), Permutation_iterator(k)}), is_end_(n == 0) {} // Used for the creating an end iterator Ordered_set_partition_iterator() : is_end_(true) {} @@ -90,16 +78,16 @@ class Ordered_set_partition_iterator : public boost::iterator_facade< Ordered_se value_.p_it_.reinitialize(); value_.s_it_.reinitialize(); } - + private: - Set_partition_iterator s_end_; // Set partition iterator and the corresponding end iterator - Permutation_iterator p_end_; // Permutation iterator and the corresponding end iterator - value_t value_; // the dereference value - bool is_end_; // is true when the current permutation is the final one + Set_partition_iterator s_end_; // Set partition iterator and the corresponding end iterator + Permutation_iterator p_end_; // Permutation iterator and the corresponding end iterator + value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h index d42e892a..9263c67e 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h @@ -36,9 +36,9 @@ namespace coxeter_triangulation { * * Forward iterator, 'value_type' is Permutahedral_representation::Vertex.*/ template -class Vertex_iterator : public boost::iterator_facade< Vertex_iterator, - typename Permutahedral_representation::Vertex const, - boost::forward_traversal_tag> { +class Vertex_iterator + : public boost::iterator_facade, + typename Permutahedral_representation::Vertex const, boost::forward_traversal_tag> { private: friend class boost::iterator_core_access; @@ -47,50 +47,40 @@ class Vertex_iterator : public boost::iterator_facade< Vertex_iterator -class Face_iterator : public boost::iterator_facade< Face_iterator, - Permutahedral_representation const, - boost::forward_traversal_tag> { +class Face_iterator : public boost::iterator_facade, + Permutahedral_representation const, boost::forward_traversal_tag> { using value_t = Permutahedral_representation; - + private: friend class boost::iterator_core_access; using Vertex = typename Permutahedral_representation::Vertex; using Ordered_partition = typename Permutahedral_representation::OrderedSetPartition; - bool equal(Face_iterator const& other) const { - return (is_end_ && other.is_end_); - } + bool equal(Face_iterator const& other) const { return (is_end_ && other.is_end_); } - value_t const& dereference() const { - return value_; - } + value_t const& dereference() const { return value_; } void increment() { if (++c_it_ == c_end_) { @@ -130,31 +115,30 @@ class Face_iterator : public boost::iterator_facade< Face_iterator(simplex_, *c_it_); } -public: + public: Face_iterator(const Permutahedral_representation& simplex, const uint& k) - : simplex_(simplex), - k_(k), - l_(simplex.dimension()), - c_it_(l_+1, k_+1), - is_end_(k_ > l_), - value_({Vertex(simplex.vertex().size()), Ordered_partition(k+1)}) - { + : simplex_(simplex), + k_(k), + l_(simplex.dimension()), + c_it_(l_ + 1, k_ + 1), + is_end_(k_ > l_), + value_({Vertex(simplex.vertex().size()), Ordered_partition(k + 1)}) { update_value(); } // Used for the creating an end iterator Face_iterator() : is_end_(true) {} - + private: - Permutahedral_representation simplex_; // Input simplex + Permutahedral_representation simplex_; // Input simplex uint k_; - uint l_; // Dimension of the input simplex - Combination_iterator c_it_, c_end_; // indicates the vertices in the current face + uint l_; // Dimension of the input simplex + Combination_iterator c_it_, c_end_; // indicates the vertices in the current face - bool is_end_; // is true when the current permutation is the final one - value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one + value_t value_; // the dereference value -}; // Face_iterator +}; // Face_iterator /*---------------------------------------------------------------------------*/ /* \brief Iterator over the k-cofaces of a simplex @@ -162,9 +146,9 @@ public: * * Forward iterator, value_type is Permutahedral_representation. */ template -class Coface_iterator : public boost::iterator_facade< Coface_iterator, - Permutahedral_representation const, - boost::forward_traversal_tag> { +class Coface_iterator + : public boost::iterator_facade, Permutahedral_representation const, + boost::forward_traversal_tag> { using value_t = Permutahedral_representation; private: @@ -173,75 +157,62 @@ class Coface_iterator : public boost::iterator_facade< Coface_iterator(simplex.partition())), - is_end_(k_ > l_), - value_({Vertex(d_), Ordered_partition(l_+1)}) - { + : simplex_(simplex), + d_(simplex.vertex().size()), + l_(l), + k_(simplex.dimension()), + i_it_(l_ - k_, k_ + 1, Size_range(simplex.partition())), + is_end_(k_ > l_), + value_({Vertex(d_), Ordered_partition(l_ + 1)}) { uint j = 0; for (; j < simplex_.partition()[k_].size(); j++) if (simplex_.partition()[k_][j] == d_) { @@ -253,8 +224,8 @@ class Coface_iterator : public boost::iterator_facade< Coface_iterator o_its_; // indicates subdivision for each simplex_[i] - Ordered_set_partition_iterator o_end_; // one end for all o_its_ + Permutahedral_representation simplex_; // Input simplex + uint d_; // Ambient dimension + uint l_; // Dimension of the coface + uint k_; // Dimension of the input simplex + uint t_; // The position of d in simplex_.partition()[k_] + Integer_combination_iterator i_it_, i_end_; // indicates in how many parts each simplex_[i] is subdivided + std::vector o_its_; // indicates subdivision for each simplex_[i] + Ordered_set_partition_iterator o_end_; // one end for all o_its_ + + bool is_end_; // is true when the current permutation is the final one + value_t value_; // the dereference value - bool is_end_; // is true when the current permutation is the final one - value_t value_; // the dereference value +}; // Coface_iterator -}; // Coface_iterator +} // namespace coxeter_triangulation -} // namespace coxeter_triangulation +} // namespace Gudhi -} // namespace Gudhi - #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h index e0142bf4..0f91d41c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutation_iterator.h @@ -24,32 +24,27 @@ typedef unsigned uint; /** \brief Class that allows the user to generate permutations. * Based on the optimization of the Heap's algorithm by Sedgewick. -*/ -class Permutation_iterator : public boost::iterator_facade< Permutation_iterator, - std::vector const, - boost::forward_traversal_tag> { + */ +class Permutation_iterator + : public boost::iterator_facade const, boost::forward_traversal_tag> { using value_t = std::vector; - + private: friend class boost::iterator_core_access; - bool equal(Permutation_iterator const& other) const { - return (is_end_ && other.is_end_); - } + bool equal(Permutation_iterator const& other) const { return (is_end_ && other.is_end_); } - value_t const& dereference() const { - return value_; - } + value_t const& dereference() const { return value_; } void swap_two_indices(std::size_t i, std::size_t j) { uint t = value_[i]; value_[i] = value_[j]; value_[j] = t; } - + void elementary_increment() { uint j = 0; - while (d_[j] == j+1) { + while (d_[j] == j + 1) { d_[j] = 0; ++j; } @@ -57,8 +52,8 @@ class Permutation_iterator : public boost::iterator_facade< Permutation_iterator is_end_ = true; return; } - uint k = j+1; - uint x = (k%2 ? d_[j] : 0); + uint k = j + 1; + uint x = (k % 2 ? d_[j] : 0); swap_two_indices(k, x); ++d_[j]; } @@ -66,12 +61,11 @@ class Permutation_iterator : public boost::iterator_facade< Permutation_iterator void elementary_increment_optim_3() { if (ct_ != 0) { --ct_; - swap_two_indices(1 + (ct_%2), 0); - } - else { + swap_two_indices(1 + (ct_ % 2), 0); + } else { ct_ = 5; uint j = 2; - while (d_[j] == j+1) { + while (d_[j] == j + 1) { d_[j] = 0; ++j; } @@ -79,59 +73,48 @@ class Permutation_iterator : public boost::iterator_facade< Permutation_iterator is_end_ = true; return; } - uint k = j+1; - uint x = (k%2 ? d_[j] : 0); + uint k = j + 1; + uint x = (k % 2 ? d_[j] : 0); swap_two_indices(k, x); ++d_[j]; } } - + void increment() { if (optim_3_) elementary_increment_optim_3(); else - elementary_increment(); + elementary_increment(); } -public: - - Permutation_iterator(const uint& n) - : - value_(n), - is_end_(n == 0), - optim_3_(n >= 3), - n_(n), - d_(n), - ct_(5) - { + public: + Permutation_iterator(const uint& n) : value_(n), is_end_(n == 0), optim_3_(n >= 3), n_(n), d_(n), ct_(5) { for (uint i = 0; i < n; ++i) { value_[i] = i; d_[i] = 0; } - if (n > 0) - d_[n-1] = -1; + if (n > 0) d_[n - 1] = -1; } // Used for the creating an end iterator Permutation_iterator() : is_end_(true), n_(0) {} void reinitialize() { - if (n_ > 0) - is_end_ = false; + if (n_ > 0) is_end_ = false; } private: - value_t value_; // the dereference value - bool is_end_; // is true when the current permutation is the final one - bool optim_3_; // true if n>=3. for n >= 3, the algorithm is optimized + value_t value_; // the dereference value + bool is_end_; // is true when the current permutation is the final one + bool optim_3_; // true if n>=3. for n >= 3, the algorithm is optimized uint n_; - std::vector d_; // mix radix digits with radix [2 3 4 ... n-1 (sentinel=-1)] - uint ct_; // counter with values in {0,...,5} used in the n>=3 optimization. + std::vector d_; // mix radix digits with radix [2 3 4 ... n-1 (sentinel=-1)] + uint ct_; // counter with values in {0,...,5} used in the n>=3 optimization. }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h index bd1770bc..94ac10c2 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Set_partition_iterator.h @@ -22,40 +22,32 @@ namespace coxeter_triangulation { typedef unsigned uint; /** \brief Class that allows the user to generate set partitions of a set {0,...,n-1} in k parts. - * -*/ -class Set_partition_iterator : public boost::iterator_facade< Set_partition_iterator, - std::vector > const, - boost::forward_traversal_tag> { + * + */ +class Set_partition_iterator + : public boost::iterator_facade> const, + boost::forward_traversal_tag> { using value_t = std::vector>; private: friend class boost::iterator_core_access; - bool equal(Set_partition_iterator const& other) const { - return (is_end_ && other.is_end_); - } + bool equal(Set_partition_iterator const& other) const { return (is_end_ && other.is_end_); } - value_t const& dereference() const { - return value_; - } + value_t const& dereference() const { return value_; } void update_value() { - for (uint i = 0; i < k_; i++) - value_[i].clear(); - for (uint i = 0; i < n_; i++) - value_[rgs_[i]].push_back(i); + for (uint i = 0; i < k_; i++) value_[i].clear(); + for (uint i = 0; i < n_; i++) value_[rgs_[i]].push_back(i); } - + void increment() { if (k_ <= 1) { is_end_ = true; return; } uint i = n_ - 1; - while (rgs_[i] + 1 > max_[i] || - rgs_[i] + 1 >= k_) - i--; + while (rgs_[i] + 1 > max_[i] || rgs_[i] + 1 >= k_) i--; if (i == 0) { is_end_ = true; return; @@ -63,14 +55,13 @@ class Set_partition_iterator : public boost::iterator_facade< Set_partition_iter rgs_[i]++; uint mm = max_[i]; mm += (rgs_[i] >= mm); - max_[i+1] = mm; + max_[i + 1] = mm; while (++i < n_) { rgs_[i] = 0; - max_[i+1] = mm; + max_[i + 1] = mm; } uint p = k_; - if (mm < p) - do { + if (mm < p) do { max_[i] = p; --i; --p; @@ -78,26 +69,17 @@ class Set_partition_iterator : public boost::iterator_facade< Set_partition_iter } while (max_[i] < p); update_value(); } - + public: Set_partition_iterator(const uint& n, const uint& k) - : - value_(k), - rgs_(n, 0), - max_(n+1), - is_end_(n == 0), - n_(n), - k_(k) - { + : value_(k), rgs_(n, 0), max_(n + 1), is_end_(n == 0), n_(n), k_(k) { max_[0] = std::numeric_limits::max(); - for (uint i = 0; i <= n-k; ++i) - value_[0].push_back(i); - for (uint i = n-k+1, j = 1; i < n; ++i, ++j) { + for (uint i = 0; i <= n - k; ++i) value_[0].push_back(i); + for (uint i = n - k + 1, j = 1; i < n; ++i, ++j) { rgs_[i] = j; value_[j].push_back(i); } - for (uint i = 1; i <= n; i++) - max_[i] = rgs_[i-1] + 1; + for (uint i = 1; i <= n; i++) max_[i] = rgs_[i - 1] + 1; update_value(); } @@ -105,30 +87,25 @@ class Set_partition_iterator : public boost::iterator_facade< Set_partition_iter Set_partition_iterator() : is_end_(true), n_(0), k_(0) {} void reinitialize() { - if (n_ > 0) - is_end_ = false; - for (uint i = 0; i <= n_-k_; ++i) - rgs_[i] = 0; - for (uint i = n_-k_+1, j = 1; i < n_; ++i, ++j) - rgs_[i] = j; - for (uint i = 1; i <= n_; i++) - max_[i] = rgs_[i-1] + 1; + if (n_ > 0) is_end_ = false; + for (uint i = 0; i <= n_ - k_; ++i) rgs_[i] = 0; + for (uint i = n_ - k_ + 1, j = 1; i < n_; ++i, ++j) rgs_[i] = j; + for (uint i = 1; i <= n_; i++) max_[i] = rgs_[i - 1] + 1; update_value(); } private: - value_t value_; // the dereference value - std::vector rgs_; // restricted growth string - std::vector max_; // max_[i] = max(rgs_[0],...,rgs[i-1]) + 1 - bool is_end_; // is true when the current permutation is the final one + value_t value_; // the dereference value + std::vector rgs_; // restricted growth string + std::vector max_; // max_[i] = max(rgs_[0],...,rgs[i-1]) + 1 + bool is_end_; // is true when the current permutation is the final one uint n_; uint k_; }; -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h index b8925d96..905d68d5 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Simplex_comparator.h @@ -15,48 +15,40 @@ namespace Gudhi { namespace coxeter_triangulation { -/** \class Simplex_comparator +/** \class Simplex_comparator * \brief A comparator class for Permutahedral_representation. * The comparison is in lexicographic order first on * vertices and then on ordered partitions with sorted parts. * The lexicographic order forces that any face is larger than * a coface. * - * \tparam Permutahdral_representation_ Needs to be + * \tparam Permutahdral_representation_ Needs to be * Permutahedral_representation * * \ingroup coxeter_triangulation */ template struct Simplex_comparator { - /** \brief Comparison between two permutahedral representations. * Both permutahedral representations need to be valid and * the vertices of both permutahedral representations need to be of the same size. */ - bool operator() (const Permutahedral_representation_& lhs, - const Permutahedral_representation_& rhs) const { - if (lhs.vertex() < rhs.vertex()) - return true; - if (lhs.vertex() > rhs.vertex()) - return false; - - if (lhs.partition().size() > rhs.partition().size()) - return true; - if (lhs.partition().size() < rhs.partition().size()) - return false; - - if (lhs.partition() < rhs.partition()) - return true; - if (lhs.partition() > rhs.partition()) - return false; - + bool operator()(const Permutahedral_representation_& lhs, const Permutahedral_representation_& rhs) const { + if (lhs.vertex() < rhs.vertex()) return true; + if (lhs.vertex() > rhs.vertex()) return false; + + if (lhs.partition().size() > rhs.partition().size()) return true; + if (lhs.partition().size() < rhs.partition().size()) return false; + + if (lhs.partition() < rhs.partition()) return true; + if (lhs.partition() > rhs.partition()) return false; + return false; } }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h index f41335e9..c43effc8 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Size_range.h @@ -22,33 +22,26 @@ namespace coxeter_triangulation { /** \brief Auxillary iterator class for sizes of parts in an ordered set partition. */ template -class Size_iterator : public boost::iterator_facade< Size_iterator, - std::size_t const, - boost::forward_traversal_tag> { +class Size_iterator + : public boost::iterator_facade, std::size_t const, boost::forward_traversal_tag> { friend class boost::iterator_core_access; private: - bool equal(Size_iterator const& other) const { - return (is_end_ && other.is_end_); - } + bool equal(Size_iterator const& other) const { return (is_end_ && other.is_end_); } - std::size_t const& dereference() const { - return value_; - } + std::size_t const& dereference() const { return value_; } void increment() { if (++t_it_ == t_end_) { is_end_ = true; return; } - value_ = t_it_->size()-1; + value_ = t_it_->size() - 1; } public: - Size_iterator(const T_it& t_begin, const T_it& t_end) - : t_it_(t_begin), t_end_(t_end), is_end_(t_begin == t_end) { - if (!is_end_) - value_ = t_it_->size()-1; + Size_iterator(const T_it& t_begin, const T_it& t_end) : t_it_(t_begin), t_end_(t_end), is_end_(t_begin == t_end) { + if (!is_end_) value_ = t_it_->size() - 1; } private: @@ -63,25 +56,18 @@ class Size_range { public: typedef Size_iterator iterator; - + Size_range(const T& t) : t_(t) {} - - std::size_t operator[](std::size_t i) const { - return t_[i].size()-1; - } - iterator begin() const { - return iterator(t_.begin(), t_.end()); - } + std::size_t operator[](std::size_t i) const { return t_[i].size() - 1; } - iterator end() const { - return iterator(t_.end(), t_.end()); - } + iterator begin() const { return iterator(t_.begin(), t_.end()); } + iterator end() const { return iterator(t_.end(), t_.end()); } }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h index 21ee3c8b..47120689 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/face_from_indices.h @@ -11,23 +11,23 @@ #ifndef PERMUTAHEDRAL_REPRESENTATION_FACE_FROM_INDICES_H_ #define PERMUTAHEDRAL_REPRESENTATION_FACE_FROM_INDICES_H_ +#include // for std::size_t +#include + namespace Gudhi { namespace coxeter_triangulation { -#include // for std::size_t -#include - - /** \brief Computes the permutahedral representation of a face of a given simplex - * and a range of the vertex indices that compose the face. - * - * \tparam Permutahedral_representation has to be Permutahedral_representation - * \tparam Index_range is a range of unsigned integers taking values in 0,...,k, - * where k is the dimension of the simplex simplex. - * - * @param[in] simplex Input simplex. - * @param[in] indices Input range of indices. - */ +/** \brief Computes the permutahedral representation of a face of a given simplex + * and a range of the vertex indices that compose the face. + * + * \tparam Permutahedral_representation has to be Permutahedral_representation + * \tparam Index_range is a range of unsigned integers taking values in 0,...,k, + * where k is the dimension of the simplex simplex. + * + * @param[in] simplex Input simplex. + * @param[in] indices Input range of indices. + */ template Permutahedral_representation face_from_indices(const Permutahedral_representation& simplex, const Index_range& indices) { @@ -38,34 +38,29 @@ Permutahedral_representation face_from_indices(const Permutahedral_representatio Permutahedral_representation value; std::size_t d = simplex.vertex().size(); value.vertex() = simplex.vertex(); - std::size_t k = indices.size()-1; - value.partition().resize(k+1); - std::size_t l = simplex.partition().size()-1; - for (std::size_t h = 1; h < k+1; h++) - for (range_index i = indices[h-1]; i < indices[h]; i++) - for (part_index j: simplex.partition()[i]) - value.partition()[h-1].push_back(j); - for (range_index i = indices[k]; i < l+1; i++) - for (part_index j: simplex.partition()[i]) - value.partition()[k].push_back(j); + std::size_t k = indices.size() - 1; + value.partition().resize(k + 1); + std::size_t l = simplex.partition().size() - 1; + for (std::size_t h = 1; h < k + 1; h++) + for (range_index i = indices[h - 1]; i < indices[h]; i++) + for (part_index j : simplex.partition()[i]) value.partition()[h - 1].push_back(j); + for (range_index i = indices[k]; i < l + 1; i++) + for (part_index j : simplex.partition()[i]) value.partition()[k].push_back(j); for (range_index i = 0; i < indices[0]; i++) - for (part_index j: simplex.partition()[i]) { + for (part_index j : simplex.partition()[i]) { if (j != d) - value.vertex()[j]++; + value.vertex()[j]++; else - for (std::size_t l = 0; l < d; l++) - value.vertex()[l]--; + for (std::size_t l = 0; l < d; l++) value.vertex()[l]--; value.partition()[k].push_back(j); } // sort the values in each part (probably not needed) - for (auto& part: value.partition()) - std::sort(part.begin(), part.end()); + for (auto& part : value.partition()) std::sort(part.begin(), part.end()); return value; } -} // namespace coxeter_triangulation - -} // namespace Gudhi +} // namespace coxeter_triangulation +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/include/gudhi/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Query_result.h index ecc40c25..5543c2fb 100644 --- a/src/Coxeter_triangulation/include/gudhi/Query_result.h +++ b/src/Coxeter_triangulation/include/gudhi/Query_result.h @@ -16,7 +16,7 @@ namespace Gudhi { namespace coxeter_triangulation { /** \class Query_result - * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. + * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. * * \tparam Simplex_handle The class of the query simplex. * @@ -33,8 +33,8 @@ struct Query_result { bool success; }; -} // namespace coxeter_triangulation +} // namespace coxeter_triangulation -} // namespace Gudhi +} // namespace Gudhi #endif diff --git a/src/Coxeter_triangulation/test/cell_complex_test.cpp b/src/Coxeter_triangulation/test/cell_complex_test.cpp index 486c4981..88b6142b 100644 --- a/src/Coxeter_triangulation/test/cell_complex_test.cpp +++ b/src/Coxeter_triangulation/test/cell_complex_test.cpp @@ -27,34 +27,33 @@ using namespace Gudhi::coxeter_triangulation; BOOST_AUTO_TEST_CASE(cell_complex) { - double radius = 1.1111; - Function_torus_in_R3 fun_torus(radius, 3*radius); + Function_torus_in_R3 fun_torus(radius, 3 * radius); Eigen::VectorXd seed = fun_torus.seed(); - Function_Sm_in_Rd fun_bound(2.5*radius, 2, seed); - + Function_Sm_in_Rd fun_bound(2.5 * radius, 2, seed); + auto oracle = make_oracle(fun_torus, fun_bound); double lambda = 0.2; Coxeter_triangulation<> cox_tr(oracle.amb_d()); cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); cox_tr.change_matrix(lambda * cox_tr.matrix()); - + using MT = Manifold_tracing >; using Out_simplex_map = typename MT::Out_simplex_map; std::vector seed_points(1, seed); Out_simplex_map interior_simplex_map, boundary_simplex_map; manifold_tracing_algorithm(seed_points, cox_tr, oracle, interior_simplex_map, boundary_simplex_map); - + std::size_t intr_d = oracle.amb_d() - oracle.cod_d(); Cell_complex cell_complex(intr_d); cell_complex.construct_complex(interior_simplex_map, boundary_simplex_map); - + std::size_t interior_sc_map_size0 = cell_complex.interior_simplex_cell_map(0).size(); std::size_t interior_sc_map_size1 = cell_complex.interior_simplex_cell_map(1).size(); std::size_t interior_sc_map_size2 = cell_complex.interior_simplex_cell_map(2).size(); std::size_t boundary_sc_map_size0 = cell_complex.boundary_simplex_cell_map(0).size(); std::size_t boundary_sc_map_size1 = cell_complex.boundary_simplex_cell_map(1).size(); - BOOST_CHECK (interior_simplex_map.size() == interior_sc_map_size0 ); - BOOST_CHECK ( boundary_sc_map_size0 - boundary_sc_map_size1 == 0 ); - BOOST_CHECK ( interior_sc_map_size0 - interior_sc_map_size1 + interior_sc_map_size2 == 0 ); + BOOST_CHECK(interior_simplex_map.size() == interior_sc_map_size0); + BOOST_CHECK(boundary_sc_map_size0 - boundary_sc_map_size1 == 0); + BOOST_CHECK(interior_sc_map_size0 - interior_sc_map_size1 + interior_sc_map_size2 == 0); } diff --git a/src/Coxeter_triangulation/test/freud_triang_test.cpp b/src/Coxeter_triangulation/test/freud_triang_test.cpp index 69729975..9e06acc9 100644 --- a/src/Coxeter_triangulation/test/freud_triang_test.cpp +++ b/src/Coxeter_triangulation/test/freud_triang_test.cpp @@ -17,13 +17,12 @@ #include BOOST_AUTO_TEST_CASE(freudenthal_triangulation) { - // Point location check typedef std::vector Point; typedef Gudhi::coxeter_triangulation::Freudenthal_triangulation<> FK_triangulation; typedef typename FK_triangulation::Simplex_handle Simplex_handle; typedef typename FK_triangulation::Vertex_handle Vertex_handle; - typedef typename Simplex_handle::OrderedSetPartition Ordered_set_partition; + typedef typename Simplex_handle::OrderedSetPartition Ordered_set_partition; typedef typename Ordered_set_partition::value_type Part; FK_triangulation tr(3); @@ -32,48 +31,47 @@ BOOST_AUTO_TEST_CASE(freudenthal_triangulation) { { Point point({3, -1, 0}); Simplex_handle s = tr.locate_point(point); - BOOST_CHECK( s.vertex() == Vertex_handle({3, -1, 0}) ); - BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0, 1, 2, 3})}) ); + BOOST_CHECK(s.vertex() == Vertex_handle({3, -1, 0})); + BOOST_CHECK(s.partition() == Ordered_set_partition({Part({0, 1, 2, 3})})); } { Point point({3.5, -1.5, 0.5}); Simplex_handle s = tr.locate_point(point); - BOOST_CHECK( s.vertex() == Vertex_handle({3, -2, 0}) ); - BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0, 1, 2}), Part({3})}) ); + BOOST_CHECK(s.vertex() == Vertex_handle({3, -2, 0})); + BOOST_CHECK(s.partition() == Ordered_set_partition({Part({0, 1, 2}), Part({3})})); } { Point point({3.5, -1.8, 0.5}); Simplex_handle s = tr.locate_point(point); - BOOST_CHECK( s.vertex() == Vertex_handle({3, -2, 0}) ); - BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0, 2}), Part({1}), Part({3})}) ); + BOOST_CHECK(s.vertex() == Vertex_handle({3, -2, 0})); + BOOST_CHECK(s.partition() == Ordered_set_partition({Part({0, 2}), Part({1}), Part({3})})); } { Point point({3.5, -1.8, 0.3}); Simplex_handle s = tr.locate_point(point); - BOOST_CHECK( s.vertex() == Vertex_handle({3, -2, 0}) ); - BOOST_CHECK( s.partition() == Ordered_set_partition({Part({0}), Part({2}), Part({1}), Part({3})}) ); + BOOST_CHECK(s.vertex() == Vertex_handle({3, -2, 0})); + BOOST_CHECK(s.partition() == Ordered_set_partition({Part({0}), Part({2}), Part({1}), Part({3})})); } // Dimension check - BOOST_CHECK( tr.dimension() == 3 ); + BOOST_CHECK(tr.dimension() == 3); // Matrix check - Eigen::MatrixXd default_matrix = Eigen::MatrixXd::Identity(3, 3); - BOOST_CHECK( tr.matrix() == default_matrix ); + Eigen::MatrixXd default_matrix = Eigen::MatrixXd::Identity(3, 3); + BOOST_CHECK(tr.matrix() == default_matrix); // Vector check - Eigen::MatrixXd default_offset = Eigen::VectorXd::Zero(3); - BOOST_CHECK( tr.offset() == default_offset ); + Eigen::MatrixXd default_offset = Eigen::VectorXd::Zero(3); + BOOST_CHECK(tr.offset() == default_offset); // Barycenter check Point point({3.5, -1.8, 0.3}); Simplex_handle s = tr.locate_point(point); Eigen::Vector3d barycenter_cart = Eigen::Vector3d::Zero(); - for (auto v: s.vertex_range()) - for (std::size_t i = 0; i < v.size(); i++) - barycenter_cart(i) += v[i]; - barycenter_cart /= 4.; // simplex is three-dimensional + for (auto v : s.vertex_range()) + for (std::size_t i = 0; i < v.size(); i++) barycenter_cart(i) += v[i]; + barycenter_cart /= 4.; // simplex is three-dimensional Eigen::Vector3d barycenter = tr.barycenter(s); for (std::size_t i = 0; (long int)i < barycenter.size(); i++) GUDHI_TEST_FLOAT_EQUALITY_CHECK(barycenter(i), barycenter_cart(i), 1e-7); @@ -81,22 +79,21 @@ BOOST_AUTO_TEST_CASE(freudenthal_triangulation) { // Barycenter check for twice the scale s = tr.locate_point(point, 2); barycenter_cart = Eigen::Vector3d::Zero(); - for (auto v: s.vertex_range()) - for (std::size_t i = 0; i < v.size(); i++) - barycenter_cart(i) += v[i]; - barycenter_cart /= 3.; // simplex is now a two-dimensional face - barycenter_cart /= 2.; // scale + for (auto v : s.vertex_range()) + for (std::size_t i = 0; i < v.size(); i++) barycenter_cart(i) += v[i]; + barycenter_cart /= 3.; // simplex is now a two-dimensional face + barycenter_cart /= 2.; // scale barycenter = tr.barycenter(s, 2); for (std::size_t i = 0; (long int)i < barycenter.size(); i++) GUDHI_TEST_FLOAT_EQUALITY_CHECK(barycenter(i), barycenter_cart(i), 1e-7); - + // Matrix and offset change check - Eigen::MatrixXd new_matrix(3,3); + Eigen::MatrixXd new_matrix(3, 3); new_matrix << 1, 0, 0, -1, 1, 0, -1, 0, 1; Eigen::Vector3d new_offset(1.5, 1, 0.5); tr.change_matrix(new_matrix); tr.change_offset(new_offset); - - BOOST_CHECK( tr.matrix() == new_matrix ); - BOOST_CHECK( tr.offset() == new_offset ); + + BOOST_CHECK(tr.matrix() == new_matrix); + BOOST_CHECK(tr.offset() == new_offset); } diff --git a/src/Coxeter_triangulation/test/function_test.cpp b/src/Coxeter_triangulation/test/function_test.cpp index c9c3f55b..d3c8d46c 100644 --- a/src/Coxeter_triangulation/test/function_test.cpp +++ b/src/Coxeter_triangulation/test/function_test.cpp @@ -11,7 +11,7 @@ // workaround for the annoying boost message in boost 1.69 #define BOOST_PENDING_INTEGER_LOG2_HPP #include -// end workaround +// end workaround #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "function" @@ -48,18 +48,17 @@ template void test_function(const Function& fun) { Eigen::VectorXd seed = fun.seed(); Eigen::VectorXd res_seed = fun(fun.seed()); - BOOST_CHECK( seed.size() == (long int)fun.amb_d() ); - BOOST_CHECK( res_seed.size() == (long int)fun.cod_d() ); - for (std::size_t i = 0; i < fun.cod_d(); i++) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(res_seed(i), 0., 1e-10); + BOOST_CHECK(seed.size() == (long int)fun.amb_d()); + BOOST_CHECK(res_seed.size() == (long int)fun.cod_d()); + for (std::size_t i = 0; i < fun.cod_d(); i++) GUDHI_TEST_FLOAT_EQUALITY_CHECK(res_seed(i), 0., 1e-10); } BOOST_AUTO_TEST_CASE(function) { - { // the sphere testing part std::size_t m = 3, d = 5; - Eigen::VectorXd center(d); center << 2, 1.5, -0.5, 4.5, -1; + Eigen::VectorXd center(d); + center << 2, 1.5, -0.5, 4.5, -1; double radius = 5; typedef Function_Sm_in_Rd Function_sphere; Function_sphere fun_sphere(radius, m, d, center); @@ -68,9 +67,8 @@ BOOST_AUTO_TEST_CASE(function) { { // the affine plane testing part std::size_t m = 0, d = 5; - Eigen::MatrixXd normal_matrix = Eigen::MatrixXd::Zero(d, d-m); - for (std::size_t i = 0; i < d-m; ++i) - normal_matrix(i,i) = 1; + Eigen::MatrixXd normal_matrix = Eigen::MatrixXd::Zero(d, d - m); + for (std::size_t i = 0; i < d - m; ++i) normal_matrix(i, i) = 1; typedef Function_affine_plane_in_Rd Function_plane; Function_plane fun_plane(normal_matrix); test_function(fun_plane); @@ -81,8 +79,7 @@ BOOST_AUTO_TEST_CASE(function) { auto x = Eigen::VectorXd::Constant(k, 1); Constant_function fun_const(d, k, x); Eigen::VectorXd res_zero = fun_const(Eigen::VectorXd::Zero(d)); - for (std::size_t i = 0; i < k; ++i) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(res_zero(i), x(i), 1e-10); + for (std::size_t i = 0; i < k; ++i) GUDHI_TEST_FLOAT_EQUALITY_CHECK(res_zero(i), x(i), 1e-10); } { // the chair function @@ -119,10 +116,10 @@ BOOST_AUTO_TEST_CASE(function) { Eigen::MatrixXd id_matrix = matrix.transpose() * matrix; for (std::size_t i = 0; i < 5; ++i) for (std::size_t j = 0; j < 5; ++j) - if (i == j) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i,j), 1.0, 1e-10); - else - GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i,j), 0.0, 1e-10); + if (i == j) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i, j), 1.0, 1e-10); + else + GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i, j), 0.0, 1e-10); } { // function embedding @@ -137,7 +134,7 @@ BOOST_AUTO_TEST_CASE(function) { // function linear transformation Eigen::MatrixXd matrix = Eigen::MatrixXd::Random(5, 5); - BOOST_CHECK( matrix.determinant() != 0. ); + BOOST_CHECK(matrix.determinant() != 0.); auto fun_lin = make_linear_transformation(fun_trans, matrix); test_function(fun_lin); @@ -150,7 +147,7 @@ BOOST_AUTO_TEST_CASE(function) { Function_sphere fun_sphere(1, 1); auto fun_prod = make_product_function(fun_sphere, fun_sphere, fun_sphere); test_function(fun_prod); - + // function PL approximation Coxeter_triangulation<> cox_tr(6); typedef Coxeter_triangulation<>::Vertex_handle Vertex_handle; @@ -159,17 +156,15 @@ BOOST_AUTO_TEST_CASE(function) { Eigen::VectorXd x0 = cox_tr.cartesian_coordinates(v0); Eigen::VectorXd value0 = fun_prod(x0); Eigen::VectorXd pl_value0 = fun_pl(x0); - for (std::size_t i = 0; i < fun_pl.cod_d(); i++) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(value0(i), pl_value0(i), 1e-10); + for (std::size_t i = 0; i < fun_pl.cod_d(); i++) GUDHI_TEST_FLOAT_EQUALITY_CHECK(value0(i), pl_value0(i), 1e-10); Vertex_handle v1 = v0; v1[0] += 1; Eigen::VectorXd x1 = cox_tr.cartesian_coordinates(v1); Eigen::VectorXd value1 = fun_prod(x1); Eigen::VectorXd pl_value1 = fun_pl(x1); + for (std::size_t i = 0; i < fun_pl.cod_d(); i++) GUDHI_TEST_FLOAT_EQUALITY_CHECK(value1(i), pl_value1(i), 1e-10); + Eigen::VectorXd pl_value_mid = fun_pl(0.5 * x0 + 0.5 * x1); for (std::size_t i = 0; i < fun_pl.cod_d(); i++) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(value1(i), pl_value1(i), 1e-10); - Eigen::VectorXd pl_value_mid = fun_pl(0.5*x0 + 0.5*x1); - for (std::size_t i = 0; i < fun_pl.cod_d(); i++) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(0.5*value0(i) + 0.5*value1(i), pl_value_mid(i), 1e-10); + GUDHI_TEST_FLOAT_EQUALITY_CHECK(0.5 * value0(i) + 0.5 * value1(i), pl_value_mid(i), 1e-10); } } diff --git a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp index 0113f8b5..68b79487 100644 --- a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp +++ b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp @@ -28,37 +28,35 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { auto oracle = make_oracle(fun_sph); Coxeter_triangulation<> cox_tr(oracle.amb_d()); // cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); - + using MT = Manifold_tracing >; Eigen::VectorXd seed = fun_sph.seed(); std::vector seed_points(1, seed); typename MT::Out_simplex_map out_simplex_map; manifold_tracing_algorithm(seed_points, cox_tr, oracle, out_simplex_map); - for (auto si_pair: out_simplex_map) { - BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d() ); - BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); + for (auto si_pair : out_simplex_map) { + BOOST_CHECK(si_pair.first.dimension() == oracle.function().cod_d()); + BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } std::cout << "out_simplex_map.size() = " << out_simplex_map.size() << "\n"; - BOOST_CHECK ( out_simplex_map.size() == 1140 ); - + BOOST_CHECK(out_simplex_map.size() == 1140); // manifold with boundary Function_Sm_in_Rd fun_boundary(3.0, 2, fun_sph.seed()); auto oracle_with_boundary = make_oracle(fun_sph, fun_boundary); typename MT::Out_simplex_map interior_simplex_map, boundary_simplex_map; manifold_tracing_algorithm(seed_points, cox_tr, oracle_with_boundary, interior_simplex_map, boundary_simplex_map); - for (auto si_pair: interior_simplex_map) { - BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d() ); - BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); + for (auto si_pair : interior_simplex_map) { + BOOST_CHECK(si_pair.first.dimension() == oracle.function().cod_d()); + BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } std::cout << "interior_simplex_map.size() = " << interior_simplex_map.size() << "\n"; - BOOST_CHECK ( interior_simplex_map.size() == 96 ); - for (auto si_pair: boundary_simplex_map) { - BOOST_CHECK ( si_pair.first.dimension() == oracle.function().cod_d()+1 ); - BOOST_CHECK ( si_pair.second.size() == (long int)oracle.function().amb_d() ); + BOOST_CHECK(interior_simplex_map.size() == 96); + for (auto si_pair : boundary_simplex_map) { + BOOST_CHECK(si_pair.first.dimension() == oracle.function().cod_d() + 1); + BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } std::cout << "boundary_simplex_map.size() = " << boundary_simplex_map.size() << "\n"; - BOOST_CHECK ( boundary_simplex_map.size() == 55 ); - + BOOST_CHECK(boundary_simplex_map.size() == 55); } diff --git a/src/Coxeter_triangulation/test/oracle_test.cpp b/src/Coxeter_triangulation/test/oracle_test.cpp index dfa19293..ed2042f5 100644 --- a/src/Coxeter_triangulation/test/oracle_test.cpp +++ b/src/Coxeter_triangulation/test/oracle_test.cpp @@ -28,31 +28,29 @@ using namespace Gudhi::coxeter_triangulation; BOOST_AUTO_TEST_CASE(oracle) { - Function_Sm_in_Rd fun_sph(5.1111, 2); auto oracle = make_oracle(fun_sph); Coxeter_triangulation<> cox_tr(oracle.amb_d()); // cox_tr.change_offset(Eigen::VectorXd::Random(oracle.amb_d())); - + Eigen::VectorXd seed = fun_sph.seed(); auto s = cox_tr.locate_point(seed); std::size_t num_intersected_edges = 0; - for (auto f: s.face_range(oracle.cod_d())) { + for (auto f : s.face_range(oracle.cod_d())) { auto qr = oracle.intersects(f, cox_tr); - if (qr.success) - num_intersected_edges++; + if (qr.success) num_intersected_edges++; auto vertex_it = f.vertex_range().begin(); Eigen::Vector3d p1 = cox_tr.cartesian_coordinates(*vertex_it++); Eigen::Vector3d p2 = cox_tr.cartesian_coordinates(*vertex_it++); - BOOST_CHECK( vertex_it == f.vertex_range().end() ); - Eigen::MatrixXd m(3,3); - if (qr.success) { + BOOST_CHECK(vertex_it == f.vertex_range().end()); + Eigen::MatrixXd m(3, 3); + if (qr.success) { m.col(0) = qr.intersection; m.col(1) = p1; m.col(2) = p2; GUDHI_TEST_FLOAT_EQUALITY_CHECK(m.determinant(), 0.0, 1e-10); } } - BOOST_CHECK( num_intersected_edges == 3 || num_intersected_edges == 4 ); + BOOST_CHECK(num_intersected_edges == 3 || num_intersected_edges == 4); } diff --git a/src/Coxeter_triangulation/test/perm_rep_test.cpp b/src/Coxeter_triangulation/test/perm_rep_test.cpp index 2376c88a..a668fc66 100644 --- a/src/Coxeter_triangulation/test/perm_rep_test.cpp +++ b/src/Coxeter_triangulation/test/perm_rep_test.cpp @@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(permutahedral_representation) { typedef std::vector Partition; typedef Gudhi::coxeter_triangulation::Permutahedral_representation Simplex_handle; Vertex v0(10, 0); - Partition omega = {Part({5}), Part({2}), Part({3,7}), Part({4,9}), Part({0,6,8}), Part({1,10})}; + Partition omega = {Part({5}), Part({2}), Part({3, 7}), Part({4, 9}), Part({0, 6, 8}), Part({1, 10})}; Simplex_handle s(v0, omega); // Dimension check @@ -28,34 +28,31 @@ BOOST_AUTO_TEST_CASE(permutahedral_representation) { // Vertex number check std::vector vertices; - for (auto& v: s.vertex_range()) - vertices.push_back(v); + for (auto& v : s.vertex_range()) vertices.push_back(v); BOOST_CHECK(vertices.size() == 6); - + // Facet number check std::vector facets; - for (auto& f: s.facet_range()) - facets.push_back(f); + for (auto& f : s.facet_range()) facets.push_back(f); BOOST_CHECK(facets.size() == 6); // Face of dim 3 number check std::vector faces3; - for (auto& f: s.face_range(3)) - faces3.push_back(f); + for (auto& f : s.face_range(3)) faces3.push_back(f); BOOST_CHECK(faces3.size() == 15); // Cofacet number check std::vector cofacets; - for (auto& f: s.cofacet_range()) - cofacets.push_back(f); + for (auto& f : s.cofacet_range()) cofacets.push_back(f); BOOST_CHECK(cofacets.size() == 12); // Is face check Vertex v1(10, 0); - Partition omega1 = {Part({5}), Part({0,1,2,3,4,6,7,8,9,10})}; + Partition omega1 = {Part({5}), Part({0, 1, 2, 3, 4, 6, 7, 8, 9, 10})}; Simplex_handle s1(v1, omega1); - Vertex v2(10, 0); v2[1] = -1; - Partition omega2 = {Part({1}), Part({5}), Part({2}), Part({3,7}), Part({4,9}), Part({0,6,8}), Part({10})}; + Vertex v2(10, 0); + v2[1] = -1; + Partition omega2 = {Part({1}), Part({5}), Part({2}), Part({3, 7}), Part({4, 9}), Part({0, 6, 8}), Part({10})}; Simplex_handle s2(v2, omega2); BOOST_CHECK(s.is_face_of(s)); BOOST_CHECK(s1.is_face_of(s)); -- cgit v1.2.3 From 63b05f9835d76f1426eec1049615c09a22ddd774 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 23 Sep 2020 07:03:32 +0200 Subject: Remove functions from doxygen group coxeter_triangulation to empty documentation page. Links are still available --- src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h | 2 -- src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h | 2 -- src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h | 4 ---- src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h | 2 -- .../include/gudhi/Functions/Function_affine_plane_in_Rd.h | 2 -- .../include/gudhi/Functions/Function_chair_in_R3.h | 2 -- .../include/gudhi/Functions/Function_iron_in_R3.h | 2 -- .../include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h | 2 -- .../include/gudhi/Functions/Function_moment_curve_in_Rd.h | 2 -- .../include/gudhi/Functions/Function_torus_in_R3.h | 2 -- .../include/gudhi/Functions/Function_whitney_umbrella_in_R3.h | 2 -- .../include/gudhi/Functions/Linear_transformation.h | 4 ---- src/Coxeter_triangulation/include/gudhi/Functions/Negation.h | 4 ---- src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h | 4 ---- src/Coxeter_triangulation/include/gudhi/Functions/Translate.h | 4 ---- 15 files changed, 40 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h index c0d6aec4..d1767eca 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -94,8 +94,6 @@ inline typename std::enable_if::type get_value(const st * * \tparam Functions A pack template parameter for functions. All functions should be models of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template struct Cartesian_product : public Function { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index 424bcbff..2873d086 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -25,8 +25,6 @@ namespace coxeter_triangulation { * \class Constant_function * \brief A class that encodes a constant function from R^d to R^k. * This class does not have any implicit manifold in correspondence. - * - * \ingroup coxeter_triangulation */ struct Constant_function : public Function { /** \brief Value of the function at a specified point. The value is constant. diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index 69bd269a..59e051c5 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -27,8 +27,6 @@ namespace coxeter_triangulation { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template struct Embed_in_Rd : public Function { @@ -82,8 +80,6 @@ struct Embed_in_Rd : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template Embed_in_Rd make_embedding(const Function_& function, std::size_t d) { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h index 25b9b5fc..d901e832 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -25,8 +25,6 @@ namespace coxeter_triangulation { * \class Function_Sm_in_Rd * \brief A class for the function that defines an m-dimensional implicit sphere embedded * in the d-dimensional Euclidean space. - * - * \ingroup coxeter_triangulation */ struct Function_Sm_in_Rd : public Function { /** \brief Value of the function at a specified point. diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h index d0089149..b7414cda 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -25,8 +25,6 @@ namespace coxeter_triangulation { * \class Function_affine_plane_in_Rd * \brief A class for the function that defines an m-dimensional implicit affine plane * embedded in d-dimensional Euclidean space. - * - * \ingroup coxeter_triangulation */ struct Function_affine_plane_in_Rd : public Function { /** diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h index e2f65144..b30f964f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -26,8 +26,6 @@ namespace coxeter_triangulation { * \class Function_chair_in_R3 * \brief A class that encodes the function, the zero-set of which is a so-called * "chair" surface embedded in R^3. - * - * \ingroup coxeter_triangulation */ struct Function_chair_in_R3 : public Function { /** diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h index 5842c58f..def2a99c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -26,8 +26,6 @@ namespace coxeter_triangulation { * \class Function_iron_in_R3 * \brief A class that encodes the function, the zero-set of which is a surface * embedded in R^3 that ressembles an iron. - * - * \ingroup coxeter_triangulation */ struct Function_iron_in_R3 : public Function { /** diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h index b5d54b24..f36ccd3c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -26,8 +26,6 @@ namespace coxeter_triangulation { * \class Function_lemniscate_revolution_in_R3 * \brief A class that encodes the function, the zero-set of which is a surface of revolution * around the x axis based on the lemniscate of Bernoulli embedded in R^3. - * - * \ingroup coxeter_triangulation */ struct Function_lemniscate_revolution_in_R3 : public Function { /** diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h index 3ea5cf12..0db8289b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -25,8 +25,6 @@ namespace coxeter_triangulation { * \class Function_moment_curve_in_Rd * \brief A class for the function that defines an implicit moment curve * in the d-dimensional Euclidean space. - * - * \ingroup coxeter_triangulation */ struct Function_moment_curve_in_Rd : public Function { /** \brief Value of the function at a specified point. diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h index cdc39199..4aa50cfd 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -26,8 +26,6 @@ namespace coxeter_triangulation { * \class Function_torus_in_R3 * \brief A class that encodes the function, the zero-set of which is a torus * surface embedded in R^3. - * - * \ingroup coxeter_triangulation */ struct Function_torus_in_R3 : public Function { /** diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h index 4415ab87..a37fec1c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -25,8 +25,6 @@ namespace coxeter_triangulation { * \class Function_whitney_umbrella_in_R3 * \brief A class that encodes the function, the zero-set of which is the Whitney umbrella * surface embedded in R^3. - * - * \ingroup coxeter_triangulation */ struct Function_whitney_umbrella_in_R3 : public Function { /** diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index 1a82984b..a25abb1b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -27,8 +27,6 @@ namespace coxeter_triangulation { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template struct Linear_transformation : public Function { @@ -77,8 +75,6 @@ struct Linear_transformation : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template Linear_transformation make_linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index 58d8ebe0..6801f3c9 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -28,8 +28,6 @@ namespace coxeter_triangulation { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template struct Negation : public Function { @@ -73,8 +71,6 @@ struct Negation : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template Negation negation(const Function_& function) { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index 3d1f3564..4fad0131 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -30,8 +30,6 @@ namespace coxeter_triangulation { * the concept FunctionForImplicitManifold. * \tparam Triangulation The triangulation template parameter. Should be a model of * the concept TriangulationForManifoldTracing. - * - * \ingroup coxeter_triangulation */ template struct PL_approximation : public Function { @@ -99,8 +97,6 @@ struct PL_approximation : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template PL_approximation make_pl_approximation(const Function_& function, diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index bd91c707..893a2f17 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -28,8 +28,6 @@ namespace coxeter_triangulation { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template struct Translate : public Function { @@ -78,8 +76,6 @@ struct Translate : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation */ template Translate translate(const Function_& function, Eigen::VectorXd off) { -- cgit v1.2.3 From acdc965eb6c1dd14508bcd0e50025bb4f01319f8 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 23 Sep 2020 10:11:45 +0200 Subject: Add Gudhi/math.h for pi --- src/common/include/gudhi/math.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/common/include/gudhi/math.h (limited to 'src') diff --git a/src/common/include/gudhi/math.h b/src/common/include/gudhi/math.h new file mode 100644 index 00000000..f367bac2 --- /dev/null +++ b/src/common/include/gudhi/math.h @@ -0,0 +1,23 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2020 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef MATH_H_ +#define MATH_H_ + +#include + +namespace Gudhi { + +// In wait of C++20 std::numbers::pi with #include +static constexpr double PI = boost::math::constants::pi(); + +} // namespace Gudhi + +#endif // MATH_H_ -- cgit v1.2.3 From 5db457afb8e3214bdd83bef51198b65e53267a8c Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 23 Sep 2020 10:12:22 +0200 Subject: Add coxeter on main page --- ...manifold_tracing_on_custom_function_example.png | Bin 0 -> 419483 bytes src/common/doc/main_page.md | 28 ++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png (limited to 'src') diff --git a/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png b/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png new file mode 100644 index 00000000..1edbadf5 Binary files /dev/null and b/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png differ diff --git a/src/common/doc/main_page.md b/src/common/doc/main_page.md index e19af537..c58b6994 100644 --- a/src/common/doc/main_page.md +++ b/src/common/doc/main_page.md @@ -135,7 +135,7 @@ -## Filtrations and reconstructions {#FiltrationsReconstructions} +## Filtrations ### Alpha complex @@ -298,6 +298,32 @@
      +## Manifold reconstructions +### Coxeter triangulation + + + + + + + + + + +
      + \image html "manifold_tracing_on_custom_function_example.png" + + Coxeter triangulation module is designed to provide tools for constructing a piecewise-linear approximation of an + \f$m\f$-dimensional smooth manifold embedded in \f$ \mathbb{R}^d \f$ using an ambient triangulation. + + Author: Siargey Kachanovich
      + Introduced in: GUDHI 3.4.0
      + Copyright: MIT [(LGPL v3)](../../licensing/)
      + Requires: \ref cgal ≥ 4.11.0 +
      + User manual: \ref coxeter_triangulation +
      + ### Tangential complex -- cgit v1.2.3 From 7d38b9f01ff11dd0b872f6112e3a5088ad5dd169 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 23 Sep 2020 10:12:46 +0200 Subject: Roll back free functions to remove doxygen warnings --- src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h | 2 ++ .../include/gudhi/Functions/Linear_transformation.h | 2 ++ src/Coxeter_triangulation/include/gudhi/Functions/Negation.h | 2 ++ src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h | 2 ++ src/Coxeter_triangulation/include/gudhi/Functions/Translate.h | 2 ++ 5 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index 59e051c5..bfeda2c3 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -80,6 +80,8 @@ struct Embed_in_Rd : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation */ template Embed_in_Rd make_embedding(const Function_& function, std::size_t d) { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index a25abb1b..9228d487 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -75,6 +75,8 @@ struct Linear_transformation : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation */ template Linear_transformation make_linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index 6801f3c9..1c202cd5 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -71,6 +71,8 @@ struct Negation : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation */ template Negation negation(const Function_& function) { diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index 4fad0131..20d4e6a8 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -97,6 +97,8 @@ struct PL_approximation : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation */ template PL_approximation make_pl_approximation(const Function_& function, diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index 893a2f17..fc91a118 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -76,6 +76,8 @@ struct Translate : public Function { * * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation */ template Translate translate(const Function_& function, Eigen::VectorXd off) { -- cgit v1.2.3 From 47988ac2b3ba546e98b01e996d7d7d0bad3b6dd3 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 24 Sep 2020 09:38:43 +0200 Subject: Modify image on main page --- ...manifold_tracing_on_custom_function_example.png | Bin 419483 -> 589120 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png b/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png index 1edbadf5..04912729 100644 Binary files a/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png and b/src/Coxeter_triangulation/doc/manifold_tracing_on_custom_function_example.png differ -- cgit v1.2.3 From faeb8717e196422bf94b3943819aa94f260631b2 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 24 Sep 2020 10:35:46 +0200 Subject: Use eigen initialization. std::size_t --- .../include/gudhi/Cell_complex/Hasse_diagram_cell.h | 19 ++++++++++--------- .../include/gudhi/Coxeter_triangulation.h | 18 ++++-------------- .../include/gudhi/Freudenthal_triangulation.h | 2 +- 3 files changed, 15 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h index 9847a6d3..24045c0c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -16,6 +16,7 @@ #include #include #include // for std::is_same +#include // for std::size_t namespace Gudhi { namespace Hasse_diagram { @@ -162,7 +163,7 @@ class Hasse_diagram_cell { void remove_deleted_elements_from_boundary_and_coboundary() { Cell_range new_boundary; new_boundary.reserve(this->boundary.size()); - for (size_t bd = 0; bd != this->boundary.size(); ++bd) { + for (std::size_t bd = 0; bd != this->boundary.size(); ++bd) { if (!this->boundary[bd].first->deleted()) { new_boundary.push_back(this->boundary[bd]); } @@ -171,7 +172,7 @@ class Hasse_diagram_cell { Cell_range new_coBoundary; new_coBoundary.reserve(this->coBoundary.size()); - for (size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { + for (std::size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { if (!this->coBoundary[cbd].first->deleted()) { new_coBoundary.push_back(this->coBoundary[cbd]); } @@ -187,7 +188,7 @@ class Hasse_diagram_cell { // cout << "position : " << c.position << ", dimension : " << c.dimension << ", filtration: " << c.filtration << ", // size of boudary : " << c.boundary.size() << "\n"; out << c.position << " " << c.dimension << " " << c.filtration << std::endl; - for (size_t bd = 0; bd != c.boundary.size(); ++bd) { + for (std::size_t bd = 0; bd != c.boundary.size(); ++bd) { // do not write out the cells that has been deleted if (c.boundary[bd].first->deleted()) continue; out << c.boundary[bd].first->position << " " << c.boundary[bd].second << " "; @@ -201,9 +202,9 @@ class Hasse_diagram_cell { **/ inline std::vector get_list_of_boundary_elements() { std::vector result; - size_t size_of_boundary = this->boundary.size(); + std::size_t size_of_boundary = this->boundary.size(); result.reserve(size_of_boundary); - for (size_t bd = 0; bd != size_of_boundary; ++bd) { + for (std::size_t bd = 0; bd != size_of_boundary; ++bd) { result.push_back(this->boundary[bd].first); } return result; @@ -214,9 +215,9 @@ class Hasse_diagram_cell { **/ inline std::vector get_list_of_positions_of_boundary_elements() { std::vector result; - size_t size_of_boundary = this->boundary.size(); + std::size_t size_of_boundary = this->boundary.size(); result.reserve(size_of_boundary); - for (size_t bd = 0; bd != size_of_boundary; ++bd) { + for (std::size_t bd = 0; bd != size_of_boundary; ++bd) { result.push_back(this->boundary[bd].first->position); } return result; @@ -244,14 +245,14 @@ class Hasse_diagram_cell { result += std::to_string(this->additional_info); } result += " boundary "; - for (size_t bd = 0; bd != this->boundary.size(); ++bd) { + for (std::size_t bd = 0; bd != this->boundary.size(); ++bd) { result += "( " + std::to_string(this->boundary[bd].first->position); result += " " + std::to_string(this->boundary[bd].second); result += ") "; } result += " coBoundary "; - for (size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { + for (std::size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { result += "( " + std::to_string(this->coBoundary[cbd].first->position); result += " " + std::to_string(this->coBoundary[cbd].second); result += ") "; diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h index 2a57666d..de68acb6 100644 --- a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation.h @@ -46,28 +46,18 @@ class Coxeter_triangulation : public Freudenthal_triangulation i + 1) cartan(i, j) = 0; Eigen::SelfAdjointEigenSolver saes(cartan); Eigen::VectorXd sqrt_diag(d); for (unsigned i = 0; i < d; ++i) sqrt_diag(i) = std::sqrt(saes.eigenvalues()[i]); - Matrix lower(d, d); - for (unsigned i = 0; i < d; i++) - for (unsigned j = 0; j < d; j++) - if (i < j) - lower(i, j) = 0; - else - lower(i, j) = 1; + Matrix lower(Matrix::Ones(d, d)); + lower = lower.triangularView(); + Matrix result = (lower * saes.eigenvectors() * sqrt_diag.asDiagonal()).inverse(); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h index 43b33d1f..6c4bb534 100644 --- a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -198,7 +198,7 @@ class Freudenthal_triangulation { */ Eigen::VectorXd barycenter(const Simplex_handle& simplex, double scale = 1) const { Eigen::VectorXd res_vector(dimension_); - for (size_t i = 0; i < dimension_; ++i) res_vector(i) = 0; + res_vector.setZero(dimension_, 1); for (auto v : simplex.vertex_range()) { res_vector += cartesian_coordinates(v, scale); } -- cgit v1.2.3 From 22df89d4715fb94c7659955886a529fda3ded2e2 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 25 Sep 2020 09:16:48 +0200 Subject: interface simplification. Remove useless include and typedefs --- src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h | 3 --- .../include/gudhi/Implicit_manifold_intersection_oracle.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h index 6c4bb534..dd059184 100644 --- a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -18,7 +18,6 @@ #include // for std::size_t #include -#include #include #include @@ -46,8 +45,6 @@ template ; - using Triplet = Eigen::Triplet; public: /** \brief Type of the simplices in the triangulation. */ diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index 4f44df7c..25f688de 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -107,6 +107,9 @@ class Implicit_manifold_intersection_oracle { /** \brief Codimension of the implicit manifold. */ std::size_t cod_d() const { return fun_.cod_d(); } + /** \brief The seed point of the implicit manifold. */ + Eigen::VectorXd seed() const { return fun_.seed(); } + /** \brief Intersection query with the relative interior of the manifold. * * \details The returned structure Query_result contains the boolean value -- cgit v1.2.3 From 2e95d8b59db0dca0750fa6d68e720952004e5c32 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 28 Sep 2020 13:44:40 +0200 Subject: Accordingly to boost optional merge --- src/Coxeter_triangulation/test/CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/test/CMakeLists.txt b/src/Coxeter_triangulation/test/CMakeLists.txt index b1900601..175601f9 100644 --- a/src/Coxeter_triangulation/test/CMakeLists.txt +++ b/src/Coxeter_triangulation/test/CMakeLists.txt @@ -3,27 +3,21 @@ project(Coxeter_triangulation_test) include(GUDHI_boost_test) add_executable ( Coxeter_triangulation_permutahedral_representation_test perm_rep_test.cpp ) -target_link_libraries( Coxeter_triangulation_permutahedral_representation_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ) gudhi_add_boost_test(Coxeter_triangulation_permutahedral_representation_test) add_executable ( Coxeter_triangulation_freudenthal_triangulation_test freud_triang_test.cpp ) -target_link_libraries( Coxeter_triangulation_freudenthal_triangulation_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) gudhi_add_boost_test(Coxeter_triangulation_freudenthal_triangulation_test) add_executable ( Coxeter_triangulation_functions_test function_test.cpp ) -target_link_libraries( Coxeter_triangulation_functions_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) gudhi_add_boost_test(Coxeter_triangulation_functions_test) add_executable ( Coxeter_triangulation_oracle_test oracle_test.cpp ) -target_link_libraries( Coxeter_triangulation_oracle_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) gudhi_add_boost_test(Coxeter_triangulation_oracle_test) add_executable ( Coxeter_triangulation_manifold_tracing_test manifold_tracing_test.cpp ) -target_link_libraries( Coxeter_triangulation_manifold_tracing_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) gudhi_add_boost_test(Coxeter_triangulation_manifold_tracing_test) add_executable ( Coxeter_triangulation_cell_complex_test cell_complex_test.cpp ) -target_link_libraries( Coxeter_triangulation_cell_complex_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) if (TBB_FOUND) target_link_libraries(Coxeter_triangulation_cell_complex_test ${TBB_LIBRARIES}) endif() -- cgit v1.2.3 From a4c6ab63074e3d79e2f0432b392f4a1bcedfce8f Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 5 Oct 2020 09:37:39 +0200 Subject: Simplify --- src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index 2873d086..86533f81 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -31,8 +31,7 @@ struct Constant_function : public Function { * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { - Eigen::VectorXd result = value_; - return result; + return value_; } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ -- cgit v1.2.3 From cf30dde33d2463172af32de208909f4638343bec Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 5 Oct 2020 22:07:26 +0200 Subject: Remove the Function inheritance and keep concept --- .../example/manifold_tracing_custom_function.cpp | 10 ++--- .../include/gudhi/Functions/Cartesian_product.h | 12 +++--- .../include/gudhi/Functions/Constant_function.h | 12 +++--- .../include/gudhi/Functions/Embed_in_Rd.h | 12 +++--- .../include/gudhi/Functions/Function.h | 50 ---------------------- .../include/gudhi/Functions/Function_Sm_in_Rd.h | 12 +++--- .../gudhi/Functions/Function_affine_plane_in_Rd.h | 12 +++--- .../include/gudhi/Functions/Function_chair_in_R3.h | 12 +++--- .../include/gudhi/Functions/Function_iron_in_R3.h | 12 +++--- .../Function_lemniscate_revolution_in_R3.h | 12 +++--- .../gudhi/Functions/Function_moment_curve_in_Rd.h | 12 +++--- .../include/gudhi/Functions/Function_torus_in_R3.h | 12 +++--- .../Functions/Function_whitney_umbrella_in_R3.h | 12 +++--- .../gudhi/Functions/Linear_transformation.h | 12 +++--- .../include/gudhi/Functions/Negation.h | 12 +++--- .../include/gudhi/Functions/PL_approximation.h | 14 +++--- .../include/gudhi/Functions/Translate.h | 12 +++--- 17 files changed, 81 insertions(+), 161 deletions(-) delete mode 100644 src/Coxeter_triangulation/include/gudhi/Functions/Function.h (limited to 'src') diff --git a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp index 7e3d95a4..a15756c6 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp @@ -19,8 +19,8 @@ using namespace Gudhi::coxeter_triangulation; * the equation of the manifold is x^3*y + y^3*z + z^3*x = 0. * The embedding consists of restricting the manifold to the affine subspace z = 1. */ -struct Function_surface_on_CP2_in_R4 : public Function { - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { +struct Function_surface_on_CP2_in_R4 { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { // The real and imaginary parts of the variables x and y double xr = p(0), xi = p(1), yr = p(2), yi = p(3); Eigen::VectorXd result(cod_d()); @@ -36,10 +36,10 @@ struct Function_surface_on_CP2_in_R4 : public Function { return result; } - virtual std::size_t amb_d() const override { return 4; }; - virtual std::size_t cod_d() const override { return 2; }; + std::size_t amb_d() const { return 4; }; + std::size_t cod_d() const { return 2; }; - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = Eigen::VectorXd::Zero(4); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h index d1767eca..0533bb83 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -16,8 +16,6 @@ #include // for std::enable_if #include // for std::size_t -#include - #include namespace Gudhi { @@ -96,25 +94,25 @@ inline typename std::enable_if::type get_value(const st * the concept FunctionForImplicitManifold. */ template -struct Cartesian_product : public Function { +struct Cartesian_product { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd result(cod_d_); get_value(function_tuple_, p, result, 0, 0); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return amb_d_; } + std::size_t amb_d() const { return amb_d_; } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return cod_d_; } + std::size_t cod_d() const { return cod_d_; } /** \brief Returns a point on the zero-set. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result(amb_d_); get_seed(function_tuple_, result, 0); return result; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h index 86533f81..0603afd8 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -26,22 +24,22 @@ namespace coxeter_triangulation { * \brief A class that encodes a constant function from R^d to R^k. * This class does not have any implicit manifold in correspondence. */ -struct Constant_function : public Function { +struct Constant_function { /** \brief Value of the function at a specified point. The value is constant. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { return value_; } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - virtual std::size_t amb_d() const override { return d_; }; + std::size_t amb_d() const { return d_; }; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - virtual std::size_t cod_d() const override { return k_; }; + std::size_t cod_d() const { return k_; }; /** \brief No seed point is available. Throws an exception on evocation. */ - virtual Eigen::VectorXd seed() const override { throw "Seed invoked on a constant function.\n"; } + Eigen::VectorXd seed() const { throw "Seed invoked on a constant function.\n"; } Constant_function() {} diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h index bfeda2c3..e1fe868f 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -29,12 +27,12 @@ namespace coxeter_triangulation { * the concept FunctionForImplicitManifold. */ template -struct Embed_in_Rd : public Function { +struct Embed_in_Rd { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd x = p; Eigen::VectorXd x_k(fun_.amb_d()), x_rest(d_ - fun_.amb_d()); for (std::size_t i = 0; i < fun_.amb_d(); ++i) x_k(i) = x(i); @@ -46,13 +44,13 @@ struct Embed_in_Rd : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return d_; } + std::size_t amb_d() const { return d_; } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return d_ - (fun_.amb_d() - fun_.cod_d()); } + std::size_t cod_d() const { return d_ - (fun_.amb_d() - fun_.cod_d()); } /** \brief Returns a point on the zero-set of the embedded function. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = fun_.seed(); result.conservativeResize(d_); for (std::size_t l = fun_.amb_d(); l < d_; ++l) result(l) = 0; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function.h deleted file mode 100644 index eddfedf5..00000000 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function.h +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Siargey Kachanovich - * - * Copyright (C) 2019 Inria - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#ifndef FUNCTIONS_FUNCTION_H_ -#define FUNCTIONS_FUNCTION_H_ - -#include - -namespace Gudhi { - -namespace coxeter_triangulation { - -/** - * \class Function - * \brief The parent class for all functions implemented in the module. - * Contains virtual methods needed to be a model of the concept FunctionForImplicitManifold. - * - * \ingroup coxeter_triangulation - */ -struct Function { - /** \brief Virtual method for the value of the function at a specified point. - * @param[in] p The input point. - */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const = 0; - - /** \brief Virtual method for the domain dimension. */ - virtual std::size_t amb_d() const = 0; - - /** \brief Virtual method for the codomain dimension. */ - virtual std::size_t cod_d() const = 0; - - /** \brief Virtual method for the seed point. */ - virtual Eigen::VectorXd seed() const = 0; - - /** \brief Virtual destructor. */ - virtual ~Function() {} -}; - -} // namespace coxeter_triangulation - -} // namespace Gudhi - -#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h index d901e832..8911f990 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -26,11 +24,11 @@ namespace coxeter_triangulation { * \brief A class for the function that defines an m-dimensional implicit sphere embedded * in the d-dimensional Euclidean space. */ -struct Function_Sm_in_Rd : public Function { +struct Function_Sm_in_Rd { /** \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd x = p; for (std::size_t i = 0; i < d_; ++i) x(i) -= center_[i]; Eigen::VectorXd result = Eigen::VectorXd::Zero(k_); @@ -41,13 +39,13 @@ struct Function_Sm_in_Rd : public Function { } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - virtual std::size_t amb_d() const override { return d_; }; + std::size_t amb_d() const { return d_; }; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - virtual std::size_t cod_d() const override { return k_; }; + std::size_t cod_d() const { return k_; }; /** \brief Returns a point on the sphere. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); result(0) += r_; for (std::size_t i = 0; i < d_; ++i) result(i) += center_[i]; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h index b7414cda..b29f0906 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -26,24 +24,24 @@ namespace coxeter_triangulation { * \brief A class for the function that defines an m-dimensional implicit affine plane * embedded in d-dimensional Euclidean space. */ -struct Function_affine_plane_in_Rd : public Function { +struct Function_affine_plane_in_Rd { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd result = normal_matrix_.transpose() * (p - off_); return result; } /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ - virtual std::size_t amb_d() const override { return d_; }; + std::size_t amb_d() const { return d_; }; /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ - virtual std::size_t cod_d() const override { return k_; }; + std::size_t cod_d() const { return k_; }; /** \brief Returns a point on the affine plane. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = off_; return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h index b30f964f..620446da 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -14,8 +14,6 @@ #include // for std::size_t #include // for std::pow -#include - #include namespace Gudhi { @@ -27,12 +25,12 @@ namespace coxeter_triangulation { * \brief A class that encodes the function, the zero-set of which is a so-called * "chair" surface embedded in R^3. */ -struct Function_chair_in_R3 : public Function { +struct Function_chair_in_R3 { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); result(0) = std::pow(x * x + y * y + z * z - a_ * k_ * k_, 2) - @@ -41,13 +39,13 @@ struct Function_chair_in_R3 : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return 3; } + std::size_t amb_d() const { return 3; } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return 1; } + std::size_t cod_d() const { return 1; } /** \brief Returns a point on the surface. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { double t1 = a_ - b_; double discr = t1 * t1 - (1.0 - b_) * (a_ * a_ - b_); double z0 = k_ * std::sqrt((t1 + std::sqrt(discr)) / (1 - b_)); diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h index def2a99c..f73c4280 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -14,8 +14,6 @@ #include // for std::size_t #include // for std::pow -#include - #include namespace Gudhi { @@ -27,12 +25,12 @@ namespace coxeter_triangulation { * \brief A class that encodes the function, the zero-set of which is a surface * embedded in R^3 that ressembles an iron. */ -struct Function_iron_in_R3 : public Function { +struct Function_iron_in_R3 { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { double x = p(0), y = p(1), z = p(2); Eigen::VectorXd result(cod_d()); result(0) = -std::pow(x, 6) / 300. - std::pow(y, 6) / 300. - std::pow(z, 6) / 300. + x * y * y * z / 2.1 + y * y + @@ -41,13 +39,13 @@ struct Function_iron_in_R3 : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return 3; }; + std::size_t amb_d() const { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return 1; }; + std::size_t cod_d() const { return 1; }; /** \brief Returns a point on the surface. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::Vector3d result(std::pow(4500, 1. / 6), 0, 0); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h index f36ccd3c..beb41e00 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -14,8 +14,6 @@ #include // for std::size_t #include // for std::sqrt -#include - #include namespace Gudhi { @@ -27,12 +25,12 @@ namespace coxeter_triangulation { * \brief A class that encodes the function, the zero-set of which is a surface of revolution * around the x axis based on the lemniscate of Bernoulli embedded in R^3. */ -struct Function_lemniscate_revolution_in_R3 : public Function { +struct Function_lemniscate_revolution_in_R3 { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); double x2 = x * x, y2 = y * y, z2 = z * z, a2 = a_ * a_; @@ -42,16 +40,16 @@ struct Function_lemniscate_revolution_in_R3 : public Function { } /** \brief Returns the (ambient) domain dimension.*/ - virtual std::size_t amb_d() const override { return 3; }; + std::size_t amb_d() const { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return 1; }; + std::size_t cod_d() const { return 1; }; /** \brief Returns a point on the surface. This seed point is only one of * two necessary seed points for the manifold tracing algorithm. * See the method seed2() for the other point. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::Vector3d result(std::sqrt(2 * a_) + off_[0], off_[1], off_[2]); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h index 0db8289b..11b379f3 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -26,24 +24,24 @@ namespace coxeter_triangulation { * \brief A class for the function that defines an implicit moment curve * in the d-dimensional Euclidean space. */ -struct Function_moment_curve_in_Rd : public Function { +struct Function_moment_curve_in_Rd { /** \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd result(k_); for (std::size_t i = 1; i < d_; ++i) result(i - 1) = p(i) - p(0) * p(i - 1); return result; } /** \brief Returns the domain (ambient) dimension.. */ - virtual std::size_t amb_d() const override { return d_; }; + std::size_t amb_d() const { return d_; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return k_; }; + std::size_t cod_d() const { return k_; }; /** \brief Returns a point on the moment curve. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h index 4aa50cfd..b54d3c74 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -14,8 +14,6 @@ #include // for std::size_t #include // for std::sqrt -#include - #include namespace Gudhi { @@ -27,12 +25,12 @@ namespace coxeter_triangulation { * \brief A class that encodes the function, the zero-set of which is a torus * surface embedded in R^3. */ -struct Function_torus_in_R3 : public Function { +struct Function_torus_in_R3 { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); result(0) = (z * z + (std::sqrt(x * x + y * y) - r_) * (std::sqrt(x * x + y * y) - r_) - R_ * R_); @@ -40,13 +38,13 @@ struct Function_torus_in_R3 : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return 3; }; + std::size_t amb_d() const { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return 1; }; + std::size_t cod_d() const { return 1; }; /** \brief Returns a point on the surface. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::Vector3d result(R_ + r_ + off_[0], off_[1], off_[2]); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h index a37fec1c..df1f1eec 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -26,12 +24,12 @@ namespace coxeter_triangulation { * \brief A class that encodes the function, the zero-set of which is the Whitney umbrella * surface embedded in R^3. */ -struct Function_whitney_umbrella_in_R3 : public Function { +struct Function_whitney_umbrella_in_R3 { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; Eigen::VectorXd result(cod_d()); result(0) = x * x - y * y * z; @@ -39,16 +37,16 @@ struct Function_whitney_umbrella_in_R3 : public Function { } /** \brief Returns the (ambient) domain dimension.*/ - virtual std::size_t amb_d() const override { return 3; }; + std::size_t amb_d() const { return 3; }; /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return 1; }; + std::size_t cod_d() const { return 1; }; /** \brief Returns a point on the surface. This seed point is only one of * two necessary seed points for the manifold tracing algorithm. * See the method seed2() for the other point. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::Vector3d result(1 + off_[0], 1 + off_[1], 1 + off_[2]); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h index 9228d487..82e25bb9 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -29,24 +27,24 @@ namespace coxeter_triangulation { * the concept FunctionForImplicitManifold. */ template -struct Linear_transformation : public Function { +struct Linear_transformation { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd result = fun_(matrix_.householderQr().solve(p)); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return fun_.amb_d(); } + std::size_t amb_d() const { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return fun_.cod_d(); } + std::size_t cod_d() const { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = fun_.seed(); result = matrix_ * result; return result; diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h index 1c202cd5..fdf07f27 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -30,24 +28,24 @@ namespace coxeter_triangulation { * the concept FunctionForImplicitManifold. */ template -struct Negation : public Function { +struct Negation { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd result = -fun_(p); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return fun_.amb_d(); } + std::size_t amb_d() const { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return fun_.cod_d(); } + std::size_t cod_d() const { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = fun_.seed(); return result; } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h index 20d4e6a8..22071d6d 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -26,18 +24,18 @@ namespace coxeter_triangulation { * \brief Constructs a piecewise-linear approximation of a function induced by * an ambient triangulation. * - * \tparam Function The function template parameter. Should be a model of + * \tparam Function_ The function template parameter. Should be a model of * the concept FunctionForImplicitManifold. * \tparam Triangulation The triangulation template parameter. Should be a model of * the concept TriangulationForManifoldTracing. */ template -struct PL_approximation : public Function { +struct PL_approximation { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { std::size_t cod_d = this->cod_d(); std::size_t amb_d = this->amb_d(); auto s = tr_.locate_point(p); @@ -62,13 +60,13 @@ struct PL_approximation : public Function { } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return fun_.amb_d(); } + std::size_t amb_d() const { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return fun_.cod_d(); } + std::size_t cod_d() const { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { // TODO: not finished. Should use an oracle. return Eigen::VectorXd(amb_d()); } diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h index fc91a118..cbe65abe 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -13,8 +13,6 @@ #include // for std::size_t -#include - #include namespace Gudhi { @@ -30,24 +28,24 @@ namespace coxeter_triangulation { * the concept FunctionForImplicitManifold. */ template -struct Translate : public Function { +struct Translate { /** * \brief Value of the function at a specified point. * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. */ - virtual Eigen::VectorXd operator()(const Eigen::VectorXd& p) const override { + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { Eigen::VectorXd result = fun_(p - off_); return result; } /** \brief Returns the domain (ambient) dimension. */ - virtual std::size_t amb_d() const override { return fun_.amb_d(); } + std::size_t amb_d() const { return fun_.amb_d(); } /** \brief Returns the codomain dimension. */ - virtual std::size_t cod_d() const override { return fun_.cod_d(); } + std::size_t cod_d() const { return fun_.cod_d(); } /** \brief Returns a point on the zero-set. */ - virtual Eigen::VectorXd seed() const override { + Eigen::VectorXd seed() const { Eigen::VectorXd result = fun_.seed(); result += off_; return result; -- cgit v1.2.3 From b118b86b7f2e7ae9ee7f080ec89d956b161aedfd Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 10 Nov 2020 15:02:29 +0100 Subject: Modify debug traces for coxeter to use gudhi DEBUG_TRACES mechanism --- src/Coxeter_triangulation/include/gudhi/Cell_complex.h | 15 ++++++++------- .../include/gudhi/IO/build_mesh_from_cell_complex.h | 17 +++++++++-------- .../include/gudhi/IO/output_debug_traces_to_html.h | 9 ++++++--- .../include/gudhi/Manifold_tracing.h | 11 ++++++----- 4 files changed, 29 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index 9cac58d9..b386e369 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -17,6 +17,7 @@ #include #include // for std::make_pair +#include // for DEBUG_TRACES #include #include // for Hasse_cell @@ -73,7 +74,7 @@ class Cell_complex { private: Hasse_cell* insert_cell(const Simplex_handle& simplex, std::size_t cell_d, bool is_boundary) { Simplex_cell_maps& simplex_cell_maps = (is_boundary ? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES CC_detail_list& cc_detail_list = (is_boundary ? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); cc_detail_list.emplace_back(CC_detail_info(simplex)); @@ -85,12 +86,12 @@ class Cell_complex { Hasse_cell* new_cell = hasse_cells_.back(); simplex_cell_map.emplace(std::make_pair(simplex, new_cell)); cell_simplex_map_.emplace(std::make_pair(new_cell, simplex)); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES cc_detail_list.back().status_ = CC_detail_info::Result_type::inserted; #endif return new_cell; } -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES CC_detail_info& cc_info = cc_detail_list.back(); cc_info.trigger_ = to_string(map_it->first); cc_info.status_ = CC_detail_info::Result_type::self; @@ -130,7 +131,7 @@ class Cell_complex { } void construct_complex_(const Out_simplex_map_& out_simplex_map) { -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); @@ -148,7 +149,7 @@ class Cell_complex { } void construct_complex_(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); @@ -168,7 +169,7 @@ class Cell_complex { Hasse_cell* new_cell = insert_cell(simplex, 0, false); cell_point_map_.emplace(std::make_pair(new_cell, point)); } -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES for (const auto& sc_pair : interior_simplex_cell_maps_[0]) cc_interior_summary_lists[0].push_back(CC_summary_info(sc_pair)); for (const auto& sc_pair : boundary_simplex_cell_maps_[0]) @@ -179,7 +180,7 @@ class Cell_complex { cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { expand_level(cell_d); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES for (const auto& sc_pair : interior_simplex_cell_maps_[cell_d]) cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); if (cell_d < boundary_simplex_cell_maps_.size()) diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index 0dc98f95..c794cfa4 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -11,6 +11,7 @@ #ifndef IO_BUILD_MESH_FROM_CELL_COMPLEX_H_ #define IO_BUILD_MESH_FROM_CELL_COMPLEX_H_ +#include // for DEBUG_TRACES #include #include @@ -58,7 +59,7 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c for (const std::size_t& v : vertex_indices) barycenter += output.vertex_points[v - 1]; ci_map.emplace(std::make_pair(cell, index++)); output.vertex_points.emplace_back((1. / vertex_indices.size()) * barycenter); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES std::string vlist = " (" + std::to_string(index - 1) + ")"; for (const std::size_t& v : vertex_indices) vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); @@ -66,12 +67,12 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c } if (configuration.toggle_edges && sc_map.size() >= 2) - for (const auto& sc_map : sc_map[1]) { - Hasse_cell* edge_cell = sc_map.second; + for (const auto& sc_pair : sc_map[1]) { + Hasse_cell* edge_cell = sc_pair.second; Mesh_element_vertices edge; for (const auto& vi_pair : edge_cell->get_boundary()) edge.push_back(vi_map[vi_pair.first]); output.edges.emplace_back(std::make_pair(edge, configuration.ref_edges)); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES std::string vlist; for (const std::size_t& v : edge) vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(edge_cell), vlist)); @@ -97,7 +98,7 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c for (const auto& vi_pair : ei_pair.first->get_boundary()) vertex_indices.emplace(vi_map[vi_pair.first]); for (const std::size_t& v : vertex_indices) barycenter += output.vertex_points[v - 1]; output.vertex_points.emplace_back((1. / vertex_indices.size()) * barycenter); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES std::string vlist = " (" + std::to_string(index) + ")"; for (const std::size_t& v : vertex_indices) vlist += " " + std::to_string(v); cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); @@ -126,7 +127,7 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, std::size_t amb_d = std::min((int)cell_complex.cell_point_map().begin()->second.size(), 3); for (const auto& cp_pair : cell_complex.cell_point_map()) { -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES std::string vlist; vlist += " " + std::to_string(index); cell_vlist_map.emplace(std::make_pair(to_string(cp_pair.first), vlist)); @@ -137,7 +138,7 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, } populate_mesh(output, cell_complex.interior_simplex_cell_maps(), i_configuration, amb_d, vi_map); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES for (const auto& sc_map : cell_complex.interior_simplex_cell_maps()) for (const auto& sc_pair : sc_map) { std::string simplex = "I" + to_string(sc_pair.first); @@ -147,7 +148,7 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, } #endif populate_mesh(output, cell_complex.boundary_simplex_cell_maps(), b_configuration, amb_d, vi_map); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES for (const auto& sc_map : cell_complex.boundary_simplex_cell_maps()) for (const auto& sc_pair : sc_map) { std::string simplex = "B" + to_string(sc_pair.first); diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h index 147ab908..1d5ee4cd 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h @@ -1,5 +1,7 @@ -#ifdef GUDHI_DEBUG -#define GUDHI_COX_OUTPUT_TO_HTML +#ifndef IO_OUTPUT_DEBUG_TRACES_TO_HTML_H_ +#define IO_OUTPUT_DEBUG_TRACES_TO_HTML_H_ + +#ifdef DEBUG_TRACES // All this part of code can be skipped if DEBUG_TRACES are not ON - cmake -DDEBUG_TRACES=ON . #include #include @@ -544,4 +546,5 @@ void write_to_html(std::string file_name) { } // namespace Gudhi -#endif +#endif // DEBUG_TRACES +#endif // IO_OUTPUT_DEBUG_TRACES_TO_HTML_H_ diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index b678566a..f7de5252 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -11,6 +11,7 @@ #ifndef MANIFOLD_TRACING_H_ #define MANIFOLD_TRACING_H_ +#include // for DEBUG_TRACES #include #include @@ -85,7 +86,7 @@ class Manifold_tracing { for (Simplex_handle face : full_simplex.face_range(cod_d)) { Query_result qr = oracle.intersects(face, triangulation); if (qr.success && out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); #endif queue.emplace(face); @@ -141,7 +142,7 @@ class Manifold_tracing { Simplex_handle full_simplex = triangulation.locate_point(p); for (Simplex_handle face : full_simplex.face_range(cod_d)) { auto qr = oracle.intersects(face, triangulation); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); #endif if (qr.success) { @@ -150,7 +151,7 @@ class Manifold_tracing { } else { for (Simplex_handle cof : face.coface_range(cod_d + 1)) { auto qrb = oracle.intersects_boundary(cof, triangulation); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES mt_seed_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); #endif if (qrb.success) boundary_simplex_map.emplace(cof, qrb.intersection); @@ -167,7 +168,7 @@ class Manifold_tracing { for (auto cof : s.coface_range(cod_d + 1)) { for (auto face : cof.face_range(cod_d)) { auto qr = oracle.intersects(face, triangulation); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES mt_inserted_list.push_back(MT_inserted_info(qr, face, false)); #endif if (qr.success) { @@ -175,7 +176,7 @@ class Manifold_tracing { if (interior_simplex_map.emplace(face, qr.intersection).second) queue.emplace(face); } else { auto qrb = oracle.intersects_boundary(cof, triangulation); -#ifdef GUDHI_COX_OUTPUT_TO_HTML +#ifdef DEBUG_TRACES mt_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); #endif // assert (qrb.success); // always a success -- cgit v1.2.3 From 1d7c18e91a73a539e807d323a47d32bbba18dac7 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 10 Nov 2020 15:48:33 +0100 Subject: Add this check in debug mode --- src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h index dd059184..845e4883 100644 --- a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -149,6 +149,7 @@ class Freudenthal_triangulation { } else { Eigen::VectorXd p_vect(d); for (std::size_t i = 0; i < d; i++) p_vect(i) = point[i]; + assert(p_vect.size() == offset_.size()); Eigen::VectorXd x_vect = colpivhouseholderqr_.solve(p_vect - offset_); for (std::size_t i = 0; i < d; i++) { double x_i = scale * x_vect(i); -- cgit v1.2.3 From f16921c170dee7a7f987afcfa5de923ac8d37dd5 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 17 Nov 2020 11:45:32 +0100 Subject: Some doxygen improvements with a cell complex construction basic example --- .../doc/intro_coxeter_triangulation.h | 15 +++++- src/Coxeter_triangulation/example/CMakeLists.txt | 7 +++ .../cell_complex_from_basic_circle_manifold.cpp | 55 ++++++++++++++++++++++ ..._complex_from_basic_circle_manifold_for_doc.txt | 26 ++++++++++ .../gudhi/Cell_complex/Hasse_diagram_cell.h | 2 - 5 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp create mode 100644 src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold_for_doc.txt (limited to 'src') diff --git a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h index 5eb0cb22..3316bd81 100644 --- a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h +++ b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h @@ -196,20 +196,31 @@ the vertex cells in the cell complex to their Cartesian coordinates. \section example Examples +\subsection examplewithoutboundaries Basic example without boundaries +\include Coxeter_triangulation/cell_complex_from_basic_circle_manifold.cpp + +The program output is: + +\include Coxeter_triangulation/cell_complex_from_basic_circle_manifold_for_doc.txt + +\subsection exampleswithboundaries Example with boundaries + Here is an example of constructing a piecewise-linear approximation of a flat torus embedded in \f$\mathbb{R}^4\f$, rotated by a random rotation in \f$\mathbb{R}^4\f$ and cut by a hyperplane. \include Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp -The output in medit is: +The output in medit is: \image html "flat_torus_with_boundary.png" "Output from the example of a flat torus with boundary" +\subsection exampleswithcustomfunction Example with a custom function + In the following more complex example, we define a custom function for the implicit manifold. \include Coxeter_triangulation/manifold_tracing_custom_function.cpp -The output in medit looks as follows: +The output in medit looks as follows: \image html "custom_function.png" "Output from the example with a custom function" diff --git a/src/Coxeter_triangulation/example/CMakeLists.txt b/src/Coxeter_triangulation/example/CMakeLists.txt index cbab2024..e7822ff7 100644 --- a/src/Coxeter_triangulation/example/CMakeLists.txt +++ b/src/Coxeter_triangulation/example/CMakeLists.txt @@ -13,3 +13,10 @@ if (TBB_FOUND) endif() add_test(NAME Coxeter_triangulation_manifold_tracing_custom_function_example COMMAND $) + +add_executable ( Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example cell_complex_from_basic_circle_manifold.cpp ) +if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example ${TBB_LIBRARIES}) +endif() +add_test(NAME Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example + COMMAND $) diff --git a/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp new file mode 100644 index 00000000..0d32f916 --- /dev/null +++ b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp @@ -0,0 +1,55 @@ +#include + +#include +#include // for Gudhi::coxeter_triangulation::make_oracle +#include +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +int main(int argc, char** argv) { + // Oracle is a circle of radius 1 + double radius = 1.; + auto oracle = make_oracle(Function_Sm_in_Rd(radius, 1)); + + // Define a Coxeter triangulation. + Coxeter_triangulation<> cox_tr(oracle.amb_d()); + // Theory forbids that a vertex of the triangulation lies exactly on the circle. + // Add some offset to avoid algorithm degeneracies. + cox_tr.change_offset(-Eigen::VectorXd::Random(oracle.amb_d())); + // For a better manifold approximation, one can change the circle radius value or change the linear transformation + // matrix. + // The number of points and edges will increase with a better resolution. + //cox_tr.change_matrix(0.5 * cox_tr.matrix()); + + // Manifold tracing algorithm + using Out_simplex_map = typename Manifold_tracing >::Out_simplex_map; + + std::vector seed_points(1, oracle.seed()); + Out_simplex_map interior_simplex_map; + manifold_tracing_algorithm(seed_points, cox_tr, oracle, interior_simplex_map); + + // Constructing the cell complex + std::size_t intr_d = oracle.amb_d() - oracle.cod_d(); + Cell_complex cell_complex(intr_d); + cell_complex.construct_complex(interior_simplex_map); + + // List of Hasse_cell pointers to retrieve vertices values from edges + std::map::Hasse_cell*, std::size_t> vi_map; + std::size_t index = 0; + + std::clog << "Vertices:" << std::endl; + for (const auto& cp_pair : cell_complex.cell_point_map()) { + std::clog << index << " : (" << cp_pair.second(0) << ", " << cp_pair.second(1) << ")" << std::endl; + vi_map.emplace(std::make_pair(cp_pair.first, index++)); + } + + std::clog << "Edges:" << std::endl; + for (const auto& sc_pair : cell_complex.interior_simplex_cell_map(1)) { + Cell_complex::Hasse_cell* edge_cell = sc_pair.second; + for (const auto& vi_pair : edge_cell->get_boundary()) std::clog << vi_map[vi_pair.first] << " "; + std::clog << std::endl; + } + return 0; +} diff --git a/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold_for_doc.txt b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold_for_doc.txt new file mode 100644 index 00000000..b323cca3 --- /dev/null +++ b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold_for_doc.txt @@ -0,0 +1,26 @@ +Vertices: +0 : (-0.680375, 0.523483) +1 : (0.147642, 0.887879) +2 : (-0.847996, 0.30801) +3 : (-0.881369, 0.0951903) +4 : (0.638494, -0.550215) +5 : (0.415344, 0.843848) +6 : (0.812453, -0.0815816) +7 : (0.319625, -0.7709) +8 : (0.319625, 0.889605) +9 : (0.579487, 0.638553) +10 : (-0.680375, -0.461325) +11 : (-0.364269, -0.760962) +Edges: +3 2 +3 10 +10 11 +11 7 +7 4 +2 0 +0 1 +6 9 +6 4 +1 8 +8 5 +5 9 diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h index 24045c0c..04d50784 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -36,8 +36,6 @@ class Hasse_diagram; * It also allow to store any additional information of a type Additional_information which is a template parameter of * the class (set by default to void). * - * Please refer to \ref Hasse_diagram for examples. - * * The complex is a template class requiring the following parameters: * Incidence_type_ - determine the type of incidence coefficients. Use integers in most general case. * Filtration_type_ - type of filtration of cells. -- cgit v1.2.3 From 62c5397566747b29bd3e8f456dd76df22b558e84 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 17 Nov 2020 22:51:17 +0100 Subject: Unvalid lambdas when matrix.colPivHouseholderQr().solve(z) is not a solution --- .../gudhi/Implicit_manifold_intersection_oracle.h | 25 ++++++++++++++++++---- .../test/manifold_tracing_test.cpp | 4 ++-- 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index 25f688de..dca97331 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -17,8 +17,11 @@ #include #include #include +#include // for GUDHI_CHECK #include +#include // for std::numeric_limits<> +#include // for std::fabs namespace Gudhi { @@ -53,6 +56,11 @@ class Implicit_manifold_intersection_oracle { z(0) = 1; for (std::size_t i = 1; i < cod_d + 1; ++i) z(i) = 0; Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z); + if (!z.isApprox(matrix*lambda)) { + // NaN non valid results + for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) lambda(i) = + std::numeric_limits::quiet_NaN(); + } return lambda; } @@ -75,6 +83,11 @@ class Implicit_manifold_intersection_oracle { z(0) = 1; for (std::size_t i = 1; i < cod_d + 2; ++i) z(i) = 0; Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z); + if (!z.isApprox(matrix*lambda)) { + // NaN non valid results + for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) lambda(i) = + std::numeric_limits::quiet_NaN(); + } return lambda; } @@ -85,10 +98,13 @@ class Implicit_manifold_intersection_oracle { using QR = Query_result; std::size_t amb_d = triangulation.dimension(); std::size_t cod_d = simplex.dimension(); - - for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) - if (lambda(i) < 0 || lambda(i) > 1) return QR({Eigen::VectorXd(), false}); - + for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) { + if (std::isnan(lambda(i))) return QR({Eigen::VectorXd(), false}); + GUDHI_CHECK((std::fabs(lambda(i) - 1.) > std::numeric_limits::epsilon() && + std::fabs(lambda(i) - 0.) > std::numeric_limits::epsilon()), + std::invalid_argument("A vertex of the triangulation lies exactly on the manifold")); + if (lambda(i) < 0. || lambda(i) > 1.) return QR({Eigen::VectorXd(), false}); + } Eigen::MatrixXd vertex_matrix(cod_d + 1, amb_d); auto v_range = simplex.vertex_range(); auto v_it = v_range.begin(); @@ -159,6 +175,7 @@ class Implicit_manifold_intersection_oracle { template Query_result intersects_boundary(const Simplex_handle& simplex, const Triangulation& triangulation) const { + //std::cout << "intersects_boundary" << std::endl; Eigen::VectorXd lambda = compute_boundary_lambda(simplex, triangulation); return intersection_result(lambda, simplex, triangulation); } diff --git a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp index 68b79487..2d7d6087 100644 --- a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp +++ b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } std::cout << "out_simplex_map.size() = " << out_simplex_map.size() << "\n"; - BOOST_CHECK(out_simplex_map.size() == 1140); + BOOST_CHECK(out_simplex_map.size() == 1118); // manifold with boundary Function_Sm_in_Rd fun_boundary(3.0, 2, fun_sph.seed()); @@ -58,5 +58,5 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } std::cout << "boundary_simplex_map.size() = " << boundary_simplex_map.size() << "\n"; - BOOST_CHECK(boundary_simplex_map.size() == 55); + BOOST_CHECK(boundary_simplex_map.size() == 54); } -- cgit v1.2.3 From 0bdf0dfbf29a39b0de47a8600331c3cc7d78d6ed Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 17 Nov 2020 22:55:13 +0100 Subject: Use std::clog for test logs --- src/Coxeter_triangulation/test/manifold_tracing_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp index 2d7d6087..63497f5a 100644 --- a/src/Coxeter_triangulation/test/manifold_tracing_test.cpp +++ b/src/Coxeter_triangulation/test/manifold_tracing_test.cpp @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { BOOST_CHECK(si_pair.first.dimension() == oracle.function().cod_d()); BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } - std::cout << "out_simplex_map.size() = " << out_simplex_map.size() << "\n"; + std::clog << "out_simplex_map.size() = " << out_simplex_map.size() << "\n"; BOOST_CHECK(out_simplex_map.size() == 1118); // manifold with boundary @@ -51,12 +51,12 @@ BOOST_AUTO_TEST_CASE(manifold_tracing) { BOOST_CHECK(si_pair.first.dimension() == oracle.function().cod_d()); BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } - std::cout << "interior_simplex_map.size() = " << interior_simplex_map.size() << "\n"; + std::clog << "interior_simplex_map.size() = " << interior_simplex_map.size() << "\n"; BOOST_CHECK(interior_simplex_map.size() == 96); for (auto si_pair : boundary_simplex_map) { BOOST_CHECK(si_pair.first.dimension() == oracle.function().cod_d() + 1); BOOST_CHECK(si_pair.second.size() == (long int)oracle.function().amb_d()); } - std::cout << "boundary_simplex_map.size() = " << boundary_simplex_map.size() << "\n"; + std::clog << "boundary_simplex_map.size() = " << boundary_simplex_map.size() << "\n"; BOOST_CHECK(boundary_simplex_map.size() == 54); } -- cgit v1.2.3 From c6fe07e6d403e733047b1ce4d86c0d5f7b4d4f38 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 18 Nov 2020 07:52:49 +0100 Subject: Use GUDHI_CHECK and exceptions instead of asserts and test them --- .../include/gudhi/Freudenthal_triangulation.h | 35 +++++++++++----------- .../include/gudhi/Manifold_tracing.h | 1 - .../test/freud_triang_test.cpp | 15 ++++++++++ 3 files changed, 33 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h index 845e4883..873c5c9b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h +++ b/src/Coxeter_triangulation/include/gudhi/Freudenthal_triangulation.h @@ -21,6 +21,7 @@ #include #include +#include // for GUDHI_CHECK namespace Gudhi { @@ -57,11 +58,9 @@ class Freudenthal_triangulation { * @param[in] dimension The dimension of the triangulation. */ Freudenthal_triangulation(std::size_t dimension) - : dimension_(dimension), - matrix_(Matrix::Identity(dimension, dimension)), - offset_(Vector::Zero(dimension)), - colpivhouseholderqr_(matrix_.colPivHouseholderQr()), - is_freudenthal(true) {} + : Freudenthal_triangulation(dimension, Matrix::Identity(dimension, dimension), Vector::Zero(dimension)) { + is_freudenthal_ = true; + } /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension under * a linear transformation by a given matrix. @@ -70,11 +69,7 @@ class Freudenthal_triangulation { * Needs to be invertible. */ Freudenthal_triangulation(std::size_t dimension, const Matrix& matrix) - : dimension_(dimension), - matrix_(matrix), - offset_(Vector::Zero(dimension)), - colpivhouseholderqr_(matrix_.colPivHouseholderQr()), - is_freudenthal(false) {} + : Freudenthal_triangulation(dimension, matrix, Vector::Zero(dimension)) {} /** \brief Constructor of the Freudenthal-Kuhn triangulation of a given dimension under * an affine transformation by a given matrix and a translation vector. @@ -82,13 +77,17 @@ class Freudenthal_triangulation { * @param[in] matrix The matrix that defines the linear transformation. * Needs to be invertible. * @param[in] offset The offset vector. + * + * @exception std::invalid_argument In debug mode, if offset size is different from dimension. */ Freudenthal_triangulation(unsigned dimension, const Matrix& matrix, const Vector& offset) : dimension_(dimension), matrix_(matrix), offset_(offset), colpivhouseholderqr_(matrix_.colPivHouseholderQr()), - is_freudenthal(false) {} + is_freudenthal_(false) { + GUDHI_CHECK(dimension == offset_.size(), std::invalid_argument("Offset must be of size 'dimension'")); + } /** \brief Dimension of the triangulation. */ unsigned dimension() const { return dimension_; } @@ -105,7 +104,7 @@ class Freudenthal_triangulation { void change_matrix(const Eigen::MatrixXd& matrix) { matrix_ = matrix; colpivhouseholderqr_ = matrix.colPivHouseholderQr(); - is_freudenthal = false; + is_freudenthal_ = false; } /** \brief Change the offset vector to a given value. @@ -113,7 +112,7 @@ class Freudenthal_triangulation { */ void change_offset(const Eigen::VectorXd& offset) { offset_ = offset; - is_freudenthal = false; + is_freudenthal_ = false; } /** \brief Returns the permutahedral representation of the simplex in the @@ -129,17 +128,20 @@ class Freudenthal_triangulation { * * @param[in] point The query point. * @param[in] scale The scale of the triangulation. + * + * @exception std::invalid_argument In debug mode, if point dimension is different from triangulation one. */ template Simplex_handle locate_point(const Point_d& point, double scale = 1) const { using Ordered_set_partition = typename Simplex_handle::OrderedSetPartition; using Part = typename Ordered_set_partition::value_type; unsigned d = point.size(); - assert(d == dimension_); + GUDHI_CHECK(d == dimension_, + std::invalid_argument("The point must be of the same dimension as the triangulation")); double error = 1e-9; Simplex_handle output; std::vector z; - if (is_freudenthal) { + if (is_freudenthal_) { for (std::size_t i = 0; i < d; i++) { double x_i = scale * point[i]; int y_i = std::floor(x_i); @@ -149,7 +151,6 @@ class Freudenthal_triangulation { } else { Eigen::VectorXd p_vect(d); for (std::size_t i = 0; i < d; i++) p_vect(i) = point[i]; - assert(p_vect.size() == offset_.size()); Eigen::VectorXd x_vect = colpivhouseholderqr_.solve(p_vect - offset_); for (std::size_t i = 0; i < d; i++) { double x_i = scale * x_vect(i); @@ -208,7 +209,7 @@ class Freudenthal_triangulation { Matrix matrix_; Vector offset_; Eigen::ColPivHouseholderQR colpivhouseholderqr_; - bool is_freudenthal; + bool is_freudenthal_; }; } // namespace coxeter_triangulation diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index f7de5252..69daf390 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -179,7 +179,6 @@ class Manifold_tracing { #ifdef DEBUG_TRACES mt_inserted_list.push_back(MT_inserted_info(qrb, cof, true)); #endif - // assert (qrb.success); // always a success if (qrb.success) boundary_simplex_map.emplace(cof, qrb.intersection); } } diff --git a/src/Coxeter_triangulation/test/freud_triang_test.cpp b/src/Coxeter_triangulation/test/freud_triang_test.cpp index 9e06acc9..2cf8f00e 100644 --- a/src/Coxeter_triangulation/test/freud_triang_test.cpp +++ b/src/Coxeter_triangulation/test/freud_triang_test.cpp @@ -97,3 +97,18 @@ BOOST_AUTO_TEST_CASE(freudenthal_triangulation) { BOOST_CHECK(tr.matrix() == new_matrix); BOOST_CHECK(tr.offset() == new_offset); } + +#ifdef GUDHI_DEBUG +BOOST_AUTO_TEST_CASE(freudenthal_triangulation_exceptions_in_debug_mode) { + // Point location check + typedef Gudhi::coxeter_triangulation::Freudenthal_triangulation<> FK_triangulation; + + BOOST_CHECK_THROW (FK_triangulation tr(3, Eigen::MatrixXd::Identity(3, 3), Eigen::VectorXd::Zero(4)), + std::invalid_argument); + + FK_triangulation tr(3); + // Point of dimension 4 + std::vector point({3.5, -1.8, 0.3, 4.1}); + BOOST_CHECK_THROW (tr.locate_point(point), std::invalid_argument); +} +#endif -- cgit v1.2.3 From 2750e632b1419741ca1b720df0103f18dd954ae1 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 1 Apr 2021 09:16:52 +0200 Subject: make Simplex_handle and Simplex_hash public for fibration purpose --- src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index 69daf390..1083e827 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -37,7 +37,8 @@ namespace coxeter_triangulation { */ template class Manifold_tracing { - typedef typename Triangulation_::Simplex_handle Simplex_handle; + public: + using Simplex_handle = typename Triangulation_::Simplex_handle; struct Simplex_hash { typedef Simplex_handle argument_type; -- cgit v1.2.3 From 29fa56b6768d7314fcddf39d7681aa6a82417b4e Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 21 Apr 2021 10:08:19 +0200 Subject: cell complex is only for coxeter. eigen is required for coxeter, not cgal --- src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h | 5 +++++ src/Coxeter_triangulation/include/gudhi/Cell_complex.h | 10 +++------- src/common/doc/main_page.md | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h index 3316bd81..99239e3a 100644 --- a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h +++ b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h @@ -166,6 +166,8 @@ The base function classes above can be composed or modified into new functions u The type of \f$T\f$ is required to be a model of the concept \ref Gudhi::coxeter_triangulation::TriangulationForManifoldTracing "TriangulationForManifoldTracing". +It is also possible to implement your own function as detailed in this \ref exampleswithcustomfunction. + \section cellcomplex Cell complex construction The output of the manifold tracing algorithm can be transformed into the Hasse diagram of a cell complex that @@ -194,6 +196,9 @@ triangulation. \li The method \ref Gudhi::coxeter_triangulation::Cell_complex::cell_point_map() "cell_point_map()" returns a map from the vertex cells in the cell complex to their Cartesian coordinates. +The use and interfaces of this \ref Gudhi::coxeter_triangulation::Cell_complex "Cell_complex" is limited to the +Coxeter_triangulation implementation. + \section example Examples \subsection examplewithoutboundaries Basic example without boundaries diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index b386e369..219f525b 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -25,18 +25,14 @@ namespace Gudhi { namespace coxeter_triangulation { -/** - * \ingroup coxeter_triangulation - */ - /** \class Cell_complex * \brief A class that constructs the cell complex from the output provided by the class - * Gudhi::Manifold_tracing. + * \ref Gudhi::coxeter_triangulation::Manifold_tracing. + * + * The use and interfaces of this cell complex is limited to the \ref coxeter_triangulation implementation. * * \tparam Out_simplex_map_ The type of a map from a simplex type that is a * model of SimplexInCoxeterTriangulation to Eigen::VectorXd. - * - * \ingroup coxeter_triangulation */ template class Cell_complex { diff --git a/src/common/doc/main_page.md b/src/common/doc/main_page.md index c58b6994..17354179 100644 --- a/src/common/doc/main_page.md +++ b/src/common/doc/main_page.md @@ -314,7 +314,7 @@ Author: Siargey Kachanovich
      Introduced in: GUDHI 3.4.0
      Copyright: MIT [(LGPL v3)](../../licensing/)
      - Requires: \ref cgal ≥ 4.11.0 + Requires: \ref eigen ≥ 3.1.0
      -- cgit v1.2.3 From 130c3057bfef7c4c1e0ee0b1940c34bc2f9d6c33 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 21 Apr 2021 11:22:18 +0200 Subject: coxeter requires eigen3. random_orthogonal_matrix requires CGAL --- src/Coxeter_triangulation/example/CMakeLists.txt | 46 +++++++++++--------- .../example/manifold_tracing_custom_function.cpp | 1 - .../manifold_tracing_flat_torus_with_boundary.cpp | 2 +- src/Coxeter_triangulation/test/CMakeLists.txt | 49 +++++++++++++--------- src/Coxeter_triangulation/test/function_test.cpp | 12 ------ .../random_orthogonal_matrix_function_test.cpp | 36 ++++++++++++++++ 6 files changed, 92 insertions(+), 54 deletions(-) create mode 100644 src/Coxeter_triangulation/test/random_orthogonal_matrix_function_test.cpp (limited to 'src') diff --git a/src/Coxeter_triangulation/example/CMakeLists.txt b/src/Coxeter_triangulation/example/CMakeLists.txt index e7822ff7..840e24e4 100644 --- a/src/Coxeter_triangulation/example/CMakeLists.txt +++ b/src/Coxeter_triangulation/example/CMakeLists.txt @@ -1,22 +1,28 @@ project(Coxeter_triangulation_example) -add_executable ( Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example manifold_tracing_flat_torus_with_boundary.cpp ) -if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${TBB_LIBRARIES}) -endif() -add_test(NAME Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example - COMMAND $) - -add_executable ( Coxeter_triangulation_manifold_tracing_custom_function_example manifold_tracing_custom_function.cpp ) -if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_manifold_tracing_custom_function_example ${TBB_LIBRARIES}) -endif() -add_test(NAME Coxeter_triangulation_manifold_tracing_custom_function_example - COMMAND $) - -add_executable ( Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example cell_complex_from_basic_circle_manifold.cpp ) -if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example ${TBB_LIBRARIES}) -endif() -add_test(NAME Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example - COMMAND $) +if (NOT EIGEN3_VERSION VERSION_LESS 3.1.0) + # because of random_orthogonal_matrix inclusion + if (NOT CGAL_VERSION VERSION_LESS 4.11.0) + add_executable ( Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example manifold_tracing_flat_torus_with_boundary.cpp ) + target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${CGAL_LIBRARY}) + if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${TBB_LIBRARIES}) + endif() + add_test(NAME Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example + COMMAND $) + endif() + + add_executable ( Coxeter_triangulation_manifold_tracing_custom_function_example manifold_tracing_custom_function.cpp ) + if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_manifold_tracing_custom_function_example ${TBB_LIBRARIES}) + endif() + add_test(NAME Coxeter_triangulation_manifold_tracing_custom_function_example + COMMAND $) + + add_executable ( Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example cell_complex_from_basic_circle_manifold.cpp ) + if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example ${TBB_LIBRARIES}) + endif() + add_test(NAME Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example + COMMAND $) +endif() \ No newline at end of file diff --git a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp index a15756c6..3a36aed4 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include diff --git a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp index 2260e692..4b5e29fc 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include // requires CGAL #include #include diff --git a/src/Coxeter_triangulation/test/CMakeLists.txt b/src/Coxeter_triangulation/test/CMakeLists.txt index 175601f9..3da2410f 100644 --- a/src/Coxeter_triangulation/test/CMakeLists.txt +++ b/src/Coxeter_triangulation/test/CMakeLists.txt @@ -2,23 +2,32 @@ project(Coxeter_triangulation_test) include(GUDHI_boost_test) -add_executable ( Coxeter_triangulation_permutahedral_representation_test perm_rep_test.cpp ) -gudhi_add_boost_test(Coxeter_triangulation_permutahedral_representation_test) - -add_executable ( Coxeter_triangulation_freudenthal_triangulation_test freud_triang_test.cpp ) -gudhi_add_boost_test(Coxeter_triangulation_freudenthal_triangulation_test) - -add_executable ( Coxeter_triangulation_functions_test function_test.cpp ) -gudhi_add_boost_test(Coxeter_triangulation_functions_test) - -add_executable ( Coxeter_triangulation_oracle_test oracle_test.cpp ) -gudhi_add_boost_test(Coxeter_triangulation_oracle_test) - -add_executable ( Coxeter_triangulation_manifold_tracing_test manifold_tracing_test.cpp ) -gudhi_add_boost_test(Coxeter_triangulation_manifold_tracing_test) - -add_executable ( Coxeter_triangulation_cell_complex_test cell_complex_test.cpp ) -if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_cell_complex_test ${TBB_LIBRARIES}) -endif() -gudhi_add_boost_test(Coxeter_triangulation_cell_complex_test) \ No newline at end of file +if (NOT EIGEN3_VERSION VERSION_LESS 3.1.0) + add_executable ( Coxeter_triangulation_permutahedral_representation_test perm_rep_test.cpp ) + gudhi_add_boost_test(Coxeter_triangulation_permutahedral_representation_test) + + add_executable ( Coxeter_triangulation_freudenthal_triangulation_test freud_triang_test.cpp ) + gudhi_add_boost_test(Coxeter_triangulation_freudenthal_triangulation_test) + + add_executable ( Coxeter_triangulation_functions_test function_test.cpp ) + gudhi_add_boost_test(Coxeter_triangulation_functions_test) + + # because of random_orthogonal_matrix inclusion + if (NOT CGAL_VERSION VERSION_LESS 4.11.0) + add_executable ( Coxeter_triangulation_random_orthogonal_matrix_function_test random_orthogonal_matrix_function_test.cpp ) + target_link_libraries(Coxeter_triangulation_random_orthogonal_matrix_function_test ${CGAL_LIBRARY}) + gudhi_add_boost_test(Coxeter_triangulation_random_orthogonal_matrix_function_test) + endif() + + add_executable ( Coxeter_triangulation_oracle_test oracle_test.cpp ) + gudhi_add_boost_test(Coxeter_triangulation_oracle_test) + + add_executable ( Coxeter_triangulation_manifold_tracing_test manifold_tracing_test.cpp ) + gudhi_add_boost_test(Coxeter_triangulation_manifold_tracing_test) + + add_executable ( Coxeter_triangulation_cell_complex_test cell_complex_test.cpp ) + if (TBB_FOUND) + target_link_libraries(Coxeter_triangulation_cell_complex_test ${TBB_LIBRARIES}) + endif() + gudhi_add_boost_test(Coxeter_triangulation_cell_complex_test) +endif() \ No newline at end of file diff --git a/src/Coxeter_triangulation/test/function_test.cpp b/src/Coxeter_triangulation/test/function_test.cpp index d3c8d46c..43dbcb75 100644 --- a/src/Coxeter_triangulation/test/function_test.cpp +++ b/src/Coxeter_triangulation/test/function_test.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -110,17 +109,6 @@ BOOST_AUTO_TEST_CASE(function) { Function_moment_curve_in_Rd fun_moment_curve(3, 5); test_function(fun_moment_curve); } - { - // random orthogonal matrix - Eigen::MatrixXd matrix = random_orthogonal_matrix(5); - Eigen::MatrixXd id_matrix = matrix.transpose() * matrix; - for (std::size_t i = 0; i < 5; ++i) - for (std::size_t j = 0; j < 5; ++j) - if (i == j) - GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i, j), 1.0, 1e-10); - else - GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i, j), 0.0, 1e-10); - } { // function embedding Function_iron_in_R3 fun_iron; diff --git a/src/Coxeter_triangulation/test/random_orthogonal_matrix_function_test.cpp b/src/Coxeter_triangulation/test/random_orthogonal_matrix_function_test.cpp new file mode 100644 index 00000000..84178741 --- /dev/null +++ b/src/Coxeter_triangulation/test/random_orthogonal_matrix_function_test.cpp @@ -0,0 +1,36 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "random_orthogonal_matrix_function" +#include +#include + +#include + +#include + +#include +#include + +using namespace Gudhi::coxeter_triangulation; + +// this test is separated as it requires CGAL +BOOST_AUTO_TEST_CASE(random_orthogonal_matrix_function) { + // random orthogonal matrix + Eigen::MatrixXd matrix = random_orthogonal_matrix(5); + Eigen::MatrixXd id_matrix = matrix.transpose() * matrix; + for (std::size_t i = 0; i < 5; ++i) + for (std::size_t j = 0; j < 5; ++j) + if (i == j) + GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i, j), 1.0, 1e-10); + else + GUDHI_TEST_FLOAT_EQUALITY_CHECK(id_matrix(i, j), 0.0, 1e-10); +} -- cgit v1.2.3 From af94bf9de8a4c08fe4d9a0c8719ae696b501169f Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 21 Apr 2021 14:25:24 +0200 Subject: doc review: build_mesh_from_cell_complex and output_meshes_to_medit was not documented --- src/Coxeter_triangulation/include/gudhi/Cell_complex.h | 2 +- src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h | 8 ++++---- .../include/gudhi/IO/build_mesh_from_cell_complex.h | 4 ++++ .../include/gudhi/IO/output_meshes_to_medit.h | 5 ++++- 4 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index 219f525b..60c83522 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -315,7 +315,7 @@ class Cell_complex { const Cell_point_map& cell_point_map() const { return cell_point_map_; } /** - * \brief Conxtructor for the class Cell_complex. + * \brief Constructor for the class Cell_complex. * * \param[in] intrinsic_dimension The dimension of the cell complex. */ diff --git a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h index 203ed6c5..ca08f629 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/Mesh_medit.h @@ -20,11 +20,11 @@ namespace Gudhi { namespace coxeter_triangulation { -/* \class Mesh_medit - * \brief Structure to store a mesh that can be output in Medit .mesh file format - * using the output_meshes_to_medit method. +/** \class Mesh_medit + * \brief Structure to store a mesh that can be output in Medit .mesh file format + * using the output_meshes_to_medit method. * - * \ingroup coxeter_triangulation + * \ingroup coxeter_triangulation */ struct Mesh_medit { /** \brief Type of a range of vertices. */ diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index c794cfa4..ecb59bfc 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -114,6 +114,10 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c } } +/** @brief Builds a Gudhi::coxeter_triangulation::Mesh_medit from a Gudhi::coxeter_triangulation::Cell_complex + * + * @ingroup coxeter_triangulation + */ template Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, Configuration i_configuration = Configuration(), diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h index 4b454373..0a87a310 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h @@ -68,11 +68,14 @@ typename std::enable_if::type fill_meshes(Vertex_p tetrahedra_scalar_range, index + mesh.vertex_points.size(), meshes...); } -/** \brief Outputs a text file with specified meshes that can be visualized in Medit. +/** \brief Outputs a text file with specified meshes that can be visualized in + * Medit. * * @param[in] amb_d Ambient dimension. Can be 2 or 3. * @param[in] file_name The name of the output file. * @param[in] meshes A pack of meshes to be specified separated by commas. + * + * @ingroup coxeter_triangulation */ template void output_meshes_to_medit(std::size_t amb_d, std::string file_name, const Meshes&... meshes) { -- cgit v1.2.3 From 1d7011f32573bb617894a3f263e2537c1f3a8649 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 22 Apr 2021 09:28:45 +0200 Subject: Add examples in doc and removes TBB link as not required by coxeter --- src/Coxeter_triangulation/example/CMakeLists.txt | 9 --------- src/Coxeter_triangulation/test/CMakeLists.txt | 3 --- src/common/doc/examples.h | 3 +++ src/common/doc/installation.h | 8 ++++++++ 4 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/example/CMakeLists.txt b/src/Coxeter_triangulation/example/CMakeLists.txt index 840e24e4..7f81c599 100644 --- a/src/Coxeter_triangulation/example/CMakeLists.txt +++ b/src/Coxeter_triangulation/example/CMakeLists.txt @@ -5,24 +5,15 @@ if (NOT EIGEN3_VERSION VERSION_LESS 3.1.0) if (NOT CGAL_VERSION VERSION_LESS 4.11.0) add_executable ( Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example manifold_tracing_flat_torus_with_boundary.cpp ) target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${CGAL_LIBRARY}) - if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example ${TBB_LIBRARIES}) - endif() add_test(NAME Coxeter_triangulation_manifold_tracing_flat_torus_with_boundary_example COMMAND $) endif() add_executable ( Coxeter_triangulation_manifold_tracing_custom_function_example manifold_tracing_custom_function.cpp ) - if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_manifold_tracing_custom_function_example ${TBB_LIBRARIES}) - endif() add_test(NAME Coxeter_triangulation_manifold_tracing_custom_function_example COMMAND $) add_executable ( Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example cell_complex_from_basic_circle_manifold.cpp ) - if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example ${TBB_LIBRARIES}) - endif() add_test(NAME Coxeter_triangulation_cell_complex_from_basic_circle_manifold_example COMMAND $) endif() \ No newline at end of file diff --git a/src/Coxeter_triangulation/test/CMakeLists.txt b/src/Coxeter_triangulation/test/CMakeLists.txt index 3da2410f..74ded91e 100644 --- a/src/Coxeter_triangulation/test/CMakeLists.txt +++ b/src/Coxeter_triangulation/test/CMakeLists.txt @@ -26,8 +26,5 @@ if (NOT EIGEN3_VERSION VERSION_LESS 3.1.0) gudhi_add_boost_test(Coxeter_triangulation_manifold_tracing_test) add_executable ( Coxeter_triangulation_cell_complex_test cell_complex_test.cpp ) - if (TBB_FOUND) - target_link_libraries(Coxeter_triangulation_cell_complex_test ${TBB_LIBRARIES}) - endif() gudhi_add_boost_test(Coxeter_triangulation_cell_complex_test) endif() \ No newline at end of file diff --git a/src/common/doc/examples.h b/src/common/doc/examples.h index 474f8699..a8548f6a 100644 --- a/src/common/doc/examples.h +++ b/src/common/doc/examples.h @@ -92,5 +92,8 @@ * @example Persistence_representations/persistence_landscapes/create_landscapes.cpp * @example Persistence_representations/persistence_landscapes/compute_distance_of_landscapes.cpp * @example Persistence_representations/persistence_landscapes/plot_landscapes.cpp + * @example Coxeter_triangulation/cell_complex_from_basic_circle_manifold.cpp + * @example Coxeter_triangulation/manifold_tracing_custom_function.cpp + * @example Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp */ diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index c2e63a24..c0e36a59 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -125,6 +125,8 @@ make doxygen * Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp * \li * Alpha_complex/alpha_complex_3d_persistence.cpp + * \li + * Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp * * \subsection eigen Eigen * Some GUDHI modules (cf. \ref main_page "modules list"), and few examples require @@ -169,6 +171,12 @@ make doxygen * Witness_complex/example_witness_complex_off.cpp * \li * Witness_complex/example_witness_complex_sphere.cpp + * \li + * Coxeter_triangulation/cell_complex_from_basic_circle_manifold.cpp + * \li + * Coxeter_triangulation/manifold_tracing_custom_function.cpp + * \li + * Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp * * \subsection tbb Threading Building Blocks * Intel® TBB lets you easily write parallel -- cgit v1.2.3 From 1ef113ff6f5db7288e4dc4c18c053b18d90dbf1a Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Fri, 30 Apr 2021 11:17:35 +0200 Subject: First version of points generation on torus --- src/python/CMakeLists.txt | 4 ++ .../gudhi/datasets/generators/points/__init__.py | 0 .../gudhi/datasets/generators/points/_torus.cc | 70 ++++++++++++++++++++++ .../gudhi/datasets/generators/points/torus.py | 52 ++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/python/gudhi/datasets/generators/points/__init__.py create mode 100644 src/python/gudhi/datasets/generators/points/_torus.cc create mode 100644 src/python/gudhi/datasets/generators/points/torus.py (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index a1440cbc..1b9db2b5 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -46,6 +46,7 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'bottleneck', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'hera', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'clustering', ") + set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'datasets/generators/points', ") endif() if(CYTHON_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'off_reader', ") @@ -151,6 +152,7 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'hera/wasserstein', ") set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'hera/bottleneck', ") if (NOT CGAL_VERSION VERSION_LESS 4.11.0) + set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/points/_torus', ") set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'bottleneck', ") set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'nerve_gic', ") endif () @@ -262,6 +264,8 @@ if(PYTHONINTERP_FOUND) file(COPY "gudhi/weighted_rips_complex.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") file(COPY "gudhi/dtm_rips_complex.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") file(COPY "gudhi/hera/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/hera") + file(COPY "gudhi/datasets/generators/points/" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/datasets/generators/points/" FILES_MATCHING PATTERN "*.py") + # Some files for pip package file(COPY "introduction.rst" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") diff --git a/src/python/gudhi/datasets/generators/points/__init__.py b/src/python/gudhi/datasets/generators/points/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/gudhi/datasets/generators/points/_torus.cc b/src/python/gudhi/datasets/generators/points/_torus.cc new file mode 100644 index 00000000..21638bb8 --- /dev/null +++ b/src/python/gudhi/datasets/generators/points/_torus.cc @@ -0,0 +1,70 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Hind Montassif + * + * Copyright (C) 2021 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#include +#include + +#include +#include + +#include + +namespace py = pybind11; + + +typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; + + +py::array_t generate_points_on_torus(size_t num_points, int dim, bool uniform) { + + std::vector points_generated; + + { + py::gil_scoped_release release; + points_generated = Gudhi::generate_points_on_torus_d(num_points, dim, uniform); + } + + size_t npoints = points_generated.size(); + + py::print("points generated size: "); + py::print(points_generated.size()); + py::print(points_generated[0].size()); + + GUDHI_CHECK(2*dim == points_generated[0].size(), "Py array second dimension not matching the double ambient space dimension"); + + py::array_t points({npoints, (size_t)2*dim}); + + py::buffer_info buf = points.request(); + double *ptr = static_cast(buf.ptr); + + for (size_t i = 0; i < npoints; i++) + for (int j = 0; j < 2*dim; j++) + ptr[i*(2*dim)+j] = points_generated[i][j]; + + return points; +} + +PYBIND11_MODULE(_torus, m) { + m.attr("__license__") = "LGPL v3"; + m.def("generate_random_points", &generate_points_on_torus, + py::arg("num_points"), py::arg("dim"), py::arg("uniform") = false, + R"pbdoc( + Generate random i.i.d. points on a d-torus in R^2d + + :param num_points: The number of points to be generated. + :type num_points: unsigned integer + :param dim: The dimension. + :type dim: integer + :param uniform: A flag to define if the points generation is uniform (generated as a grid). + :type uniform: bool + :rtype: numpy array of float + :returns: the generated points on a torus. + )pbdoc"); +} diff --git a/src/python/gudhi/datasets/generators/points/torus.py b/src/python/gudhi/datasets/generators/points/torus.py new file mode 100644 index 00000000..2de696b2 --- /dev/null +++ b/src/python/gudhi/datasets/generators/points/torus.py @@ -0,0 +1,52 @@ +# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. +# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. +# Author(s): Hind Montassif +# +# Copyright (C) 2021 Inria +# +# Modification(s): +# - YYYY/MM Author: Description of the modification + +import numpy as np +import math + + +def generate_random_points(num_points, dim): + + # Generate random angles of size num_points*dim + alpha = 2*math.pi*np.random.rand(num_points*dim) + + # Based on angles, construct points of size num_points*dim on a circle and reshape the result in a num_points*2*dim array + array_points = np.asarray([[np.cos(a), np.sin(a)] for a in alpha]).ravel().reshape(num_points, 2*dim) + + return array_points + + +def generate_grid_points(num_points, dim): + + num_points_grid = (int(num_points**(1./dim)))**dim + + alpha = 2*math.pi*np.random.rand(num_points_grid*dim) + + array_points = np.asarray([[np.cos(a), np.sin(a)] for a in alpha]).ravel().reshape(num_points_grid, 2*dim) + + return array_points + +def generate_points(num_points, dim, sample='random'): + if sample == 'random': + print("Sample is random") + npoints = num_points + elif sample == 'grid': + print("Sample is grid") + npoints = (int(num_points**(1./dim)))**dim + else: + print("Sample type '{}' is not supported".format(sample)) + return + + # Generate random angles of size num_points*dim + alpha = 2*math.pi*np.random.rand(npoints*dim) + + # Based on angles, construct points of size num_points*dim on a circle and reshape the result in a num_points*2*dim array + array_points = np.asarray([[np.cos(a), np.sin(a)] for a in alpha]).ravel().reshape(npoints, 2*dim) + + return array_points -- cgit v1.2.3 From 5c140bbdae08561ce69f0cc05841eb1467aa8eab Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Fri, 7 May 2021 15:11:24 +0200 Subject: Use PI constant from numpy instead of math Modify grid points generation incorrect formula --- .../gudhi/datasets/generators/points/torus.py | 30 ++++++++-------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/points/torus.py b/src/python/gudhi/datasets/generators/points/torus.py index 2de696b2..5a2b9016 100644 --- a/src/python/gudhi/datasets/generators/points/torus.py +++ b/src/python/gudhi/datasets/generators/points/torus.py @@ -8,45 +8,35 @@ # - YYYY/MM Author: Description of the modification import numpy as np -import math - +import itertools def generate_random_points(num_points, dim): # Generate random angles of size num_points*dim - alpha = 2*math.pi*np.random.rand(num_points*dim) + alpha = 2*np.pi*np.random.rand(num_points*dim) - # Based on angles, construct points of size num_points*dim on a circle and reshape the result in a num_points*2*dim array - array_points = np.asarray([[np.cos(a), np.sin(a)] for a in alpha]).ravel().reshape(num_points, 2*dim) + # Based on angles, construct points of size num_points*dim on a circle and reshape the result in a num_points*2*dim array + array_points = np.column_stack([np.cos(alpha), np.sin(alpha)]).reshape(-1, 2*dim) return array_points - def generate_grid_points(num_points, dim): - num_points_grid = (int(num_points**(1./dim)))**dim + num_points_grid = int(num_points**(1./dim)) + alpha = np.linspace(0, 2*np.pi, num_points_grid, endpoint=False) - alpha = 2*math.pi*np.random.rand(num_points_grid*dim) - - array_points = np.asarray([[np.cos(a), np.sin(a)] for a in alpha]).ravel().reshape(num_points_grid, 2*dim) + array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)]) + array_points = np.array(list(itertools.product(array_points_inter, repeat=dim))).reshape(-1, 2*dim) return array_points def generate_points(num_points, dim, sample='random'): if sample == 'random': print("Sample is random") - npoints = num_points + generate_random_points(num_points, dim) elif sample == 'grid': print("Sample is grid") - npoints = (int(num_points**(1./dim)))**dim + generate_grid_points(num_points, dim) else: print("Sample type '{}' is not supported".format(sample)) return - - # Generate random angles of size num_points*dim - alpha = 2*math.pi*np.random.rand(npoints*dim) - - # Based on angles, construct points of size num_points*dim on a circle and reshape the result in a num_points*2*dim array - array_points = np.asarray([[np.cos(a), np.sin(a)] for a in alpha]).ravel().reshape(npoints, 2*dim) - - return array_points -- cgit v1.2.3 From a1497289e6808d247f3b2be69b97dc9053e2b4d1 Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Fri, 7 May 2021 15:30:08 +0200 Subject: Replace num_points with n_samples to be consistent with sphere --- .../gudhi/datasets/generators/points/_torus.cc | 18 +++++++----------- src/python/gudhi/datasets/generators/points/torus.py | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/points/_torus.cc b/src/python/gudhi/datasets/generators/points/_torus.cc index 21638bb8..f4b4f14e 100644 --- a/src/python/gudhi/datasets/generators/points/_torus.cc +++ b/src/python/gudhi/datasets/generators/points/_torus.cc @@ -22,22 +22,18 @@ namespace py = pybind11; typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; -py::array_t generate_points_on_torus(size_t num_points, int dim, bool uniform) { +py::array_t generate_points_on_torus(size_t n_samples, int dim, bool uniform) { std::vector points_generated; { py::gil_scoped_release release; - points_generated = Gudhi::generate_points_on_torus_d(num_points, dim, uniform); + points_generated = Gudhi::generate_points_on_torus_d(n_samples, dim, uniform); } size_t npoints = points_generated.size(); - py::print("points generated size: "); - py::print(points_generated.size()); - py::print(points_generated[0].size()); - - GUDHI_CHECK(2*dim == points_generated[0].size(), "Py array second dimension not matching the double ambient space dimension"); + GUDHI_CHECK(2*dim == points_generated[0].size(), "Py array second dimension not matching the double torus dimension"); py::array_t points({npoints, (size_t)2*dim}); @@ -54,15 +50,15 @@ py::array_t generate_points_on_torus(size_t num_points, int dim, bool un PYBIND11_MODULE(_torus, m) { m.attr("__license__") = "LGPL v3"; m.def("generate_random_points", &generate_points_on_torus, - py::arg("num_points"), py::arg("dim"), py::arg("uniform") = false, + py::arg("n_samples"), py::arg("dim"), py::arg("uniform") = false, R"pbdoc( Generate random i.i.d. points on a d-torus in R^2d - :param num_points: The number of points to be generated. - :type num_points: unsigned integer + :param n_samples: The number of points to be generated. + :type n_samples: integer :param dim: The dimension. :type dim: integer - :param uniform: A flag to define if the points generation is uniform (generated as a grid). + :param uniform: A flag to define if the points generation is uniform (i.e generated as a grid). :type uniform: bool :rtype: numpy array of float :returns: the generated points on a torus. diff --git a/src/python/gudhi/datasets/generators/points/torus.py b/src/python/gudhi/datasets/generators/points/torus.py index 5a2b9016..1df0a930 100644 --- a/src/python/gudhi/datasets/generators/points/torus.py +++ b/src/python/gudhi/datasets/generators/points/torus.py @@ -10,33 +10,33 @@ import numpy as np import itertools -def generate_random_points(num_points, dim): +def generate_random_points(n_samples, dim): - # Generate random angles of size num_points*dim - alpha = 2*np.pi*np.random.rand(num_points*dim) + # Generate random angles of size n_samples*dim + alpha = 2*np.pi*np.random.rand(n_samples*dim) - # Based on angles, construct points of size num_points*dim on a circle and reshape the result in a num_points*2*dim array + # Based on angles, construct points of size n_samples*dim on a circle and reshape the result in a n_samples*2*dim array array_points = np.column_stack([np.cos(alpha), np.sin(alpha)]).reshape(-1, 2*dim) return array_points -def generate_grid_points(num_points, dim): +def generate_grid_points(n_samples, dim): - num_points_grid = int(num_points**(1./dim)) - alpha = np.linspace(0, 2*np.pi, num_points_grid, endpoint=False) + n_samples_grid = int(n_samples**(1./dim)) + alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False) array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)]) array_points = np.array(list(itertools.product(array_points_inter, repeat=dim))).reshape(-1, 2*dim) return array_points -def generate_points(num_points, dim, sample='random'): +def generate_points(n_samples, dim, sample='random'): if sample == 'random': print("Sample is random") - generate_random_points(num_points, dim) + generate_random_points(n_samples, dim) elif sample == 'grid': print("Sample is grid") - generate_grid_points(num_points, dim) + generate_grid_points(n_samples, dim) else: print("Sample type '{}' is not supported".format(sample)) return -- cgit v1.2.3 From 303b014508f849d8cb8a4369430068f54fa74c46 Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Mon, 10 May 2021 10:27:57 +0200 Subject: Add __init__.py files at every module level Standardize functions to match the existing ones in sphere --- src/python/CMakeLists.txt | 6 +- src/python/gudhi/datasets/__init__.py | 0 src/python/gudhi/datasets/generators/__init__.py | 0 src/python/gudhi/datasets/generators/_points.cc | 66 ++++++++++++++++++++++ src/python/gudhi/datasets/generators/points.py | 42 ++++++++++++++ .../gudhi/datasets/generators/points/__init__.py | 0 .../gudhi/datasets/generators/points/_torus.cc | 66 ---------------------- .../gudhi/datasets/generators/points/torus.py | 42 -------------- 8 files changed, 111 insertions(+), 111 deletions(-) create mode 100644 src/python/gudhi/datasets/__init__.py create mode 100644 src/python/gudhi/datasets/generators/__init__.py create mode 100644 src/python/gudhi/datasets/generators/_points.cc create mode 100644 src/python/gudhi/datasets/generators/points.py delete mode 100644 src/python/gudhi/datasets/generators/points/__init__.py delete mode 100644 src/python/gudhi/datasets/generators/points/_torus.cc delete mode 100644 src/python/gudhi/datasets/generators/points/torus.py (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 1b9db2b5..e146fedc 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -46,7 +46,7 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'bottleneck', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'hera', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'clustering', ") - set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'datasets/generators/points', ") + set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'datasets', ") endif() if(CYTHON_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'off_reader', ") @@ -152,7 +152,7 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'hera/wasserstein', ") set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'hera/bottleneck', ") if (NOT CGAL_VERSION VERSION_LESS 4.11.0) - set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/points/_torus', ") + set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/_points', ") set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'bottleneck', ") set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'nerve_gic', ") endif () @@ -264,7 +264,7 @@ if(PYTHONINTERP_FOUND) file(COPY "gudhi/weighted_rips_complex.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") file(COPY "gudhi/dtm_rips_complex.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") file(COPY "gudhi/hera/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/hera") - file(COPY "gudhi/datasets/generators/points/" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/datasets/generators/points/" FILES_MATCHING PATTERN "*.py") + file(COPY "gudhi/datasets" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi" FILES_MATCHING PATTERN "*.py") # Some files for pip package diff --git a/src/python/gudhi/datasets/__init__.py b/src/python/gudhi/datasets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/gudhi/datasets/generators/__init__.py b/src/python/gudhi/datasets/generators/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc new file mode 100644 index 00000000..561fd6d8 --- /dev/null +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -0,0 +1,66 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Hind Montassif + * + * Copyright (C) 2021 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#include +#include + +#include +#include + +#include + +namespace py = pybind11; + + +typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; + + +py::array_t generate_points_on_torus(size_t n_samples, int dim, bool uniform) { + + std::vector points_generated; + + { + py::gil_scoped_release release; + points_generated = Gudhi::generate_points_on_torus_d(n_samples, dim, uniform); + } + + size_t npoints = points_generated.size(); + + GUDHI_CHECK(2*dim == points_generated[0].size(), "Py array second dimension not matching the double torus dimension"); + + py::array_t points({npoints, (size_t)2*dim}); + + py::buffer_info buf = points.request(); + double *ptr = static_cast(buf.ptr); + + for (size_t i = 0; i < npoints; i++) + for (int j = 0; j < 2*dim; j++) + ptr[i*(2*dim)+j] = points_generated[i][j]; + + return points; +} + +PYBIND11_MODULE(_points, m) { + m.attr("__license__") = "LGPL v3"; + m.def("torus", &generate_points_on_torus, + py::arg("n_samples"), py::arg("dim"), py::arg("uniform") = false, + R"pbdoc( + Generate random i.i.d. points on a d-torus in R^2d + + :param n_samples: The number of points to be generated. + :type n_samples: integer + :param dim: The dimension. + :type dim: integer + :param uniform: A flag to define if the points generation is uniform (i.e generated as a grid). + :type uniform: bool + :rtype: numpy array of float + :returns: the generated points on a torus. + )pbdoc"); +} diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py new file mode 100644 index 00000000..d5a370ad --- /dev/null +++ b/src/python/gudhi/datasets/generators/points.py @@ -0,0 +1,42 @@ +# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. +# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. +# Author(s): Hind Montassif +# +# Copyright (C) 2021 Inria +# +# Modification(s): +# - YYYY/MM Author: Description of the modification + +import numpy as np +import itertools + +def _generate_random_points(n_samples, dim): + + # Generate random angles of size n_samples*dim + alpha = 2*np.pi*np.random.rand(n_samples*dim) + + # Based on angles, construct points of size n_samples*dim on a circle and reshape the result in a n_samples*2*dim array + array_points = np.column_stack([np.cos(alpha), np.sin(alpha)]).reshape(-1, 2*dim) + + return array_points + +def _generate_grid_points(n_samples, dim): + + n_samples_grid = int(n_samples**(1./dim)) + alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False) + + array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)]) + array_points = np.array(list(itertools.product(array_points_inter, repeat=dim))).reshape(-1, 2*dim) + + return array_points + +def torus(n_samples, dim, sample='random'): + if sample == 'random': + print("Sample is random") + return _generate_random_points(n_samples, dim) + elif sample == 'grid': + print("Sample is grid") + return _generate_grid_points(n_samples, dim) + else: + raise Exception("Sample type '{}' is not supported".format(sample)) + return diff --git a/src/python/gudhi/datasets/generators/points/__init__.py b/src/python/gudhi/datasets/generators/points/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/python/gudhi/datasets/generators/points/_torus.cc b/src/python/gudhi/datasets/generators/points/_torus.cc deleted file mode 100644 index f4b4f14e..00000000 --- a/src/python/gudhi/datasets/generators/points/_torus.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Hind Montassif - * - * Copyright (C) 2021 Inria - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#include -#include - -#include -#include - -#include - -namespace py = pybind11; - - -typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; - - -py::array_t generate_points_on_torus(size_t n_samples, int dim, bool uniform) { - - std::vector points_generated; - - { - py::gil_scoped_release release; - points_generated = Gudhi::generate_points_on_torus_d(n_samples, dim, uniform); - } - - size_t npoints = points_generated.size(); - - GUDHI_CHECK(2*dim == points_generated[0].size(), "Py array second dimension not matching the double torus dimension"); - - py::array_t points({npoints, (size_t)2*dim}); - - py::buffer_info buf = points.request(); - double *ptr = static_cast(buf.ptr); - - for (size_t i = 0; i < npoints; i++) - for (int j = 0; j < 2*dim; j++) - ptr[i*(2*dim)+j] = points_generated[i][j]; - - return points; -} - -PYBIND11_MODULE(_torus, m) { - m.attr("__license__") = "LGPL v3"; - m.def("generate_random_points", &generate_points_on_torus, - py::arg("n_samples"), py::arg("dim"), py::arg("uniform") = false, - R"pbdoc( - Generate random i.i.d. points on a d-torus in R^2d - - :param n_samples: The number of points to be generated. - :type n_samples: integer - :param dim: The dimension. - :type dim: integer - :param uniform: A flag to define if the points generation is uniform (i.e generated as a grid). - :type uniform: bool - :rtype: numpy array of float - :returns: the generated points on a torus. - )pbdoc"); -} diff --git a/src/python/gudhi/datasets/generators/points/torus.py b/src/python/gudhi/datasets/generators/points/torus.py deleted file mode 100644 index 1df0a930..00000000 --- a/src/python/gudhi/datasets/generators/points/torus.py +++ /dev/null @@ -1,42 +0,0 @@ -# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. -# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. -# Author(s): Hind Montassif -# -# Copyright (C) 2021 Inria -# -# Modification(s): -# - YYYY/MM Author: Description of the modification - -import numpy as np -import itertools - -def generate_random_points(n_samples, dim): - - # Generate random angles of size n_samples*dim - alpha = 2*np.pi*np.random.rand(n_samples*dim) - - # Based on angles, construct points of size n_samples*dim on a circle and reshape the result in a n_samples*2*dim array - array_points = np.column_stack([np.cos(alpha), np.sin(alpha)]).reshape(-1, 2*dim) - - return array_points - -def generate_grid_points(n_samples, dim): - - n_samples_grid = int(n_samples**(1./dim)) - alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False) - - array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)]) - array_points = np.array(list(itertools.product(array_points_inter, repeat=dim))).reshape(-1, 2*dim) - - return array_points - -def generate_points(n_samples, dim, sample='random'): - if sample == 'random': - print("Sample is random") - generate_random_points(n_samples, dim) - elif sample == 'grid': - print("Sample is grid") - generate_grid_points(n_samples, dim) - else: - print("Sample type '{}' is not supported".format(sample)) - return -- cgit v1.2.3 From 896dd694833ee48b0c8082ae1f56a379059fb409 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 17 May 2021 09:21:35 +0200 Subject: Fix Coxeter documentation with new doxygen requirements --- src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h index 99239e3a..395996c9 100644 --- a/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h +++ b/src/Coxeter_triangulation/doc/intro_coxeter_triangulation.h @@ -202,18 +202,18 @@ Coxeter_triangulation implementation. \section example Examples \subsection examplewithoutboundaries Basic example without boundaries -\include Coxeter_triangulation/cell_complex_from_basic_circle_manifold.cpp +\include cell_complex_from_basic_circle_manifold.cpp The program output is: -\include Coxeter_triangulation/cell_complex_from_basic_circle_manifold_for_doc.txt +\include cell_complex_from_basic_circle_manifold_for_doc.txt \subsection exampleswithboundaries Example with boundaries Here is an example of constructing a piecewise-linear approximation of a flat torus embedded in \f$\mathbb{R}^4\f$, rotated by a random rotation in \f$\mathbb{R}^4\f$ and cut by a hyperplane. -\include Coxeter_triangulation/manifold_tracing_flat_torus_with_boundary.cpp +\include manifold_tracing_flat_torus_with_boundary.cpp The output in medit is: @@ -223,7 +223,7 @@ The output in medit looks as follows: -- cgit v1.2.3 From 0b238a336f15128d777252cd084ee996491e6882 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Thu, 27 May 2021 09:56:02 +0200 Subject: Add documentation to python torus fonction and apply some modifications according to PR comments --- src/python/gudhi/datasets/generators/_points.cc | 2 +- src/python/gudhi/datasets/generators/points.py | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 561fd6d8..003b65a3 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -56,7 +56,7 @@ PYBIND11_MODULE(_points, m) { :param n_samples: The number of points to be generated. :type n_samples: integer - :param dim: The dimension. + :param dim: The dimension of the torus on which points would be generated in R^2*dim. :type dim: integer :param uniform: A flag to define if the points generation is uniform (i.e generated as a grid). :type uniform: bool diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index d5a370ad..a8f5ad54 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -10,7 +10,7 @@ import numpy as np import itertools -def _generate_random_points(n_samples, dim): +def _generate_random_points_on_torus(n_samples, dim): # Generate random angles of size n_samples*dim alpha = 2*np.pi*np.random.rand(n_samples*dim) @@ -20,8 +20,9 @@ def _generate_random_points(n_samples, dim): return array_points -def _generate_grid_points(n_samples, dim): +def _generate_grid_points_on_torus(n_samples, dim): + # Generate points on a dim-torus as a grid n_samples_grid = int(n_samples**(1./dim)) alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False) @@ -31,12 +32,25 @@ def _generate_grid_points(n_samples, dim): return array_points def torus(n_samples, dim, sample='random'): + ''' + Generate points on a dim-torus in R^2dim either randomly or on a grid + + :param n_samples: The number of points to be generated. + :param dim: The dimension of the torus on which points would be generated in R^2*dim. + :param sample: The sample type of the generated points. Can be 'random' or 'grid'. + :returns: numpy array containing the generated points on a torus. + The shape of returned numpy array is : + if sample is 'random' : (n_samples, 2*dim) + if sample is 'grid' : ((int(n_samples**(1./dim)))**dim, 2*dim) + ''' if sample == 'random': + # Generate points randomly print("Sample is random") - return _generate_random_points(n_samples, dim) + return _generate_random_points_on_torus(n_samples, dim) elif sample == 'grid': + # Generate points on a grid print("Sample is grid") - return _generate_grid_points(n_samples, dim) + return _generate_grid_points_on_torus(n_samples, dim) else: - raise Exception("Sample type '{}' is not supported".format(sample)) + raise ValueError("Sample type '{}' is not supported".format(sample)) return -- cgit v1.2.3 From 09214d0ad3abd0c81b3a2c8051bf8b370350d6e5 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Tue, 1 Jun 2021 11:20:26 +0200 Subject: Add datasets generators documentation --- src/python/doc/datasets_generators.inc | 14 ++++ src/python/doc/datasets_generators.rst | 97 ++++++++++++++++++++++++++ src/python/doc/examples.rst | 1 + src/python/doc/index.rst | 5 ++ src/python/gudhi/datasets/generators/points.py | 10 +-- 5 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 src/python/doc/datasets_generators.inc create mode 100644 src/python/doc/datasets_generators.rst (limited to 'src') diff --git a/src/python/doc/datasets_generators.inc b/src/python/doc/datasets_generators.inc new file mode 100644 index 00000000..c88115c3 --- /dev/null +++ b/src/python/doc/datasets_generators.inc @@ -0,0 +1,14 @@ +.. table:: + :widths: 30 40 30 + + +-----------------------------------+--------------------------------------------+--------------------------------------------------------------------------------------+ + | | :math:`(x_1, x_2, \ldots, x_d)` | Datasets generators (points). | :Authors: Hind Montassif | + | | | | + | | | :Since: GUDHI 3.5.0 | + | | | | + | | | :License: MIT (`LGPL v3 `_) | + | | | | + | | | :Requires: `CGAL `_ | + +-----------------------------------+--------------------------------------------+--------------------------------------------------------------------------------------+ + | * :doc:`datasets_generators` | + +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------+ diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst new file mode 100644 index 00000000..ef21c9d2 --- /dev/null +++ b/src/python/doc/datasets_generators.rst @@ -0,0 +1,97 @@ + +:orphan: + +.. To get rid of WARNING: document isn't included in any toctree + +=========================== +Datasets generators manual +=========================== + +We provide the generation of different customizable datasets to use as inputs for Gudhi complexes and data structures. + + +Points generators +------------------ + +Points on sphere +^^^^^^^^^^^^^^^^ + +The module **_points** enables the generation of random i.i.d. points uniformly on a (d-1)-sphere in :math:`R^d`. +The user should provide the number of points to be generated on the sphere :code:`n_samples` and the ambient dimension :code:`ambient_dim`. +The :code:`radius` of sphere is optional and is equal to **1** by default. +Only random points generation is currently available. + +The generated points are given as an array of shape :math:`(n\_samples, ambient\_dim)`. + +Example +""""""" + +.. code-block:: python + + from gudhi.datasets.generators import _points + from gudhi import AlphaComplex + + # Generate 50 points on a sphere in R^2 + gen_points = _points.sphere(n_samples = 50, ambient_dim = 2, radius = 1, sample = "random") + + # Create an alpha complex from the generated points + alpha_complex = AlphaComplex(points = gen_points) + +.. autofunction:: gudhi.datasets.generators._points.sphere + +Points on torus +^^^^^^^^^^^^^^^^ + +You can also generate points on a torus. + +Two modules are available and give the same output: the first one depends on **CGAL** and the second does not and consists of full python code. + +On another hand, two sample types are provided : you can either generate i.i.d. points on a d-torus in :math:`R^{2d}` *randomly* or on a *grid*. + +First module : **_points** +"""""""""""""""""""""""""" + +The user should provide the number of points to be generated on the torus :code:`n_samples`, and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. +The flag :code:`uniform` is optional and is set to **False** by default, meaning that the points will be generated randomly. +In this case, the returned generated points would be an array of shape :math:`(n\_samples, 2*dim)`. +Otherwise, if set to **True**, the points are generated as a grid and would be given as an array of shape : + +.. math:: + + ( [n\_samples^{1 \over {dim}}]^{dim}, 2*dim ) + +Example +""""""" +.. code-block:: python + + from gudhi.datasets.generators import _points + + # Generate 50 points randomly on a torus in R^6 + gen_points = _points.torus(n_samples = 50, dim = 3) + + # Generate 27 points on a torus as a grid in R^6 + gen_points = _points.torus(n_samples = 50, dim = 3, uniform = True) + +.. autofunction:: gudhi.datasets.generators._points.torus + +Second module : **points** +"""""""""""""""""""""""""" + +The user should provide the number of points to be generated on the torus :code:`n_samples` and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. +The :code:`sample` argument is optional and is set to **'random'** by default. +The other allowed value of sample type is **'grid'** and is equivalent to :code:`uniform = True` in the first module. + +Example +""""""" +.. code-block:: python + + from gudhi.datasets.generators import points + + # Generate 50 points randomly on a torus in R^6 + gen_points = points.torus(n_samples = 50, dim = 3) + + # Generate 27 points on a torus as a grid in R^6 + gen_points = points.torus(n_samples = 50, dim = 3, sample = 'grid') + + +.. autofunction:: gudhi.datasets.generators.points.torus diff --git a/src/python/doc/examples.rst b/src/python/doc/examples.rst index 76e5d4c7..1442f185 100644 --- a/src/python/doc/examples.rst +++ b/src/python/doc/examples.rst @@ -8,6 +8,7 @@ Examples .. only:: builder_html * :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>` + * :download:`alpha_complex_from_generated_points_on_sphere_example.py <../example/alpha_complex_from_generated_points_on_sphere_example.py>` * :download:`alpha_complex_from_points_example.py <../example/alpha_complex_from_points_example.py>` * :download:`alpha_rips_persistence_bottleneck_distance.py <../example/alpha_rips_persistence_bottleneck_distance.py>` * :download:`bottleneck_basic_example.py <../example/bottleneck_basic_example.py>` diff --git a/src/python/doc/index.rst b/src/python/doc/index.rst index 040e57a4..2d7921ae 100644 --- a/src/python/doc/index.rst +++ b/src/python/doc/index.rst @@ -91,3 +91,8 @@ Clustering ********** .. include:: clustering.inc + +Datasets generators +******************* + +.. include:: datasets_generators.inc diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index a8f5ad54..3870dea6 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -32,17 +32,17 @@ def _generate_grid_points_on_torus(n_samples, dim): return array_points def torus(n_samples, dim, sample='random'): - ''' + """ Generate points on a dim-torus in R^2dim either randomly or on a grid :param n_samples: The number of points to be generated. :param dim: The dimension of the torus on which points would be generated in R^2*dim. :param sample: The sample type of the generated points. Can be 'random' or 'grid'. :returns: numpy array containing the generated points on a torus. - The shape of returned numpy array is : - if sample is 'random' : (n_samples, 2*dim) - if sample is 'grid' : ((int(n_samples**(1./dim)))**dim, 2*dim) - ''' + The shape of returned numpy array is : + if sample is 'random' : (n_samples, 2*dim). + if sample is 'grid' : ([n_samples**(1./dim)]**dim, 2*dim). + """ if sample == 'random': # Generate points randomly print("Sample is random") -- cgit v1.2.3 From b04759faf8f474ff98e9e229c41d85ff3bf009da Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 7 Jun 2021 11:56:48 +0200 Subject: Add a 3d sphere image to doc for datasets_generators --- src/python/doc/datasets_generators.inc | 4 ++-- src/python/doc/img/sphere_3d.png | Bin 0 -> 90550 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 src/python/doc/img/sphere_3d.png (limited to 'src') diff --git a/src/python/doc/datasets_generators.inc b/src/python/doc/datasets_generators.inc index c88115c3..8d169275 100644 --- a/src/python/doc/datasets_generators.inc +++ b/src/python/doc/datasets_generators.inc @@ -2,8 +2,8 @@ :widths: 30 40 30 +-----------------------------------+--------------------------------------------+--------------------------------------------------------------------------------------+ - | | :math:`(x_1, x_2, \ldots, x_d)` | Datasets generators (points). | :Authors: Hind Montassif | - | | | | + | .. figure:: | Datasets generators (points). | :Authors: Hind Montassif | + | img/sphere_3d.png | | | | | | :Since: GUDHI 3.5.0 | | | | | | | | :License: MIT (`LGPL v3 `_) | diff --git a/src/python/doc/img/sphere_3d.png b/src/python/doc/img/sphere_3d.png new file mode 100644 index 00000000..7e7f0ab2 Binary files /dev/null and b/src/python/doc/img/sphere_3d.png differ -- cgit v1.2.3 From b9160fb8410bbb999913b0b4e91f1aa1ff58d2cd Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 7 Jun 2021 17:07:55 +0200 Subject: Replace 'uniform' flag of torus generation with 'sample' taking two possible values: 'grid'(i.e uniform==True) or 'random' (i.e uniform==False) --- src/Tangential_complex/benchmark/benchmark_tc.cpp | 2 +- src/common/include/gudhi/random_point_generators.h | 10 +++++----- src/common/utilities/off_file_from_shape_generator.cpp | 2 +- src/python/doc/datasets_generators.rst | 8 ++++---- src/python/gudhi/datasets/generators/_points.cc | 10 +++++----- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Tangential_complex/benchmark/benchmark_tc.cpp b/src/Tangential_complex/benchmark/benchmark_tc.cpp index e3b2a04f..6da1425f 100644 --- a/src/Tangential_complex/benchmark/benchmark_tc.cpp +++ b/src/Tangential_complex/benchmark/benchmark_tc.cpp @@ -704,7 +704,7 @@ int main() { points = Gudhi::generate_points_on_torus_d( num_points, intrinsic_dim, - param1 == "Y", // uniform + (param1 == "Y") ? "grid" : "random", // grid or random sample type std::atof(param2.c_str())); // radius_noise_percentage } else if (input == "generate_klein_bottle_3D") { points = Gudhi::generate_points_on_klein_bottle_3D( diff --git a/src/common/include/gudhi/random_point_generators.h b/src/common/include/gudhi/random_point_generators.h index 33fb182d..07e4f3da 100644 --- a/src/common/include/gudhi/random_point_generators.h +++ b/src/common/include/gudhi/random_point_generators.h @@ -185,7 +185,7 @@ std::vector generate_points_on_torus_3D(std::size_t nu // "Private" function used by generate_points_on_torus_d template -static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::size_t num_slices, +static void generate_grid_points_on_torus_d(const Kernel &k, int dim, std::size_t num_slices, OutputIterator out, double radius_noise_percentage = 0., std::vector current_point = @@ -208,14 +208,14 @@ static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::si double alpha = two_pi * slice_idx / num_slices; cp2.push_back(radius_noise_ratio * std::cos(alpha)); cp2.push_back(radius_noise_ratio * std::sin(alpha)); - generate_uniform_points_on_torus_d( + generate_grid_points_on_torus_d( k, dim, num_slices, out, radius_noise_percentage, cp2); } } } template -std::vector generate_points_on_torus_d(std::size_t num_points, int dim, bool uniform = false, +std::vector generate_points_on_torus_d(std::size_t num_points, int dim, std::string sample = "random", double radius_noise_percentage = 0.) { using namespace boost::math::double_constants; @@ -226,9 +226,9 @@ std::vector generate_points_on_torus_d(std::size_t num std::vector points; points.reserve(num_points); - if (uniform) { + if (sample == "grid") { std::size_t num_slices = (std::size_t)std::pow(num_points, 1. / dim); - generate_uniform_points_on_torus_d( + generate_grid_points_on_torus_d( k, dim, num_slices, std::back_inserter(points), radius_noise_percentage); } else { for (std::size_t i = 0; i < num_points;) { diff --git a/src/common/utilities/off_file_from_shape_generator.cpp b/src/common/utilities/off_file_from_shape_generator.cpp index 6efef4fc..71ede434 100644 --- a/src/common/utilities/off_file_from_shape_generator.cpp +++ b/src/common/utilities/off_file_from_shape_generator.cpp @@ -135,7 +135,7 @@ int main(int argc, char **argv) { if (dimension == 3) points = Gudhi::generate_points_on_torus_3D(points_number, dimension, radius, radius/2.); else - points = Gudhi::generate_points_on_torus_d(points_number, dimension, true); + points = Gudhi::generate_points_on_torus_d(points_number, dimension, "grid"); break; case Data_shape::klein: switch (dimension) { diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst index ef21c9d2..2802eccd 100644 --- a/src/python/doc/datasets_generators.rst +++ b/src/python/doc/datasets_generators.rst @@ -52,9 +52,9 @@ First module : **_points** """""""""""""""""""""""""" The user should provide the number of points to be generated on the torus :code:`n_samples`, and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. -The flag :code:`uniform` is optional and is set to **False** by default, meaning that the points will be generated randomly. +The :code:`sample` argument is optional and is set to **'random'** by default. In this case, the returned generated points would be an array of shape :math:`(n\_samples, 2*dim)`. -Otherwise, if set to **True**, the points are generated as a grid and would be given as an array of shape : +Otherwise, if set to **'grid'**, the points are generated on a grid and would be given as an array of shape : .. math:: @@ -70,7 +70,7 @@ Example gen_points = _points.torus(n_samples = 50, dim = 3) # Generate 27 points on a torus as a grid in R^6 - gen_points = _points.torus(n_samples = 50, dim = 3, uniform = True) + gen_points = _points.torus(n_samples = 50, dim = 3, sample = 'grid') .. autofunction:: gudhi.datasets.generators._points.torus @@ -79,7 +79,7 @@ Second module : **points** The user should provide the number of points to be generated on the torus :code:`n_samples` and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. The :code:`sample` argument is optional and is set to **'random'** by default. -The other allowed value of sample type is **'grid'** and is equivalent to :code:`uniform = True` in the first module. +The other allowed value of sample type is **'grid'**. Example """"""" diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 55b21b2b..6bbdf284 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -46,13 +46,13 @@ py::array_t generate_points_on_sphere(size_t n_samples, int ambient_dim, return points; } -py::array_t generate_points_on_torus(size_t n_samples, int dim, bool uniform) { +py::array_t generate_points_on_torus(size_t n_samples, int dim, std::string sample) { std::vector points_generated; { py::gil_scoped_release release; - points_generated = Gudhi::generate_points_on_torus_d(n_samples, dim, uniform); + points_generated = Gudhi::generate_points_on_torus_d(n_samples, dim, sample); } size_t npoints = points_generated.size(); @@ -93,7 +93,7 @@ PYBIND11_MODULE(_points, m) { )pbdoc"); m.def("torus", &generate_points_on_torus, - py::arg("n_samples"), py::arg("dim"), py::arg("uniform") = false, + py::arg("n_samples"), py::arg("dim"), py::arg("sample") = "random", R"pbdoc( Generate random i.i.d. points on a d-torus in R^2d @@ -101,8 +101,8 @@ PYBIND11_MODULE(_points, m) { :type n_samples: integer :param dim: The dimension of the torus on which points would be generated in R^2*dim. :type dim: integer - :param uniform: A flag to define if the points generation is uniform (i.e generated as a grid). - :type uniform: bool + :param sample: The sample type. Available values are: `"random"` and `"grid"`. Default value is `"random"`. + :type sample: string :rtype: numpy array of float :returns: the generated points on a torus. )pbdoc"); -- cgit v1.2.3 From 44b7b7ceca93ee6f5ce5ec2831f107e4196a0350 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 7 Jun 2021 17:35:44 +0200 Subject: Warns that Hasse_diagram_cell is experimental and only for coxeter --- .../include/gudhi/Cell_complex/Hasse_diagram_cell.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h index 04d50784..59e9a350 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h @@ -31,7 +31,9 @@ class Hasse_diagram; * \ingroup Hasse_diagram * * \details - * This is a data structure to store a cell in a general Hasse diagram data structure. It store the following + * The use and interfaces of this Hasse diagram cell is limited to the \ref coxeter_triangulation implementation. + * + * This is a data structure to store a cell in a general Hasse diagram data structure. It stores the following * information about the cell: References to boundary and coBoundary elements, dimension of a cell and its filtration. * It also allow to store any additional information of a type Additional_information which is a template parameter of * the class (set by default to void). -- cgit v1.2.3 From 0828b90ffabf239dc9811f299427349d6d4f8bf4 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 7 Jun 2021 17:45:34 +0200 Subject: code review: The whole point of emplace/emplace_back is to remove std::make_pair or constructor call --- .../cell_complex_from_basic_circle_manifold.cpp | 2 +- .../include/gudhi/Cell_complex.h | 18 +++++++++--------- .../gudhi/IO/build_mesh_from_cell_complex.h | 22 +++++++++++----------- .../include/gudhi/IO/output_debug_traces_to_html.h | 2 +- .../include/gudhi/IO/output_meshes_to_medit.h | 6 +++--- .../include/gudhi/Manifold_tracing.h | 6 +++--- .../Permutahedral_representation_iterators.h | 4 ++-- 7 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp index 0d32f916..fc2afce4 100644 --- a/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp +++ b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp @@ -42,7 +42,7 @@ int main(int argc, char** argv) { std::clog << "Vertices:" << std::endl; for (const auto& cp_pair : cell_complex.cell_point_map()) { std::clog << index << " : (" << cp_pair.second(0) << ", " << cp_pair.second(1) << ")" << std::endl; - vi_map.emplace(std::make_pair(cp_pair.first, index++)); + vi_map.emplace(cp_pair.first, index++); } std::clog << "Edges:" << std::endl; diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h index 60c83522..561fe4ca 100644 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h @@ -73,15 +73,15 @@ class Cell_complex { #ifdef DEBUG_TRACES CC_detail_list& cc_detail_list = (is_boundary ? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); - cc_detail_list.emplace_back(CC_detail_info(simplex)); + cc_detail_list.emplace_back(simplex); #endif Simplex_cell_map& simplex_cell_map = simplex_cell_maps[cell_d]; auto map_it = simplex_cell_map.find(simplex); if (map_it == simplex_cell_map.end()) { hasse_cells_.push_back(new Hasse_cell(is_boundary, cell_d)); Hasse_cell* new_cell = hasse_cells_.back(); - simplex_cell_map.emplace(std::make_pair(simplex, new_cell)); - cell_simplex_map_.emplace(std::make_pair(new_cell, simplex)); + simplex_cell_map.emplace(simplex, new_cell); + cell_simplex_map_.emplace(new_cell, simplex); #ifdef DEBUG_TRACES cc_detail_list.back().status_ = CC_detail_info::Result_type::inserted; #endif @@ -102,7 +102,7 @@ class Cell_complex { Hasse_cell* cell = sc_pair.second; for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d)) { Hasse_cell* new_cell = insert_cell(coface, cell_d, false); - new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + new_cell->get_boundary().emplace_back(cell, 1); } } @@ -113,14 +113,14 @@ class Cell_complex { if (cell_d != intr_d_) for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d + 1)) { Hasse_cell* new_cell = insert_cell(coface, cell_d, true); - new_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + new_cell->get_boundary().emplace_back(cell, 1); } auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex); if (map_it == interior_simplex_cell_maps_[cell_d].end()) std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n"; else { Hasse_cell* i_cell = map_it->second; - i_cell->get_boundary().emplace_back(std::make_pair(cell, 1)); + i_cell->get_boundary().emplace_back(cell, 1); } } } @@ -136,7 +136,7 @@ class Cell_complex { const Simplex_handle& simplex = os_pair.first; const Eigen::VectorXd& point = os_pair.second; Hasse_cell* new_cell = insert_cell(simplex, 0, false); - cell_point_map_.emplace(std::make_pair(new_cell, point)); + cell_point_map_.emplace(new_cell, point); } for (std::size_t cell_d = 1; cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { @@ -157,13 +157,13 @@ class Cell_complex { const Simplex_handle& simplex = os_pair.first; const Eigen::VectorXd& point = os_pair.second; Hasse_cell* new_cell = insert_cell(simplex, 0, true); - cell_point_map_.emplace(std::make_pair(new_cell, point)); + cell_point_map_.emplace(new_cell, point); } for (auto& os_pair : interior_simplex_map) { const Simplex_handle& simplex = os_pair.first; const Eigen::VectorXd& point = os_pair.second; Hasse_cell* new_cell = insert_cell(simplex, 0, false); - cell_point_map_.emplace(std::make_pair(new_cell, point)); + cell_point_map_.emplace(new_cell, point); } #ifdef DEBUG_TRACES for (const auto& sc_pair : interior_simplex_cell_maps_[0]) diff --git a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h index ecb59bfc..9750f366 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/build_mesh_from_cell_complex.h @@ -57,12 +57,12 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c for (const auto& ei_pair : cell->get_boundary()) for (const auto& vi_pair : ei_pair.first->get_boundary()) vertex_indices.emplace(vi_map[vi_pair.first]); for (const std::size_t& v : vertex_indices) barycenter += output.vertex_points[v - 1]; - ci_map.emplace(std::make_pair(cell, index++)); + ci_map.emplace(cell, index++); output.vertex_points.emplace_back((1. / vertex_indices.size()) * barycenter); #ifdef DEBUG_TRACES std::string vlist = " (" + std::to_string(index - 1) + ")"; for (const std::size_t& v : vertex_indices) vlist += " " + std::to_string(v); - cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); + cell_vlist_map.emplace(to_string(cell), vlist); #endif } @@ -71,11 +71,11 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c Hasse_cell* edge_cell = sc_pair.second; Mesh_element_vertices edge; for (const auto& vi_pair : edge_cell->get_boundary()) edge.push_back(vi_map[vi_pair.first]); - output.edges.emplace_back(std::make_pair(edge, configuration.ref_edges)); + output.edges.emplace_back(edge, configuration.ref_edges); #ifdef DEBUG_TRACES std::string vlist; for (const std::size_t& v : edge) vlist += " " + std::to_string(v); - cell_vlist_map.emplace(std::make_pair(to_string(edge_cell), vlist)); + cell_vlist_map.emplace(to_string(edge_cell), vlist); #endif } @@ -84,7 +84,7 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c for (const auto& ei_pair : sc_pair.second->get_boundary()) { Mesh_element_vertices triangle(1, ci_map[sc_pair.second]); for (const auto& vi_pair : ei_pair.first->get_boundary()) triangle.push_back(vi_map[vi_pair.first]); - output.triangles.emplace_back(std::make_pair(triangle, configuration.ref_triangles)); + output.triangles.emplace_back(triangle, configuration.ref_triangles); } } @@ -101,14 +101,14 @@ void populate_mesh(Mesh_medit& output, Simplex_cell_map& sc_map, Configuration c #ifdef DEBUG_TRACES std::string vlist = " (" + std::to_string(index) + ")"; for (const std::size_t& v : vertex_indices) vlist += " " + std::to_string(v); - cell_vlist_map.emplace(std::make_pair(to_string(cell), vlist)); + cell_vlist_map.emplace(to_string(cell), vlist); #endif for (const auto& ci_pair : cell->get_boundary()) for (const auto& ei_pair : ci_pair.first->get_boundary()) { Mesh_element_vertices tetrahedron = {index, ci_map[sc_pair.second]}; for (const auto& vi_pair : ei_pair.first->get_boundary()) tetrahedron.push_back(vi_map[vi_pair.first]); - output.tetrahedra.emplace_back(std::make_pair(tetrahedron, configuration.ref_tetrahedra)); + output.tetrahedra.emplace_back(tetrahedron, configuration.ref_tetrahedra); } index++; } @@ -134,9 +134,9 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, #ifdef DEBUG_TRACES std::string vlist; vlist += " " + std::to_string(index); - cell_vlist_map.emplace(std::make_pair(to_string(cp_pair.first), vlist)); + cell_vlist_map.emplace(to_string(cp_pair.first), vlist); #endif - vi_map.emplace(std::make_pair(cp_pair.first, index++)); + vi_map.emplace(cp_pair.first, index++); output.vertex_points.push_back(cp_pair.second); output.vertex_points.back().conservativeResize(amb_d); } @@ -148,7 +148,7 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, std::string simplex = "I" + to_string(sc_pair.first); std::string cell = to_string(sc_pair.second); std::string vlist = cell_vlist_map.at(cell).substr(1); - simplex_vlist_map.emplace(std::make_pair(simplex, vlist)); + simplex_vlist_map.emplace(simplex, vlist); } #endif populate_mesh(output, cell_complex.boundary_simplex_cell_maps(), b_configuration, amb_d, vi_map); @@ -158,7 +158,7 @@ Mesh_medit build_mesh_from_cell_complex(const Cell_complex& cell_complex, std::string simplex = "B" + to_string(sc_pair.first); std::string cell = to_string(sc_pair.second); std::string vlist = cell_vlist_map.at(cell).substr(1); - simplex_vlist_map.emplace(std::make_pair(simplex, vlist)); + simplex_vlist_map.emplace(simplex, vlist); } #endif return output; diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h index 1d5ee4cd..a2995738 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_debug_traces_to_html.h @@ -514,7 +514,7 @@ void write_visu(std::ofstream& ofs) { << "

      Visualization details debug trace

      \n"; // std::vector > vs_maps(cc_interior_summary_lists.size()); std::map vs_map; - for (const auto& sv_pair : simplex_vlist_map) vs_map.emplace(std::make_pair(sv_pair.second, sv_pair.first)); + for (const auto& sv_pair : simplex_vlist_map) vs_map.emplace(sv_pair.second, sv_pair.first); ofs << "
        \n"; for (const auto& vs_pair : vs_map) { std::string w_simplex = vs_pair.second.substr(1); diff --git a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h index 0a87a310..f69d8b29 100644 --- a/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h +++ b/src/Coxeter_triangulation/include/gudhi/IO/output_meshes_to_medit.h @@ -50,17 +50,17 @@ typename std::enable_if::type fill_meshes(Vertex_p for (const auto& e : mesh.edges) { std::vector edge; for (const auto& v_i : e.first) edge.push_back(v_i + index); - edges.emplace_back(std::make_pair(edge, e.second)); + edges.emplace_back(edge, e.second); } for (const auto& t : mesh.triangles) { std::vector triangle; for (const auto& v_i : t.first) triangle.push_back(v_i + index); - triangles.emplace_back(std::make_pair(triangle, t.second)); + triangles.emplace_back(triangle, t.second); } for (const auto& t : mesh.tetrahedra) { std::vector tetrahedron; for (const auto& v_i : t.first) tetrahedron.push_back(v_i + index); - tetrahedra.emplace_back(std::make_pair(tetrahedron, t.second)); + tetrahedra.emplace_back(tetrahedron, t.second); } for (const auto& b : mesh.triangles_scalar_range) triangles_scalar_range.push_back(b); for (const auto& b : mesh.tetrahedra_scalar_range) tetrahedra_scalar_range.push_back(b); diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index 1083e827..71de47e1 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -86,7 +86,7 @@ class Manifold_tracing { Simplex_handle full_simplex = triangulation.locate_point(p); for (Simplex_handle face : full_simplex.face_range(cod_d)) { Query_result qr = oracle.intersects(face, triangulation); - if (qr.success && out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) { + if (qr.success && out_simplex_map.emplace(face, qr.intersection).second) { #ifdef DEBUG_TRACES mt_seed_inserted_list.push_back(MT_inserted_info(qr, face, false)); #endif @@ -102,7 +102,7 @@ class Manifold_tracing { for (auto cof : s.coface_range(cod_d + 1)) { for (auto face : cof.face_range(cod_d)) { Query_result qr = oracle.intersects(face, triangulation); - if (qr.success && out_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) queue.emplace(face); + if (qr.success && out_simplex_map.emplace(face, qr.intersection).second) queue.emplace(face); } } } @@ -148,7 +148,7 @@ class Manifold_tracing { #endif if (qr.success) { if (oracle.lies_in_domain(qr.intersection, triangulation)) { - if (interior_simplex_map.emplace(std::make_pair(face, qr.intersection)).second) queue.emplace(face); + if (interior_simplex_map.emplace(face, qr.intersection).second) queue.emplace(face); } else { for (Simplex_handle cof : face.coface_range(cod_d + 1)) { auto qrb = oracle.intersects_boundary(cof, triangulation); diff --git a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h index 9263c67e..db145741 100644 --- a/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h +++ b/src/Coxeter_triangulation/include/gudhi/Permutahedral_representation/Permutahedral_representation_iterators.h @@ -173,7 +173,7 @@ class Coface_iterator } o_its_.clear(); for (uint j = 0; j < k_ + 1; j++) - o_its_.emplace_back(Ordered_set_partition_iterator(simplex_.partition()[j].size(), (*i_it_)[j] + 1)); + o_its_.emplace_back(simplex_.partition()[j].size(), (*i_it_)[j] + 1); } else for (uint j = 0; j < i; j++) o_its_[j].reinitialize(); update_value(); @@ -225,7 +225,7 @@ class Coface_iterator return; } for (uint i = 0; i < k_ + 1; i++) - o_its_.emplace_back(Ordered_set_partition_iterator(simplex_.partition()[i].size(), (*i_it_)[i] + 1)); + o_its_.emplace_back(simplex_.partition()[i].size(), (*i_it_)[i] + 1); update_value(); } -- cgit v1.2.3 From 3a06eff2f6345133270ddc50b625139761c06df6 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 7 Jun 2021 17:59:27 +0200 Subject: Use boost pi and do not declare a gudhi one. cf. PR #480 --- .../gudhi/Functions/random_orthogonal_matrix.h | 6 +++--- src/common/include/gudhi/math.h | 23 ---------------------- 2 files changed, 3 insertions(+), 26 deletions(-) delete mode 100644 src/common/include/gudhi/math.h (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h index fbc1c895..6a896e94 100644 --- a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -15,8 +15,6 @@ #include // for std::cos, std::sin #include // for std::uniform_real_distribution, std::random_device -#include - #include #include #include @@ -24,6 +22,8 @@ #include #include +#include // for PI value + namespace Gudhi { namespace coxeter_triangulation { @@ -44,7 +44,7 @@ Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) { if (d == 1) return Eigen::VectorXd::Constant(1, 1.0); if (d == 2) { // 0. < alpha < 2 Pi - std::uniform_real_distribution unif(0., 2 * Gudhi::PI); + std::uniform_real_distribution unif(0., 2 * boost::math::constants::pi()); std::random_device rand_dev; std::mt19937 rand_engine(rand_dev()); double alpha = unif(rand_engine); diff --git a/src/common/include/gudhi/math.h b/src/common/include/gudhi/math.h deleted file mode 100644 index f367bac2..00000000 --- a/src/common/include/gudhi/math.h +++ /dev/null @@ -1,23 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Vincent Rouvreau - * - * Copyright (C) 2020 Inria - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#ifndef MATH_H_ -#define MATH_H_ - -#include - -namespace Gudhi { - -// In wait of C++20 std::numbers::pi with #include -static constexpr double PI = boost::math::constants::pi(); - -} // namespace Gudhi - -#endif // MATH_H_ -- cgit v1.2.3 From 9e27d361e2f34d90f4d32fc417dd1facf6a36f3c Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 7 Jun 2021 18:13:03 +0200 Subject: code review: move Query_result.h in a Manifold_tracing directory as its name is too generic --- .../gudhi/Implicit_manifold_intersection_oracle.h | 2 +- .../include/gudhi/Manifold_tracing.h | 2 +- .../include/gudhi/Manifold_tracing/Query_result.h | 40 ++++++++++++++++++++++ .../include/gudhi/Query_result.h | 40 ---------------------- 4 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h delete mode 100644 src/Coxeter_triangulation/include/gudhi/Query_result.h (limited to 'src') diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index dca97331..b8c38188 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include // for GUDHI_CHECK #include diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index 71de47e1..29005bc5 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -12,7 +12,7 @@ #define MANIFOLD_TRACING_H_ #include // for DEBUG_TRACES -#include +#include #include diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h new file mode 100644 index 00000000..5543c2fb --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h @@ -0,0 +1,40 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef QUERY_RESULT_H_ +#define QUERY_RESULT_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Query_result + * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. + * + * \tparam Simplex_handle The class of the query simplex. + * + * \ingroup coxeter_triangulation + */ +template +struct Query_result { + /** \brief The potentially lower-dimensional face of the query simplex + * that contains the intersection point. OBSOLETE: as the snapping is removed. */ + // Simplex_handle face; + /** \brief The intersection point. */ + Eigen::VectorXd intersection; + /** \brief True if the query simplex intersects the manifold. */ + bool success; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Query_result.h deleted file mode 100644 index 5543c2fb..00000000 --- a/src/Coxeter_triangulation/include/gudhi/Query_result.h +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Siargey Kachanovich - * - * Copyright (C) 2019 Inria - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#ifndef QUERY_RESULT_H_ -#define QUERY_RESULT_H_ - -namespace Gudhi { - -namespace coxeter_triangulation { - -/** \class Query_result - * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. - * - * \tparam Simplex_handle The class of the query simplex. - * - * \ingroup coxeter_triangulation - */ -template -struct Query_result { - /** \brief The potentially lower-dimensional face of the query simplex - * that contains the intersection point. OBSOLETE: as the snapping is removed. */ - // Simplex_handle face; - /** \brief The intersection point. */ - Eigen::VectorXd intersection; - /** \brief True if the query simplex intersects the manifold. */ - bool success; -}; - -} // namespace coxeter_triangulation - -} // namespace Gudhi - -#endif -- cgit v1.2.3 From bc9411b2c9a837b2a444686ea153fe808e34f467 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Mon, 7 Jun 2021 18:24:34 +0200 Subject: code review: move Query_result.h in a Coxeter_triangulation directory and move Cell complex in it to be more specific about its use --- .../cell_complex_from_basic_circle_manifold.cpp | 2 +- .../example/manifold_tracing_custom_function.cpp | 2 +- .../manifold_tracing_flat_torus_with_boundary.cpp | 2 +- .../include/gudhi/Cell_complex.h | 340 --------------------- .../gudhi/Cell_complex/Hasse_diagram_cell.h | 285 ----------------- .../Cell_complex/Cell_complex.h | 340 +++++++++++++++++++++ .../Cell_complex/Hasse_diagram_cell.h | 285 +++++++++++++++++ .../gudhi/Coxeter_triangulation/Query_result.h | 40 +++ .../gudhi/Implicit_manifold_intersection_oracle.h | 2 +- .../include/gudhi/Manifold_tracing.h | 2 +- .../include/gudhi/Manifold_tracing/Query_result.h | 40 --- .../test/cell_complex_test.cpp | 2 +- 12 files changed, 671 insertions(+), 671 deletions(-) delete mode 100644 src/Coxeter_triangulation/include/gudhi/Cell_complex.h delete mode 100644 src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Cell_complex.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Hasse_diagram_cell.h create mode 100644 src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Query_result.h delete mode 100644 src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h (limited to 'src') diff --git a/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp index fc2afce4..dfaaffa8 100644 --- a/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp +++ b/src/Coxeter_triangulation/example/cell_complex_from_basic_circle_manifold.cpp @@ -3,7 +3,7 @@ #include #include // for Gudhi::coxeter_triangulation::make_oracle #include -#include +#include #include using namespace Gudhi::coxeter_triangulation; diff --git a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp index 3a36aed4..fe2051bb 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_custom_function.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp index 4b5e29fc..59fe2e2b 100644 --- a/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp +++ b/src/Coxeter_triangulation/example/manifold_tracing_flat_torus_with_boundary.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include // requires CGAL #include diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex.h deleted file mode 100644 index 561fe4ca..00000000 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex.h +++ /dev/null @@ -1,340 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Siargey Kachanovich - * - * Copyright (C) 2019 Inria - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#ifndef CELL_COMPLEX_H_ -#define CELL_COMPLEX_H_ - -#include - -#include -#include -#include // for std::make_pair - -#include // for DEBUG_TRACES -#include -#include // for Hasse_cell - -namespace Gudhi { - -namespace coxeter_triangulation { - -/** \class Cell_complex - * \brief A class that constructs the cell complex from the output provided by the class - * \ref Gudhi::coxeter_triangulation::Manifold_tracing. - * - * The use and interfaces of this cell complex is limited to the \ref coxeter_triangulation implementation. - * - * \tparam Out_simplex_map_ The type of a map from a simplex type that is a - * model of SimplexInCoxeterTriangulation to Eigen::VectorXd. - */ -template -class Cell_complex { - public: - /** \brief Type of a simplex in the ambient triangulation. - * Is a model of the concept SimplexInCoxeterTriangulation. - */ - using Simplex_handle = typename Out_simplex_map_::key_type; - /** \brief Type of a cell in the cell complex. - * Always is Gudhi::Hasse_cell from the Hasse diagram module. - * The additional information is the boolean that is true if and only if the cell lies - * on the boundary. - */ - using Hasse_cell = Gudhi::Hasse_diagram::Hasse_diagram_cell; - /** \brief Type of a map from permutahedral representations of simplices in the - * ambient triangulation to the corresponding cells in the cell complex of some - * specific dimension. - */ - using Simplex_cell_map = std::map >; - /** \brief Type of a vector of maps from permutahedral representations of simplices in the - * ambient triangulation to the corresponding cells in the cell complex of various dimensions. - */ - using Simplex_cell_maps = std::vector; - - /** \brief Type of a map from cells in the cell complex to the permutahedral representations - * of the corresponding simplices in the ambient triangulation. - */ - using Cell_simplex_map = std::map; - - /** \brief Type of a map from vertex cells in the cell complex to the permutahedral representations - * of their Cartesian coordinates. - */ - using Cell_point_map = std::map; - - private: - Hasse_cell* insert_cell(const Simplex_handle& simplex, std::size_t cell_d, bool is_boundary) { - Simplex_cell_maps& simplex_cell_maps = (is_boundary ? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); -#ifdef DEBUG_TRACES - CC_detail_list& cc_detail_list = - (is_boundary ? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); - cc_detail_list.emplace_back(simplex); -#endif - Simplex_cell_map& simplex_cell_map = simplex_cell_maps[cell_d]; - auto map_it = simplex_cell_map.find(simplex); - if (map_it == simplex_cell_map.end()) { - hasse_cells_.push_back(new Hasse_cell(is_boundary, cell_d)); - Hasse_cell* new_cell = hasse_cells_.back(); - simplex_cell_map.emplace(simplex, new_cell); - cell_simplex_map_.emplace(new_cell, simplex); -#ifdef DEBUG_TRACES - cc_detail_list.back().status_ = CC_detail_info::Result_type::inserted; -#endif - return new_cell; - } -#ifdef DEBUG_TRACES - CC_detail_info& cc_info = cc_detail_list.back(); - cc_info.trigger_ = to_string(map_it->first); - cc_info.status_ = CC_detail_info::Result_type::self; -#endif - return map_it->second; - } - - void expand_level(std::size_t cell_d) { - bool is_manifold_with_boundary = boundary_simplex_cell_maps_.size() > 0; - for (auto& sc_pair : interior_simplex_cell_maps_[cell_d - 1]) { - const Simplex_handle& simplex = sc_pair.first; - Hasse_cell* cell = sc_pair.second; - for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d)) { - Hasse_cell* new_cell = insert_cell(coface, cell_d, false); - new_cell->get_boundary().emplace_back(cell, 1); - } - } - - if (is_manifold_with_boundary) { - for (auto& sc_pair : boundary_simplex_cell_maps_[cell_d - 1]) { - const Simplex_handle& simplex = sc_pair.first; - Hasse_cell* cell = sc_pair.second; - if (cell_d != intr_d_) - for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d + 1)) { - Hasse_cell* new_cell = insert_cell(coface, cell_d, true); - new_cell->get_boundary().emplace_back(cell, 1); - } - auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex); - if (map_it == interior_simplex_cell_maps_[cell_d].end()) - std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n"; - else { - Hasse_cell* i_cell = map_it->second; - i_cell->get_boundary().emplace_back(cell, 1); - } - } - } - } - - void construct_complex_(const Out_simplex_map_& out_simplex_map) { -#ifdef DEBUG_TRACES - cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); - cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); - cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); -#endif - for (auto& os_pair : out_simplex_map) { - const Simplex_handle& simplex = os_pair.first; - const Eigen::VectorXd& point = os_pair.second; - Hasse_cell* new_cell = insert_cell(simplex, 0, false); - cell_point_map_.emplace(new_cell, point); - } - for (std::size_t cell_d = 1; - cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { - expand_level(cell_d); - } - } - - void construct_complex_(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { -#ifdef DEBUG_TRACES - cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); - cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); - cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); - cc_boundary_summary_lists.resize(boundary_simplex_cell_maps_.size()); - cc_boundary_prejoin_lists.resize(boundary_simplex_cell_maps_.size()); - cc_boundary_detail_lists.resize(boundary_simplex_cell_maps_.size()); -#endif - for (auto& os_pair : boundary_simplex_map) { - const Simplex_handle& simplex = os_pair.first; - const Eigen::VectorXd& point = os_pair.second; - Hasse_cell* new_cell = insert_cell(simplex, 0, true); - cell_point_map_.emplace(new_cell, point); - } - for (auto& os_pair : interior_simplex_map) { - const Simplex_handle& simplex = os_pair.first; - const Eigen::VectorXd& point = os_pair.second; - Hasse_cell* new_cell = insert_cell(simplex, 0, false); - cell_point_map_.emplace(new_cell, point); - } -#ifdef DEBUG_TRACES - for (const auto& sc_pair : interior_simplex_cell_maps_[0]) - cc_interior_summary_lists[0].push_back(CC_summary_info(sc_pair)); - for (const auto& sc_pair : boundary_simplex_cell_maps_[0]) - cc_boundary_summary_lists[0].push_back(CC_summary_info(sc_pair)); -#endif - - for (std::size_t cell_d = 1; - cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { - expand_level(cell_d); - -#ifdef DEBUG_TRACES - for (const auto& sc_pair : interior_simplex_cell_maps_[cell_d]) - cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); - if (cell_d < boundary_simplex_cell_maps_.size()) - for (const auto& sc_pair : boundary_simplex_cell_maps_[cell_d]) - cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); -#endif - } - } - - public: - /** - * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold - * without boundary embedded in the \f$ d \f$-dimensional Euclidean space - * from the output of the class Gudhi::Manifold_tracing. - * - * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold - * to the intersection points. - */ - void construct_complex(const Out_simplex_map_& out_simplex_map) { - interior_simplex_cell_maps_.resize(intr_d_ + 1); - if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); - construct_complex_(out_simplex_map); - } - - /** - * \brief Constructs the skeleton of the cell complex that approximates - * an \f$m\f$-dimensional manifold without boundary embedded - * in the \f$d\f$-dimensional Euclidean space - * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. - * - * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold - * to the intersection points. - * \param[in] limit_dimension The dimension of the constructed skeleton. - */ - void construct_complex(const Out_simplex_map_& out_simplex_map, std::size_t limit_dimension) { - interior_simplex_cell_maps_.resize(limit_dimension + 1); - if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); - construct_complex_(out_simplex_map); - } - - /** - * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold - * with boundary embedded in the \f$ d \f$-dimensional Euclidean space - * from the output of the class Gudhi::Manifold_tracing. - * - * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold - * to the intersection points. - * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ - * in the ambient triangulation that intersect the boundary of the manifold - * to the intersection points. - */ - void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { - interior_simplex_cell_maps_.resize(intr_d_ + 1); - boundary_simplex_cell_maps_.resize(intr_d_); - if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension(); - construct_complex_(interior_simplex_map, boundary_simplex_map); - } - - /** - * \brief Constructs the skeleton of the cell complex that approximates - * an \f$m\f$-dimensional manifold with boundary embedded - * in the \f$d\f$-dimensional Euclidean space - * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. - * - * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ - * in the ambient triangulation that intersect the relative interior of the manifold - * to the intersection points. - * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ - * in the ambient triangulation that intersect the boundary of the manifold - * to the intersection points. - * \param[in] limit_dimension The dimension of the constructed skeleton. - */ - void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map, - std::size_t limit_dimension) { - interior_simplex_cell_maps_.resize(limit_dimension + 1); - boundary_simplex_cell_maps_.resize(limit_dimension); - if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension(); - construct_complex_(interior_simplex_map, boundary_simplex_map); - } - - /** - * \brief Returns the dimension of the cell complex. - */ - std::size_t intrinsic_dimension() const { return intr_d_; } - - /** - * \brief Returns a vector of maps from the cells of various dimensions in the interior - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations - * of the corresponding simplices in the ambient triangulation. - */ - const Simplex_cell_maps& interior_simplex_cell_maps() const { return interior_simplex_cell_maps_; } - - /** - * \brief Returns a vector of maps from the cells of various dimensions on the boundary - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations - * of the corresponding simplices in the ambient triangulation. - */ - const Simplex_cell_maps& boundary_simplex_cell_maps() const { return boundary_simplex_cell_maps_; } - - /** - * \brief Returns a map from the cells of a given dimension in the interior - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations - * of the corresponding simplices in the ambient triangulation. - * - * \param[in] cell_d The dimension of the cells. - */ - const Simplex_cell_map& interior_simplex_cell_map(std::size_t cell_d) const { - return interior_simplex_cell_maps_[cell_d]; - } - - /** - * \brief Returns a map from the cells of a given dimension on the boundary - * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations - * of the corresponding simplices in the ambient triangulation. - * - * \param[in] cell_d The dimension of the cells. - */ - const Simplex_cell_map& boundary_simplex_cell_map(std::size_t cell_d) const { - return boundary_simplex_cell_maps_[cell_d]; - } - - /** - * \brief Returns a map from the cells in the cell complex of type Gudhi::Hasse_cell - * to the permutahedral representations of the corresponding simplices in the - * ambient triangulation. - */ - const Cell_simplex_map& cell_simplex_map() const { return cell_simplex_map_; } - - /** - * \brief Returns a map from the vertex cells in the cell complex of type Gudhi::Hasse_cell - * to their Cartesian coordinates. - */ - const Cell_point_map& cell_point_map() const { return cell_point_map_; } - - /** - * \brief Constructor for the class Cell_complex. - * - * \param[in] intrinsic_dimension The dimension of the cell complex. - */ - Cell_complex(std::size_t intrinsic_dimension) : intr_d_(intrinsic_dimension) {} - - ~Cell_complex() { - for (Hasse_cell* hs_ptr : hasse_cells_) delete hs_ptr; - } - - private: - std::size_t intr_d_, cod_d_; - Simplex_cell_maps interior_simplex_cell_maps_, boundary_simplex_cell_maps_; - Cell_simplex_map cell_simplex_map_; - Cell_point_map cell_point_map_; - std::vector hasse_cells_; -}; - -} // namespace coxeter_triangulation - -} // namespace Gudhi - -#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h deleted file mode 100644 index 59e9a350..00000000 --- a/src/Coxeter_triangulation/include/gudhi/Cell_complex/Hasse_diagram_cell.h +++ /dev/null @@ -1,285 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Pawel Dlotko - * - * Copyright (C) 2017 Swansea University UK - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#ifndef HASSE_DIAGRAM_CELL_H -#define HASSE_DIAGRAM_CELL_H - -#include -#include // for std::pair -#include -#include -#include // for std::is_same -#include // for std::size_t - -namespace Gudhi { -namespace Hasse_diagram { - -template -class Hasse_diagram; - -/** - * \class Hasse_diagram_cell - * \brief Data structure to store a cell in a Hasse diagram. - * - * \ingroup Hasse_diagram - * - * \details - * The use and interfaces of this Hasse diagram cell is limited to the \ref coxeter_triangulation implementation. - * - * This is a data structure to store a cell in a general Hasse diagram data structure. It stores the following - * information about the cell: References to boundary and coBoundary elements, dimension of a cell and its filtration. - * It also allow to store any additional information of a type Additional_information which is a template parameter of - * the class (set by default to void). - * - * The complex is a template class requiring the following parameters: - * Incidence_type_ - determine the type of incidence coefficients. Use integers in most general case. - * Filtration_type_ - type of filtration of cells. - * Additional_information_ (set by default to void) - allows to store any - * additional information in the cells of Hasse diagrams. - * - */ -template -class Hasse_diagram_cell { - public: - typedef Incidence_type_ Incidence_type; - typedef Filtration_type_ Filtration_type; - typedef Additional_information_ Additional_information; - using Cell_range = std::vector >; - - /** - * Default constructor. - **/ - Hasse_diagram_cell() : dimension(0), position(0), deleted_(false) {} - - /** - * Constructor of a cell of dimension dim. - **/ - Hasse_diagram_cell(int dim) : dimension(dim), position(0), deleted_(false) {} - - /** - * Constructor of a cell of dimension dim. - **/ - Hasse_diagram_cell(int dim, Filtration_type filt_) - : dimension(dim), position(0), deleted_(false), filtration(filt_) {} - - /** - * Constructor of a cell of dimension dim with a given boundary. - **/ - Hasse_diagram_cell(const Cell_range& boundary_, int dim) - : dimension(dim), boundary(boundary_), position(0), deleted_(false) {} - - /** - * Constructor of a cell of dimension dim with a given boundary and coboundary. - **/ - Hasse_diagram_cell(const Cell_range& boundary_, const Cell_range& coboundary_, int dim) - : dimension(dim), boundary(boundary_), coBoundary(coboundary_), position(0), deleted_(false) {} - - /** - * Constructor of a cell of dimension dim with a given boundary, coboundary and - * additional information. - **/ - Hasse_diagram_cell(const Cell_range& boundary_, const Cell_range& coboundary_, const Additional_information& ai, - int dim) - : dimension(dim), - boundary(boundary_), - coBoundary(coboundary_), - additional_info(ai), - position(0), - deleted_(false) {} - - /** - * Construcor of a cell of dimension dim having given additional information. - **/ - Hasse_diagram_cell(Additional_information ai, int dim) - : dimension(dim), additional_info(ai), position(0), deleted_(false) {} - - /** - * Procedure to get the boundary of a fiven cell. The output format - * is a vector of pairs of pointers to boundary elements and incidence - * coefficients. - **/ - inline Cell_range& get_boundary() { return this->boundary; } - - /** - * Procedure to get the coboundary of a fiven cell. The output format - * is a vector of pairs of pointers to coboundary elements and incidence - * coefficients. - **/ - inline Cell_range& get_coBoundary() { return this->coBoundary; } - - /** - * Procedure to get the dimension of a cell. - **/ - inline int& get_dimension() { return this->dimension; } - - /** - * Procedure to get additional information about the cell.s - **/ - inline Additional_information& get_additional_information() { return this->additional_info; } - - /** - * Procedure to retrive position of the cell in the structure. It is used in - * the implementation of Hasse diagram and set by it. Note that removal of - * cell and subsequent call of clean_up_the_structure will change those - * positions. - **/ - inline unsigned& get_position() { return this->position; } - - /** - * Accessing the filtration of the cell. - **/ - inline Filtration_type& get_filtration() { - // std::cout << "Accessing the filtration of a cell : " << *this << std::endl; - return this->filtration; - } - - /** - * A procedure used to check if the cell is deleted. It is used by the - * subsequent implementation of Hasse diagram that is absed on lazy - * delete. - **/ - inline bool deleted() { return this->deleted_; } - - template - friend class Hasse_diagram; - - template - friend class is_before_in_filtration; - - template - friend std::vector convert_to_vector_of_Cell_type(Complex_type& cmplx); - - /** - * Procedure to remove deleted boundary and coboundary elements from the - * vectors of boundary and coboundary elements of this cell. - **/ - void remove_deleted_elements_from_boundary_and_coboundary() { - Cell_range new_boundary; - new_boundary.reserve(this->boundary.size()); - for (std::size_t bd = 0; bd != this->boundary.size(); ++bd) { - if (!this->boundary[bd].first->deleted()) { - new_boundary.push_back(this->boundary[bd]); - } - } - this->boundary.swap(new_boundary); - - Cell_range new_coBoundary; - new_coBoundary.reserve(this->coBoundary.size()); - for (std::size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { - if (!this->coBoundary[cbd].first->deleted()) { - new_coBoundary.push_back(this->coBoundary[cbd]); - } - } - this->coBoundary.swap(new_coBoundary); - } - - /** - * Writing to a stream operator. - **/ - friend std::ostream& operator<<( - std::ostream& out, const Hasse_diagram_cell& c) { - // cout << "position : " << c.position << ", dimension : " << c.dimension << ", filtration: " << c.filtration << ", - // size of boudary : " << c.boundary.size() << "\n"; - out << c.position << " " << c.dimension << " " << c.filtration << std::endl; - for (std::size_t bd = 0; bd != c.boundary.size(); ++bd) { - // do not write out the cells that has been deleted - if (c.boundary[bd].first->deleted()) continue; - out << c.boundary[bd].first->position << " " << c.boundary[bd].second << " "; - } - out << std::endl; - return out; - } - - /** - * Procedure that return vector of pointers to boundary elements of a given cell. - **/ - inline std::vector get_list_of_boundary_elements() { - std::vector result; - std::size_t size_of_boundary = this->boundary.size(); - result.reserve(size_of_boundary); - for (std::size_t bd = 0; bd != size_of_boundary; ++bd) { - result.push_back(this->boundary[bd].first); - } - return result; - } - - /** - * Procedure that return vector of positios of boundary elements of a given cell. - **/ - inline std::vector get_list_of_positions_of_boundary_elements() { - std::vector result; - std::size_t size_of_boundary = this->boundary.size(); - result.reserve(size_of_boundary); - for (std::size_t bd = 0; bd != size_of_boundary; ++bd) { - result.push_back(this->boundary[bd].first->position); - } - return result; - } - - /** - * Function that display a string being a signature of a structure. - * Used mainly for debugging purposes. - **/ - std::string full_signature_of_the_structure() { - std::string result; - result += "dimension: "; - result += std::to_string(this->dimension); - result += " filtration: "; - result += std::to_string(this->filtration); - result += " position: "; - result += std::to_string(this->position); - result += " deleted_: "; - result += std::to_string(this->deleted_); - - // if the Additional_information is not void, add them to - // the signature as well. - if (std::is_same::value) { - result += " Additional_information: "; - result += std::to_string(this->additional_info); - } - result += " boundary "; - for (std::size_t bd = 0; bd != this->boundary.size(); ++bd) { - result += "( " + std::to_string(this->boundary[bd].first->position); - result += " " + std::to_string(this->boundary[bd].second); - result += ") "; - } - - result += " coBoundary "; - for (std::size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { - result += "( " + std::to_string(this->coBoundary[cbd].first->position); - result += " " + std::to_string(this->coBoundary[cbd].second); - result += ") "; - } - - return result; - } - - protected: - Cell_range boundary; - Cell_range coBoundary; - int dimension; - Additional_information additional_info; - unsigned position; - bool deleted_; - Filtration_type filtration; - - /** - * A procedure to delete a cell. It is a private function of the Hasse_diagram_cell - * class, since in the Hasse_diagram class I want to have a control - * of removal of cells. Therefore, to remove cell please use - * remove_cell in the Hasse_diagram structure. - **/ - void delete_cell() { this->deleted_ = true; } -}; // Hasse_diagram_cell - -} // namespace Hasse_diagram -} // namespace Gudhi - -#endif // CELL_H diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Cell_complex.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Cell_complex.h new file mode 100644 index 00000000..de342ecc --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Cell_complex.h @@ -0,0 +1,340 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef CELL_COMPLEX_H_ +#define CELL_COMPLEX_H_ + +#include + +#include +#include +#include // for std::make_pair + +#include // for DEBUG_TRACES +#include +#include // for Hasse_cell + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Cell_complex + * \brief A class that constructs the cell complex from the output provided by the class + * \ref Gudhi::coxeter_triangulation::Manifold_tracing. + * + * The use and interfaces of this cell complex is limited to the \ref coxeter_triangulation implementation. + * + * \tparam Out_simplex_map_ The type of a map from a simplex type that is a + * model of SimplexInCoxeterTriangulation to Eigen::VectorXd. + */ +template +class Cell_complex { + public: + /** \brief Type of a simplex in the ambient triangulation. + * Is a model of the concept SimplexInCoxeterTriangulation. + */ + using Simplex_handle = typename Out_simplex_map_::key_type; + /** \brief Type of a cell in the cell complex. + * Always is Gudhi::Hasse_cell from the Hasse diagram module. + * The additional information is the boolean that is true if and only if the cell lies + * on the boundary. + */ + using Hasse_cell = Gudhi::Hasse_diagram::Hasse_diagram_cell; + /** \brief Type of a map from permutahedral representations of simplices in the + * ambient triangulation to the corresponding cells in the cell complex of some + * specific dimension. + */ + using Simplex_cell_map = std::map >; + /** \brief Type of a vector of maps from permutahedral representations of simplices in the + * ambient triangulation to the corresponding cells in the cell complex of various dimensions. + */ + using Simplex_cell_maps = std::vector; + + /** \brief Type of a map from cells in the cell complex to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + */ + using Cell_simplex_map = std::map; + + /** \brief Type of a map from vertex cells in the cell complex to the permutahedral representations + * of their Cartesian coordinates. + */ + using Cell_point_map = std::map; + + private: + Hasse_cell* insert_cell(const Simplex_handle& simplex, std::size_t cell_d, bool is_boundary) { + Simplex_cell_maps& simplex_cell_maps = (is_boundary ? boundary_simplex_cell_maps_ : interior_simplex_cell_maps_); +#ifdef DEBUG_TRACES + CC_detail_list& cc_detail_list = + (is_boundary ? cc_boundary_detail_lists[cell_d] : cc_interior_detail_lists[cell_d]); + cc_detail_list.emplace_back(simplex); +#endif + Simplex_cell_map& simplex_cell_map = simplex_cell_maps[cell_d]; + auto map_it = simplex_cell_map.find(simplex); + if (map_it == simplex_cell_map.end()) { + hasse_cells_.push_back(new Hasse_cell(is_boundary, cell_d)); + Hasse_cell* new_cell = hasse_cells_.back(); + simplex_cell_map.emplace(simplex, new_cell); + cell_simplex_map_.emplace(new_cell, simplex); +#ifdef DEBUG_TRACES + cc_detail_list.back().status_ = CC_detail_info::Result_type::inserted; +#endif + return new_cell; + } +#ifdef DEBUG_TRACES + CC_detail_info& cc_info = cc_detail_list.back(); + cc_info.trigger_ = to_string(map_it->first); + cc_info.status_ = CC_detail_info::Result_type::self; +#endif + return map_it->second; + } + + void expand_level(std::size_t cell_d) { + bool is_manifold_with_boundary = boundary_simplex_cell_maps_.size() > 0; + for (auto& sc_pair : interior_simplex_cell_maps_[cell_d - 1]) { + const Simplex_handle& simplex = sc_pair.first; + Hasse_cell* cell = sc_pair.second; + for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d)) { + Hasse_cell* new_cell = insert_cell(coface, cell_d, false); + new_cell->get_boundary().emplace_back(cell, 1); + } + } + + if (is_manifold_with_boundary) { + for (auto& sc_pair : boundary_simplex_cell_maps_[cell_d - 1]) { + const Simplex_handle& simplex = sc_pair.first; + Hasse_cell* cell = sc_pair.second; + if (cell_d != intr_d_) + for (Simplex_handle coface : simplex.coface_range(cod_d_ + cell_d + 1)) { + Hasse_cell* new_cell = insert_cell(coface, cell_d, true); + new_cell->get_boundary().emplace_back(cell, 1); + } + auto map_it = interior_simplex_cell_maps_[cell_d].find(simplex); + if (map_it == interior_simplex_cell_maps_[cell_d].end()) + std::cerr << "Cell_complex::expand_level error: A boundary cell does not have an interior counterpart.\n"; + else { + Hasse_cell* i_cell = map_it->second; + i_cell->get_boundary().emplace_back(cell, 1); + } + } + } + } + + void construct_complex_(const Out_simplex_map_& out_simplex_map) { +#ifdef DEBUG_TRACES + cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); +#endif + for (auto& os_pair : out_simplex_map) { + const Simplex_handle& simplex = os_pair.first; + const Eigen::VectorXd& point = os_pair.second; + Hasse_cell* new_cell = insert_cell(simplex, 0, false); + cell_point_map_.emplace(new_cell, point); + } + for (std::size_t cell_d = 1; + cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { + expand_level(cell_d); + } + } + + void construct_complex_(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { +#ifdef DEBUG_TRACES + cc_interior_summary_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_prejoin_lists.resize(interior_simplex_cell_maps_.size()); + cc_interior_detail_lists.resize(interior_simplex_cell_maps_.size()); + cc_boundary_summary_lists.resize(boundary_simplex_cell_maps_.size()); + cc_boundary_prejoin_lists.resize(boundary_simplex_cell_maps_.size()); + cc_boundary_detail_lists.resize(boundary_simplex_cell_maps_.size()); +#endif + for (auto& os_pair : boundary_simplex_map) { + const Simplex_handle& simplex = os_pair.first; + const Eigen::VectorXd& point = os_pair.second; + Hasse_cell* new_cell = insert_cell(simplex, 0, true); + cell_point_map_.emplace(new_cell, point); + } + for (auto& os_pair : interior_simplex_map) { + const Simplex_handle& simplex = os_pair.first; + const Eigen::VectorXd& point = os_pair.second; + Hasse_cell* new_cell = insert_cell(simplex, 0, false); + cell_point_map_.emplace(new_cell, point); + } +#ifdef DEBUG_TRACES + for (const auto& sc_pair : interior_simplex_cell_maps_[0]) + cc_interior_summary_lists[0].push_back(CC_summary_info(sc_pair)); + for (const auto& sc_pair : boundary_simplex_cell_maps_[0]) + cc_boundary_summary_lists[0].push_back(CC_summary_info(sc_pair)); +#endif + + for (std::size_t cell_d = 1; + cell_d < interior_simplex_cell_maps_.size() && !interior_simplex_cell_maps_[cell_d - 1].empty(); ++cell_d) { + expand_level(cell_d); + +#ifdef DEBUG_TRACES + for (const auto& sc_pair : interior_simplex_cell_maps_[cell_d]) + cc_interior_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); + if (cell_d < boundary_simplex_cell_maps_.size()) + for (const auto& sc_pair : boundary_simplex_cell_maps_[cell_d]) + cc_boundary_summary_lists[cell_d].push_back(CC_summary_info(sc_pair)); +#endif + } + } + + public: + /** + * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold + * without boundary embedded in the \f$ d \f$-dimensional Euclidean space + * from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + */ + void construct_complex(const Out_simplex_map_& out_simplex_map) { + interior_simplex_cell_maps_.resize(intr_d_ + 1); + if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); + construct_complex_(out_simplex_map); + } + + /** + * \brief Constructs the skeleton of the cell complex that approximates + * an \f$m\f$-dimensional manifold without boundary embedded + * in the \f$d\f$-dimensional Euclidean space + * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] out_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + * \param[in] limit_dimension The dimension of the constructed skeleton. + */ + void construct_complex(const Out_simplex_map_& out_simplex_map, std::size_t limit_dimension) { + interior_simplex_cell_maps_.resize(limit_dimension + 1); + if (!out_simplex_map.empty()) cod_d_ = out_simplex_map.begin()->first.dimension(); + construct_complex_(out_simplex_map); + } + + /** + * \brief Constructs the the cell complex that approximates an \f$m\f$-dimensional manifold + * with boundary embedded in the \f$ d \f$-dimensional Euclidean space + * from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ + * in the ambient triangulation that intersect the boundary of the manifold + * to the intersection points. + */ + void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map) { + interior_simplex_cell_maps_.resize(intr_d_ + 1); + boundary_simplex_cell_maps_.resize(intr_d_); + if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension(); + construct_complex_(interior_simplex_map, boundary_simplex_map); + } + + /** + * \brief Constructs the skeleton of the cell complex that approximates + * an \f$m\f$-dimensional manifold with boundary embedded + * in the \f$d\f$-dimensional Euclidean space + * up to a limit dimension from the output of the class Gudhi::Manifold_tracing. + * + * \param[in] interior_simplex_map A map from simplices of dimension \f$(d-m)\f$ + * in the ambient triangulation that intersect the relative interior of the manifold + * to the intersection points. + * \param[in] boundary_simplex_map A map from simplices of dimension \f$(d-m+1)\f$ + * in the ambient triangulation that intersect the boundary of the manifold + * to the intersection points. + * \param[in] limit_dimension The dimension of the constructed skeleton. + */ + void construct_complex(const Out_simplex_map_& interior_simplex_map, const Out_simplex_map_& boundary_simplex_map, + std::size_t limit_dimension) { + interior_simplex_cell_maps_.resize(limit_dimension + 1); + boundary_simplex_cell_maps_.resize(limit_dimension); + if (!interior_simplex_map.empty()) cod_d_ = interior_simplex_map.begin()->first.dimension(); + construct_complex_(interior_simplex_map, boundary_simplex_map); + } + + /** + * \brief Returns the dimension of the cell complex. + */ + std::size_t intrinsic_dimension() const { return intr_d_; } + + /** + * \brief Returns a vector of maps from the cells of various dimensions in the interior + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + */ + const Simplex_cell_maps& interior_simplex_cell_maps() const { return interior_simplex_cell_maps_; } + + /** + * \brief Returns a vector of maps from the cells of various dimensions on the boundary + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + */ + const Simplex_cell_maps& boundary_simplex_cell_maps() const { return boundary_simplex_cell_maps_; } + + /** + * \brief Returns a map from the cells of a given dimension in the interior + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + * + * \param[in] cell_d The dimension of the cells. + */ + const Simplex_cell_map& interior_simplex_cell_map(std::size_t cell_d) const { + return interior_simplex_cell_maps_[cell_d]; + } + + /** + * \brief Returns a map from the cells of a given dimension on the boundary + * of the cell complex of type Gudhi::Hasse_cell to the permutahedral representations + * of the corresponding simplices in the ambient triangulation. + * + * \param[in] cell_d The dimension of the cells. + */ + const Simplex_cell_map& boundary_simplex_cell_map(std::size_t cell_d) const { + return boundary_simplex_cell_maps_[cell_d]; + } + + /** + * \brief Returns a map from the cells in the cell complex of type Gudhi::Hasse_cell + * to the permutahedral representations of the corresponding simplices in the + * ambient triangulation. + */ + const Cell_simplex_map& cell_simplex_map() const { return cell_simplex_map_; } + + /** + * \brief Returns a map from the vertex cells in the cell complex of type Gudhi::Hasse_cell + * to their Cartesian coordinates. + */ + const Cell_point_map& cell_point_map() const { return cell_point_map_; } + + /** + * \brief Constructor for the class Cell_complex. + * + * \param[in] intrinsic_dimension The dimension of the cell complex. + */ + Cell_complex(std::size_t intrinsic_dimension) : intr_d_(intrinsic_dimension) {} + + ~Cell_complex() { + for (Hasse_cell* hs_ptr : hasse_cells_) delete hs_ptr; + } + + private: + std::size_t intr_d_, cod_d_; + Simplex_cell_maps interior_simplex_cell_maps_, boundary_simplex_cell_maps_; + Cell_simplex_map cell_simplex_map_; + Cell_point_map cell_point_map_; + std::vector hasse_cells_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Hasse_diagram_cell.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Hasse_diagram_cell.h new file mode 100644 index 00000000..59e9a350 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Cell_complex/Hasse_diagram_cell.h @@ -0,0 +1,285 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Pawel Dlotko + * + * Copyright (C) 2017 Swansea University UK + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef HASSE_DIAGRAM_CELL_H +#define HASSE_DIAGRAM_CELL_H + +#include +#include // for std::pair +#include +#include +#include // for std::is_same +#include // for std::size_t + +namespace Gudhi { +namespace Hasse_diagram { + +template +class Hasse_diagram; + +/** + * \class Hasse_diagram_cell + * \brief Data structure to store a cell in a Hasse diagram. + * + * \ingroup Hasse_diagram + * + * \details + * The use and interfaces of this Hasse diagram cell is limited to the \ref coxeter_triangulation implementation. + * + * This is a data structure to store a cell in a general Hasse diagram data structure. It stores the following + * information about the cell: References to boundary and coBoundary elements, dimension of a cell and its filtration. + * It also allow to store any additional information of a type Additional_information which is a template parameter of + * the class (set by default to void). + * + * The complex is a template class requiring the following parameters: + * Incidence_type_ - determine the type of incidence coefficients. Use integers in most general case. + * Filtration_type_ - type of filtration of cells. + * Additional_information_ (set by default to void) - allows to store any + * additional information in the cells of Hasse diagrams. + * + */ +template +class Hasse_diagram_cell { + public: + typedef Incidence_type_ Incidence_type; + typedef Filtration_type_ Filtration_type; + typedef Additional_information_ Additional_information; + using Cell_range = std::vector >; + + /** + * Default constructor. + **/ + Hasse_diagram_cell() : dimension(0), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim. + **/ + Hasse_diagram_cell(int dim) : dimension(dim), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim. + **/ + Hasse_diagram_cell(int dim, Filtration_type filt_) + : dimension(dim), position(0), deleted_(false), filtration(filt_) {} + + /** + * Constructor of a cell of dimension dim with a given boundary. + **/ + Hasse_diagram_cell(const Cell_range& boundary_, int dim) + : dimension(dim), boundary(boundary_), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim with a given boundary and coboundary. + **/ + Hasse_diagram_cell(const Cell_range& boundary_, const Cell_range& coboundary_, int dim) + : dimension(dim), boundary(boundary_), coBoundary(coboundary_), position(0), deleted_(false) {} + + /** + * Constructor of a cell of dimension dim with a given boundary, coboundary and + * additional information. + **/ + Hasse_diagram_cell(const Cell_range& boundary_, const Cell_range& coboundary_, const Additional_information& ai, + int dim) + : dimension(dim), + boundary(boundary_), + coBoundary(coboundary_), + additional_info(ai), + position(0), + deleted_(false) {} + + /** + * Construcor of a cell of dimension dim having given additional information. + **/ + Hasse_diagram_cell(Additional_information ai, int dim) + : dimension(dim), additional_info(ai), position(0), deleted_(false) {} + + /** + * Procedure to get the boundary of a fiven cell. The output format + * is a vector of pairs of pointers to boundary elements and incidence + * coefficients. + **/ + inline Cell_range& get_boundary() { return this->boundary; } + + /** + * Procedure to get the coboundary of a fiven cell. The output format + * is a vector of pairs of pointers to coboundary elements and incidence + * coefficients. + **/ + inline Cell_range& get_coBoundary() { return this->coBoundary; } + + /** + * Procedure to get the dimension of a cell. + **/ + inline int& get_dimension() { return this->dimension; } + + /** + * Procedure to get additional information about the cell.s + **/ + inline Additional_information& get_additional_information() { return this->additional_info; } + + /** + * Procedure to retrive position of the cell in the structure. It is used in + * the implementation of Hasse diagram and set by it. Note that removal of + * cell and subsequent call of clean_up_the_structure will change those + * positions. + **/ + inline unsigned& get_position() { return this->position; } + + /** + * Accessing the filtration of the cell. + **/ + inline Filtration_type& get_filtration() { + // std::cout << "Accessing the filtration of a cell : " << *this << std::endl; + return this->filtration; + } + + /** + * A procedure used to check if the cell is deleted. It is used by the + * subsequent implementation of Hasse diagram that is absed on lazy + * delete. + **/ + inline bool deleted() { return this->deleted_; } + + template + friend class Hasse_diagram; + + template + friend class is_before_in_filtration; + + template + friend std::vector convert_to_vector_of_Cell_type(Complex_type& cmplx); + + /** + * Procedure to remove deleted boundary and coboundary elements from the + * vectors of boundary and coboundary elements of this cell. + **/ + void remove_deleted_elements_from_boundary_and_coboundary() { + Cell_range new_boundary; + new_boundary.reserve(this->boundary.size()); + for (std::size_t bd = 0; bd != this->boundary.size(); ++bd) { + if (!this->boundary[bd].first->deleted()) { + new_boundary.push_back(this->boundary[bd]); + } + } + this->boundary.swap(new_boundary); + + Cell_range new_coBoundary; + new_coBoundary.reserve(this->coBoundary.size()); + for (std::size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { + if (!this->coBoundary[cbd].first->deleted()) { + new_coBoundary.push_back(this->coBoundary[cbd]); + } + } + this->coBoundary.swap(new_coBoundary); + } + + /** + * Writing to a stream operator. + **/ + friend std::ostream& operator<<( + std::ostream& out, const Hasse_diagram_cell& c) { + // cout << "position : " << c.position << ", dimension : " << c.dimension << ", filtration: " << c.filtration << ", + // size of boudary : " << c.boundary.size() << "\n"; + out << c.position << " " << c.dimension << " " << c.filtration << std::endl; + for (std::size_t bd = 0; bd != c.boundary.size(); ++bd) { + // do not write out the cells that has been deleted + if (c.boundary[bd].first->deleted()) continue; + out << c.boundary[bd].first->position << " " << c.boundary[bd].second << " "; + } + out << std::endl; + return out; + } + + /** + * Procedure that return vector of pointers to boundary elements of a given cell. + **/ + inline std::vector get_list_of_boundary_elements() { + std::vector result; + std::size_t size_of_boundary = this->boundary.size(); + result.reserve(size_of_boundary); + for (std::size_t bd = 0; bd != size_of_boundary; ++bd) { + result.push_back(this->boundary[bd].first); + } + return result; + } + + /** + * Procedure that return vector of positios of boundary elements of a given cell. + **/ + inline std::vector get_list_of_positions_of_boundary_elements() { + std::vector result; + std::size_t size_of_boundary = this->boundary.size(); + result.reserve(size_of_boundary); + for (std::size_t bd = 0; bd != size_of_boundary; ++bd) { + result.push_back(this->boundary[bd].first->position); + } + return result; + } + + /** + * Function that display a string being a signature of a structure. + * Used mainly for debugging purposes. + **/ + std::string full_signature_of_the_structure() { + std::string result; + result += "dimension: "; + result += std::to_string(this->dimension); + result += " filtration: "; + result += std::to_string(this->filtration); + result += " position: "; + result += std::to_string(this->position); + result += " deleted_: "; + result += std::to_string(this->deleted_); + + // if the Additional_information is not void, add them to + // the signature as well. + if (std::is_same::value) { + result += " Additional_information: "; + result += std::to_string(this->additional_info); + } + result += " boundary "; + for (std::size_t bd = 0; bd != this->boundary.size(); ++bd) { + result += "( " + std::to_string(this->boundary[bd].first->position); + result += " " + std::to_string(this->boundary[bd].second); + result += ") "; + } + + result += " coBoundary "; + for (std::size_t cbd = 0; cbd != this->coBoundary.size(); ++cbd) { + result += "( " + std::to_string(this->coBoundary[cbd].first->position); + result += " " + std::to_string(this->coBoundary[cbd].second); + result += ") "; + } + + return result; + } + + protected: + Cell_range boundary; + Cell_range coBoundary; + int dimension; + Additional_information additional_info; + unsigned position; + bool deleted_; + Filtration_type filtration; + + /** + * A procedure to delete a cell. It is a private function of the Hasse_diagram_cell + * class, since in the Hasse_diagram class I want to have a control + * of removal of cells. Therefore, to remove cell please use + * remove_cell in the Hasse_diagram structure. + **/ + void delete_cell() { this->deleted_ = true; } +}; // Hasse_diagram_cell + +} // namespace Hasse_diagram +} // namespace Gudhi + +#endif // CELL_H diff --git a/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Query_result.h new file mode 100644 index 00000000..5543c2fb --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Coxeter_triangulation/Query_result.h @@ -0,0 +1,40 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef QUERY_RESULT_H_ +#define QUERY_RESULT_H_ + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Query_result + * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. + * + * \tparam Simplex_handle The class of the query simplex. + * + * \ingroup coxeter_triangulation + */ +template +struct Query_result { + /** \brief The potentially lower-dimensional face of the query simplex + * that contains the intersection point. OBSOLETE: as the snapping is removed. */ + // Simplex_handle face; + /** \brief The intersection point. */ + Eigen::VectorXd intersection; + /** \brief True if the query simplex intersects the manifold. */ + bool success; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h index b8c38188..277f8b6c 100644 --- a/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h +++ b/src/Coxeter_triangulation/include/gudhi/Implicit_manifold_intersection_oracle.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include // for GUDHI_CHECK #include diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h index 29005bc5..d61bbed7 100644 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h +++ b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing.h @@ -12,7 +12,7 @@ #define MANIFOLD_TRACING_H_ #include // for DEBUG_TRACES -#include +#include #include diff --git a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h b/src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h deleted file mode 100644 index 5543c2fb..00000000 --- a/src/Coxeter_triangulation/include/gudhi/Manifold_tracing/Query_result.h +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. - * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. - * Author(s): Siargey Kachanovich - * - * Copyright (C) 2019 Inria - * - * Modification(s): - * - YYYY/MM Author: Description of the modification - */ - -#ifndef QUERY_RESULT_H_ -#define QUERY_RESULT_H_ - -namespace Gudhi { - -namespace coxeter_triangulation { - -/** \class Query_result - * \brief The result of a query by an oracle such as Implicit_manifold_intersection_oracle. - * - * \tparam Simplex_handle The class of the query simplex. - * - * \ingroup coxeter_triangulation - */ -template -struct Query_result { - /** \brief The potentially lower-dimensional face of the query simplex - * that contains the intersection point. OBSOLETE: as the snapping is removed. */ - // Simplex_handle face; - /** \brief The intersection point. */ - Eigen::VectorXd intersection; - /** \brief True if the query simplex intersects the manifold. */ - bool success; -}; - -} // namespace coxeter_triangulation - -} // namespace Gudhi - -#endif diff --git a/src/Coxeter_triangulation/test/cell_complex_test.cpp b/src/Coxeter_triangulation/test/cell_complex_test.cpp index 88b6142b..4f7f3ec5 100644 --- a/src/Coxeter_triangulation/test/cell_complex_test.cpp +++ b/src/Coxeter_triangulation/test/cell_complex_test.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include using namespace Gudhi::coxeter_triangulation; -- cgit v1.2.3 From 575beed582f9288d83a403f4f578731f172f7f5f Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 11 Aug 2021 14:35:25 +0200 Subject: Add test for sphere and torus Fix numerical approximations inconsistencies with dim fraction exponent when generating points as grid on torus Add notes in doc regarding the torus versions use cases --- src/common/include/gudhi/random_point_generators.h | 2 +- src/python/CMakeLists.txt | 3 ++ src/python/doc/datasets_generators.rst | 5 +++ src/python/gudhi/datasets/generators/_points.cc | 4 +++ src/python/gudhi/datasets/generators/points.py | 5 +-- src/python/test/test_datasets_generators.py | 40 ++++++++++++++++++++++ 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100755 src/python/test/test_datasets_generators.py (limited to 'src') diff --git a/src/common/include/gudhi/random_point_generators.h b/src/common/include/gudhi/random_point_generators.h index 07e4f3da..25a7392d 100644 --- a/src/common/include/gudhi/random_point_generators.h +++ b/src/common/include/gudhi/random_point_generators.h @@ -227,7 +227,7 @@ std::vector generate_points_on_torus_d(std::size_t num std::vector points; points.reserve(num_points); if (sample == "grid") { - std::size_t num_slices = (std::size_t)std::pow(num_points, 1. / dim); + std::size_t num_slices = (std::size_t)std::pow(num_points + .5, 1. / dim); // add .5 to avoid rounding down with numerical approximations generate_grid_points_on_torus_d( k, dim, num_slices, std::back_inserter(points), radius_noise_percentage); } else { diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 8c46004a..f30dfe6d 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -443,6 +443,9 @@ if(PYTHONINTERP_FOUND) # Euclidean witness add_gudhi_py_test(test_euclidean_witness_complex) + # Datasets generators + add_gudhi_py_test(test_datasets_generators) # TODO separate full python datasets generators in another test file independant from CGAL ? + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) # Cubical diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst index 2802eccd..e63dde82 100644 --- a/src/python/doc/datasets_generators.rst +++ b/src/python/doc/datasets_generators.rst @@ -60,6 +60,9 @@ Otherwise, if set to **'grid'**, the points are generated on a grid and would be ( [n\_samples^{1 \over {dim}}]^{dim}, 2*dim ) + +**Note:** This version is recommended when the user wishes to use **'grid'** as sample type, or **'random'** with a relatively small number of samples (~ less than 150). + Example """"""" .. code-block:: python @@ -81,6 +84,8 @@ The user should provide the number of points to be generated on the torus :code: The :code:`sample` argument is optional and is set to **'random'** by default. The other allowed value of sample type is **'grid'**. +**Note:** This version is recommended when the user wishes to use **'random'** as sample type with a great number of samples and a low dimension. + Example """"""" .. code-block:: python diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 6bbdf284..3d38ff90 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -48,6 +48,10 @@ py::array_t generate_points_on_sphere(size_t n_samples, int ambient_dim, py::array_t generate_points_on_torus(size_t n_samples, int dim, std::string sample) { + if ( (sample != "random") && (sample != "grid")) { + throw pybind11::value_error("This sample type is not supported"); + } + std::vector points_generated; { diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index 3870dea6..daada486 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -23,7 +23,7 @@ def _generate_random_points_on_torus(n_samples, dim): def _generate_grid_points_on_torus(n_samples, dim): # Generate points on a dim-torus as a grid - n_samples_grid = int(n_samples**(1./dim)) + n_samples_grid = int((n_samples+.5)**(1./dim)) # add .5 to avoid rounding down with numerical approximations alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False) array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)]) @@ -45,12 +45,9 @@ def torus(n_samples, dim, sample='random'): """ if sample == 'random': # Generate points randomly - print("Sample is random") return _generate_random_points_on_torus(n_samples, dim) elif sample == 'grid': # Generate points on a grid - print("Sample is grid") return _generate_grid_points_on_torus(n_samples, dim) else: raise ValueError("Sample type '{}' is not supported".format(sample)) - return diff --git a/src/python/test/test_datasets_generators.py b/src/python/test/test_datasets_generators.py new file mode 100755 index 00000000..656c30ee --- /dev/null +++ b/src/python/test/test_datasets_generators.py @@ -0,0 +1,40 @@ +""" This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + Author(s): Hind Montassif + + Copyright (C) 2021 Inria + + Modification(s): + - YYYY/MM Author: Description of the modification +""" + +from gudhi.datasets.generators import points +from gudhi.datasets.generators import _points + +import pytest + +def test_sphere(): + assert _points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'random').shape == (10, 2) + + with pytest.raises(ValueError): + _points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'other') + +def test_torus(): + assert _points.torus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) + assert _points.torus(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) + + assert _points.torus(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) + assert _points.torus(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) + + with pytest.raises(ValueError): + _points.torus(n_samples = 10, dim = 4, sample = 'other') + +def test_torus_full_python(): + assert points.torus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) + assert points.torus(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) + + assert points.torus(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) + assert points.torus(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) + + with pytest.raises(ValueError): + points.torus(n_samples = 10, dim = 4, sample = 'other') -- cgit v1.2.3 From e758542b427045c6cf727a99ba6e5ff7debc309a Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 16 Aug 2021 11:19:26 +0200 Subject: Fix issue #515 : Avoid confusion between dimension and field of coefficients in persistent_cohomology_unit_test.cpp and persistent_cohomology_unit_test_multi_field.cpp --- .../test/persistent_cohomology_unit_test.cpp | 78 +++++++++++----------- ...persistent_cohomology_unit_test_multi_field.cpp | 44 +++++++----- 2 files changed, 67 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 041cb0fd..3c4672a5 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -53,7 +53,7 @@ std::string test_rips_persistence(int coefficient, int min_persistence) { return strInfinite; } -void test_rips_persistence_in_dimension(int dimension) { +void test_rips_persistence_with_coeff_field(int coeff_field) { std::string value0(" 0 0.02 1.12"); std::string value1(" 0 0.03 1.13"); std::string value2(" 0 0.04 1.14"); @@ -65,21 +65,21 @@ void test_rips_persistence_in_dimension(int dimension) { std::string value8(" 0 0 inf" ); std::string value9(" 0 0.01 inf" ); - value0.insert(0,std::to_string(dimension)); - value1.insert(0,std::to_string(dimension)); - value2.insert(0,std::to_string(dimension)); - value3.insert(0,std::to_string(dimension)); - value4.insert(0,std::to_string(dimension)); - value5.insert(0,std::to_string(dimension)); - value6.insert(0,std::to_string(dimension)); - value7.insert(0,std::to_string(dimension)); - value8.insert(0,std::to_string(dimension)); - value9.insert(0,std::to_string(dimension)); + value0.insert(0,std::to_string(coeff_field)); + value1.insert(0,std::to_string(coeff_field)); + value2.insert(0,std::to_string(coeff_field)); + value3.insert(0,std::to_string(coeff_field)); + value4.insert(0,std::to_string(coeff_field)); + value5.insert(0,std::to_string(coeff_field)); + value6.insert(0,std::to_string(coeff_field)); + value7.insert(0,std::to_string(coeff_field)); + value8.insert(0,std::to_string(coeff_field)); + value9.insert(0,std::to_string(coeff_field)); std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=0" << std::endl; + std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=0" << std::endl; - std::string str_rips_persistence = test_rips_persistence(dimension, 0); + std::string str_rips_persistence = test_rips_persistence(coeff_field, 0); std::clog << str_rips_persistence << std::endl; BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found @@ -95,9 +95,9 @@ void test_rips_persistence_in_dimension(int dimension) { std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=1" << std::endl; + std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=1" << std::endl; - str_rips_persistence = test_rips_persistence(dimension, 1); + str_rips_persistence = test_rips_persistence(coeff_field, 1); BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found @@ -112,9 +112,9 @@ void test_rips_persistence_in_dimension(int dimension) { std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=2" << std::endl; + std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=2" << std::endl; - str_rips_persistence = test_rips_persistence(dimension, 2); + str_rips_persistence = test_rips_persistence(coeff_field, 2); BOOST_CHECK(str_rips_persistence.find(value0) == std::string::npos); // Check not found BOOST_CHECK(str_rips_persistence.find(value1) == std::string::npos); // Check not found @@ -129,9 +129,9 @@ void test_rips_persistence_in_dimension(int dimension) { std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD DIM=" << dimension << " MIN_PERS=Inf" << std::endl; + std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=Inf" << std::endl; - str_rips_persistence = test_rips_persistence(dimension, (std::numeric_limits::max)()); + str_rips_persistence = test_rips_persistence(coeff_field, (std::numeric_limits::max)()); BOOST_CHECK(str_rips_persistence.find(value0) == std::string::npos); // Check not found BOOST_CHECK(str_rips_persistence.find(value1) == std::string::npos); // Check not found @@ -146,54 +146,54 @@ void test_rips_persistence_in_dimension(int dimension) { std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_0 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_0 ) { - BOOST_CHECK_THROW(test_rips_persistence_in_dimension(0), std::invalid_argument); + BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(0), std::invalid_argument); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_1 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_1 ) { - BOOST_CHECK_THROW(test_rips_persistence_in_dimension(1), std::invalid_argument); + BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(1), std::invalid_argument); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_2 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_2 ) { - test_rips_persistence_in_dimension(2); + test_rips_persistence_with_coeff_field(2); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_3 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_3 ) { - test_rips_persistence_in_dimension(3); + test_rips_persistence_with_coeff_field(3); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_4 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_4 ) { - BOOST_CHECK_THROW(test_rips_persistence_in_dimension(4), std::invalid_argument); + BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(4), std::invalid_argument); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_5 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_5 ) { - test_rips_persistence_in_dimension(5); + test_rips_persistence_with_coeff_field(5); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_6 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_6 ) { - BOOST_CHECK_THROW(test_rips_persistence_in_dimension(6), std::invalid_argument); + BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(6), std::invalid_argument); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_11 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_11 ) { - test_rips_persistence_in_dimension(11); + test_rips_persistence_with_coeff_field(11); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_13 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_13 ) { - test_rips_persistence_in_dimension(13); + test_rips_persistence_with_coeff_field(13); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_46349 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_46349 ) { - BOOST_CHECK_THROW(test_rips_persistence_in_dimension(46349), std::invalid_argument); + BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(46349), std::invalid_argument); } /** SimplexTree minimal options to test the limits. diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp index 3602aa09..24a3890c 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp @@ -54,7 +54,7 @@ std::string test_rips_persistence(int min_coefficient, int max_coefficient, doub return strRips; } -void test_rips_persistence_in_dimension(int min_dimension, int max_dimension) { +void test_rips_persistence_with_coeff_field(int min_coefficient, int max_coefficient) { // there are 2 discontinued ensembles std::string value0(" 0 0.25 inf"); std::string value1(" 1 0.4 inf"); @@ -69,16 +69,16 @@ void test_rips_persistence_in_dimension(int min_dimension, int max_dimension) { std::string value7(" 2 0.4 inf"); std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_MULTI_FIELD MIN_DIM=" << min_dimension << " MAX_DIM=" << max_dimension << " MIN_PERS=0" << std::endl; + std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_MULTI_FIELD MIN_COEFF=" << min_coefficient << " MAX_COEFF=" << max_coefficient << " MIN_PERS=0" << std::endl; - std::string str_rips_persistence = test_rips_persistence(min_dimension, max_dimension, 0.0); + std::string str_rips_persistence = test_rips_persistence(min_coefficient, max_coefficient, 0.0); std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found - if ((min_dimension < 2) && (max_dimension < 2)) { + if ((min_coefficient < 2) && (max_coefficient < 2)) { BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found @@ -94,22 +94,34 @@ void test_rips_persistence_in_dimension(int min_dimension, int max_dimension) { } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_dim_1_2) { - test_rips_persistence_in_dimension(0, 1); +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_0_0) { + test_rips_persistence_with_coeff_field(0, 0); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_dim_2_3) { - test_rips_persistence_in_dimension(1, 3); +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_0_1) { + test_rips_persistence_with_coeff_field(0, 1); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_dim_1_5) { - test_rips_persistence_in_dimension(1, 5); +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_0_6) { + test_rips_persistence_with_coeff_field(0, 6); } -// TODO(VR): not working from 6 -// std::string str_rips_persistence = test_rips_persistence(6, 0); -// TODO(VR): division by zero -// std::string str_rips_persistence = test_rips_persistence(0, 0); -// TODO(VR): is result OK of : -// test_rips_persistence_in_dimension(3, 4); +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_1_2) { + test_rips_persistence_with_coeff_field(1, 2); +} + +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_1_3) { + test_rips_persistence_with_coeff_field(1, 3); +} + +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_1_5) { + test_rips_persistence_with_coeff_field(1, 5); +} + +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_2_3) { + test_rips_persistence_with_coeff_field(2, 3); +} +BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_3_4) { + test_rips_persistence_with_coeff_field(3, 4); +} -- cgit v1.2.3 From 327a374bf86249f566ca05191ed5de8676055a83 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Thu, 19 Aug 2021 09:47:47 +0200 Subject: Compress the different unit tests into two main categories: prime and non-prime --- .../test/persistent_cohomology_unit_test.cpp | 47 ++++------------------ 1 file changed, 7 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 3c4672a5..19bb1b90 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -146,52 +146,19 @@ void test_rips_persistence_with_coeff_field(int coeff_field) { std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_0 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_not_prime ) { - BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(0), std::invalid_argument); + for (auto non_prime : {0, 1, 4, 6}) + BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(non_prime), std::invalid_argument); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_1 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_prime ) { - BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(1), std::invalid_argument); + for (auto prime : {2, 3, 5, 11, 13}) + test_rips_persistence_with_coeff_field(prime); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_2 ) -{ - test_rips_persistence_with_coeff_field(2); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_3 ) -{ - test_rips_persistence_with_coeff_field(3); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_4 ) -{ - BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(4), std::invalid_argument); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_5 ) -{ - test_rips_persistence_with_coeff_field(5); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_6 ) -{ - BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(6), std::invalid_argument); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_11 ) -{ - test_rips_persistence_with_coeff_field(11); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_13 ) -{ - test_rips_persistence_with_coeff_field(13); -} - -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_46349 ) +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_limit ) { BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(46349), std::invalid_argument); } -- cgit v1.2.3 From 675d0dd55955eb1b93529546003052fd550dea12 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 25 Aug 2021 17:53:41 +0200 Subject: Remove irrelevant 'rips' word from persistent cohomology unit tests --- .../test/persistent_cohomology_unit_test.cpp | 144 ++++++++++----------- ...persistent_cohomology_unit_test_multi_field.cpp | 78 +++++------ 2 files changed, 111 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 19bb1b90..ea41a8aa 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -21,7 +21,7 @@ using namespace boost::unit_test; typedef Simplex_tree<> typeST; -std::string test_rips_persistence(int coefficient, int min_persistence) { +std::string test_persistence(int coefficient, int min_persistence) { // file is copied in CMakeLists.txt std::ifstream simplex_tree_stream; simplex_tree_stream.open("simplex_tree_file_for_unit_test.txt"); @@ -44,16 +44,16 @@ std::string test_rips_persistence(int coefficient, int min_persistence) { Persistent_cohomology, Field_Zp> pcoh(st); pcoh.init_coefficients( coefficient ); // initializes the coefficient field for homology - // Check infinite rips + // Compute the persistent homology of the complex pcoh.compute_persistent_cohomology( min_persistence ); // Minimal lifetime of homology feature to be recorded. - std::ostringstream ossInfinite; + std::ostringstream ossPers; - pcoh.output_diagram(ossInfinite); - std::string strInfinite = ossInfinite.str(); - return strInfinite; + pcoh.output_diagram(ossPers); + std::string strPers = ossPers.str(); + return strPers; } -void test_rips_persistence_with_coeff_field(int coeff_field) { +void test_persistence_with_coeff_field(int coeff_field) { std::string value0(" 0 0.02 1.12"); std::string value1(" 0 0.03 1.13"); std::string value2(" 0 0.04 1.14"); @@ -77,90 +77,90 @@ void test_rips_persistence_with_coeff_field(int coeff_field) { value9.insert(0,std::to_string(coeff_field)); std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=0" << std::endl; + std::clog << "TEST OF PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=0" << std::endl; - std::string str_rips_persistence = test_rips_persistence(coeff_field, 0); - std::clog << str_rips_persistence << std::endl; + std::string str_persistence = test_persistence(coeff_field, 0); + std::clog << str_persistence << std::endl; - BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value6) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value7) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found - std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; + BOOST_CHECK(str_persistence.find(value0) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value1) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value2) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value3) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value4) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value5) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value6) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value7) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value8) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value9) != std::string::npos); // Check found + std::clog << "str_persistence=" << str_persistence << std::endl; std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=1" << std::endl; - - str_rips_persistence = test_rips_persistence(coeff_field, 1); - - BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value6) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value7) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found - std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; + std::clog << "TEST OF PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=1" << std::endl; + + str_persistence = test_persistence(coeff_field, 1); + + BOOST_CHECK(str_persistence.find(value0) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value1) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value2) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value3) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value4) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value5) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value6) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value7) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value8) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value9) != std::string::npos); // Check found + std::clog << "str_persistence=" << str_persistence << std::endl; std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=2" << std::endl; - - str_rips_persistence = test_rips_persistence(coeff_field, 2); - - BOOST_CHECK(str_rips_persistence.find(value0) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value1) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value2) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value3) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value4) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value5) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value6) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value7) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found - std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; + std::clog << "TEST OF PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=2" << std::endl; + + str_persistence = test_persistence(coeff_field, 2); + + BOOST_CHECK(str_persistence.find(value0) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value1) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value2) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value3) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value4) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value5) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value6) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value7) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value8) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value9) != std::string::npos); // Check found + std::clog << "str_persistence=" << str_persistence << std::endl; std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=Inf" << std::endl; - - str_rips_persistence = test_rips_persistence(coeff_field, (std::numeric_limits::max)()); - - BOOST_CHECK(str_rips_persistence.find(value0) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value1) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value2) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value3) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value4) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value5) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value6) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value7) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value8) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value9) != std::string::npos); // Check found - std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; + std::clog << "TEST OF PERSISTENT_COHOMOLOGY_SINGLE_FIELD COEFF_FIELD=" << coeff_field << " MIN_PERS=Inf" << std::endl; + + str_persistence = test_persistence(coeff_field, (std::numeric_limits::max)()); + + BOOST_CHECK(str_persistence.find(value0) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value1) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value2) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value3) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value4) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value5) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value6) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value7) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value8) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value9) != std::string::npos); // Check found + std::clog << "str_persistence=" << str_persistence << std::endl; } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_not_prime ) +BOOST_AUTO_TEST_CASE( persistent_cohomology_single_field_coeff_not_prime ) { for (auto non_prime : {0, 1, 4, 6}) - BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(non_prime), std::invalid_argument); + BOOST_CHECK_THROW(test_persistence_with_coeff_field(non_prime), std::invalid_argument); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_prime ) +BOOST_AUTO_TEST_CASE( persistent_cohomology_single_field_coeff_prime ) { for (auto prime : {2, 3, 5, 11, 13}) - test_rips_persistence_with_coeff_field(prime); + test_persistence_with_coeff_field(prime); } -BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_coeff_limit ) +BOOST_AUTO_TEST_CASE( persistent_cohomology_single_field_coeff_limit ) { - BOOST_CHECK_THROW(test_rips_persistence_with_coeff_field(46349), std::invalid_argument); + BOOST_CHECK_THROW(test_persistence_with_coeff_field(46349), std::invalid_argument); } /** SimplexTree minimal options to test the limits. diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp index 24a3890c..c6c0bfaf 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test_multi_field.cpp @@ -21,7 +21,7 @@ using namespace boost::unit_test; typedef Simplex_tree<> typeST; -std::string test_rips_persistence(int min_coefficient, int max_coefficient, double min_persistence) { +std::string test_persistence(int min_coefficient, int max_coefficient, double min_persistence) { // file is copied in CMakeLists.txt std::ifstream simplex_tree_stream; simplex_tree_stream.open("simplex_tree_file_for_multi_field_unit_test.txt"); @@ -44,17 +44,17 @@ std::string test_rips_persistence(int min_coefficient, int max_coefficient, doub Persistent_cohomology, Multi_field> pcoh(st); pcoh.init_coefficients(min_coefficient, max_coefficient); // initializes the coefficient field for homology - // Check infinite rips + // Compute the persistent homology of the complex pcoh.compute_persistent_cohomology(min_persistence); // Minimal lifetime of homology feature to be recorded. - std::ostringstream ossRips; - pcoh.output_diagram(ossRips); + std::ostringstream ossPers; + pcoh.output_diagram(ossPers); - std::string strRips = ossRips.str(); - return strRips; + std::string strPers = ossPers.str(); + return strPers; } -void test_rips_persistence_with_coeff_field(int min_coefficient, int max_coefficient) { +void test_persistence_with_coeff_field(int min_coefficient, int max_coefficient) { // there are 2 discontinued ensembles std::string value0(" 0 0.25 inf"); std::string value1(" 1 0.4 inf"); @@ -69,59 +69,59 @@ void test_rips_persistence_with_coeff_field(int min_coefficient, int max_coeffic std::string value7(" 2 0.4 inf"); std::clog << "********************************************************************" << std::endl; - std::clog << "TEST OF RIPS_PERSISTENT_COHOMOLOGY_MULTI_FIELD MIN_COEFF=" << min_coefficient << " MAX_COEFF=" << max_coefficient << " MIN_PERS=0" << std::endl; + std::clog << "TEST OF PERSISTENT_COHOMOLOGY_MULTI_FIELD MIN_COEFF=" << min_coefficient << " MAX_COEFF=" << max_coefficient << " MIN_PERS=0" << std::endl; - std::string str_rips_persistence = test_rips_persistence(min_coefficient, max_coefficient, 0.0); - std::clog << "str_rips_persistence=" << str_rips_persistence << std::endl; + std::string str_persistence = test_persistence(min_coefficient, max_coefficient, 0.0); + std::clog << "str_persistence=" << str_persistence << std::endl; - BOOST_CHECK(str_rips_persistence.find(value0) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value1) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value2) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value0) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value1) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value2) != std::string::npos); // Check found if ((min_coefficient < 2) && (max_coefficient < 2)) { - BOOST_CHECK(str_rips_persistence.find(value3) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value4) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value5) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value6) != std::string::npos); // Check found - BOOST_CHECK(str_rips_persistence.find(value7) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value3) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value4) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value5) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value6) != std::string::npos); // Check found + BOOST_CHECK(str_persistence.find(value7) != std::string::npos); // Check found } else { - BOOST_CHECK(str_rips_persistence.find(value3) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value4) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value5) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value6) == std::string::npos); // Check not found - BOOST_CHECK(str_rips_persistence.find(value7) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value3) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value4) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value5) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value6) == std::string::npos); // Check not found + BOOST_CHECK(str_persistence.find(value7) == std::string::npos); // Check not found } } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_0_0) { - test_rips_persistence_with_coeff_field(0, 0); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_0_0) { + test_persistence_with_coeff_field(0, 0); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_0_1) { - test_rips_persistence_with_coeff_field(0, 1); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_0_1) { + test_persistence_with_coeff_field(0, 1); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_0_6) { - test_rips_persistence_with_coeff_field(0, 6); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_0_6) { + test_persistence_with_coeff_field(0, 6); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_1_2) { - test_rips_persistence_with_coeff_field(1, 2); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_1_2) { + test_persistence_with_coeff_field(1, 2); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_1_3) { - test_rips_persistence_with_coeff_field(1, 3); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_1_3) { + test_persistence_with_coeff_field(1, 3); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_1_5) { - test_rips_persistence_with_coeff_field(1, 5); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_1_5) { + test_persistence_with_coeff_field(1, 5); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_2_3) { - test_rips_persistence_with_coeff_field(2, 3); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_2_3) { + test_persistence_with_coeff_field(2, 3); } -BOOST_AUTO_TEST_CASE(rips_persistent_cohomology_multi_field_coeff_3_4) { - test_rips_persistence_with_coeff_field(3, 4); +BOOST_AUTO_TEST_CASE(persistent_cohomology_multi_field_coeff_3_4) { + test_persistence_with_coeff_field(3, 4); } -- cgit v1.2.3 From b786b34a30544cdfcdf04caae6db0e20e940e14d Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 26 Aug 2021 14:56:25 +0200 Subject: remove install_requires as pep 518 recommands --- src/python/setup.py.in | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/python/setup.py.in b/src/python/setup.py.in index c400b601..fd22962e 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -86,6 +86,5 @@ setup( long_description=long_description, ext_modules = ext_modules, install_requires = ['numpy >= 1.15.0',], - setup_requires = ['cython','numpy >= 1.15.0','pybind11',], package_data={"": ["*.dll"], }, ) -- cgit v1.2.3 From 6ffa047e76b680cc7b36b36d330d52a7419ce1ba Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 26 Aug 2021 15:00:19 +0200 Subject: Add all build dependencies (to be buildable in a virtual env - even if cmake already detects it) --- src/python/pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/python/pyproject.toml (limited to 'src') diff --git a/src/python/pyproject.toml b/src/python/pyproject.toml new file mode 100644 index 00000000..a9fb4985 --- /dev/null +++ b/src/python/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel", "numpy>=1.15.0", "cython", "pybind11"] +build-backend = "setuptools.build_meta" -- cgit v1.2.3 From 9c96a0711853c342fda5cf00e06d795c55783bf8 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 26 Aug 2021 15:04:48 +0200 Subject: Deploy pyproject.toml --- src/python/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index f534fc2a..927440ef 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -278,6 +278,7 @@ if(PYTHONINTERP_FOUND) # Some files for pip package file(COPY "introduction.rst" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") + file(COPY "pyproject.toml" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") add_custom_command( OUTPUT gudhi.so -- cgit v1.2.3 From cdd91e723aaf9e99d8161397fee683824e67cd78 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 26 Aug 2021 15:37:32 +0200 Subject: Pybind11 is mandatory for python module (as explained in the doc and as it is imported by setup.py) --- src/python/CMakeLists.txt | 76 ++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 927440ef..96107cfe 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -41,14 +41,15 @@ function( add_gudhi_debug_info DEBUG_INFO ) endfunction( add_gudhi_debug_info ) if(PYTHONINTERP_FOUND) - if(PYBIND11_FOUND) + if(PYBIND11_FOUND AND CYTHON_FOUND) add_gudhi_debug_info("Pybind11 version ${PYBIND11_VERSION}") + # PyBind11 modules set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'bottleneck', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'hera', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'clustering', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'datasets', ") - endif() - if(CYTHON_FOUND) + + # Cython modules set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'off_reader', ") set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'simplex_tree', ") set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'rips_complex', ") @@ -299,35 +300,30 @@ if(PYTHONINTERP_FOUND) if(SCIPY_FOUND) if(SKLEARN_FOUND) if(OT_FOUND) - if(PYBIND11_FOUND) - if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") - # User warning - Sphinx is a static pages generator, and configured to work fine with user_version - # Images and biblio warnings because not found on developper version - if (GUDHI_PYTHON_PATH STREQUAL "src/python") - set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") - endif() - # sphinx target requires gudhi.so, because conf.py reads gudhi version from it - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc - COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" - ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) - add_test(NAME sphinx_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" - ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) - # Set missing or not modules - set(GUDHI_MODULES ${GUDHI_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MODULES") - else(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - message("++ Python documentation module will not be compiled because it requires a Eigen3 and CGAL version >= 4.11.0") - set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) - else(PYBIND11_FOUND) - message("++ Python documentation module will not be compiled because pybind11 was not found") + if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") + # User warning - Sphinx is a static pages generator, and configured to work fine with user_version + # Images and biblio warnings because not found on developper version + if (GUDHI_PYTHON_PATH STREQUAL "src/python") + set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") + endif() + # sphinx target requires gudhi.so, because conf.py reads gudhi version from it + add_custom_target(sphinx + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc + COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" + ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) + add_test(NAME sphinx_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" + ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) + # Set missing or not modules + set(GUDHI_MODULES ${GUDHI_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MODULES") + else(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) + message("++ Python documentation module will not be compiled because it requires a Eigen3 and CGAL version >= 4.11.0") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(PYBIND11_FOUND) + endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0) else(OT_FOUND) message("++ Python documentation module will not be compiled because POT was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") @@ -403,9 +399,7 @@ if(PYTHONINTERP_FOUND) COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/bottleneck_basic_example.py") - if (PYBIND11_FOUND) - add_gudhi_py_test(test_bottleneck_distance) - endif() + add_gudhi_py_test(test_bottleneck_distance) # Cover complex file(COPY ${CMAKE_SOURCE_DIR}/data/points/human.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) @@ -519,14 +513,14 @@ if(PYTHONINTERP_FOUND) add_gudhi_py_test(test_reader_utils) # Wasserstein - if(OT_FOUND AND PYBIND11_FOUND) + if(OT_FOUND) # EagerPy dependency because of enable_autodiff=True if(EAGERPY_FOUND) add_gudhi_py_test(test_wasserstein_distance) endif() + add_gudhi_py_test(test_wasserstein_barycenter) - endif() - if(OT_FOUND) + if(TORCH_FOUND AND TENSORFLOW_FOUND AND EAGERPY_FOUND) add_gudhi_py_test(test_wasserstein_with_tensors) endif() @@ -547,7 +541,7 @@ if(PYTHONINTERP_FOUND) endif() # Tomato - if(SCIPY_FOUND AND SKLEARN_FOUND AND PYBIND11_FOUND) + if(SCIPY_FOUND AND SKLEARN_FOUND) add_gudhi_py_test(test_tomato) endif() @@ -564,10 +558,10 @@ if(PYTHONINTERP_FOUND) # Set missing or not modules set(GUDHI_MODULES ${GUDHI_MODULES} "python" CACHE INTERNAL "GUDHI_MODULES") - else(CYTHON_FOUND) - message("++ Python module will not be compiled because cython was not found") + else(PYBIND11_FOUND AND CYTHON_FOUND) + message("++ Python module will not be compiled because cython and/or pybind11 was/were not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(CYTHON_FOUND) + endif(PYBIND11_FOUND AND CYTHON_FOUND) else(PYTHONINTERP_FOUND) message("++ Python module will not be compiled because no Python interpreter was found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python" CACHE INTERNAL "GUDHI_MISSING_MODULES") -- cgit v1.2.3 From 3954d88bf505e4ae5af0dec81b978b1cdf0f5adf Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 26 Aug 2021 15:38:41 +0200 Subject: Fix #416 --- src/python/setup.py.in | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/python/setup.py.in b/src/python/setup.py.in index fd22962e..23746998 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -82,6 +82,7 @@ setup( }, description='The Gudhi library is an open source library for ' \ 'Computational Topology and Topological Data Analysis (TDA).', + data_files=[('.', ['./introduction.rst'])], long_description_content_type='text/x-rst', long_description=long_description, ext_modules = ext_modules, -- cgit v1.2.3 From 2024c0af61c1b14e50eccfae9a0011cb061b16d2 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Fri, 27 Aug 2021 11:34:08 +0200 Subject: Fix issue #314 Add overflow and nan warnings in knn when using torch and hnswlib --- src/python/gudhi/point_cloud/knn.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/knn.py b/src/python/gudhi/point_cloud/knn.py index 829bf1bf..7a5616e3 100644 --- a/src/python/gudhi/point_cloud/knn.py +++ b/src/python/gudhi/point_cloud/knn.py @@ -257,6 +257,12 @@ class KNearestNeighbors: if ef is not None: self.graph.set_ef(ef) neighbors, distances = self.graph.knn_query(X, k, num_threads=self.params["num_threads"]) + if numpy.any(numpy.isnan(distances)): + import warnings + warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) + if numpy.any(numpy.isinf(distances)): + import warnings + warnings.warn("Overflow value encountered while computing 'distances'", RuntimeWarning) # The k nearest neighbors are always sorted. I couldn't find it in the doc, but the code calls searchKnn, # which returns a priority_queue, and then fills the return array backwards with top/pop on the queue. if self.return_index: @@ -290,6 +296,12 @@ class KNearestNeighbors: if self.return_index: if self.return_distance: distances, neighbors = mat.Kmin_argKmin(k, dim=1) + if distances.isnan().any(): + import warnings + warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) + if distances.isinf().any(): + import warnings + warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: distances = distances ** (1.0 / p) return neighbors, distances @@ -298,6 +310,12 @@ class KNearestNeighbors: return neighbors if self.return_distance: distances = mat.Kmin(k, dim=1) + if distances.isnan().any(): + import warnings + warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) + if distances.isinf().any(): + import warnings + warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: distances = distances ** (1.0 / p) return distances -- cgit v1.2.3 From 7ea4e020af2fa8bf2fdfefe85ca24a1bcc2d08e1 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 30 Aug 2021 15:34:15 +0200 Subject: Fix dtm and knn failing tests --- src/python/gudhi/point_cloud/knn.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/knn.py b/src/python/gudhi/point_cloud/knn.py index 7a5616e3..dec5f88f 100644 --- a/src/python/gudhi/point_cloud/knn.py +++ b/src/python/gudhi/point_cloud/knn.py @@ -296,10 +296,10 @@ class KNearestNeighbors: if self.return_index: if self.return_distance: distances, neighbors = mat.Kmin_argKmin(k, dim=1) - if distances.isnan().any(): + if torch.isnan(distances).any(): import warnings warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) - if distances.isinf().any(): + if torch.isinf(distances).any(): import warnings warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: @@ -310,10 +310,10 @@ class KNearestNeighbors: return neighbors if self.return_distance: distances = mat.Kmin(k, dim=1) - if distances.isnan().any(): + if torch.isnan(distances).any(): import warnings warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) - if distances.isinf().any(): + if torch.isinf(distances).any(): import warnings warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: -- cgit v1.2.3 From 4db14bad8006638fc8249cb867a1720f581e044d Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 31 Aug 2021 18:18:51 +0200 Subject: Fix broken links. Add a tool to generate cpp example page --- biblio/bibliography.bib | 1 - scripts/cpp_examples_for_doxygen.py | 16 ++ .../utilities/bottleneckdistance.md | 4 +- src/common/doc/examples.h | 164 ++++++++++++--------- src/common/doc/installation.h | 40 ++--- src/python/doc/installation.rst | 2 +- 6 files changed, 137 insertions(+), 90 deletions(-) create mode 100644 scripts/cpp_examples_for_doxygen.py (limited to 'src') diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index 16fa29d0..eed871be 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -15,7 +15,6 @@ title = {{Statistical analysis and parameter selection for Mapper}}, volume = {19}, year = {2018}, url = {http://jmlr.org/papers/v19/17-291.html}, -doi = {10.5555/3291125.3291137} } @inproceedings{Dey13, diff --git a/scripts/cpp_examples_for_doxygen.py b/scripts/cpp_examples_for_doxygen.py new file mode 100644 index 00000000..5c091c4f --- /dev/null +++ b/scripts/cpp_examples_for_doxygen.py @@ -0,0 +1,16 @@ +import os +import glob + +for gd_mod in glob.glob("src/*/"): + mod_files = [] + for paths in [gd_mod + 'utilities', gd_mod + 'example']: + if os.path.isdir(paths): + for root, dirs, files in os.walk(paths): + for file in files: + if file.endswith(".cpp"): + mod_files.append(str(os.path.join(root, file)).split(paths)[1][1:]) + if len(mod_files) > 0: + mod = str(gd_mod).split('/')[1] + print(' * \section ' + mod + '_example_section ' + mod) + for file in mod_files: + print(' * @example ' + file) diff --git a/src/Bottleneck_distance/utilities/bottleneckdistance.md b/src/Bottleneck_distance/utilities/bottleneckdistance.md index a81426cf..2f5dedc9 100644 --- a/src/Bottleneck_distance/utilities/bottleneckdistance.md +++ b/src/Bottleneck_distance/utilities/bottleneckdistance.md @@ -10,14 +10,14 @@ Leave the lines above as it is required by the web site generator 'Jekyll' {:/comment} -## bottleneck_read_file_example ## +## bottleneck_distance ## This program computes the Bottleneck distance between two persistence diagram files. **Usage** ``` - bottleneck_read_file_example [] + bottleneck_distance [] ``` where diff --git a/src/common/doc/examples.h b/src/common/doc/examples.h index b557727b..a2de4335 100644 --- a/src/common/doc/examples.h +++ b/src/common/doc/examples.h @@ -1,98 +1,130 @@ -// List of GUDHI examples - Doxygen needs at least a file tag to analyse comments -// In user_version, `find . -name "*.cpp"` in example and utilities folders +// List of GUDHI examples and utils - Doxygen needs at least a file tag to analyse comments +// Generated from scripts/cpp_examples_for_doxygen.py /*! @file Examples - * \section Alpha_complex_examples Alpha complex - * @example Alpha_complex_from_off.cpp + * \section Skeleton_blocker_example_section Skeleton_blocker + * @example Skeleton_blocker_iteration.cpp + * @example Skeleton_blocker_from_simplices.cpp + * @example Skeleton_blocker_link.cpp + * \section Alpha_complex_example_section Alpha_complex + * @example alpha_complex_persistence.cpp + * @example alpha_complex_3d_persistence.cpp * @example Alpha_complex_from_points.cpp - * \section bottleneck_examples bottleneck - * @example bottleneck_basic_example.cpp - * @example alpha_rips_persistence_bottleneck_distance.cpp - * @example example_nearest_landmark_table.cpp - * @example example_witness_complex_off.cpp - * @example example_witness_complex_sphere.cpp - * @example example_strong_witness_complex_off.cpp + * @example Alpha_complex_3d_from_points.cpp + * @example Weighted_alpha_complex_3d_from_points.cpp + * @example Fast_alpha_complex_from_off.cpp + * @example Alpha_complex_from_off.cpp + * @example Weighted_alpha_complex_from_points.cpp + * \section Simplex_tree_example_section Simplex_tree + * @example cech_complex_cgal_mini_sphere_3d.cpp * @example mini_simplex_tree.cpp + * @example example_alpha_shapes_3_simplex_tree_from_off_file.cpp * @example graph_expansion_with_blocker.cpp * @example simple_simplex_tree.cpp * @example simplex_tree_from_cliques_of_graph.cpp - * @example example_alpha_shapes_3_simplex_tree_from_off_file.cpp - * @example cech_complex_cgal_mini_sphere_3d.cpp - * @example plain_homology.cpp - * @example persistence_from_file.cpp - * @example rips_persistence_step_by_step.cpp + * \section Collapse_example_section Collapse + * @example point_cloud_edge_collapse_rips_persistence.cpp + * @example distance_matrix_edge_collapse_rips_persistence.cpp + * @example edge_collapse_basic_example.cpp + * @example edge_collapse_conserve_persistence.cpp + * \section Persistent_cohomology_example_section Persistent_cohomology * @example rips_persistence_via_boundary_matrix.cpp + * @example rips_persistence_step_by_step.cpp + * @example plain_homology.cpp * @example custom_persistence_sort.cpp * @example persistence_from_simple_simplex_tree.cpp + * @example persistence_from_file.cpp * @example rips_multifield_persistence.cpp - * @example Skeleton_blocker_from_simplices.cpp - * @example Skeleton_blocker_iteration.cpp - * @example Skeleton_blocker_link.cpp - * @example Garland_heckbert.cpp - * @example Rips_contraction.cpp - * @example Random_bitmap_cubical_complex.cpp - * @example example_CGAL_3D_points_off_reader.cpp - * @example example_vector_double_points_off_reader.cpp - * @example example_CGAL_points_off_reader.cpp - * @example example_one_skeleton_rips_from_distance_matrix.cpp - * @example example_one_skeleton_rips_from_points.cpp - * @example example_rips_complex_from_csv_distance_matrix_file.cpp - * @example example_rips_complex_from_off_file.cpp - * @example persistence_intervals.cpp - * @example persistence_vectors.cpp - * @example persistence_heat_maps.cpp - * @example persistence_landscape_on_grid.cpp - * @example persistence_landscape.cpp - * @example example_basic.cpp - * @example example_with_perturb.cpp - * @example example_custom_distance.cpp - * @example example_choose_n_farthest_points.cpp - * @example example_sparsify_point_set.cpp - * @example example_pick_n_random_points.cpp - * @example CoordGIC.cpp + * \section Nerve_GIC_example_section Nerve_GIC + * @example VoronoiGIC.cpp * @example Nerve.cpp * @example FuncGIC.cpp - * @example VoronoiGIC.cpp - * @example example_spatial_searching.cpp - * @example alpha_complex_3d_persistence.cpp - * @example alpha_complex_persistence.cpp - * @example Weighted_alpha_complex_3d_from_points.cpp - * @example bottleneck_distance.cpp - * @example weak_witness_persistence.cpp - * @example strong_witness_persistence.cpp - * @example cubical_complex_persistence.cpp - * @example periodic_cubical_complex_persistence.cpp - * @example off_file_from_shape_generator.cpp - * @example rips_distance_matrix_persistence.cpp + * @example CoordGIC.cpp + * \section Rips_complex_example_section Rips_complex * @example rips_persistence.cpp + * @example sparse_rips_persistence.cpp + * @example rips_correlation_matrix_persistence.cpp + * @example rips_distance_matrix_persistence.cpp + * @example example_one_skeleton_rips_from_correlation_matrix.cpp + * @example example_rips_complex_from_csv_distance_matrix_file.cpp + * @example example_sparse_rips.cpp + * @example example_one_skeleton_rips_from_distance_matrix.cpp + * @example example_rips_complex_from_off_file.cpp + * @example example_one_skeleton_rips_from_points.cpp + * \section Persistence_representations_example_section Persistence_representations + * @example persistence_landscapes_on_grid/average_landscapes_on_grid.cpp * @example persistence_landscapes_on_grid/create_landscapes_on_grid.cpp + * @example persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp * @example persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp * @example persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp - * @example persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp - * @example persistence_landscapes_on_grid/average_landscapes_on_grid.cpp * @example persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp - * @example persistence_intervals/compute_number_of_dominant_intervals.cpp - * @example persistence_intervals/plot_persistence_Betti_numbers.cpp * @example persistence_intervals/plot_persistence_intervals.cpp * @example persistence_intervals/plot_histogram_of_intervals_lengths.cpp * @example persistence_intervals/compute_bottleneck_distance.cpp - * @example persistence_heat_maps/create_pssk.cpp - * @example persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp + * @example persistence_intervals/plot_persistence_Betti_numbers.cpp + * @example persistence_intervals/compute_number_of_dominant_intervals.cpp + * @example persistence_heat_maps/average_persistence_heat_maps.cpp * @example persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp - * @example persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp - * @example persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp + * @example persistence_heat_maps/create_pssk.cpp * @example persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp - * @example persistence_heat_maps/average_persistence_heat_maps.cpp + * @example persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp + * @example persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp * @example persistence_heat_maps/plot_persistence_heat_map.cpp + * @example persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp * @example persistence_heat_maps/create_persistence_heat_maps.cpp - * @example persistence_vectors/plot_persistence_vectors.cpp - * @example persistence_vectors/compute_distance_of_persistence_vectors.cpp * @example persistence_vectors/average_persistence_vectors.cpp + * @example persistence_vectors/plot_persistence_vectors.cpp * @example persistence_vectors/create_persistence_vectors.cpp * @example persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp - * @example persistence_landscapes/average_landscapes.cpp - * @example persistence_landscapes/compute_scalar_product_of_landscapes.cpp + * @example persistence_vectors/compute_distance_of_persistence_vectors.cpp * @example persistence_landscapes/create_landscapes.cpp + * @example persistence_landscapes/average_landscapes.cpp * @example persistence_landscapes/compute_distance_of_landscapes.cpp * @example persistence_landscapes/plot_landscapes.cpp + * @example persistence_landscapes/compute_scalar_product_of_landscapes.cpp + * @example persistence_heat_maps.cpp + * @example sliced_wasserstein.cpp + * @example persistence_intervals.cpp + * @example persistence_vectors.cpp + * @example persistence_landscape.cpp + * @example persistence_landscape_on_grid.cpp + * \section common_example_section common + * @example off_file_from_shape_generator.cpp + * @example example_CGAL_points_off_reader.cpp + * @example example_vector_double_points_off_reader.cpp + * @example example_CGAL_3D_points_off_reader.cpp + * \section Subsampling_example_section Subsampling + * @example example_pick_n_random_points.cpp + * @example example_choose_n_farthest_points.cpp + * @example example_sparsify_point_set.cpp + * @example example_custom_distance.cpp + * \section Contraction_example_section Contraction + * @example Rips_contraction.cpp + * @example Garland_heckbert.cpp + * \section Bottleneck_distance_example_section Bottleneck_distance + * @example bottleneck_distance.cpp + * @example bottleneck_basic_example.cpp + * @example alpha_rips_persistence_bottleneck_distance.cpp + * \section Tangential_complex_example_section Tangential_complex + * @example example_basic.cpp + * @example example_with_perturb.cpp + * \section Cech_complex_example_section Cech_complex + * @example cech_persistence.cpp + * @example cech_complex_example_from_points.cpp + * @example cech_complex_step_by_step.cpp + * \section Spatial_searching_example_section Spatial_searching + * @example example_spatial_searching.cpp + * \section Bitmap_cubical_complex_example_section Bitmap_cubical_complex + * @example periodic_cubical_complex_persistence.cpp + * @example cubical_complex_persistence.cpp + * @example Random_bitmap_cubical_complex.cpp + * \section Toplex_map_example_section Toplex_map + * @example simple_toplex_map.cpp + * \section Witness_complex_example_section Witness_complex + * @example weak_witness_persistence.cpp + * @example strong_witness_persistence.cpp + * @example example_witness_complex_sphere.cpp + * @example example_strong_witness_complex_off.cpp + * @example example_nearest_landmark_table.cpp + * @example example_witness_complex_off.cpp */ diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index 5d40a48e..609f2f2f 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -88,9 +88,9 @@ make \endverbatim * Witness_complex/example_witness_complex_off.cpp * \li * Witness_complex/example_witness_complex_sphere.cpp - * \li + * \li * Alpha_complex/Alpha_complex_from_off.cpp - * \li + * \li * Alpha_complex/Alpha_complex_from_points.cpp * \li * Alpha_complex/alpha_complex_persistence.cpp @@ -100,15 +100,15 @@ make \endverbatim * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp * \li * Bottleneck_distance/bottleneck_basic_example.cpp - * \li + * \li * Bottleneck_distance/bottleneck_distance.cpp - * \li + * \li * Nerve_GIC/CoordGIC.cpp - * \li + * \li * Nerve_GIC/FuncGIC.cpp - * \li + * \li * Nerve_GIC/Nerve.cpp - * \li + * \li * Nerve_GIC/VoronoiGIC.cpp * \li * Spatial_searching/example_spatial_searching.cpp @@ -122,7 +122,7 @@ make \endverbatim * Tangential_complex/example_basic.cpp * \li * Tangential_complex/example_with_perturb.cpp - * \li + * \li * Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp * \li * Alpha_complex/alpha_complex_3d_persistence.cpp @@ -134,15 +134,15 @@ make \endverbatim * * The following examples/utilities require the Eigen and will not be * built if Eigen is not installed: - * \li + * \li * Alpha_complex/Alpha_complex_from_off.cpp - * \li + * \li * Alpha_complex/Alpha_complex_from_points.cpp * \li * Alpha_complex/alpha_complex_persistence.cpp * \li * Alpha_complex/alpha_complex_3d_persistence.cpp - * \li + * \li * Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp * \li * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp @@ -179,27 +179,27 @@ make \endverbatim * Having Intel® TBB installed is recommended to parallelize and accelerate some GUDHI computations. * * The following examples/utilities are using Intel® TBB if installed: - * \li + * \li * Alpha_complex/Alpha_complex_from_off.cpp - * \li + * \li * Alpha_complex/Alpha_complex_from_points.cpp * \li * Alpha_complex/alpha_complex_3d_persistence.cpp * \li * Alpha_complex/alpha_complex_persistence.cpp - * \li + * \li * Bitmap_cubical_complex/cubical_complex_persistence.cpp - * \li + * \li * Bitmap_cubical_complex/periodic_cubical_complex_persistence.cpp - * \li + * \li * Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp - * \li + * \li * Nerve_GIC/CoordGIC.cpp - * \li + * \li * Nerve_GIC/FuncGIC.cpp - * \li + * \li * Nerve_GIC/Nerve.cpp - * \li + * \li * Nerve_GIC/VoronoiGIC.cpp * \li * Simplex_tree/simple_simplex_tree.cpp diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index cb7700ce..35c344e3 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -359,7 +359,7 @@ Python Optimal Transport ------------------------ The :doc:`Wasserstein distance ` -module requires `POT `_, a library that provides +module requires `POT `_, a library that provides several solvers for optimization problems related to Optimal Transport. PyTorch -- cgit v1.2.3 From 145fcba2de5f174b8fcdeab5ac1997978ffcdc0d Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 8 Sep 2021 18:01:11 +0200 Subject: Set the warning filter to "always" Add test for dtm overflow warning --- src/python/gudhi/point_cloud/knn.py | 6 ++++++ src/python/test/test_dtm.py | 14 ++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/knn.py b/src/python/gudhi/point_cloud/knn.py index dec5f88f..0724ce94 100644 --- a/src/python/gudhi/point_cloud/knn.py +++ b/src/python/gudhi/point_cloud/knn.py @@ -259,9 +259,11 @@ class KNearestNeighbors: neighbors, distances = self.graph.knn_query(X, k, num_threads=self.params["num_threads"]) if numpy.any(numpy.isnan(distances)): import warnings + warnings.simplefilter("always") warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) if numpy.any(numpy.isinf(distances)): import warnings + warnings.simplefilter("always") warnings.warn("Overflow value encountered while computing 'distances'", RuntimeWarning) # The k nearest neighbors are always sorted. I couldn't find it in the doc, but the code calls searchKnn, # which returns a priority_queue, and then fills the return array backwards with top/pop on the queue. @@ -298,9 +300,11 @@ class KNearestNeighbors: distances, neighbors = mat.Kmin_argKmin(k, dim=1) if torch.isnan(distances).any(): import warnings + warnings.simplefilter("always") warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) if torch.isinf(distances).any(): import warnings + warnings.simplefilter("always") warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: distances = distances ** (1.0 / p) @@ -312,9 +316,11 @@ class KNearestNeighbors: distances = mat.Kmin(k, dim=1) if torch.isnan(distances).any(): import warnings + warnings.simplefilter("always") warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) if torch.isinf(distances).any(): import warnings + warnings.simplefilter("always") warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: distances = distances ** (1.0 / p) diff --git a/src/python/test/test_dtm.py b/src/python/test/test_dtm.py index 0a52279e..c29471cf 100755 --- a/src/python/test/test_dtm.py +++ b/src/python/test/test_dtm.py @@ -13,6 +13,7 @@ import numpy import pytest import torch import math +import warnings def test_dtm_compare_euclidean(): @@ -87,3 +88,16 @@ def test_density(): assert density == pytest.approx(expected) density = DTMDensity(weights=[0.5, 0.5], metric="neighbors", dim=1).fit_transform(distances) assert density == pytest.approx(expected) + +def test_dtm_overflow_warnings(): + pts = numpy.array([[10., 100000000000000000000000000000.], [1000., 100000000000000000000000000.]]) + impl_warn = ["keops", "hnsw"] + + with warnings.catch_warnings(record=True) as w: + for impl in impl_warn: + dtm = DistanceToMeasure(2, q=10000, implementation=impl) + r = dtm.fit_transform(pts) + assert len(w) == 2 + for i in range(len(w)): + assert issubclass(w[i].category, RuntimeWarning) + assert "Overflow" in str(w[i].message) -- cgit v1.2.3 From c5a12380e0744eaa26b59ae043dd4fa160d9f268 Mon Sep 17 00:00:00 2001 From: VincentRouvreau Date: Mon, 13 Sep 2021 16:34:23 +0200 Subject: make_filtration_non_decreasing no more called in alpha complex dD exact version and exact and safe 3d versions --- src/Alpha_complex/doc/Intro_alpha_complex.h | 2 ++ src/Alpha_complex/include/gudhi/Alpha_complex.h | 6 ++++-- src/Alpha_complex/include/gudhi/Alpha_complex_3d.h | 6 ++++-- src/python/doc/alpha_complex_user.rst | 3 +++ 4 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Alpha_complex/doc/Intro_alpha_complex.h b/src/Alpha_complex/doc/Intro_alpha_complex.h index f417ebb2..5ab23720 100644 --- a/src/Alpha_complex/doc/Intro_alpha_complex.h +++ b/src/Alpha_complex/doc/Intro_alpha_complex.h @@ -152,6 +152,8 @@ Table of Contents * not quite define a proper filtration (i.e. non-decreasing with respect to inclusion). * We fix that up by calling `SimplicialComplexForAlpha::make_filtration_non_decreasing()`. * + * \note This is not the case in `exact` version, this is the reason why it is not called in this case. + * * \subsubsection pruneabove Prune above given filtration value * * The simplex tree is pruned from the given maximum \f$ \alpha^2 \f$ value (cf. diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex.h b/src/Alpha_complex/include/gudhi/Alpha_complex.h index b315fa99..e03bb161 100644 --- a/src/Alpha_complex/include/gudhi/Alpha_complex.h +++ b/src/Alpha_complex/include/gudhi/Alpha_complex.h @@ -435,8 +435,10 @@ class Alpha_complex { // -------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------- - // As Alpha value is an approximation, we have to make filtration non decreasing while increasing the dimension - complex.make_filtration_non_decreasing(); + if (!exact) + // As Alpha value is an approximation, we have to make filtration non decreasing while increasing the dimension + // Only in not exact version, cf. https://github.com/GUDHI/gudhi-devel/issues/57 + complex.make_filtration_non_decreasing(); // Remove all simplices that have a filtration value greater than max_alpha_square complex.prune_above_filtration(max_alpha_square); // -------------------------------------------------------------------------------------------- diff --git a/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h b/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h index 4e5fc933..ccc3d852 100644 --- a/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h +++ b/src/Alpha_complex/include/gudhi/Alpha_complex_3d.h @@ -554,8 +554,10 @@ Weighted_alpha_complex_3d::Weighted_point_3 wp0(Weighted_alpha_complex_3d::Bare_ std::clog << "cells \t\t" << count_cells << std::endl; #endif // DEBUG_TRACES // -------------------------------------------------------------------------------------------- - // As Alpha value is an approximation, we have to make filtration non decreasing while increasing the dimension - complex.make_filtration_non_decreasing(); + if (Complexity == complexity::FAST) + // As Alpha value is an approximation, we have to make filtration non decreasing while increasing the dimension + // Only in FAST version, cf. https://github.com/GUDHI/gudhi-devel/issues/57 + complex.make_filtration_non_decreasing(); // Remove all simplices that have a filtration value greater than max_alpha_square complex.prune_above_filtration(max_alpha_square); // -------------------------------------------------------------------------------------------- diff --git a/src/python/doc/alpha_complex_user.rst b/src/python/doc/alpha_complex_user.rst index fffcb3db..ef67a457 100644 --- a/src/python/doc/alpha_complex_user.rst +++ b/src/python/doc/alpha_complex_user.rst @@ -165,6 +165,9 @@ respect to inclusion). We fix that up by calling :func:`~gudhi.SimplexTree.make_filtration_non_decreasing` (cf. `C++ version `_). +.. note:: + This is not the case in `exact` version, this is the reason why it is not called in this case. + Prune above given filtration value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From 65619d48af98680294bf41c4023e04ee94f2745d Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 22 Sep 2021 09:36:18 +0200 Subject: Replace the doc sphere image plotted with trisurf with another using scattered points --- src/python/doc/img/sphere_3d.png | Bin 90550 -> 529148 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'src') diff --git a/src/python/doc/img/sphere_3d.png b/src/python/doc/img/sphere_3d.png index 7e7f0ab2..70f3184f 100644 Binary files a/src/python/doc/img/sphere_3d.png and b/src/python/doc/img/sphere_3d.png differ -- cgit v1.2.3 From e23ca84fadcc2c65fd8cf2d141be804bf18b2fd6 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 22 Sep 2021 15:20:03 +0200 Subject: Rename function of torus cpp version and import it with sphere in points Change documentation accordingly --- src/python/doc/datasets_generators.rst | 28 +++++++++++++------------ src/python/gudhi/datasets/generators/_points.cc | 9 +++++--- src/python/gudhi/datasets/generators/points.py | 3 +++ src/python/test/test_datasets_generators.py | 15 +++++++------ 4 files changed, 31 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst index e63dde82..c0bbb973 100644 --- a/src/python/doc/datasets_generators.rst +++ b/src/python/doc/datasets_generators.rst @@ -13,10 +13,12 @@ We provide the generation of different customizable datasets to use as inputs fo Points generators ------------------ +The module **points** enables the generation of random points on a sphere, random points on a torus and as a grid. + Points on sphere ^^^^^^^^^^^^^^^^ -The module **_points** enables the generation of random i.i.d. points uniformly on a (d-1)-sphere in :math:`R^d`. +The function **sphere** enables the generation of random i.i.d. points uniformly on a (d-1)-sphere in :math:`R^d`. The user should provide the number of points to be generated on the sphere :code:`n_samples` and the ambient dimension :code:`ambient_dim`. The :code:`radius` of sphere is optional and is equal to **1** by default. Only random points generation is currently available. @@ -28,28 +30,28 @@ Example .. code-block:: python - from gudhi.datasets.generators import _points + from gudhi.datasets.generators import points from gudhi import AlphaComplex # Generate 50 points on a sphere in R^2 - gen_points = _points.sphere(n_samples = 50, ambient_dim = 2, radius = 1, sample = "random") + gen_points = points.sphere(n_samples = 50, ambient_dim = 2, radius = 1, sample = "random") # Create an alpha complex from the generated points alpha_complex = AlphaComplex(points = gen_points) -.. autofunction:: gudhi.datasets.generators._points.sphere +.. autofunction:: gudhi.datasets.generators.points.sphere Points on torus ^^^^^^^^^^^^^^^^ You can also generate points on a torus. -Two modules are available and give the same output: the first one depends on **CGAL** and the second does not and consists of full python code. +Two functions are available and give the same output: the first one depends on **CGAL** and the second does not and consists of full python code. On another hand, two sample types are provided : you can either generate i.i.d. points on a d-torus in :math:`R^{2d}` *randomly* or on a *grid*. -First module : **_points** -"""""""""""""""""""""""""" +First function : **ctorus** +""""""""""""""""""""""""""" The user should provide the number of points to be generated on the torus :code:`n_samples`, and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. The :code:`sample` argument is optional and is set to **'random'** by default. @@ -67,18 +69,18 @@ Example """"""" .. code-block:: python - from gudhi.datasets.generators import _points + from gudhi.datasets.generators import points # Generate 50 points randomly on a torus in R^6 - gen_points = _points.torus(n_samples = 50, dim = 3) + gen_points = points.ctorus(n_samples = 50, dim = 3) # Generate 27 points on a torus as a grid in R^6 - gen_points = _points.torus(n_samples = 50, dim = 3, sample = 'grid') + gen_points = points.ctorus(n_samples = 50, dim = 3, sample = 'grid') -.. autofunction:: gudhi.datasets.generators._points.torus +.. autofunction:: gudhi.datasets.generators.points.ctorus -Second module : **points** -"""""""""""""""""""""""""" +Second function : **torus** +""""""""""""""""""""""""""" The user should provide the number of points to be generated on the torus :code:`n_samples` and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. The :code:`sample` argument is optional and is set to **'random'** by default. diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 3d38ff90..536fa949 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -96,10 +96,10 @@ PYBIND11_MODULE(_points, m) { :returns: the generated points on a sphere. )pbdoc"); - m.def("torus", &generate_points_on_torus, + m.def("ctorus", &generate_points_on_torus, py::arg("n_samples"), py::arg("dim"), py::arg("sample") = "random", R"pbdoc( - Generate random i.i.d. points on a d-torus in R^2d + Generate random i.i.d. points on a d-torus in R^2d or as a grid :param n_samples: The number of points to be generated. :type n_samples: integer @@ -107,7 +107,10 @@ PYBIND11_MODULE(_points, m) { :type dim: integer :param sample: The sample type. Available values are: `"random"` and `"grid"`. Default value is `"random"`. :type sample: string - :rtype: numpy array of float + :rtype: numpy array of float. + The shape of returned numpy array is : + if sample is 'random' : (n_samples, 2*dim). + if sample is 'grid' : ([n_samples**(1./dim)]**dim, 2*dim). :returns: the generated points on a torus. )pbdoc"); } diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index daada486..1995f769 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -10,6 +10,9 @@ import numpy as np import itertools +from ._points import ctorus +from ._points import sphere + def _generate_random_points_on_torus(n_samples, dim): # Generate random angles of size n_samples*dim diff --git a/src/python/test/test_datasets_generators.py b/src/python/test/test_datasets_generators.py index 656c30ee..4c087c57 100755 --- a/src/python/test/test_datasets_generators.py +++ b/src/python/test/test_datasets_generators.py @@ -9,25 +9,24 @@ """ from gudhi.datasets.generators import points -from gudhi.datasets.generators import _points import pytest def test_sphere(): - assert _points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'random').shape == (10, 2) + assert points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'random').shape == (10, 2) with pytest.raises(ValueError): - _points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'other') + points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'other') def test_torus(): - assert _points.torus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) - assert _points.torus(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) + assert points.ctorus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) + assert points.ctorus(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) - assert _points.torus(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) - assert _points.torus(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) + assert points.ctorus(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) + assert points.ctorus(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) with pytest.raises(ValueError): - _points.torus(n_samples = 10, dim = 4, sample = 'other') + points.ctorus(n_samples = 10, dim = 4, sample = 'other') def test_torus_full_python(): assert points.torus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) -- cgit v1.2.3 From dbdc62a494e54c3dd409a2e80fa169560355ce19 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Thu, 7 Oct 2021 15:25:25 +0200 Subject: Move warnings import to the beginning of knn.py file Use isfinite instead of isinf and isnan Use catch_warnings context manager instead of "always" with simplefilter --- src/python/gudhi/point_cloud/knn.py | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/knn.py b/src/python/gudhi/point_cloud/knn.py index 0724ce94..de5844f9 100644 --- a/src/python/gudhi/point_cloud/knn.py +++ b/src/python/gudhi/point_cloud/knn.py @@ -8,6 +8,7 @@ # - YYYY/MM Author: Description of the modification import numpy +import warnings # TODO: https://github.com/facebookresearch/faiss @@ -257,14 +258,9 @@ class KNearestNeighbors: if ef is not None: self.graph.set_ef(ef) neighbors, distances = self.graph.knn_query(X, k, num_threads=self.params["num_threads"]) - if numpy.any(numpy.isnan(distances)): - import warnings - warnings.simplefilter("always") - warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) - if numpy.any(numpy.isinf(distances)): - import warnings - warnings.simplefilter("always") - warnings.warn("Overflow value encountered while computing 'distances'", RuntimeWarning) + with warnings.catch_warnings(): + if not(numpy.all(numpy.isfinite(distances))): + warnings.warn("Overflow/infinite value encountered while computing 'distances'", RuntimeWarning) # The k nearest neighbors are always sorted. I couldn't find it in the doc, but the code calls searchKnn, # which returns a priority_queue, and then fills the return array backwards with top/pop on the queue. if self.return_index: @@ -298,14 +294,9 @@ class KNearestNeighbors: if self.return_index: if self.return_distance: distances, neighbors = mat.Kmin_argKmin(k, dim=1) - if torch.isnan(distances).any(): - import warnings - warnings.simplefilter("always") - warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) - if torch.isinf(distances).any(): - import warnings - warnings.simplefilter("always") - warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) + with warnings.catch_warnings(): + if not(torch.isfinite(distances).all()): + warnings.warn("Overflow/infinite value encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: distances = distances ** (1.0 / p) return neighbors, distances @@ -314,14 +305,9 @@ class KNearestNeighbors: return neighbors if self.return_distance: distances = mat.Kmin(k, dim=1) - if torch.isnan(distances).any(): - import warnings - warnings.simplefilter("always") - warnings.warn("NaN value encountered while computing 'distances'", RuntimeWarning) - if torch.isinf(distances).any(): - import warnings - warnings.simplefilter("always") - warnings.warn("Overflow encountered while computing 'distances'", RuntimeWarning) + with warnings.catch_warnings(): + if not(torch.isfinite(distances).all()): + warnings.warn("Overflow/infinite value encountered while computing 'distances'", RuntimeWarning) if p != numpy.inf: distances = distances ** (1.0 / p) return distances -- cgit v1.2.3 From f461f050ee8bad509814b4851ab7ae8f43502962 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Fri, 8 Oct 2021 11:18:46 +0200 Subject: Add warnings in dtm.py for DistanceToMeasure and DTMDensity Add DTMDensity warning test --- src/python/gudhi/point_cloud/dtm.py | 11 +++++++++++ src/python/test/test_dtm.py | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/dtm.py b/src/python/gudhi/point_cloud/dtm.py index 55ac58e6..96a9e7bf 100644 --- a/src/python/gudhi/point_cloud/dtm.py +++ b/src/python/gudhi/point_cloud/dtm.py @@ -9,6 +9,7 @@ from .knn import KNearestNeighbors import numpy as np +import warnings __author__ = "Marc Glisse" __copyright__ = "Copyright (C) 2020 Inria" @@ -66,6 +67,11 @@ class DistanceToMeasure: distances = distances ** self.q dtm = distances.sum(-1) / self.k dtm = dtm ** (1.0 / self.q) + with warnings.catch_warnings(): + import torch + if isinstance(dtm, torch.Tensor): + if not(torch.isfinite(dtm).all()): + warnings.warn("Overflow/infinite value encountered while computing 'dtm'", RuntimeWarning) # We compute too many powers, 1/p in knn then q in dtm, 1/q in dtm then q or some log in the caller. # Add option to skip the final root? return dtm @@ -163,6 +169,11 @@ class DTMDensity: distances = self.knn.transform(X) distances = distances ** q dtm = (distances * weights).sum(-1) + with warnings.catch_warnings(): + import torch + if isinstance(dtm, torch.Tensor): + if not(torch.isfinite(dtm).all()): + warnings.warn("Overflow/infinite value encountered while computing 'dtm' for density", RuntimeWarning) if self.normalize: dtm /= (np.arange(1, k + 1) ** (q / dim) * weights).sum() density = dtm ** (-dim / q) diff --git a/src/python/test/test_dtm.py b/src/python/test/test_dtm.py index c29471cf..52468d0f 100755 --- a/src/python/test/test_dtm.py +++ b/src/python/test/test_dtm.py @@ -97,7 +97,15 @@ def test_dtm_overflow_warnings(): for impl in impl_warn: dtm = DistanceToMeasure(2, q=10000, implementation=impl) r = dtm.fit_transform(pts) - assert len(w) == 2 + assert len(w) == 3 for i in range(len(w)): assert issubclass(w[i].category, RuntimeWarning) assert "Overflow" in str(w[i].message) + +def test_density_overflow_warning(): + distances = numpy.array([[10., 100.], [10000000000000., 10.]]) + with warnings.catch_warnings(record=True) as w: + density = DTMDensity(k=2, q=100000, implementation="keops", dim=1).fit_transform(distances) + assert len(w) == 1 + assert issubclass(w[0].category, RuntimeWarning) + assert "Overflow" in str(w[0].message) -- cgit v1.2.3 From 44659b4d5c2df18745e36280317ecbc9c6a5b411 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Fri, 8 Oct 2021 16:03:54 +0200 Subject: Add torch dependency for some python tests --- src/python/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index f534fc2a..7b7aff1e 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -546,17 +546,17 @@ if(PYTHONINTERP_FOUND) endif() # Tomato - if(SCIPY_FOUND AND SKLEARN_FOUND AND PYBIND11_FOUND) + if(SCIPY_FOUND AND SKLEARN_FOUND AND PYBIND11_FOUND AND TORCH_FOUND) add_gudhi_py_test(test_tomato) endif() # Weighted Rips - if(SCIPY_FOUND) + if(SCIPY_FOUND AND TORCH_FOUND) add_gudhi_py_test(test_weighted_rips_complex) endif() # DTM Rips - if(SCIPY_FOUND) + if(SCIPY_FOUND AND TORCH_FOUND) add_gudhi_py_test(test_dtm_rips_complex) endif() -- cgit v1.2.3 From ec06a9b9ae0a9ff1897249dcbc2b497764f54aaf Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Mon, 18 Oct 2021 17:01:02 +0200 Subject: First part of the fix --- src/python/gudhi/cubical_complex.pyx | 7 ++- src/python/gudhi/periodic_cubical_complex.pyx | 7 ++- src/python/gudhi/representations/vector_methods.py | 60 ++++++++++++++-------- src/python/gudhi/simplex_tree.pyx | 26 ++++++---- src/python/test/test_cubical_complex.py | 25 +++++++++ src/python/test/test_representations.py | 37 +++++++++++++ 6 files changed, 129 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 97c69a2d..04569bd8 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -281,4 +281,9 @@ cdef class CubicalComplex: launched first. """ assert self.pcohptr != NULL, "compute_persistence() must be called before persistence_intervals_in_dimension()" - return np.array(self.pcohptr.intervals_in_dimension(dimension)) + piid = np.array(self.pcohptr.intervals_in_dimension(dimension)) + # Workaround https://github.com/GUDHI/gudhi-devel/issues/507 + if piid.shape[0] == 0: + return np.empty(shape = [0, 2]) + else: + return piid diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index ef1d3080..bd91ccde 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -280,4 +280,9 @@ cdef class PeriodicCubicalComplex: launched first. """ assert self.pcohptr != NULL, "compute_persistence() must be called before persistence_intervals_in_dimension()" - return np.array(self.pcohptr.intervals_in_dimension(dimension)) + piid = np.array(self.pcohptr.intervals_in_dimension(dimension)) + # Workaround https://github.com/GUDHI/gudhi-devel/issues/507 + if piid.shape[0] == 0: + return np.empty(shape = [0, 2]) + else: + return piid diff --git a/src/python/gudhi/representations/vector_methods.py b/src/python/gudhi/representations/vector_methods.py index 84bc99a2..711c32a7 100644 --- a/src/python/gudhi/representations/vector_methods.py +++ b/src/python/gudhi/representations/vector_methods.py @@ -44,11 +44,15 @@ class PersistenceImage(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - if np.isnan(np.array(self.im_range)).any(): - new_X = BirthPersistenceTransform().fit_transform(X) - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(new_X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.im_range = np.where(np.isnan(np.array(self.im_range)), np.array([mx, Mx, my, My]), np.array(self.im_range)) + try: + if np.isnan(np.array(self.im_range)).any(): + new_X = BirthPersistenceTransform().fit_transform(X) + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(new_X,y) + [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + self.im_range = np.where(np.isnan(np.array(self.im_range)), np.array([mx, Mx, my, My]), np.array(self.im_range)) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): @@ -120,9 +124,13 @@ class Landscape(BaseEstimator, TransformerMixin): y (n x 1 array): persistence diagram labels (unused). """ if self.nan_in_range.any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(self.nan_in_range, np.array([mx, My]), np.array(self.sample_range)) + try: + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) + [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + self.sample_range = np.where(self.nan_in_range, np.array([mx, My]), np.array(self.sample_range)) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): @@ -218,10 +226,14 @@ class Silhouette(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - if np.isnan(np.array(self.sample_range)).any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + try: + if np.isnan(np.array(self.sample_range)).any(): + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) + [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): @@ -307,10 +319,14 @@ class BettiCurve(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - if np.isnan(np.array(self.sample_range)).any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + try: + if np.isnan(np.array(self.sample_range)).any(): + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) + [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): @@ -374,10 +390,14 @@ class Entropy(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - if np.isnan(np.array(self.sample_range)).any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + try: + if np.isnan(np.array(self.sample_range)).any(): + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) + [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index 9c51cb46..e9bac036 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -9,8 +9,7 @@ from cython.operator import dereference, preincrement from libc.stdint cimport intptr_t -import numpy -from numpy import array as np_array +import numpy as np cimport gudhi.simplex_tree __author__ = "Vincent Rouvreau" @@ -542,7 +541,12 @@ cdef class SimplexTree: function to be launched first. """ assert self.pcohptr != NULL, "compute_persistence() must be called before persistence_intervals_in_dimension()" - return np_array(self.pcohptr.intervals_in_dimension(dimension)) + piid = np.array(self.pcohptr.intervals_in_dimension(dimension)) + # Workaround https://github.com/GUDHI/gudhi-devel/issues/507 + if piid.shape[0] == 0: + return np.empty(shape = [0, 2]) + else: + return piid def persistence_pairs(self): """This function returns a list of persistence birth and death simplices pairs. @@ -583,8 +587,8 @@ cdef class SimplexTree: """ assert self.pcohptr != NULL, "lower_star_persistence_generators() requires that persistence() be called first." gen = self.pcohptr.lower_star_generators() - normal = [np_array(d).reshape(-1,2) for d in gen.first] - infinite = [np_array(d) for d in gen.second] + normal = [np.array(d).reshape(-1,2) for d in gen.first] + infinite = [np.array(d) for d in gen.second] return (normal, infinite) def flag_persistence_generators(self): @@ -602,19 +606,19 @@ cdef class SimplexTree: assert self.pcohptr != NULL, "flag_persistence_generators() requires that persistence() be called first." gen = self.pcohptr.flag_generators() if len(gen.first) == 0: - normal0 = numpy.empty((0,3)) + normal0 = np.empty((0,3)) normals = [] else: l = iter(gen.first) - normal0 = np_array(next(l)).reshape(-1,3) - normals = [np_array(d).reshape(-1,4) for d in l] + normal0 = np.array(next(l)).reshape(-1,3) + normals = [np.array(d).reshape(-1,4) for d in l] if len(gen.second) == 0: - infinite0 = numpy.empty(0) + infinite0 = np.empty(0) infinites = [] else: l = iter(gen.second) - infinite0 = np_array(next(l)) - infinites = [np_array(d).reshape(-1,2) for d in l] + infinite0 = np.array(next(l)) + infinites = [np.array(d).reshape(-1,2) for d in l] return (normal0, normals, infinite0, infinites) def collapse_edges(self, nb_iterations = 1): diff --git a/src/python/test/test_cubical_complex.py b/src/python/test/test_cubical_complex.py index d0e4e9e8..29d559b3 100755 --- a/src/python/test/test_cubical_complex.py +++ b/src/python/test/test_cubical_complex.py @@ -174,3 +174,28 @@ def test_periodic_cofaces_of_persistence_pairs_when_pd_has_no_paired_birth_and_d assert np.array_equal(pairs[1][0], np.array([0])) assert np.array_equal(pairs[1][1], np.array([0, 1])) assert np.array_equal(pairs[1][2], np.array([1])) + +def test_cubical_persistence_intervals_in_dimension(): + cub = CubicalComplex( + dimensions=[3, 3], + top_dimensional_cells=[1, 2, 3, 4, 5, 6, 7, 8, 9], + ) + cub.compute_persistence() + H0 = cub.persistence_intervals_in_dimension(0) + assert np.array_equal(H0, np.array([[ 1., float("inf")]])) + assert cub.persistence_intervals_in_dimension(1).shape == (0, 2) + +def test_periodic_cubical_persistence_intervals_in_dimension(): + cub = PeriodicCubicalComplex( + dimensions=[3, 3], + top_dimensional_cells=[1, 2, 3, 4, 5, 6, 7, 8, 9], + periodic_dimensions = [True, True] + ) + cub.compute_persistence() + H0 = cub.persistence_intervals_in_dimension(0) + assert np.array_equal(H0, np.array([[ 1., float("inf")]])) + H1 = cub.persistence_intervals_in_dimension(1) + assert np.array_equal(H1, np.array([[ 3., float("inf")], [ 7., float("inf")]])) + H2 = cub.persistence_intervals_in_dimension(2) + assert np.array_equal(H2, np.array([[ 9., float("inf")]])) + assert cub.persistence_intervals_in_dimension(3).shape == (0, 2) diff --git a/src/python/test/test_representations.py b/src/python/test/test_representations.py index cda1a15b..c1f4df12 100755 --- a/src/python/test/test_representations.py +++ b/src/python/test/test_representations.py @@ -6,6 +6,12 @@ import pytest from sklearn.cluster import KMeans +from gudhi.representations import (DiagramSelector, Clamping, Landscape, Silhouette, BettiCurve, ComplexPolynomial,\ + TopologicalVector, DiagramScaler, BirthPersistenceTransform,\ + PersistenceImage, PersistenceWeightedGaussianKernel, Entropy, \ + PersistenceScaleSpaceKernel, SlicedWassersteinDistance,\ + SlicedWassersteinKernel, PersistenceFisherKernel, WassersteinDistance) + def test_representations_examples(): # Disable graphics for testing purposes @@ -98,3 +104,34 @@ def test_infinity(): assert c[1] == 0 assert c[7] == 3 assert c[9] == 2 + +def pow(n): + return lambda x: np.power(x[1]-x[0],n) + +def test_vectorization_empty_diagrams(): + empty_diag = np.empty(shape = [0, 2]) + Landscape(resolution=1000)(empty_diag) + Silhouette(resolution=1000, weight=pow(2))(empty_diag) + BettiCurve(resolution=1000)(empty_diag) + ComplexPolynomial(threshold=-1, polynomial_type="T")(empty_diag) + TopologicalVector(threshold=-1)(empty_diag) + PersistenceImage(bandwidth=.1, weight=lambda x: x[1], im_range=[0,1,0,1], resolution=[100,100])(empty_diag) + #Entropy(mode="scalar")(empty_diag) + #Entropy(mode="vector", normalized=False)(empty_diag) + +#def arctan(C,p): +# return lambda x: C*np.arctan(np.power(x[1], p)) +# +#def test_kernel_empty_diagrams(): +# empty_diag = np.empty(shape = [0, 2]) +# PersistenceWeightedGaussianKernel(bandwidth=1., kernel_approx=None, weight=arctan(1.,1.))(empty_diag, empty_diag) +# PersistenceWeightedGaussianKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])), weight=arctan(1.,1.))(empty_diag, empty_diag) +# PersistenceScaleSpaceKernel(bandwidth=1.)(empty_diag, empty_diag) +# PersistenceScaleSpaceKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) +# SlicedWassersteinDistance(num_directions=100)(empty_diag, empty_diag) +# SlicedWassersteinKernel(num_directions=100, bandwidth=1.)(empty_diag, empty_diag) +# WassersteinDistance(order=2, internal_p=2, mode="pot")(empty_diag, empty_diag) +# WassersteinDistance(order=2, internal_p=2, mode="hera", delta=0.0001)(empty_diag, empty_diag) +# BottleneckDistance(epsilon=.001)(empty_diag, empty_diag) +# PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1.)(empty_diag, empty_diag) +# PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1., kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) -- cgit v1.2.3 From 0c8e1e2b69c7658c153df99931e3407ec18c1332 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 19 Oct 2021 21:20:01 +0200 Subject: Add empty diags tests --- src/python/test/test_representations.py | 60 +++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/python/test/test_representations.py b/src/python/test/test_representations.py index c1f4df12..b888b7f1 100755 --- a/src/python/test/test_representations.py +++ b/src/python/test/test_representations.py @@ -6,9 +6,16 @@ import pytest from sklearn.cluster import KMeans -from gudhi.representations import (DiagramSelector, Clamping, Landscape, Silhouette, BettiCurve, ComplexPolynomial,\ - TopologicalVector, DiagramScaler, BirthPersistenceTransform,\ - PersistenceImage, PersistenceWeightedGaussianKernel, Entropy, \ +# Vectorization +from gudhi.representations import (Landscape, Silhouette, BettiCurve, ComplexPolynomial,\ + TopologicalVector, PersistenceImage, Entropy) + +# Preprocessing +from gudhi.representations import (BirthPersistenceTransform, Clamping, DiagramScaler, Padding, ProminentPoints, \ + DiagramSelector) + +# Kernel +from gudhi.representations import (PersistenceWeightedGaussianKernel, \ PersistenceScaleSpaceKernel, SlicedWassersteinDistance,\ SlicedWassersteinKernel, PersistenceFisherKernel, WassersteinDistance) @@ -105,33 +112,44 @@ def test_infinity(): assert c[7] == 3 assert c[9] == 2 + +def test_preprocessing_empty_diagrams(): + empty_diag = np.empty(shape = [0, 2]) + assert not np.any(BirthPersistenceTransform()(empty_diag)) + assert not np.any(Clamping().fit_transform(empty_diag)) + assert not np.any(DiagramScaler()(empty_diag)) + assert not np.any(Padding()(empty_diag)) + assert not np.any(ProminentPoints()(empty_diag)) + assert not np.any(DiagramSelector()(empty_diag)) + def pow(n): return lambda x: np.power(x[1]-x[0],n) def test_vectorization_empty_diagrams(): empty_diag = np.empty(shape = [0, 2]) - Landscape(resolution=1000)(empty_diag) - Silhouette(resolution=1000, weight=pow(2))(empty_diag) - BettiCurve(resolution=1000)(empty_diag) - ComplexPolynomial(threshold=-1, polynomial_type="T")(empty_diag) - TopologicalVector(threshold=-1)(empty_diag) - PersistenceImage(bandwidth=.1, weight=lambda x: x[1], im_range=[0,1,0,1], resolution=[100,100])(empty_diag) - #Entropy(mode="scalar")(empty_diag) - #Entropy(mode="vector", normalized=False)(empty_diag) - -#def arctan(C,p): -# return lambda x: C*np.arctan(np.power(x[1], p)) + assert not np.any(Landscape(resolution=1000)(empty_diag)) + assert not np.any(Silhouette(resolution=1000, weight=pow(2))(empty_diag)) + assert not np.any(BettiCurve(resolution=1000)(empty_diag)) + assert not np.any(ComplexPolynomial(threshold=-1, polynomial_type="T")(empty_diag)) + assert not np.any(TopologicalVector(threshold=-1)(empty_diag)) + assert not np.any(PersistenceImage(bandwidth=.1, weight=lambda x: x[1], im_range=[0,1,0,1], resolution=[100,100])(empty_diag)) + assert not np.any(Entropy(mode="scalar")(empty_diag)) + assert not np.any(Entropy(mode="vector", normalized=False)(empty_diag)) + +def arctan(C,p): + return lambda x: C*np.arctan(np.power(x[1], p)) # -#def test_kernel_empty_diagrams(): -# empty_diag = np.empty(shape = [0, 2]) +def test_kernel_empty_diagrams(): + empty_diag = np.empty(shape = [0, 2]) # PersistenceWeightedGaussianKernel(bandwidth=1., kernel_approx=None, weight=arctan(1.,1.))(empty_diag, empty_diag) # PersistenceWeightedGaussianKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])), weight=arctan(1.,1.))(empty_diag, empty_diag) # PersistenceScaleSpaceKernel(bandwidth=1.)(empty_diag, empty_diag) # PersistenceScaleSpaceKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) -# SlicedWassersteinDistance(num_directions=100)(empty_diag, empty_diag) -# SlicedWassersteinKernel(num_directions=100, bandwidth=1.)(empty_diag, empty_diag) -# WassersteinDistance(order=2, internal_p=2, mode="pot")(empty_diag, empty_diag) -# WassersteinDistance(order=2, internal_p=2, mode="hera", delta=0.0001)(empty_diag, empty_diag) -# BottleneckDistance(epsilon=.001)(empty_diag, empty_diag) + assert SlicedWassersteinDistance(num_directions=100)(empty_diag, empty_diag) == 0. + assert SlicedWassersteinKernel(num_directions=100, bandwidth=1.)(empty_diag, empty_diag) == 1. + assert WassersteinDistance(mode="hera", delta=0.0001)(empty_diag, empty_diag) == 0. + assert WassersteinDistance(mode="pot")(empty_diag, empty_diag) == 0. + assert BottleneckDistance(epsilon=.001)(empty_diag, empty_diag) == 0. + assert BottleneckDistance()(empty_diag, empty_diag) == 0. # PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1.)(empty_diag, empty_diag) # PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1., kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) -- cgit v1.2.3 From 74e6bad5e4bb848ad7d15afd5d6302ec4c698ac9 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Wed, 20 Oct 2021 09:57:43 +0200 Subject: Improve tests for empty representations --- src/python/test/test_representations.py | 48 ++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/python/test/test_representations.py b/src/python/test/test_representations.py index b888b7f1..93461f1e 100755 --- a/src/python/test/test_representations.py +++ b/src/python/test/test_representations.py @@ -3,6 +3,7 @@ import sys import matplotlib.pyplot as plt import numpy as np import pytest +import random from sklearn.cluster import KMeans @@ -127,29 +128,44 @@ def pow(n): def test_vectorization_empty_diagrams(): empty_diag = np.empty(shape = [0, 2]) - assert not np.any(Landscape(resolution=1000)(empty_diag)) - assert not np.any(Silhouette(resolution=1000, weight=pow(2))(empty_diag)) - assert not np.any(BettiCurve(resolution=1000)(empty_diag)) - assert not np.any(ComplexPolynomial(threshold=-1, polynomial_type="T")(empty_diag)) - assert not np.any(TopologicalVector(threshold=-1)(empty_diag)) - assert not np.any(PersistenceImage(bandwidth=.1, weight=lambda x: x[1], im_range=[0,1,0,1], resolution=[100,100])(empty_diag)) - assert not np.any(Entropy(mode="scalar")(empty_diag)) - assert not np.any(Entropy(mode="vector", normalized=False)(empty_diag)) - -def arctan(C,p): - return lambda x: C*np.arctan(np.power(x[1], p)) -# + random_resolution = random.randint(50,100)*10 # between 500 and 1000 + print("resolution = ", random_resolution) + lsc = Landscape(resolution=random_resolution)(empty_diag) + assert not np.any(lsc) + assert lsc.shape[0]%random_resolution == 0 + slt = Silhouette(resolution=random_resolution, weight=pow(2))(empty_diag) + assert not np.any(slt) + assert slt.shape[0] == random_resolution + btc = BettiCurve(resolution=random_resolution)(empty_diag) + assert not np.any(btc) + assert btc.shape[0] == random_resolution + cpp = ComplexPolynomial(threshold=random_resolution, polynomial_type="T")(empty_diag) + assert not np.any(cpp) + assert cpp.shape[0] == random_resolution + tpv = TopologicalVector(threshold=random_resolution)(empty_diag) + assert tpv.shape[0] == random_resolution + assert not np.any(tpv) + prmg = PersistenceImage(resolution=[random_resolution,random_resolution])(empty_diag) + assert not np.any(prmg) + assert prmg.shape[0] == random_resolution * random_resolution + sce = Entropy(mode="scalar", resolution=random_resolution)(empty_diag) + assert not np.any(sce) + assert sce.shape[0] == 1 + scv = Entropy(mode="vector", normalized=False, resolution=random_resolution)(empty_diag) + assert not np.any(scv) + assert scv.shape[0] == random_resolution + def test_kernel_empty_diagrams(): empty_diag = np.empty(shape = [0, 2]) -# PersistenceWeightedGaussianKernel(bandwidth=1., kernel_approx=None, weight=arctan(1.,1.))(empty_diag, empty_diag) -# PersistenceWeightedGaussianKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])), weight=arctan(1.,1.))(empty_diag, empty_diag) -# PersistenceScaleSpaceKernel(bandwidth=1.)(empty_diag, empty_diag) -# PersistenceScaleSpaceKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) assert SlicedWassersteinDistance(num_directions=100)(empty_diag, empty_diag) == 0. assert SlicedWassersteinKernel(num_directions=100, bandwidth=1.)(empty_diag, empty_diag) == 1. assert WassersteinDistance(mode="hera", delta=0.0001)(empty_diag, empty_diag) == 0. assert WassersteinDistance(mode="pot")(empty_diag, empty_diag) == 0. assert BottleneckDistance(epsilon=.001)(empty_diag, empty_diag) == 0. assert BottleneckDistance()(empty_diag, empty_diag) == 0. +# PersistenceWeightedGaussianKernel(bandwidth=1., kernel_approx=None, weight=arctan(1.,1.))(empty_diag, empty_diag) +# PersistenceWeightedGaussianKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])), weight=arctan(1.,1.))(empty_diag, empty_diag) +# PersistenceScaleSpaceKernel(bandwidth=1.)(empty_diag, empty_diag) +# PersistenceScaleSpaceKernel(kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) # PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1.)(empty_diag, empty_diag) # PersistenceFisherKernel(bandwidth_fisher=1., bandwidth=1., kernel_approx=RBFSampler(gamma=1./2, n_components=100000).fit(np.ones([1,2])))(empty_diag, empty_diag) -- cgit v1.2.3 From 44946b900ea13b2d6bb8d285c18cf0d37d515215 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Wed, 20 Oct 2021 11:30:29 +0200 Subject: Add simplex tree test for persistence_intervals_in_dimension --- src/python/test/test_simplex_tree.py | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src') diff --git a/src/python/test/test_simplex_tree.py b/src/python/test/test_simplex_tree.py index a3eacaa9..31c46213 100755 --- a/src/python/test/test_simplex_tree.py +++ b/src/python/test/test_simplex_tree.py @@ -9,6 +9,7 @@ """ from gudhi import SimplexTree, __GUDHI_USE_EIGEN3 +import numpy as np import pytest __author__ = "Vincent Rouvreau" @@ -404,3 +405,46 @@ def test_boundaries_iterator(): with pytest.raises(RuntimeError): list(st.get_boundaries([6])) # (6) does not exist + +def test_persistence_intervals_in_dimension(): + # Here is our triangulation of a 2-torus - taken from https://dioscuri-tda.org/Paris_TDA_Tutorial_2021.html + # 0-----3-----4-----0 + # | \ | \ | \ | \ | + # | \ | \ | \| \ | + # 1-----8-----7-----1 + # | \ | \ | \ | \ | + # | \ | \ | \ | \ | + # 2-----5-----6-----2 + # | \ | \ | \ | \ | + # | \ | \ | \ | \ | + # 0-----3-----4-----0 + st = SimplexTree() + st.insert([0,1,8]) + st.insert([0,3,8]) + st.insert([3,7,8]) + st.insert([3,4,7]) + st.insert([1,4,7]) + st.insert([0,1,4]) + st.insert([1,2,5]) + st.insert([1,5,8]) + st.insert([5,6,8]) + st.insert([6,7,8]) + st.insert([2,6,7]) + st.insert([1,2,7]) + st.insert([0,2,3]) + st.insert([2,3,5]) + st.insert([3,4,5]) + st.insert([4,5,6]) + st.insert([0,4,6]) + st.insert([0,2,6]) + st.compute_persistence(persistence_dim_max=True) + + H0 = st.persistence_intervals_in_dimension(0) + assert np.array_equal(H0, np.array([[ 0., float("inf")]])) + H1 = st.persistence_intervals_in_dimension(1) + assert np.array_equal(H1, np.array([[ 0., float("inf")], [ 0., float("inf")]])) + H2 = st.persistence_intervals_in_dimension(2) + assert np.array_equal(H2, np.array([[ 0., float("inf")]])) + # Test empty case + assert st.persistence_intervals_in_dimension(3).shape == (0, 2) + \ No newline at end of file -- cgit v1.2.3 From e4122147ee4643dbca6c65efebf83eb2adad6aec Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Wed, 20 Oct 2021 11:31:00 +0200 Subject: Make Entropy work and also fix a bug in the loop --- src/python/gudhi/representations/vector_methods.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/representations/vector_methods.py b/src/python/gudhi/representations/vector_methods.py index 711c32a7..47c5224c 100644 --- a/src/python/gudhi/representations/vector_methods.py +++ b/src/python/gudhi/representations/vector_methods.py @@ -416,9 +416,12 @@ class Entropy(BaseEstimator, TransformerMixin): new_X = BirthPersistenceTransform().fit_transform(X) for i in range(num_diag): - orig_diagram, diagram, num_pts_in_diag = X[i], new_X[i], X[i].shape[0] - new_diagram = DiagramScaler(use=True, scalers=[([1], MaxAbsScaler())]).fit_transform([diagram])[0] + try: + new_diagram = DiagramScaler(use=True, scalers=[([1], MaxAbsScaler())]).fit_transform([diagram])[0] + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + new_diagram = np.empty(shape = [0, 2]) if self.mode == "scalar": ent = - np.sum( np.multiply(new_diagram[:,1], np.log(new_diagram[:,1])) ) @@ -432,12 +435,11 @@ class Entropy(BaseEstimator, TransformerMixin): max_idx = np.clip(np.ceil((py - self.sample_range[0]) / step_x).astype(int), 0, self.resolution) for k in range(min_idx, max_idx): ent[k] += (-1) * new_diagram[j,1] * np.log(new_diagram[j,1]) - if self.normalized: - ent = ent / np.linalg.norm(ent, ord=1) - Xfit.append(np.reshape(ent,[1,-1])) - - Xfit = np.concatenate(Xfit, 0) + if self.normalized: + ent = ent / np.linalg.norm(ent, ord=1) + Xfit.append(np.reshape(ent,[1,-1])) + Xfit = np.concatenate(Xfit, axis=0) return Xfit def __call__(self, diag): -- cgit v1.2.3 From 36959807d5091b79aedabbc67c363dd761c9d5ee Mon Sep 17 00:00:00 2001 From: Hind-M Date: Thu, 21 Oct 2021 17:08:43 +0200 Subject: Factorize cpp and python torus tests implementations --- src/python/test/test_datasets_generators.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/python/test/test_datasets_generators.py b/src/python/test/test_datasets_generators.py index 4c087c57..e2d300e0 100755 --- a/src/python/test/test_datasets_generators.py +++ b/src/python/test/test_datasets_generators.py @@ -18,22 +18,16 @@ def test_sphere(): with pytest.raises(ValueError): points.sphere(n_samples = 10, ambient_dim = 2, radius = 1., sample = 'other') -def test_torus(): - assert points.ctorus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) - assert points.ctorus(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) - - assert points.ctorus(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) - assert points.ctorus(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) - - with pytest.raises(ValueError): - points.ctorus(n_samples = 10, dim = 4, sample = 'other') +def _basic_torus(impl): + assert impl(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) + assert impl(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) -def test_torus_full_python(): - assert points.torus(n_samples = 64, dim = 3, sample = 'random').shape == (64, 6) - assert points.torus(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) - - assert points.torus(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) - assert points.torus(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) + assert impl(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) + assert impl(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) with pytest.raises(ValueError): - points.torus(n_samples = 10, dim = 4, sample = 'other') + impl(n_samples = 10, dim = 4, sample = 'other') + +def test_torus(): + for torus_impl in [points.torus, points.ctorus]: + _basic_torus(torus_impl) -- cgit v1.2.3 From 4a0bc0fe1d6424da9bf979cfc322067a62f41cc9 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Fri, 22 Oct 2021 12:44:07 +0200 Subject: Fix exception management when sklearn version < 1.0 --- src/python/gudhi/representations/vector_methods.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/representations/vector_methods.py b/src/python/gudhi/representations/vector_methods.py index 47c5224c..b83c2a87 100644 --- a/src/python/gudhi/representations/vector_methods.py +++ b/src/python/gudhi/representations/vector_methods.py @@ -500,7 +500,11 @@ class TopologicalVector(BaseEstimator, TransformerMixin): diagram, num_pts_in_diag = X[i], X[i].shape[0] pers = 0.5 * (diagram[:,1]-diagram[:,0]) min_pers = np.minimum(pers,np.transpose(pers)) - distances = DistanceMetric.get_metric("chebyshev").pairwise(diagram) + # Works fine with sklearn 1.0, but an ValueError exception is thrown on past versions + try: + distances = DistanceMetric.get_metric("chebyshev").pairwise(diagram) + except ValueError: + distances = np.empty(shape = [0, 0]) vect = np.flip(np.sort(np.triu(np.minimum(distances, min_pers)), axis=None), 0) dim = min(len(vect), thresh) Xfit[i, :dim] = vect[:dim] -- cgit v1.2.3 From 00dc44281f59aa2b7bb612ec2a7f46720bb944f9 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 25 Oct 2021 10:21:59 +0200 Subject: Revert "Add torch dependency for some python tests" This reverts commit 44659b4d5c2df18745e36280317ecbc9c6a5b411. --- src/python/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 7b7aff1e..f534fc2a 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -546,17 +546,17 @@ if(PYTHONINTERP_FOUND) endif() # Tomato - if(SCIPY_FOUND AND SKLEARN_FOUND AND PYBIND11_FOUND AND TORCH_FOUND) + if(SCIPY_FOUND AND SKLEARN_FOUND AND PYBIND11_FOUND) add_gudhi_py_test(test_tomato) endif() # Weighted Rips - if(SCIPY_FOUND AND TORCH_FOUND) + if(SCIPY_FOUND) add_gudhi_py_test(test_weighted_rips_complex) endif() # DTM Rips - if(SCIPY_FOUND AND TORCH_FOUND) + if(SCIPY_FOUND) add_gudhi_py_test(test_dtm_rips_complex) endif() -- cgit v1.2.3 From 0bf357f6346fab6edf96d580a9195c2acbb79bae Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 25 Oct 2021 10:23:45 +0200 Subject: Revert "Add warnings in dtm.py for DistanceToMeasure and DTMDensity" This reverts commit f461f050ee8bad509814b4851ab7ae8f43502962. --- src/python/gudhi/point_cloud/dtm.py | 11 ----------- src/python/test/test_dtm.py | 10 +--------- 2 files changed, 1 insertion(+), 20 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/dtm.py b/src/python/gudhi/point_cloud/dtm.py index 96a9e7bf..55ac58e6 100644 --- a/src/python/gudhi/point_cloud/dtm.py +++ b/src/python/gudhi/point_cloud/dtm.py @@ -9,7 +9,6 @@ from .knn import KNearestNeighbors import numpy as np -import warnings __author__ = "Marc Glisse" __copyright__ = "Copyright (C) 2020 Inria" @@ -67,11 +66,6 @@ class DistanceToMeasure: distances = distances ** self.q dtm = distances.sum(-1) / self.k dtm = dtm ** (1.0 / self.q) - with warnings.catch_warnings(): - import torch - if isinstance(dtm, torch.Tensor): - if not(torch.isfinite(dtm).all()): - warnings.warn("Overflow/infinite value encountered while computing 'dtm'", RuntimeWarning) # We compute too many powers, 1/p in knn then q in dtm, 1/q in dtm then q or some log in the caller. # Add option to skip the final root? return dtm @@ -169,11 +163,6 @@ class DTMDensity: distances = self.knn.transform(X) distances = distances ** q dtm = (distances * weights).sum(-1) - with warnings.catch_warnings(): - import torch - if isinstance(dtm, torch.Tensor): - if not(torch.isfinite(dtm).all()): - warnings.warn("Overflow/infinite value encountered while computing 'dtm' for density", RuntimeWarning) if self.normalize: dtm /= (np.arange(1, k + 1) ** (q / dim) * weights).sum() density = dtm ** (-dim / q) diff --git a/src/python/test/test_dtm.py b/src/python/test/test_dtm.py index 52468d0f..c29471cf 100755 --- a/src/python/test/test_dtm.py +++ b/src/python/test/test_dtm.py @@ -97,15 +97,7 @@ def test_dtm_overflow_warnings(): for impl in impl_warn: dtm = DistanceToMeasure(2, q=10000, implementation=impl) r = dtm.fit_transform(pts) - assert len(w) == 3 + assert len(w) == 2 for i in range(len(w)): assert issubclass(w[i].category, RuntimeWarning) assert "Overflow" in str(w[i].message) - -def test_density_overflow_warning(): - distances = numpy.array([[10., 100.], [10000000000000., 10.]]) - with warnings.catch_warnings(record=True) as w: - density = DTMDensity(k=2, q=100000, implementation="keops", dim=1).fit_transform(distances) - assert len(w) == 1 - assert issubclass(w[0].category, RuntimeWarning) - assert "Overflow" in str(w[0].message) -- cgit v1.2.3 From bb8c4994b89fb6bfdd80b76912acadf6197f93cc Mon Sep 17 00:00:00 2001 From: Hind-M Date: Tue, 26 Oct 2021 13:59:44 +0200 Subject: Add comments and some minor changes following code review --- src/python/doc/datasets_generators.rst | 13 +++++++------ src/python/gudhi/datasets/generators/_points.cc | 2 +- src/python/gudhi/datasets/generators/points.py | 6 +++--- src/python/test/test_datasets_generators.py | 2 ++ 4 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst index c0bbb973..3700b8a2 100644 --- a/src/python/doc/datasets_generators.rst +++ b/src/python/doc/datasets_generators.rst @@ -48,22 +48,23 @@ You can also generate points on a torus. Two functions are available and give the same output: the first one depends on **CGAL** and the second does not and consists of full python code. -On another hand, two sample types are provided : you can either generate i.i.d. points on a d-torus in :math:`R^{2d}` *randomly* or on a *grid*. +On another hand, two sample types are provided: you can either generate i.i.d. points on a d-torus in :math:`R^{2d}` *randomly* or on a *grid*. -First function : **ctorus** +First function: **ctorus** """"""""""""""""""""""""""" The user should provide the number of points to be generated on the torus :code:`n_samples`, and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. The :code:`sample` argument is optional and is set to **'random'** by default. In this case, the returned generated points would be an array of shape :math:`(n\_samples, 2*dim)`. -Otherwise, if set to **'grid'**, the points are generated on a grid and would be given as an array of shape : +Otherwise, if set to **'grid'**, the points are generated on a grid and would be given as an array of shape: .. math:: - ( [n\_samples^{1 \over {dim}}]^{dim}, 2*dim ) + ( ⌊n\_samples^{1 \over {dim}}⌋^{dim}, 2*dim ) +**Note 1:** The output array first shape is rounded down to the closest perfect :math:`dim^{th}` power. -**Note:** This version is recommended when the user wishes to use **'grid'** as sample type, or **'random'** with a relatively small number of samples (~ less than 150). +**Note 2:** This version is recommended when the user wishes to use **'grid'** as sample type, or **'random'** with a relatively small number of samples (~ less than 150). Example """"""" @@ -79,7 +80,7 @@ Example .. autofunction:: gudhi.datasets.generators.points.ctorus -Second function : **torus** +Second function: **torus** """"""""""""""""""""""""""" The user should provide the number of points to be generated on the torus :code:`n_samples` and the dimension :code:`dim` of the torus on which points would be generated in :math:`R^{2dim}`. diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 536fa949..5d675930 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -110,7 +110,7 @@ PYBIND11_MODULE(_points, m) { :rtype: numpy array of float. The shape of returned numpy array is : if sample is 'random' : (n_samples, 2*dim). - if sample is 'grid' : ([n_samples**(1./dim)]**dim, 2*dim). + if sample is 'grid' : (⌊n_samples**(1./dim)⌋**dim, 2*dim), where shape[0] is rounded down to the closest perfect 'dim'th power. :returns: the generated points on a torus. )pbdoc"); } diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index 1995f769..7f4667af 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -36,15 +36,15 @@ def _generate_grid_points_on_torus(n_samples, dim): def torus(n_samples, dim, sample='random'): """ - Generate points on a dim-torus in R^2dim either randomly or on a grid + Generate points on a flat dim-torus in R^2dim either randomly or on a grid :param n_samples: The number of points to be generated. :param dim: The dimension of the torus on which points would be generated in R^2*dim. :param sample: The sample type of the generated points. Can be 'random' or 'grid'. :returns: numpy array containing the generated points on a torus. - The shape of returned numpy array is : + The shape of returned numpy array is: if sample is 'random' : (n_samples, 2*dim). - if sample is 'grid' : ([n_samples**(1./dim)]**dim, 2*dim). + if sample is 'grid' : (⌊n_samples**(1./dim)⌋**dim, 2*dim), where shape[0] is rounded down to the closest perfect 'dim'th power. """ if sample == 'random': # Generate points randomly diff --git a/src/python/test/test_datasets_generators.py b/src/python/test/test_datasets_generators.py index e2d300e0..933a763e 100755 --- a/src/python/test/test_datasets_generators.py +++ b/src/python/test/test_datasets_generators.py @@ -23,6 +23,8 @@ def _basic_torus(impl): assert impl(n_samples = 64, dim = 3, sample = 'grid').shape == (64, 6) assert impl(n_samples = 10, dim = 4, sample = 'random').shape == (10, 8) + + # Here 1**dim < n_samples < 2**dim, the output shape is therefore (1, 2*dim) = (1, 8), where shape[0] is rounded down to the closest perfect 'dim'th power assert impl(n_samples = 10, dim = 4, sample = 'grid').shape == (1, 8) with pytest.raises(ValueError): -- cgit v1.2.3 From 3a29558decccafe0b07dbf07d66f1410df6c187f Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 27 Oct 2021 09:58:52 +0200 Subject: Replace itertools in grid torus generation function with something faster in most general use cases --- src/python/gudhi/datasets/generators/points.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index 7f4667af..cf97777d 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -8,7 +8,6 @@ # - YYYY/MM Author: Description of the modification import numpy as np -import itertools from ._points import ctorus from ._points import sphere @@ -29,10 +28,11 @@ def _generate_grid_points_on_torus(n_samples, dim): n_samples_grid = int((n_samples+.5)**(1./dim)) # add .5 to avoid rounding down with numerical approximations alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False) - array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)]) - array_points = np.array(list(itertools.product(array_points_inter, repeat=dim))).reshape(-1, 2*dim) - - return array_points + array_points = np.column_stack([np.cos(alpha), np.sin(alpha)]) + array_points_idx = np.empty([n_samples_grid]*dim + [dim], dtype=int) + for i, x in enumerate(np.ix_(*([np.arange(n_samples_grid)]*dim))): + array_points_idx[...,i] = x + return array_points[array_points_idx].reshape(-1, 2*dim) def torus(n_samples, dim, sample='random'): """ -- cgit v1.2.3 From 2ffbd4d63afd59b9d1995a7755db087b31f9c998 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 27 Oct 2021 10:01:23 +0200 Subject: Add test to check outputs of the two torus implementations --- src/python/test/test_datasets_generators.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/python/test/test_datasets_generators.py b/src/python/test/test_datasets_generators.py index 933a763e..91ec4a65 100755 --- a/src/python/test/test_datasets_generators.py +++ b/src/python/test/test_datasets_generators.py @@ -33,3 +33,7 @@ def _basic_torus(impl): def test_torus(): for torus_impl in [points.torus, points.ctorus]: _basic_torus(torus_impl) + # Check that the two versions (torus and ctorus) generate the same output + assert points.ctorus(n_samples = 64, dim = 3, sample = 'random').all() == points.torus(n_samples = 64, dim = 3, sample = 'random').all() + assert points.ctorus(n_samples = 64, dim = 3, sample = 'grid').all() == points.torus(n_samples = 64, dim = 3, sample = 'grid').all() + assert points.ctorus(n_samples = 10, dim = 3, sample = 'grid').all() == points.torus(n_samples = 10, dim = 3, sample = 'grid').all() -- cgit v1.2.3 From 6bbd3c0c62d02ac5641ba77a33f7c5d100320ce0 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Tue, 2 Nov 2021 14:38:01 +0100 Subject: Precise the torus is flat Co-authored-by: Marc Glisse --- src/python/doc/datasets_generators.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst index 3700b8a2..6f36bce1 100644 --- a/src/python/doc/datasets_generators.rst +++ b/src/python/doc/datasets_generators.rst @@ -41,7 +41,7 @@ Example .. autofunction:: gudhi.datasets.generators.points.sphere -Points on torus +Points on a flat torus ^^^^^^^^^^^^^^^^ You can also generate points on a torus. -- cgit v1.2.3 From 93df8a0622836ab03ada2eac075132388708d2c4 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Tue, 2 Nov 2021 14:38:46 +0100 Subject: Apply MG's suggestion --- src/python/gudhi/datasets/generators/_points.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 5d675930..70ce4925 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -36,8 +36,12 @@ py::array_t generate_points_on_sphere(size_t n_samples, int ambient_dim, GUDHI_CHECK(ambient_dim == buf.shape[1], "Py array second dimension not matching the ambient space dimension"); - py::gil_scoped_release release; - auto points_generated = Gudhi::generate_points_on_sphere_d(n_samples, ambient_dim, radius); + std::vector points_generated; + + { + py::gil_scoped_release release; + points_generated = Gudhi::generate_points_on_sphere_d(n_samples, ambient_dim, radius); + } for (size_t i = 0; i < n_samples; i++) for (int j = 0; j < ambient_dim; j++) -- cgit v1.2.3 From 79e6a20ce026ff4c86b1632bb3f1ed16ae5c92a1 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 2 Nov 2021 17:27:25 +0100 Subject: No more gforge references --- .../for_maintainers/new_gudhi_version_creation.md | 22 ++++---- scripts/create_gudhi_version.sh | 66 ---------------------- src/python/doc/alpha_complex_user.rst | 2 +- 3 files changed, 11 insertions(+), 79 deletions(-) delete mode 100755 scripts/create_gudhi_version.sh (limited to 'src') diff --git a/.github/for_maintainers/new_gudhi_version_creation.md b/.github/for_maintainers/new_gudhi_version_creation.md index 3e5295c5..812758e3 100644 --- a/.github/for_maintainers/new_gudhi_version_creation.md +++ b/.github/for_maintainers/new_gudhi_version_creation.md @@ -68,20 +68,18 @@ make -j 4 all && ctest -j 4 --output-on-failure ## Upload the documentation -Upload by ftp the content of the directory gudhi.doc.@GUDHI_VERSION@/cpp in a new directory on ForgeLogin@scm.gforge.inria.fr:/home/groups/gudhi/htdocs/doc/@GUDHI_VERSION@ +[GUDHI GitHub pages](https://gudhi.github.io/) is only used as a _"qualification"_ web hosting service. +The _"production"_ web hosting service is https://files.inria.fr (cf. [this doc](https://doc-si.inria.fr/display/SU/Espace+web) +or [this one](https://www.nextinpact.com/article/30325/109058-se-connecter-a-serveur-webdav-sous-linux-macos-ou-windows)). -Upload by ftp the content of the directory gudhi.doc.@GUDHI_VERSION@/python in a new directory on ForgeLogin@scm.gforge.inria.fr:/home/groups/gudhi/htdocs/python/@GUDHI_VERSION@ +Upload the content of the directory gudhi.doc.@GUDHI_VERSION@/cpp in a new directory on gudhi WebDAV in doc/@GUDHI_VERSION@ +Delete the directory doc/latest on gudhi WebDAV. +Copy gudhi WebDAV doc/@GUDHI_VERSION@ as doc/latest (no symbolic link with WebDAV). + +Upload the content of the directory gudhi.doc.@GUDHI_VERSION@/python in a new directory on gudhi WebDAV in python/@GUDHI_VERSION@ +Delete the directory python/latest on gudhi WebDAV. +Copy gudhi WebDAV python/@GUDHI_VERSION@ as python/latest (no symbolic link with WebDAV). -Through ssh, make the **latest** link to your new version of the documentation: -```bash -ssh ForgeLogin@scm.gforge.inria.fr -cd /home/groups/gudhi/htdocs/doc -rm latest -ln -s @GUDHI_VERSION@ latest -cd /home/groups/gudhi/htdocs/python -rm latest -ln -s @GUDHI_VERSION@ latest -``` ## Put a version label on files diff --git a/scripts/create_gudhi_version.sh b/scripts/create_gudhi_version.sh deleted file mode 100755 index f2a9233f..00000000 --- a/scripts/create_gudhi_version.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash - -login="vrouvrea" -version="2.3.0" -cgaldir="/home/vincent/workspace/CGAL-4.11-HO/build" -cpucount=7 - - -# We start from scripts dir in the dev branch -cd .. -RELATIVEURL=`svn info . |grep -F "Relative URL:" | awk '{print $NF}'` - -if [ "$RELATIVEURL" != "^/trunk" ] -then -echo "Script must be launched in trunk and not in $RELATIVEURL" -exit -fi - -rm -rf build; mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=Debug -DDEBUG_TRACES=ON -DCGAL_DIR=${cgaldir} -DWITH_GUDHI_EXAMPLE=ON -DWITH_GUDHI_BENCHMARK=ON -DPython_ADDITIONAL_VERSIONS=3 .. -cmake -DCMAKE_BUILD_TYPE=Debug . - -CURRENTDIRECTORY=`pwd` -export PYTHONPATH=$CURRENTDIRECTORY/src/cython:$PYTHONPATH - -make -j ${cpucount} all test - -cd .. -svn st | grep -v GUDHIVersion.cmake | grep "^\?" | awk "{print \$2}" | xargs rm -rf - -svn copy svn+ssh://${login}@scm.gforge.inria.fr/svnroot/gudhi/trunk svn+ssh://${login}@scm.gforge.inria.fr/svnroot/gudhi/tags/gudhi-release-${version} \ - -m "Creating a tag of Gudhi release version ${version}." - -cd build -make user_version - -userversiondir=`find . -type d -name "*_GUDHI_${version}" | sed 's/\.\///g'` -echo "User version directory = ${userversiondir}" - -tar -czvf ${userversiondir}.tar.gz ${userversiondir} - -userdocdir=${userversiondir/GUDHI/GUDHI_DOC} -echo "User documentation directory = ${userdocdir}" -mkdir ${userdocdir} -make doxygen - -cp -R ${userversiondir}/doc/html ${userdocdir}/cpp -cd ${userversiondir} -rm -rf build; mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed -DCGAL_DIR=${cgaldir} -DWITH_GUDHI_EXAMPLE=ON -DPython_ADDITIONAL_VERSIONS=3 .. - -CURRENTDIRECTORY=`pwd` -export PYTHONPATH=$CURRENTDIRECTORY/cython:$PYTHONPATH - -make sphinx - -cp -R cython/sphinx ../../${userdocdir}/python -cd ../.. -tar -czvf ${userdocdir}.tar.gz ${userdocdir} - -cd ${userversiondir}/build -make -j ${cpucount} all test install - -cd ../.. -actualdir=`pwd` -echo "Library is available at ${actualdir}/${userversiondir}.tar.gz" -sha256sum ${userversiondir}.tar.gz -echo "Documentation is available at ${actualdir}/${userdocdir}.tar.gz" diff --git a/src/python/doc/alpha_complex_user.rst b/src/python/doc/alpha_complex_user.rst index fffcb3db..3de94bb8 100644 --- a/src/python/doc/alpha_complex_user.rst +++ b/src/python/doc/alpha_complex_user.rst @@ -163,7 +163,7 @@ As the squared radii computed by CGAL are an approximation, it might happen that :math:`\alpha^2` values do not quite define a proper filtration (i.e. non-decreasing with respect to inclusion). We fix that up by calling :func:`~gudhi.SimplexTree.make_filtration_non_decreasing` (cf. -`C++ version `_). +`C++ version `_). Prune above given filtration value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- cgit v1.2.3 From a2761c01ceb26a057b94be1d45433335704c1581 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Thu, 4 Nov 2021 17:24:15 +0100 Subject: code review: try-except inside the if --- src/python/gudhi/representations/vector_methods.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/representations/vector_methods.py b/src/python/gudhi/representations/vector_methods.py index b83c2a87..e7ee57a4 100644 --- a/src/python/gudhi/representations/vector_methods.py +++ b/src/python/gudhi/representations/vector_methods.py @@ -44,15 +44,15 @@ class PersistenceImage(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - try: - if np.isnan(np.array(self.im_range)).any(): + if np.isnan(np.array(self.im_range)).any(): + try: new_X = BirthPersistenceTransform().fit_transform(X) pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(new_X,y) [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] self.im_range = np.where(np.isnan(np.array(self.im_range)), np.array([mx, Mx, my, My]), np.array(self.im_range)) - except ValueError: - # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 - pass + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): -- cgit v1.2.3 From 7c26436a703a476d28cf568949275d26d1827c36 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Thu, 4 Nov 2021 17:26:04 +0100 Subject: code review: use len instead of .shape[0] --- src/python/gudhi/cubical_complex.pyx | 5 ++--- src/python/gudhi/periodic_cubical_complex.pyx | 5 ++--- src/python/gudhi/simplex_tree.pyx | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 04569bd8..8e244bb8 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -283,7 +283,6 @@ cdef class CubicalComplex: assert self.pcohptr != NULL, "compute_persistence() must be called before persistence_intervals_in_dimension()" piid = np.array(self.pcohptr.intervals_in_dimension(dimension)) # Workaround https://github.com/GUDHI/gudhi-devel/issues/507 - if piid.shape[0] == 0: + if len(piid) == 0: return np.empty(shape = [0, 2]) - else: - return piid + return piid diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index bd91ccde..6c21e902 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -282,7 +282,6 @@ cdef class PeriodicCubicalComplex: assert self.pcohptr != NULL, "compute_persistence() must be called before persistence_intervals_in_dimension()" piid = np.array(self.pcohptr.intervals_in_dimension(dimension)) # Workaround https://github.com/GUDHI/gudhi-devel/issues/507 - if piid.shape[0] == 0: + if len(piid) == 0: return np.empty(shape = [0, 2]) - else: - return piid + return piid diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index e9bac036..c3720936 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -543,10 +543,9 @@ cdef class SimplexTree: assert self.pcohptr != NULL, "compute_persistence() must be called before persistence_intervals_in_dimension()" piid = np.array(self.pcohptr.intervals_in_dimension(dimension)) # Workaround https://github.com/GUDHI/gudhi-devel/issues/507 - if piid.shape[0] == 0: + if len(piid) == 0: return np.empty(shape = [0, 2]) - else: - return piid + return piid def persistence_pairs(self): """This function returns a list of persistence birth and death simplices pairs. -- cgit v1.2.3 From 3094e1fe51acc49e4ea7e4f38648bb25d96784a4 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Fri, 5 Nov 2021 10:27:46 +0100 Subject: code review: factorize sample range computation --- src/python/gudhi/representations/vector_methods.py | 46 ++++++++++++---------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/representations/vector_methods.py b/src/python/gudhi/representations/vector_methods.py index e7ee57a4..140162af 100644 --- a/src/python/gudhi/representations/vector_methods.py +++ b/src/python/gudhi/representations/vector_methods.py @@ -6,6 +6,7 @@ # # Modification(s): # - 2020/06 Martin: ATOL integration +# - 2021/11 Vincent Rouvreau: factorize _automatic_sample_range import numpy as np from sklearn.base import BaseEstimator, TransformerMixin @@ -98,6 +99,23 @@ class PersistenceImage(BaseEstimator, TransformerMixin): """ return self.fit_transform([diag])[0,:] +def _automatic_sample_range(sample_range, X, y): + """ + Compute and returns sample range from the persistence diagrams if one of the sample_range values is numpy.nan. + + Parameters: + sample_range (a numpy array of 2 float): minimum and maximum of all piecewise-linear function domains, of + the form [x_min, x_max]. + X (list of n x 2 numpy arrays): input persistence diagrams. + y (n x 1 array): persistence diagram labels (unused). + """ + nan_in_range = np.isnan(sample_range) + if nan_in_range.any(): + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) + [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + return np.where(nan_in_range, np.array([mx, My]), sample_range) + return sample_range + class Landscape(BaseEstimator, TransformerMixin): """ This is a class for computing persistence landscapes from a list of persistence diagrams. A persistence landscape is a collection of 1D piecewise-linear functions computed from the rank function associated to the persistence diagram. These piecewise-linear functions are then sampled evenly on a given range and the corresponding vectors of samples are concatenated and returned. See http://jmlr.org/papers/v16/bubenik15a.html for more details. @@ -123,14 +141,11 @@ class Landscape(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - if self.nan_in_range.any(): - try: - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(self.nan_in_range, np.array([mx, My]), np.array(self.sample_range)) - except ValueError: - # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 - pass + try: + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return self def transform(self, X): @@ -227,10 +242,7 @@ class Silhouette(BaseEstimator, TransformerMixin): y (n x 1 array): persistence diagram labels (unused). """ try: - if np.isnan(np.array(self.sample_range)).any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) except ValueError: # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 pass @@ -320,10 +332,7 @@ class BettiCurve(BaseEstimator, TransformerMixin): y (n x 1 array): persistence diagram labels (unused). """ try: - if np.isnan(np.array(self.sample_range)).any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) except ValueError: # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 pass @@ -391,10 +400,7 @@ class Entropy(BaseEstimator, TransformerMixin): y (n x 1 array): persistence diagram labels (unused). """ try: - if np.isnan(np.array(self.sample_range)).any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - self.sample_range = np.where(np.isnan(np.array(self.sample_range)), np.array([mx, My]), np.array(self.sample_range)) + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) except ValueError: # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 pass -- cgit v1.2.3 From 37d7743a91f7fb970425a06798ac6cb61b0be109 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Fri, 5 Nov 2021 12:05:45 +0100 Subject: code review: try/except in function and assert on length of diagrams for error menagement --- src/python/gudhi/representations/vector_methods.py | 38 +++++++++------------- 1 file changed, 15 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/representations/vector_methods.py b/src/python/gudhi/representations/vector_methods.py index 140162af..e883b5dd 100644 --- a/src/python/gudhi/representations/vector_methods.py +++ b/src/python/gudhi/representations/vector_methods.py @@ -111,9 +111,14 @@ def _automatic_sample_range(sample_range, X, y): """ nan_in_range = np.isnan(sample_range) if nan_in_range.any(): - pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) - [mx,my],[Mx,My] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]], [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] - return np.where(nan_in_range, np.array([mx, My]), sample_range) + try: + pre = DiagramScaler(use=True, scalers=[([0], MinMaxScaler()), ([1], MinMaxScaler())]).fit(X,y) + [mx,my] = [pre.scalers[0][1].data_min_[0], pre.scalers[1][1].data_min_[0]] + [Mx,My] = [pre.scalers[0][1].data_max_[0], pre.scalers[1][1].data_max_[0]] + return np.where(nan_in_range, np.array([mx, My]), sample_range) + except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + pass return sample_range class Landscape(BaseEstimator, TransformerMixin): @@ -141,11 +146,7 @@ class Landscape(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - try: - self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) - except ValueError: - # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 - pass + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) return self def transform(self, X): @@ -241,11 +242,7 @@ class Silhouette(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - try: - self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) - except ValueError: - # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 - pass + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) return self def transform(self, X): @@ -331,11 +328,7 @@ class BettiCurve(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - try: - self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) - except ValueError: - # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 - pass + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) return self def transform(self, X): @@ -399,11 +392,7 @@ class Entropy(BaseEstimator, TransformerMixin): X (list of n x 2 numpy arrays): input persistence diagrams. y (n x 1 array): persistence diagram labels (unused). """ - try: - self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) - except ValueError: - # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 - pass + self.sample_range = _automatic_sample_range(np.array(self.sample_range), X, y) return self def transform(self, X): @@ -427,6 +416,7 @@ class Entropy(BaseEstimator, TransformerMixin): new_diagram = DiagramScaler(use=True, scalers=[([1], MaxAbsScaler())]).fit_transform([diagram])[0] except ValueError: # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + assert len(diagram) == 0 new_diagram = np.empty(shape = [0, 2]) if self.mode == "scalar": @@ -510,6 +500,8 @@ class TopologicalVector(BaseEstimator, TransformerMixin): try: distances = DistanceMetric.get_metric("chebyshev").pairwise(diagram) except ValueError: + # Empty persistence diagram case - https://github.com/GUDHI/gudhi-devel/issues/507 + assert len(diagram) == 0 distances = np.empty(shape = [0, 0]) vect = np.flip(np.sort(np.triu(np.minimum(distances, min_pers)), axis=None), 0) dim = min(len(vect), thresh) -- cgit v1.2.3