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 951e23a37eb12eaa0e804c7d3d5b4e135c415691 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 6 Jul 2020 17:35:55 +0200 Subject: adding essential parts management in wasserstein distance --- src/python/gudhi/wasserstein/wasserstein.py | 146 ++++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index b37d30bb..283ecd9d 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -79,6 +79,9 @@ def _perstot(X, order, internal_p, enable_autodiff): transparent to automatic differentiation. :type enable_autodiff: bool :returns: float, the total persistence of the diagram (that is, its distance to the empty diagram). + + .. note:: + Can be +infty if the diagram has an essential part (points with infinite coordinates). ''' if enable_autodiff: import eagerpy as ep @@ -88,32 +91,136 @@ def _perstot(X, order, internal_p, enable_autodiff): return np.linalg.norm(_dist_to_diag(X, internal_p), ord=order) -def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enable_autodiff=False): +def _get_essential_parts(a): + ''' + :param a: (n x 2) numpy.array (point of a diagram) + :retuns: five lists of indices (between 0 and len(a)) accounting for the five types of points with infinite + coordinates that can occur in a diagram, namely: + type0 : (-inf, finite) + type1 : (finite, +inf) + type2 : (-inf, +inf) + type3 : (-inf, -inf) + type4 : (+inf, +inf) + .. note:: + For instance, a[_get_essential_parts(a)[0]] returns the points in a of coordinates (-inf, x) for some finite x. + ''' + if len(a): + ess_first_type = np.where(np.isfinite(a[:,1]) & (a[:,0] == -np.inf))[0] # coord (-inf, x) + ess_second_type = np.where(np.isfinite(a[:,0]) & (a[:,1] == np.inf))[0] # coord (x, +inf) + ess_third_type = np.where((a[:,0] == -np.inf) & (a[:,1] == np.inf))[0] # coord (-inf, +inf) + ess_fourth_type = np.where((a[:,0] == -np.inf) & (a[:,1] == -np.inf))[0] # coord (-inf, -inf) + ess_fifth_type = np.where((a[:,0] == np.inf) & (a[:,1] == np.inf))[0] # coord (+inf, +inf) + return ess_first_type, ess_second_type, ess_third_type, ess_fourth_type, ess_fifth_type + else: + return [], [], [], [], [] + + +def _cost_and_match_essential_parts(X, Y, idX, idY, order, axis): + ''' + :param X: (n x 2) numpy.array (dgm points) + :param Y: (n x 2) numpy.array (dgm points) + :param idX: indices to consider for this one dimensional OT problem (in X) + :param idY: indices to consider for this one dimensional OT problem (in Y) + :param order: exponent for Wasserstein distanc ecomputation + :param axis: must be 0 or 1, correspond to the coordinate which is finite. + :returns: cost (float) and match for points with *one* infinite coordinate. + + .. note:: + Assume idX, idY come when calling _handle_essential_parts, thus have same length. ''' - :param X: (n x 2) numpy.array encoding the (finite points of the) first diagram. Must not contain essential points - (i.e. with infinite coordinate). + u = X[idX, axis] + v = Y[idY, axis] + + cost = np.sum(np.abs(np.sort(u) - np.sort(v))**(order)) # OT cost in 1D + + sortidX = idX[np.argsort(u)] + sortidY = idY[np.argsort(v)] + # We return [i,j] sorted per value, and then [i, -1] (or [-1, j]) to account for essential points matched to the diagonal + match = list(zip(sortidX, sortidY)) + + return cost, match + + +def _handle_essential_parts(X, Y, order): + ''' + :param X: (n x 2) numpy array, first diagram. + :param Y: (n x 2) numpy array, second diagram. + :order: Wasserstein order for cost computation. + :returns: cost and matching due to essential parts. If cost is +inf, matching will be set to None. + ''' + c = 0 + m = [] + + ess_parts_X = _get_essential_parts(X) + ess_parts_Y = _get_essential_parts(Y) + + # Treats the case of infinite cost (cardinalities of essential parts differ). + for u, v in zip(ess_parts_X, ess_parts_Y): + if len(u) != len(v): + return np.inf, None + + # Now we know each essential part has the same number of points in both diagrams. + # Handle type 0 and type 1 essential parts (those with one finite coordinates) + c1, m1 = _cost_and_match_essential_parts(X, Y, ess_parts_X[0], ess_parts_Y[0], axis=1, order=order) + c2, m2 = _cost_and_match_essential_parts(X, Y, ess_parts_X[1], ess_parts_Y[1], axis=0, order=order) + + c += c1 + c2 + m += m1 + m2 + + # Handle type >= 2 (both coordinates are infinite, so we essentially just align points) + for u, v in zip(ess_parts_X[2:], ess_parts_Y[2:]): + m += list(zip(u, v)) # cost is 0 + + return c, np.array(m) + + +def _offdiag(X): + ''' + :param X: (n x 2) numpy array encoding a persistence diagram. + :returns: The off-diagonal part of a diagram `X` (points with finite coordinates). + ''' + return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] + + +def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enable_autodiff=False, + keep_essential_parts=True): + ''' + :param X: (n x 2) numpy.array encoding the first diagram. Can now contain essential parts (points with infinite + coordinates). :param Y: (m x 2) numpy.array encoding the second diagram. :param matching: if True, computes and returns the optimal matching between X and Y, encoded as a (n x 2) np.array [...[i,j]...], meaning the i-th point in X is matched to the j-th point in Y, with the convention (-1) represents the diagonal. + Note that if the cost is +inf (essential parts have different number of points, + then the optimal matching will be set to `None`. :param order: exponent for Wasserstein; Default value is 1. :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2); - Default value is `np.inf`. + default value is `np.inf`. :param enable_autodiff: If X and Y are torch.tensor, tensorflow.Tensor or jax.numpy.ndarray, make the computation transparent to automatic differentiation. This requires the package EagerPy and is currently incompatible - with `matching=True`. + with `matching=True` and with `keep_essential_parts=True`. .. note:: This considers the function defined on the coordinates of the off-diagonal points of X and Y and lets the various frameworks compute its gradient. It never pulls new points from the diagonal. :type enable_autodiff: bool + :param keep_essential_parts: If False, only considers the off-diagonal points in the diagrams. + Otherwise, computes the distance between the essential parts separately. + :type keep_essential_parts: bool :returns: the Wasserstein distance of order q (1 <= q < infinity) between persistence diagrams with respect to the internal_p-norm as ground metric. If matching is set to True, also returns the optimal matching between X and Y. + If cost is +inf, any matching is optimal and thus it returns `None` instead. ''' + # Zeroth step: check compatibility of arguments + if keep_essential_parts and enable_autodiff: + import warnings + warnings.warn("enable_autodiff does not handle essential parts yet. These will be ignored in the following computations") + keep_essential_parts = False + + # First step: handle empty diagrams n = len(X) m = len(Y) - # handle empty diagrams if n == 0: if m == 0: if not matching: @@ -132,6 +239,25 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab else: return _perstot(X, order, internal_p, enable_autodiff), np.array([[i, -1] for i in range(n)]) + + # Second step: handle essential parts + if keep_essential_parts: + essential_cost, essential_matching = _handle_essential_parts(X, Y, order=order) + if (essential_cost == np.inf): + if matching: + return np.inf, None + else: + return np.inf # avoid computing off-diagonal transport cost if essential parts do not match (saves time) + + else: + essential_cost = 0 + essential_matching = None + + X, Y = _offdiag(X), _offdiag(Y) + n = len(X) + m = len(Y) + + # Now the standard pipeline for off-diagonal parts if enable_autodiff: import eagerpy as ep @@ -139,6 +265,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab Y_orig = ep.astensor(Y) X = X_orig.numpy() Y = Y_orig.numpy() + M = _build_dist_matrix(X, Y, order=order, internal_p=internal_p) a = np.ones(n+1) # weight vector of the input diagram. Uniform here. a[-1] = m @@ -154,7 +281,10 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab # Now we turn to -1 points encoding the diagonal match[:,0][match[:,0] >= n] = -1 match[:,1][match[:,1] >= m] = -1 - return ot_cost ** (1./order) , match + # Finally incorporate the essential part matching + if essential_matching is not None: + match = np.concatenate([match, essential_matching]) if essential_matching.size else match + return (ot_cost + essential_cost) ** (1./order) , match if enable_autodiff: P = ot.emd(a=a, b=b, M=M, numItermax=2000000) @@ -178,4 +308,4 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab # The default numItermax=100000 is not sufficient for some examples with 5000 points, what is a good value? ot_cost = ot.emd2(a, b, M, numItermax=2000000) - return ot_cost ** (1./order) + return (ot_cost + essential_cost) ** (1./order) -- cgit v1.2.3 From 91a9d77ed48847a8859e6bdd759390001910d411 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 6 Jul 2020 17:52:47 +0200 Subject: update doc (examples) with essential parts --- src/python/doc/wasserstein_distance_user.rst | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index 96ec7872..d747344b 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -44,7 +44,7 @@ Basic example ************* This example computes the 1-Wasserstein distance from 2 persistence diagrams with Euclidean ground metric. -Note that persistence diagrams must be submitted as (n x 2) numpy arrays and must not contain inf values. +Note that persistence diagrams must be submitted as (n x 2) numpy arrays. .. testcode:: @@ -67,14 +67,16 @@ We can also have access to the optimal matching by letting `matching=True`. It is encoded as a list of indices (i,j), meaning that the i-th point in X is mapped to the j-th point in Y. An index of -1 represents the diagonal. +It handles essential parts (points with infinite coordinates). However if the cardinalities of the essential parts differ, +any matching has a cost +inf and thus can be considered to be optimal. In such a case, the function returns `(np.inf, None)`. .. testcode:: import gudhi.wasserstein import numpy as np - dgm1 = np.array([[2.7, 3.7],[9.6, 14.],[34.2, 34.974]]) - dgm2 = np.array([[2.8, 4.45], [5, 6], [9.5, 14.1]]) + dgm1 = np.array([[2.7, 3.7],[9.6, 14.],[34.2, 34.974], [3, np.inf]]) + dgm2 = np.array([[2.8, 4.45], [5, 6], [9.5, 14.1], [4, np.inf]]) cost, matchings = gudhi.wasserstein.wasserstein_distance(dgm1, dgm2, matching=True, order=1, internal_p=2) message_cost = "Wasserstein distance value = %.2f" %cost @@ -90,16 +92,30 @@ An index of -1 represents the diagonal. for j in dgm2_to_diagonal: print("point %s in dgm2 is matched to the diagonal" %j) + dgm3 = np.array([[1, 2], [0, np.inf]]) + dgm4 = np.array([[1, 2], [0, np.inf], [1, np.inf]]) + cost, matchings = gudhi.wasserstein.wasserstein_distance(dgm3, dgm4, matching=True, order=1, internal_p=2) + print("\nSecond example:") + print("cost:", cost) + print("matchings:", matchings) + + The output is: .. testoutput:: - Wasserstein distance value = 2.15 + Wasserstein distance value = 3.15 point 0 in dgm1 is matched to point 0 in dgm2 point 1 in dgm1 is matched to point 2 in dgm2 + point 3 in dgm1 is matched to point 3 in dgm2 point 2 in dgm1 is matched to the diagonal point 1 in dgm2 is matched to the diagonal + Second example: + cost: inf + matchings: None + + Barycenters ----------- -- cgit v1.2.3 From fe3e6a3a47828841ba3cb4a0721e5d8c16ab126f Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 6 Jul 2020 18:27:52 +0200 Subject: update test including essential parts --- src/python/gudhi/wasserstein/wasserstein.py | 18 +++++-- src/python/test/test_wasserstein_distance.py | 72 +++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 283ecd9d..2a1dee7a 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -105,10 +105,10 @@ def _get_essential_parts(a): For instance, a[_get_essential_parts(a)[0]] returns the points in a of coordinates (-inf, x) for some finite x. ''' if len(a): - ess_first_type = np.where(np.isfinite(a[:,1]) & (a[:,0] == -np.inf))[0] # coord (-inf, x) + ess_first_type = np.where(np.isfinite(a[:,1]) & (a[:,0] == -np.inf))[0] # coord (-inf, x) ess_second_type = np.where(np.isfinite(a[:,0]) & (a[:,1] == np.inf))[0] # coord (x, +inf) - ess_third_type = np.where((a[:,0] == -np.inf) & (a[:,1] == np.inf))[0] # coord (-inf, +inf) - ess_fourth_type = np.where((a[:,0] == -np.inf) & (a[:,1] == -np.inf))[0] # coord (-inf, -inf) + ess_third_type = np.where((a[:,0] == -np.inf) & (a[:,1] == np.inf))[0] # coord (-inf, +inf) + ess_fourth_type = np.where((a[:,0] == -np.inf) & (a[:,1] == -np.inf))[0] # coord (-inf, -inf) ess_fifth_type = np.where((a[:,0] == np.inf) & (a[:,1] == np.inf))[0] # coord (+inf, +inf) return ess_first_type, ess_second_type, ess_third_type, ess_fourth_type, ess_fifth_type else: @@ -232,12 +232,20 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab if not matching: return _perstot(Y, order, internal_p, enable_autodiff) else: - return _perstot(Y, order, internal_p, enable_autodiff), np.array([[-1, j] for j in range(m)]) + cost = _perstot(Y, order, internal_p, enable_autodiff) + if cost == np.inf: # We had some essential part here. + return cost, None + else: + return cost, np.array([[-1, j] for j in range(m)]) elif m == 0: if not matching: return _perstot(X, order, internal_p, enable_autodiff) else: - return _perstot(X, order, internal_p, enable_autodiff), np.array([[i, -1] for i in range(n)]) + cost = _perstot(X, order, internal_p, enable_autodiff) + if cost == np.inf: + return cost, None + else: + return np.array([[i, -1] for i in range(n)]) # Second step: handle essential parts diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 90d26809..24be228b 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -5,10 +5,11 @@ Copyright (C) 2019 Inria Modification(s): + - 2020/07 Théo Lacombe: Added tests about handling essential parts in diagrams. - YYYY/MM Author: Description of the modification """ -from gudhi.wasserstein.wasserstein import _proj_on_diag +from gudhi.wasserstein.wasserstein import _proj_on_diag, _offdiag, _handle_essential_parts from gudhi.wasserstein import wasserstein_distance as pot from gudhi.hera import wasserstein_distance as hera import numpy as np @@ -18,12 +19,62 @@ __author__ = "Theo Lacombe" __copyright__ = "Copyright (C) 2019 Inria" __license__ = "MIT" + def test_proj_on_diag(): dgm = np.array([[1., 1.], [1., 2.], [3., 5.]]) assert np.array_equal(_proj_on_diag(dgm), [[1., 1.], [1.5, 1.5], [4., 4.]]) empty = np.empty((0, 2)) assert np.array_equal(_proj_on_diag(empty), empty) + +def test_offdiag(): + diag = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], + [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) + assert np.array_equal(_offdiag(diag), [[0, 1], [3, 5]]) + + +def test_handle_essential_parts(): + diag1 = np.array([[0, 1], [3, 5], + [2, np.inf], [3, np.inf], + [-np.inf, 8], [-np.inf, 12], + [-np.inf, -np.inf], + [np.inf, np.inf], + [-np.inf, np.inf], [-np.inf, np.inf]]) + + diag2 = np.array([[0, 2], [3, 5], + [2, np.inf], [4, np.inf], + [-np.inf, 8], [-np.inf, 11], + [-np.inf, -np.inf], + [np.inf, np.inf], + [-np.inf, np.inf], [-np.inf, np.inf]]) + + diag3 = np.array([[0, 2], [3, 5], + [2, np.inf], [4, np.inf], + [-np.inf, 8], [-np.inf, 11], + [-np.inf, -np.inf], [-np.inf, -np.inf], + [np.inf, np.inf], + [-np.inf, np.inf], [-np.inf, np.inf]]) + + c, m = _handle_essential_parts(diag1, diag2, matching=True, order=1) + assert c == pytest.approx(3, 0.0001) + assert np.array_equal(m, [[0,0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]) + c, m = _handle_essential_parts(diag1, diag3, matching=True, order=1) + assert c == np.inf + assert (m is None) + + +def test_get_essential_parts(): + diag = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], + [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) + + res = _get_essential_parts(diag) + assert res[0] = [4, 5] + assert res[1] = [2, 3] + assert res[2] = [8, 9] + assert res[3] = [6] + assert res[4] = [7] + + def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_matching=True): diag1 = np.array([[2.7, 3.7], [9.6, 14.0], [34.2, 34.974]]) diag2 = np.array([[2.8, 4.45], [9.5, 14.1]]) @@ -64,7 +115,7 @@ def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_mat assert wasserstein_distance(diag4, diag5) == np.inf assert wasserstein_distance(diag5, diag6, order=1, internal_p=np.inf) == approx(4.) - + assert wasserstein_distance(diag5, emptydiag) == np.inf if test_matching: match = wasserstein_distance(emptydiag, emptydiag, matching=True, internal_p=1., order=2)[1] @@ -78,6 +129,13 @@ def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_mat match = wasserstein_distance(diag1, diag2, matching=True, internal_p=2., order=2.)[1] assert np.array_equal(match, [[0, 0], [1, 1], [2, -1]]) + if test_matching and test_infinity: + diag7 = np.array([[0, 3], [4, np.inf], [5, np.inf]]) + + match = wasserstein_distance(diag5, diag6, matching=True, internal_p=2., order=2.)[1] + assert np.array_equal(match, [[0, -1], [-1,0], [-1, 1], [1, 2]]) + match = wasserstein_distance(diag5, diag7, matching=True, internal_p=2., order=2.)[1] + assert (match is None) def hera_wrap(**extra): @@ -92,7 +150,7 @@ def pot_wrap(**extra): def test_wasserstein_distance_pot(): _basic_wasserstein(pot, 1e-15, test_infinity=False, test_matching=True) - _basic_wasserstein(pot_wrap(enable_autodiff=True), 1e-15, test_infinity=False, test_matching=False) + _basic_wasserstein(pot_wrap(enable_autodiff=True, keep_essential_parts=False), 1e-15, test_infinity=False, test_matching=False) def test_wasserstein_distance_hera(): _basic_wasserstein(hera_wrap(delta=1e-12), 1e-12, test_matching=False) @@ -105,19 +163,19 @@ def test_wasserstein_distance_grad(): diag2 = torch.tensor([[2.8, 4.45], [9.5, 14.1]], requires_grad=True) diag3 = torch.tensor([[2.8, 4.45], [9.5, 14.1]], requires_grad=True) assert diag1.grad is None and diag2.grad is None and diag3.grad is None - dist12 = pot(diag1, diag2, internal_p=2, order=2, enable_autodiff=True) - dist30 = pot(diag3, torch.tensor([]), internal_p=2, order=2, enable_autodiff=True) + dist12 = pot(diag1, diag2, internal_p=2, order=2, enable_autodiff=True, keep_essential_parts=False) + dist30 = pot(diag3, torch.tensor([]), internal_p=2, order=2, enable_autodiff=True, keep_essential_parts=False) dist12.backward() dist30.backward() assert not torch.isnan(diag1.grad).any() and not torch.isnan(diag2.grad).any() and not torch.isnan(diag3.grad).any() diag4 = torch.tensor([[0., 10.]], requires_grad=True) diag5 = torch.tensor([[1., 11.], [3., 4.]], requires_grad=True) - dist45 = pot(diag4, diag5, internal_p=1, order=1, enable_autodiff=True) + dist45 = pot(diag4, diag5, internal_p=1, order=1, enable_autodiff=True, keep_essential_parts=False) assert dist45 == 3. dist45.backward() assert np.array_equal(diag4.grad, [[-1., -1.]]) assert np.array_equal(diag5.grad, [[1., 1.], [-1., 1.]]) diag6 = torch.tensor([[5., 10.]], requires_grad=True) - pot(diag6, diag6, internal_p=2, order=2, enable_autodiff=True).backward() + pot(diag6, diag6, internal_p=2, order=2, enable_autodiff=True, keep_essential_parts=False).backward() # https://github.com/jonasrauber/eagerpy/issues/6 # assert np.array_equal(diag6.grad, [[0., 0.]]) -- cgit v1.2.3 From e0eba14109e02676825f8c24563872a5b49c6120 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 7 Jul 2020 11:52:35 +0200 Subject: correction typo in test wdist --- src/python/gudhi/wasserstein/wasserstein.py | 2 +- src/python/test/test_wasserstein_distance.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 2a1dee7a..009c1bf7 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -245,7 +245,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab if cost == np.inf: return cost, None else: - return np.array([[i, -1] for i in range(n)]) + return cost, np.array([[i, -1] for i in range(n)]) # Second step: handle essential parts diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 24be228b..e50091e9 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -55,10 +55,10 @@ def test_handle_essential_parts(): [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) - c, m = _handle_essential_parts(diag1, diag2, matching=True, order=1) + c, m = _handle_essential_parts(diag1, diag2, order=1) assert c == pytest.approx(3, 0.0001) assert np.array_equal(m, [[0,0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]) - c, m = _handle_essential_parts(diag1, diag3, matching=True, order=1) + c, m = _handle_essential_parts(diag1, diag3, order=1) assert c == np.inf assert (m is None) @@ -68,11 +68,11 @@ def test_get_essential_parts(): [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) res = _get_essential_parts(diag) - assert res[0] = [4, 5] - assert res[1] = [2, 3] - assert res[2] = [8, 9] - assert res[3] = [6] - assert res[4] = [7] + assert res[0] == [4, 5] + assert res[1] == [2, 3] + assert res[2] == [8, 9] + assert res[3] == [6] + assert res[4] == [7] def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_matching=True): -- cgit v1.2.3 From 42a399c273fde7c76ec23d2993957fcbb492ee79 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 7 Jul 2020 12:37:51 +0200 Subject: correction mistake in tests --- src/python/gudhi/wasserstein/wasserstein.py | 4 ++-- src/python/test/test_wasserstein_distance.py | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 009c1bf7..981bbf08 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -214,7 +214,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab # Zeroth step: check compatibility of arguments if keep_essential_parts and enable_autodiff: import warnings - warnings.warn("enable_autodiff does not handle essential parts yet. These will be ignored in the following computations") + warnings.warn("enable_autodiff does not handle essential parts yet. keep_essential_parts set to False.") keep_essential_parts = False # First step: handle empty diagrams @@ -256,11 +256,11 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab return np.inf, None else: return np.inf # avoid computing off-diagonal transport cost if essential parts do not match (saves time) - else: essential_cost = 0 essential_matching = None + # Extract off-diaognal points of the diagrams. X, Y = _offdiag(X), _offdiag(Y) n = len(X) m = len(Y) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index e50091e9..285b95c9 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -9,12 +9,13 @@ - YYYY/MM Author: Description of the modification """ -from gudhi.wasserstein.wasserstein import _proj_on_diag, _offdiag, _handle_essential_parts +from gudhi.wasserstein.wasserstein import _proj_on_diag, _offdiag, _handle_essential_parts, _get_essential_parts from gudhi.wasserstein import wasserstein_distance as pot from gudhi.hera import wasserstein_distance as hera import numpy as np import pytest + __author__ = "Theo Lacombe" __copyright__ = "Copyright (C) 2019 Inria" __license__ = "MIT" @@ -56,8 +57,10 @@ def test_handle_essential_parts(): [-np.inf, np.inf], [-np.inf, np.inf]]) c, m = _handle_essential_parts(diag1, diag2, order=1) - assert c == pytest.approx(3, 0.0001) - assert np.array_equal(m, [[0,0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]) + assert c == pytest.approx(2, 0.0001) # Note: here c is only the cost due to essential part (thus 2, not 3) + # Similarly, the matching only corresponds to essential parts. + assert np.array_equal(m, [[4, 4], [5, 5], [2, 2], [3, 3], [8, 8], [9, 9], [6, 6], [7, 7]]) + c, m = _handle_essential_parts(diag1, diag3, order=1) assert c == np.inf assert (m is None) @@ -68,11 +71,11 @@ def test_get_essential_parts(): [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) res = _get_essential_parts(diag) - assert res[0] == [4, 5] - assert res[1] == [2, 3] - assert res[2] == [8, 9] - assert res[3] == [6] - assert res[4] == [7] + assert np.array_equal(res[0], [4, 5]) + assert np.array_equal(res[1], [2, 3]) + assert np.array_equal(res[2], [8, 9]) + assert np.array_equal(res[3], [6] ) + assert np.array_equal(res[4], [7] ) def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_matching=True): -- cgit v1.2.3 From 107f8e6668509f5fd36e179f9a538b460d3941a9 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 7 Jul 2020 18:15:17 +0200 Subject: added enable autodiff management in _offdiag utils function --- src/python/gudhi/wasserstein/wasserstein.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 981bbf08..495142c4 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -70,6 +70,7 @@ def _perstot_autodiff(X, order, internal_p): ''' return _dist_to_diag(X, internal_p).norms.lp(order) + def _perstot(X, order, internal_p, enable_autodiff): ''' :param X: (n x 2) numpy.array (points of a given diagram). @@ -174,12 +175,18 @@ def _handle_essential_parts(X, Y, order): return c, np.array(m) -def _offdiag(X): +def _offdiag(X, enable_autodiff): ''' :param X: (n x 2) numpy array encoding a persistence diagram. :returns: The off-diagonal part of a diagram `X` (points with finite coordinates). ''' - return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] + if enable_autodiff: + import eagerpy as ep + + return ep.astensor(X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))]) + + else: + return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enable_autodiff=False, @@ -261,7 +268,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab essential_matching = None # Extract off-diaognal points of the diagrams. - X, Y = _offdiag(X), _offdiag(Y) + X, Y = _offdiag(X, enable_autodiff), _offdiag(Y, enable_autodiff) n = len(X) m = len(Y) -- cgit v1.2.3 From e94892f972357283e70c7534f84662dfaa21cc3e Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 20 Jul 2020 11:41:13 +0200 Subject: update test enable_autodiff and _offdiag --- src/python/gudhi/wasserstein/wasserstein.py | 16 ++++++---------- src/python/test/test_wasserstein_distance.py | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 495142c4..142385b1 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -178,13 +178,13 @@ def _handle_essential_parts(X, Y, order): def _offdiag(X, enable_autodiff): ''' :param X: (n x 2) numpy array encoding a persistence diagram. + :param enable_autodiff: boolean, to handle the case where X is a eagerpy tensor. :returns: The off-diagonal part of a diagram `X` (points with finite coordinates). ''' if enable_autodiff: - import eagerpy as ep - - return ep.astensor(X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))]) - + # Assumes the diagrams only have finite coordinates. Thus, return X directly. + # TODO improve this to get rid of essential parts if there are any. + return X else: return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] @@ -218,11 +218,6 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab If matching is set to True, also returns the optimal matching between X and Y. If cost is +inf, any matching is optimal and thus it returns `None` instead. ''' - # Zeroth step: check compatibility of arguments - if keep_essential_parts and enable_autodiff: - import warnings - warnings.warn("enable_autodiff does not handle essential parts yet. keep_essential_parts set to False.") - keep_essential_parts = False # First step: handle empty diagrams n = len(X) @@ -267,7 +262,8 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab essential_cost = 0 essential_matching = None - # Extract off-diaognal points of the diagrams. + # Extract off-diaognal points of the diagrams. Note that if enable_autodiff is True, nothing is done here (X,Y are + # assumed to be tensors with only finite coordinates). X, Y = _offdiag(X, enable_autodiff), _offdiag(Y, enable_autodiff) n = len(X) m = len(Y) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 285b95c9..6701c7ba 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -31,7 +31,7 @@ def test_proj_on_diag(): def test_offdiag(): diag = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) - assert np.array_equal(_offdiag(diag), [[0, 1], [3, 5]]) + assert np.array_equal(_offdiag(diag, enable_autodiff=False), [[0, 1], [3, 5]]) def test_handle_essential_parts(): -- 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 89bb3d11064de40f2b4fda958aa2e2e8cfa5b489 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 12 Apr 2021 10:45:32 +0200 Subject: change name _offdiag to _finite_part --- src/python/gudhi/wasserstein/wasserstein.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 572d4249..d64d433e 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -175,11 +175,11 @@ def _handle_essential_parts(X, Y, order): return c, np.array(m) -def _offdiag(X, enable_autodiff): +def _finite_part(X, enable_autodiff): ''' :param X: (n x 2) numpy array encoding a persistence diagram. :param enable_autodiff: boolean, to handle the case where X is a eagerpy tensor. - :returns: The off-diagonal part of a diagram `X` (points with finite coordinates). + :returns: The finite part of a diagram `X` (points with finite coordinates). ''' if enable_autodiff: # Assumes the diagrams only have finite coordinates. Thus, return X directly. @@ -262,13 +262,13 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab essential_cost = 0 essential_matching = None - # Extract off-diaognal points of the diagrams. Note that if enable_autodiff is True, nothing is done here (X,Y are + # Extract finite points of the diagrams. Note that if enable_autodiff is True, nothing is done here (X,Y are # assumed to be tensors with only finite coordinates). - X, Y = _offdiag(X, enable_autodiff), _offdiag(Y, enable_autodiff) + X, Y = _finite_part(X, enable_autodiff), _finite_part(Y, enable_autodiff) n = len(X) m = len(Y) - # Now the standard pipeline for off-diagonal parts + # Now the standard pipeline for finite parts if enable_autodiff: import eagerpy as ep -- cgit v1.2.3 From 01bd9eef85b0d93eb1629f1a0c5a28a359e4e7b9 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 12 Apr 2021 10:47:18 +0200 Subject: change name _offdiag to _finite_part in test file --- src/python/test/test_wasserstein_distance.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 6701c7ba..12bf71df 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -9,7 +9,7 @@ - YYYY/MM Author: Description of the modification """ -from gudhi.wasserstein.wasserstein import _proj_on_diag, _offdiag, _handle_essential_parts, _get_essential_parts +from gudhi.wasserstein.wasserstein import _proj_on_diag, _finite_part, _handle_essential_parts, _get_essential_parts from gudhi.wasserstein import wasserstein_distance as pot from gudhi.hera import wasserstein_distance as hera import numpy as np @@ -28,10 +28,10 @@ def test_proj_on_diag(): assert np.array_equal(_proj_on_diag(empty), empty) -def test_offdiag(): +def test_finite_part(): diag = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) - assert np.array_equal(_offdiag(diag, enable_autodiff=False), [[0, 1], [3, 5]]) + assert np.array_equal(_finite_part(diag, enable_autodiff=False), [[0, 1], [3, 5]]) def test_handle_essential_parts(): -- cgit v1.2.3 From 777522b82bde16b55f15c21471bad06038849fd1 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 12 Apr 2021 15:52:36 +0200 Subject: improved essential part and enable autodiff management --- src/python/gudhi/wasserstein/wasserstein.py | 75 ++++++++++++++++------------- 1 file changed, 41 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index d64d433e..2911f826 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -95,7 +95,7 @@ def _perstot(X, order, internal_p, enable_autodiff): def _get_essential_parts(a): ''' :param a: (n x 2) numpy.array (point of a diagram) - :retuns: five lists of indices (between 0 and len(a)) accounting for the five types of points with infinite + :returns: five lists of indices (between 0 and len(a)) accounting for the five types of points with infinite coordinates that can occur in a diagram, namely: type0 : (-inf, finite) type1 : (finite, +inf) @@ -104,13 +104,20 @@ def _get_essential_parts(a): type4 : (+inf, +inf) .. note:: For instance, a[_get_essential_parts(a)[0]] returns the points in a of coordinates (-inf, x) for some finite x. + Note also that points with (+inf, -inf) are not handled (points (x,y) in dgm satisfy by assumption (y >= x)). ''' if len(a): - ess_first_type = np.where(np.isfinite(a[:,1]) & (a[:,0] == -np.inf))[0] # coord (-inf, x) - ess_second_type = np.where(np.isfinite(a[:,0]) & (a[:,1] == np.inf))[0] # coord (x, +inf) - ess_third_type = np.where((a[:,0] == -np.inf) & (a[:,1] == np.inf))[0] # coord (-inf, +inf) - ess_fourth_type = np.where((a[:,0] == -np.inf) & (a[:,1] == -np.inf))[0] # coord (-inf, -inf) - ess_fifth_type = np.where((a[:,0] == np.inf) & (a[:,1] == np.inf))[0] # coord (+inf, +inf) + first_coord_finite = np.isfinite(a[:,0]) + second_coord_finite = np.isfinite(a[:,1]) + first_coord_infinite_positive = (a[:,0] == np.inf) + second_coord_infinite_positive = (a[:,1] == np.inf) + first_coord_infinite_negative = (a[:,0] == -np.inf) + second_coord_infinite_negative = (a[:,1] == -np.inf) + ess_first_type = np.where(second_coord_finite & first_coord_infinite_negative)[0] # coord (-inf, x) + ess_second_type = np.where(first_coord_finite & second_coord_infinite_positive)[0] # coord (x, +inf) + ess_third_type = np.where(first_coord_infinite_negative & second_coord_infinite_positive)[0] # coord (-inf, +inf) + ess_fourth_type = np.where(first_coord_infinite_negative & second_coord_infinite_negative)[0] # coord (-inf, -inf) + ess_fifth_type = np.where(first_coord_infinite_positive & second_coord_infinite_positive)[0] # coord (+inf, +inf) return ess_first_type, ess_second_type, ess_third_type, ess_fourth_type, ess_fifth_type else: return [], [], [], [], [] @@ -136,7 +143,7 @@ def _cost_and_match_essential_parts(X, Y, idX, idY, order, axis): sortidX = idX[np.argsort(u)] sortidY = idY[np.argsort(v)] - # We return [i,j] sorted per value, and then [i, -1] (or [-1, j]) to account for essential points matched to the diagonal + # We return [i,j] sorted per value match = list(zip(sortidX, sortidY)) return cost, match @@ -149,9 +156,6 @@ def _handle_essential_parts(X, Y, order): :order: Wasserstein order for cost computation. :returns: cost and matching due to essential parts. If cost is +inf, matching will be set to None. ''' - c = 0 - m = [] - ess_parts_X = _get_essential_parts(X) ess_parts_Y = _get_essential_parts(Y) @@ -165,8 +169,8 @@ def _handle_essential_parts(X, Y, order): c1, m1 = _cost_and_match_essential_parts(X, Y, ess_parts_X[0], ess_parts_Y[0], axis=1, order=order) c2, m2 = _cost_and_match_essential_parts(X, Y, ess_parts_X[1], ess_parts_Y[1], axis=0, order=order) - c += c1 + c2 - m += m1 + m2 + c = c1 + c2 + m = m1 + m2 # Handle type >= 2 (both coordinates are infinite, so we essentially just align points) for u, v in zip(ess_parts_X[2:], ess_parts_Y[2:]): @@ -175,24 +179,18 @@ def _handle_essential_parts(X, Y, order): return c, np.array(m) -def _finite_part(X, enable_autodiff): +def _finite_part(X): ''' :param X: (n x 2) numpy array encoding a persistence diagram. - :param enable_autodiff: boolean, to handle the case where X is a eagerpy tensor. :returns: The finite part of a diagram `X` (points with finite coordinates). ''' - if enable_autodiff: - # Assumes the diagrams only have finite coordinates. Thus, return X directly. - # TODO improve this to get rid of essential parts if there are any. - return X - else: - return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] + return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enable_autodiff=False, keep_essential_parts=True): ''' - :param X: (n x 2) numpy.array encoding the first diagram. Can now contain essential parts (points with infinite + :param X: (n x 2) numpy.array encoding the first diagram. Can contain essential parts (points with infinite coordinates). :param Y: (m x 2) numpy.array encoding the second diagram. :param matching: if True, computes and returns the optimal matching between X and Y, encoded as @@ -200,17 +198,17 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab the j-th point in Y, with the convention (-1) represents the diagonal. Note that if the cost is +inf (essential parts have different number of points, then the optimal matching will be set to `None`. - :param order: exponent for Wasserstein; Default value is 1. - :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2); + :param order: exponent for Wasserstein. Default value is 1. + :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2). Default value is `np.inf`. :param enable_autodiff: If X and Y are torch.tensor or tensorflow.Tensor, make the computation transparent to automatic differentiation. This requires the package EagerPy and is currently incompatible with `matching=True` and with `keep_essential_parts=True`. - .. note:: This considers the function defined on the coordinates of the off-diagonal points of X and Y + .. note:: This considers the function defined on the coordinates of the off-diagonal finite points of X and Y and lets the various frameworks compute its gradient. It never pulls new points from the diagonal. :type enable_autodiff: bool - :param keep_essential_parts: If False, only considers the off-diagonal points in the diagrams. + :param keep_essential_parts: If False, only considers the finite points in the diagrams. Otherwise, computes the distance between the essential parts separately. :type keep_essential_parts: bool :returns: the Wasserstein distance of order q (1 <= q < infinity) between persistence diagrams with @@ -235,7 +233,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab return _perstot(Y, order, internal_p, enable_autodiff) else: cost = _perstot(Y, order, internal_p, enable_autodiff) - if cost == np.inf: # We had some essential part here. + if cost == np.inf: # We had some essential part in Y. return cost, None else: return cost, np.array([[-1, j] for j in range(m)]) @@ -250,24 +248,28 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab return cost, np.array([[i, -1] for i in range(n)]) - # Second step: handle essential parts + # Check essential part and enable autodiff together + if enable_autodiff and keep_essential_parts: + import warnings # should it be done at the top of the file? + warnings.warn('''enable_autodiff=True and keep_essential_parts=True are incompatible together. + keep_essential_parts is set to False: only points with finite coordiantes are considered + in the following. + ''') + keep_essential_parts = False + + # Second step: handle essential parts if needed. if keep_essential_parts: essential_cost, essential_matching = _handle_essential_parts(X, Y, order=order) if (essential_cost == np.inf): if matching: return np.inf, None else: - return np.inf # avoid computing off-diagonal transport cost if essential parts do not match (saves time) + return np.inf # avoid computing transport cost between the finite parts if essential parts + # cardinalities do not match (saves time) else: essential_cost = 0 essential_matching = None - # Extract finite points of the diagrams. Note that if enable_autodiff is True, nothing is done here (X,Y are - # assumed to be tensors with only finite coordinates). - X, Y = _finite_part(X, enable_autodiff), _finite_part(Y, enable_autodiff) - n = len(X) - m = len(Y) - # Now the standard pipeline for finite parts if enable_autodiff: import eagerpy as ep @@ -277,6 +279,11 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab X = X_orig.numpy() Y = Y_orig.numpy() + # Extract finite points of the diagrams. + X, Y = _finite_part(X), _finite_part(Y) + n = len(X) + m = len(Y) + M = _build_dist_matrix(X, Y, order=order, internal_p=internal_p) a = np.ones(n+1) # weight vector of the input diagram. Uniform here. a[-1] = m -- cgit v1.2.3 From 2a11e3651c2d66df8371a9aa1d23dff69ffbc31c Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 12 Apr 2021 15:54:26 +0200 Subject: removed test_wasserstein_distance_grad to be consistent with master --- src/python/test/test_wasserstein_distance.py | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'src') diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 12bf71df..14d5c2ca 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -159,26 +159,3 @@ def test_wasserstein_distance_hera(): _basic_wasserstein(hera_wrap(delta=1e-12), 1e-12, test_matching=False) _basic_wasserstein(hera_wrap(delta=.1), .1, test_matching=False) -def test_wasserstein_distance_grad(): - import torch - - diag1 = torch.tensor([[2.7, 3.7], [9.6, 14.0], [34.2, 34.974]], requires_grad=True) - diag2 = torch.tensor([[2.8, 4.45], [9.5, 14.1]], requires_grad=True) - diag3 = torch.tensor([[2.8, 4.45], [9.5, 14.1]], requires_grad=True) - assert diag1.grad is None and diag2.grad is None and diag3.grad is None - dist12 = pot(diag1, diag2, internal_p=2, order=2, enable_autodiff=True, keep_essential_parts=False) - dist30 = pot(diag3, torch.tensor([]), internal_p=2, order=2, enable_autodiff=True, keep_essential_parts=False) - dist12.backward() - dist30.backward() - assert not torch.isnan(diag1.grad).any() and not torch.isnan(diag2.grad).any() and not torch.isnan(diag3.grad).any() - diag4 = torch.tensor([[0., 10.]], requires_grad=True) - diag5 = torch.tensor([[1., 11.], [3., 4.]], requires_grad=True) - dist45 = pot(diag4, diag5, internal_p=1, order=1, enable_autodiff=True, keep_essential_parts=False) - assert dist45 == 3. - dist45.backward() - assert np.array_equal(diag4.grad, [[-1., -1.]]) - assert np.array_equal(diag5.grad, [[1., 1.], [-1., 1.]]) - diag6 = torch.tensor([[5., 10.]], requires_grad=True) - pot(diag6, diag6, internal_p=2, order=2, enable_autodiff=True, keep_essential_parts=False).backward() - # https://github.com/jonasrauber/eagerpy/issues/6 - # assert np.array_equal(diag6.grad, [[0., 0.]]) -- cgit v1.2.3 From cdab3c9e32923f83d25d2cdf207f3cddbb3f94f6 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 12 Apr 2021 17:02:34 +0200 Subject: handle essential parts test --- src/python/gudhi/wasserstein/wasserstein.py | 1 + src/python/test/test_wasserstein_distance.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 2911f826..7cb9d5d9 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -113,6 +113,7 @@ def _get_essential_parts(a): second_coord_infinite_positive = (a[:,1] == np.inf) first_coord_infinite_negative = (a[:,0] == -np.inf) second_coord_infinite_negative = (a[:,1] == -np.inf) + ess_first_type = np.where(second_coord_finite & first_coord_infinite_negative)[0] # coord (-inf, x) ess_second_type = np.where(first_coord_finite & second_coord_infinite_positive)[0] # coord (x, +inf) ess_third_type = np.where(first_coord_infinite_negative & second_coord_infinite_positive)[0] # coord (-inf, +inf) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 14d5c2ca..df7acc91 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -31,7 +31,7 @@ def test_proj_on_diag(): def test_finite_part(): diag = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) - assert np.array_equal(_finite_part(diag, enable_autodiff=False), [[0, 1], [3, 5]]) + assert np.array_equal(_finite_part(diag), [[0, 1], [3, 5]]) def test_handle_essential_parts(): -- cgit v1.2.3 From bb0792ed7bfe9d718be3e8039e8fb89af6d160e5 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 12 Apr 2021 19:48:57 +0200 Subject: added warning when cost is infty and matching is None --- src/python/doc/wasserstein_distance_user.rst | 4 +-- src/python/gudhi/wasserstein/wasserstein.py | 44 ++++++++++++++++++---------- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index b3d17495..091c9fd9 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -100,7 +100,7 @@ any matching has a cost +inf and thus can be considered to be optimal. In such a print("matchings:", matchings) -The output is: +The output is: .. testoutput:: @@ -197,4 +197,4 @@ Tutorial This `notebook `_ -presents the concept of barycenter, or Fréchet mean, of a family of persistence diagrams. \ No newline at end of file +presents the concept of barycenter, or Fréchet mean, of a family of persistence diagrams. diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 7cb9d5d9..8ccbe12e 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -9,6 +9,7 @@ import numpy as np import scipy.spatial.distance as sc +import warnings try: import ot @@ -188,6 +189,20 @@ def _finite_part(X): return X[np.where(np.isfinite(X[:,0]) & np.isfinite(X[:,1]))] +def _warn_infty(matching): + ''' + Handle essential parts with different cardinalities. Warn the user about cost being infinite and (if + `matching=True`) about the returned matching being `None`. + ''' + if matching: + warnings.warn('Cardinality of essential parts differs. Distance (cost) is +infty, and the returned matching is None.') + return np.inf, None + else: + warnings.warn('Cardinality of essential parts diffes. Distance (cost) is +infty.') + return np.inf + + + def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enable_autodiff=False, keep_essential_parts=True): ''' @@ -230,28 +245,27 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab else: return 0., np.array([]) else: - if not matching: - return _perstot(Y, order, internal_p, enable_autodiff) + cost = _perstot(Y, order, internal_p, enable_autodiff) + if cost == np.inf: + return _warn_infty(matching) else: - cost = _perstot(Y, order, internal_p, enable_autodiff) - if cost == np.inf: # We had some essential part in Y. - return cost, None + if not matching: + return cost else: return cost, np.array([[-1, j] for j in range(m)]) elif m == 0: - if not matching: - return _perstot(X, order, internal_p, enable_autodiff) + cost = _perstot(X, order, internal_p, enable_autodiff) + if cost == np.inf: + return _warn_infty(matching) else: - cost = _perstot(X, order, internal_p, enable_autodiff) - if cost == np.inf: - return cost, None + if not matching: + return cost else: return cost, np.array([[i, -1] for i in range(n)]) # Check essential part and enable autodiff together if enable_autodiff and keep_essential_parts: - import warnings # should it be done at the top of the file? warnings.warn('''enable_autodiff=True and keep_essential_parts=True are incompatible together. keep_essential_parts is set to False: only points with finite coordiantes are considered in the following. @@ -262,11 +276,9 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab if keep_essential_parts: essential_cost, essential_matching = _handle_essential_parts(X, Y, order=order) if (essential_cost == np.inf): - if matching: - return np.inf, None - else: - return np.inf # avoid computing transport cost between the finite parts if essential parts - # cardinalities do not match (saves time) + return _warn_infty(matching) # Tells the user that cost is infty and matching (if True) is None. + # avoid computing transport cost between the finite parts if essential parts + # cardinalities do not match (saves time) else: essential_cost = 0 essential_matching = None -- cgit v1.2.3 From 0e11a3a2232770b0526918d2b543848abd092254 Mon Sep 17 00:00:00 2001 From: Hind Date: Thu, 15 Apr 2021 09:46:27 +0200 Subject: Set Cython language level to remove warning --- src/python/gudhi/simplex_tree.pyx | 2 +- src/python/setup.py.in | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index d7991417..be08a3a1 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -11,7 +11,7 @@ from cython.operator import dereference, preincrement from libc.stdint cimport intptr_t import numpy from numpy import array as np_array -cimport simplex_tree +cimport gudhi.simplex_tree __author__ = "Vincent Rouvreau" __copyright__ = "Copyright (C) 2016 Inria" diff --git a/src/python/setup.py.in b/src/python/setup.py.in index 98d058fc..65f5446e 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -41,10 +41,9 @@ for module in cython_modules: libraries=libraries, library_dirs=library_dirs, include_dirs=include_dirs, - runtime_library_dirs=runtime_library_dirs, - cython_directives = {'language_level': str(sys.version_info[0])},)) + runtime_library_dirs=runtime_library_dirs,)) -ext_modules = cythonize(ext_modules) +ext_modules = cythonize(ext_modules, compiler_directives={'language_level': str(sys.version_info[0])}) for module in pybind11_modules: my_include_dirs = include_dirs + [pybind11.get_include(False), pybind11.get_include(True)] -- cgit v1.2.3 From e72aacb4c9a83f22da50f71c3528458d6e539ef9 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 15 Apr 2021 18:16:30 +0200 Subject: Fix contradictory color --- src/python/gudhi/clustering/tomato.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/clustering/tomato.py b/src/python/gudhi/clustering/tomato.py index fbba3cc8..d0e9995c 100644 --- a/src/python/gudhi/clustering/tomato.py +++ b/src/python/gudhi/clustering/tomato.py @@ -271,7 +271,7 @@ class Tomato: l = self.max_weight_per_cc_.min() r = self.max_weight_per_cc_.max() if self.diagram_.size > 0: - plt.plot(self.diagram_[:, 0], self.diagram_[:, 1], "ro") + plt.plot(self.diagram_[:, 0], self.diagram_[:, 1], "o", color="red") l = min(l, self.diagram_[:, 1].min()) r = max(r, self.diagram_[:, 0].max()) if l == r: @@ -283,7 +283,7 @@ class Tomato: l, r = -1.0, 1.0 plt.plot([l, r], [l, r]) plt.plot( - self.max_weight_per_cc_, numpy.full(self.max_weight_per_cc_.shape, 1.1 * l - 0.1 * r), "ro", color="green" + self.max_weight_per_cc_, numpy.full(self.max_weight_per_cc_.shape, 1.1 * l - 0.1 * r), "o", color="green" ) plt.show() -- cgit v1.2.3 From d2f12c8563d9f7aa1f8ead0da0034796a88704e9 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 15 Apr 2021 20:41:49 +0200 Subject: Compare lists with == numpy/core/_asarray.py:102: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray. --- src/python/test/test_tomato.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/test/test_tomato.py b/src/python/test/test_tomato.py index ecab03c4..c571f799 100755 --- a/src/python/test/test_tomato.py +++ b/src/python/test/test_tomato.py @@ -37,7 +37,7 @@ def test_tomato_1(): t = Tomato(metric="euclidean", graph_type="radius", r=4.7, k=4) t.fit(a) assert t.max_weight_per_cc_.size == 2 - assert np.array_equal(t.neighbors_, [[0, 1, 2], [0, 1, 2], [0, 1, 2], [3, 4, 5, 6], [3, 4, 5], [3, 4, 5], [3, 6]]) + assert t.neighbors_ == [[0, 1, 2], [0, 1, 2], [0, 1, 2], [3, 4, 5, 6], [3, 4, 5], [3, 4, 5], [3, 6]] t.plot_diagram() t = Tomato(graph_type="radius", r=4.7, k=4, symmetrize_graph=True) -- cgit v1.2.3 From 2ce8b315fe5e069d6444b79f6b01e76327fa5d1d Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 15 Apr 2021 21:25:03 +0200 Subject: Name the argument n_neighbors of NearestNeighbors It seems that it has had the same name for a while, so this shouldn't break anything. sklearn/utils/validation.py:70: FutureWarning: Pass n_neighbors=3 as keyword args. From version 1.0 (renaming of 0.25) passing these as positional arguments will result in an error --- src/python/gudhi/point_cloud/knn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/point_cloud/knn.py b/src/python/gudhi/point_cloud/knn.py index 994be3b6..829bf1bf 100644 --- a/src/python/gudhi/point_cloud/knn.py +++ b/src/python/gudhi/point_cloud/knn.py @@ -111,7 +111,7 @@ class KNearestNeighbors: nargs = { k: v for k, v in self.params.items() if k in {"p", "n_jobs", "metric_params", "algorithm", "leaf_size"} } - self.nn = NearestNeighbors(self.k, metric=self.metric, **nargs) + self.nn = NearestNeighbors(n_neighbors=self.k, metric=self.metric, **nargs) self.nn.fit(X) if self.params["implementation"] == "hnsw": -- cgit v1.2.3 From 9616e2b8f616366393bf0b74a76029ae8a95d77a Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 16 Apr 2021 22:49:55 +0200 Subject: Rewrite choose_n_farthest_points Introduce an indirection to help with points with multiplicity. Limit the use of magic values like 0 and infinity. --- .../include/gudhi/choose_n_farthest_points.h | 55 +++++++++++++++------- .../test/test_choose_n_farthest_points.cpp | 5 +- 2 files changed, 42 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Subsampling/include/gudhi/choose_n_farthest_points.h b/src/Subsampling/include/gudhi/choose_n_farthest_points.h index e6347d96..44c02df1 100644 --- a/src/Subsampling/include/gudhi/choose_n_farthest_points.h +++ b/src/Subsampling/include/gudhi/choose_n_farthest_points.h @@ -42,7 +42,7 @@ enum : std::size_t { * The iteration starts with the landmark `starting point` or, if `starting point==random_starting_point`, * with a random landmark. * It chooses `final_size` points from a random access range - * `input_pts` (or the number of distinct points if `final_size` is larger) + * `input_pts` (or the number of input points if `final_size` is larger) * and outputs them in the output iterator `output_it`. It also * outputs the distance from each of those points to the set of previous * points in `dist_it`. @@ -88,34 +88,57 @@ void choose_n_farthest_points(Distance dist, starting_point = dis(gen); } - std::size_t current_number_of_landmarks = 0; // counter for landmarks - static_assert(std::numeric_limits::has_infinity, "the number type needs to support infinity()"); // FIXME: don't hard-code the type as double. For Epeck_d, we also want to handle types that do not have an infinity. - const double infty = std::numeric_limits::infinity(); // infinity (see next entry) - std::vector< double > dist_to_L(nb_points, infty); // vector of current distances to L from input_pts + static_assert(std::numeric_limits::has_infinity, "the number type needs to support infinity()"); + + *output_it++ = input_pts[starting_point]; + *dist_it++ = std::numeric_limits::infinity(); + if (final_size == 1) return; + + std::vector points(nb_points); // map from remaining points to indexes in input_pts + std::vector< double > dist_to_L(nb_points); // vector of current distances to L from points + for(std::size_t i = 0; i < nb_points; ++i) { + points[i] = i; + dist_to_L[i] = dist(input_pts[i], input_pts[starting_point]); + } + // The indirection through points makes the program a bit slower. Some alternatives: + // - the original code never removed points and counted on them not + // reappearing because of a self-distance of 0. This causes unnecessary + // computations when final_size is large. It also causes trouble if there are + // input points at distance 0 from each other. + // - copy input_pts and update the local copy when removing points. std::size_t curr_max_w = starting_point; - for (current_number_of_landmarks = 0; current_number_of_landmarks != final_size; current_number_of_landmarks++) { - // curr_max_w at this point is the next landmark - *output_it++ = input_pts[curr_max_w]; - *dist_it++ = dist_to_L[curr_max_w]; + for (std::size_t current_number_of_landmarks = 1; current_number_of_landmarks != final_size; current_number_of_landmarks++) { + std::size_t latest_landmark = points[curr_max_w]; + // To remove the latest landmark at index curr_max_w, replace it + // with the last point and reduce the length of the vector. + std::size_t last = points.size() - 1; + if (curr_max_w != last) { + points[curr_max_w] = points[last]; + dist_to_L[curr_max_w] = dist_to_L[last]; + } + points.pop_back(); + + // Update distances to L. std::size_t i = 0; - for (auto&& p : input_pts) { - double curr_dist = dist(p, input_pts[curr_max_w]); + for (auto p : points) { + double curr_dist = dist(input_pts[p], input_pts[latest_landmark]); if (curr_dist < dist_to_L[i]) dist_to_L[i] = curr_dist; ++i; } - // choose the next curr_max_w - double curr_max_dist = 0; // used for defining the furhest point from L - for (i = 0; i < dist_to_L.size(); i++) + // choose the next landmark + curr_max_w = 0; + double curr_max_dist = dist_to_L[curr_max_w]; // used for defining the furthest point from L + for (i = 1; i < points.size(); i++) if (dist_to_L[i] > curr_max_dist) { curr_max_dist = dist_to_L[i]; curr_max_w = i; } - // If all that remains are duplicates of points already taken, stop. - if (curr_max_dist == 0) break; + *output_it++ = input_pts[points[curr_max_w]]; + *dist_it++ = dist_to_L[curr_max_w]; } } diff --git a/src/Subsampling/test/test_choose_n_farthest_points.cpp b/src/Subsampling/test/test_choose_n_farthest_points.cpp index 94793295..c384c61b 100644 --- a/src/Subsampling/test/test_choose_n_farthest_points.cpp +++ b/src/Subsampling/test/test_choose_n_farthest_points.cpp @@ -102,11 +102,12 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_choose_farthest_point_limits, Kernel, list_of BOOST_CHECK(distances[1] == 1); landmarks.clear(); distances.clear(); - // Ignore duplicated points + // Accept duplicated points points.emplace_back(point.begin(), point.end()); Gudhi::subsampling::choose_n_farthest_points(d, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); - BOOST_CHECK(landmarks.size() == 2 && distances.size() == 2); + BOOST_CHECK(landmarks.size() == 3 && distances.size() == 3); BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); BOOST_CHECK(distances[1] == 1); + BOOST_CHECK(distances[2] == 0); landmarks.clear(); distances.clear(); } -- cgit v1.2.3 From 0a00c46d770699bbe467ade1c619dc94c8fad7b7 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 17 Apr 2021 14:53:53 +0200 Subject: Sparse Rips: disable `mini`, optimize a bit redundant points --- .../include/gudhi/Sparse_rips_complex.h | 23 +++++++++++++++++----- src/python/test/test_rips_complex.py | 21 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h index a5501004..d7669dad 100644 --- a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h +++ b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h @@ -45,6 +45,7 @@ template class Sparse_rips_complex { private: // TODO(MG): use a different graph where we know we can safely insert in parallel. + // Use a graph that lets us skip some vertices, for `mini` or redundant points. typedef typename boost::adjacency_list, boost::property> @@ -58,7 +59,8 @@ class Sparse_rips_complex { * @param[in] points Range of points. * @param[in] distance Distance function that returns a `Filtration_value` from 2 given points. * @param[in] epsilon Approximation parameter. epsilon must be positive. - * @param[in] mini Minimal filtration value. Ignore anything below this scale. This is a less efficient version of `Gudhi::subsampling::sparsify_point_set()`. + * @param[in] mini Not implemented yet, and broken in previous versions. Minimal filtration value. + * Ignore anything below this scale. This is a less efficient version of `Gudhi::subsampling::sparsify_point_set()`. * @param[in] maxi Maximal filtration value. Ignore anything above this scale. * */ @@ -67,6 +69,7 @@ class Sparse_rips_complex { : epsilon_(epsilon) { GUDHI_CHECK(epsilon > 0, "epsilon must be positive"); auto dist_fun = [&](Vertex_handle i, Vertex_handle j) { return distance(points[i], points[j]); }; + // TODO: stop choose_n_farthest_points once it reaches mini? Then the graph vertices would not be [0, ..., n-1] which complicates things. subsampling::choose_n_farthest_points(dist_fun, boost::irange(0, boost::size(points)), -1, -1, std::back_inserter(sorted_points), std::back_inserter(params)); compute_sparse_graph(dist_fun, epsilon, mini, maxi); @@ -116,9 +119,9 @@ class Sparse_rips_complex { double cst = epsilon_ * (1 - epsilon_) / 2; auto block = [cst,&complex,&lambda](typename SimplicialComplexForRips::Simplex_handle sh){ auto filt = complex.filtration(sh); - auto mini = filt * cst; + auto min_f = filt * cst; for(auto v : complex.simplex_vertex_range(sh)){ - if(lambda[v] < mini) + if(lambda[v] < min_f) return true; // v died before this simplex could be born } return false; @@ -149,12 +152,22 @@ class Sparse_rips_complex { for (int i = 0; i < n; ++i) { auto&& pi = points[i]; auto li = params[i]; - if (li < mini) break; + // FIXME: see below about mini. It might be ok to uncomment just this one, but it requires a proof. + // if ((li < mini || li <= 0) && i != 0) break; + if (li <= 0 && i != 0) break; + // The parameter of the first point is not very meaningful, it is supposed to be infinite, + // but if the type does not support it... + // Points with multiplicity get connected to their first representative, no need to handle + // the redundant ones in the outer loop. for (int j = i + 1; j < n; ++j) { auto&& pj = points[j]; auto d = dist(pi, pj); auto lj = params[j]; - if (lj < mini) break; + // FIXME: It would make sense to ignore the points with low param completely, but the current graph type we are + // using implicitly inserts all the vertices 0 ... n-1, so this would create isolated vertices, which is bad. + // If we do end up ignoring those points, we should do it early, around choose_n_farthest_points. But be careful + // that the size of lambda should reflect the original number of points then. + // if (lj < mini) break; GUDHI_CHECK(lj <= li, "Bad furthest point sorting"); Filtration_value alpha; diff --git a/src/python/test/test_rips_complex.py b/src/python/test/test_rips_complex.py index b86e7498..cae21435 100755 --- a/src/python/test/test_rips_complex.py +++ b/src/python/test/test_rips_complex.py @@ -133,3 +133,24 @@ def test_filtered_rips_from_distance_matrix(): assert simplex_tree.num_simplices() == 8 assert simplex_tree.num_vertices() == 4 + + +def test_sparse_with_multiplicity(): + points = [ + [3, 4], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [0.1, 2], + [3, 4.1], + ] + rips = RipsComplex(points=points, sparse=0.01) + simplex_tree = rips.create_simplex_tree(max_dimension=2) + assert simplex_tree.num_simplices() == 25 + diag = simplex_tree.persistence() -- cgit v1.2.3 From 21741a3a415d6bc1b552c5b621f02a50db771c22 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 17 Apr 2021 16:54:09 +0200 Subject: Don't qualify calls for the graph concept --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 85d6c3b0..85790baf 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -1060,8 +1060,8 @@ class Simplex_tree { * * Inserts all vertices and edges given by a OneSkeletonGraph. * OneSkeletonGraph must be a model of - * boost::EdgeListGraph - * and boost::PropertyGraph. + * boost::VertexAndEdgeListGraph + * and boost::PropertyGraph. * * The vertex filtration value is accessible through the property tag * vertex_filtration_t. @@ -1081,7 +1081,10 @@ class Simplex_tree { // the simplex tree must be empty assert(num_simplices() == 0); - if (boost::num_vertices(skel_graph) == 0) { + // is there a better way to let the compiler know that we don't mean Simplex_tree::num_vertices? + using boost::num_vertices; + + if (num_vertices(skel_graph) == 0) { return; } if (num_edges(skel_graph) == 0) { @@ -1090,18 +1093,18 @@ class Simplex_tree { dimension_ = 1; } - root_.members_.reserve(boost::num_vertices(skel_graph)); + root_.members_.reserve(num_vertices(skel_graph)); typename boost::graph_traits::vertex_iterator v_it, v_it_end; - for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end; + for (std::tie(v_it, v_it_end) = vertices(skel_graph); v_it != v_it_end; ++v_it) { root_.members_.emplace_hint( root_.members_.end(), *v_it, - Node(&root_, boost::get(vertex_filtration_t(), skel_graph, *v_it))); + Node(&root_, get(vertex_filtration_t(), skel_graph, *v_it))); } std::pair::edge_iterator, - typename boost::graph_traits::edge_iterator> boost_edges = boost::edges(skel_graph); + typename boost::graph_traits::edge_iterator> boost_edges = edges(skel_graph); // boost_edges.first is the equivalent to boost_edges.begin() // boost_edges.second is the equivalent to boost_edges.end() for (; boost_edges.first != boost_edges.second; boost_edges.first++) { @@ -1123,7 +1126,7 @@ class Simplex_tree { } sh->second.children()->members().emplace(v, - Node(sh->second.children(), boost::get(edge_filtration_t(), skel_graph, edge))); + Node(sh->second.children(), get(edge_filtration_t(), skel_graph, edge))); } } -- cgit v1.2.3 From 20bee15a2e7dc68deb3141ebab7a30a3edcfb401 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 17 Apr 2021 16:54:38 +0200 Subject: Introduce a custom graph type --- .../include/gudhi/Sparse_rips_complex.h | 76 ++++++++++++++++++---- 1 file changed, 63 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h index d7669dad..30afb1d0 100644 --- a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h +++ b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h @@ -17,9 +17,68 @@ #include #include +#include #include +namespace Gudhi { +namespace rips_complex { +// A custom graph class, because boost::adjacency_list does not conveniently allow to choose vertex descriptors +template +struct Graph { + typedef std::vector VList; + typedef std::vector> EList; + typedef typename VList::const_iterator vertex_iterator; + typedef boost::counting_iterator edge_iterator; + VList vlist; + EList elist; +}; +template +void add_vertex(Vertex_handle v, Graph&g) { g.vlist.push_back(v); } +template +void add_edge(Vertex_handle u, Vertex_handle v, Filtration_value f, Graph&g) { g.elist.emplace_back(u, v, f); } +template +std::size_t num_vertices(Graph const&g) { return g.vlist.size(); } +template +std::size_t num_edges(Graph const&g) { return g.elist.size(); } +template ::vertex_iterator> +std::pair +vertices(Graph const&g) { + return { g.vlist.begin(), g.vlist.end() }; +} +template +std::pair, boost::counting_iterator> +edges(Graph const&g) { + typedef boost::counting_iterator I; + return { I(0), I(g.elist.size()) }; +} +template +std::size_t source(std::size_t e, Graph const&g) { return std::get<0>(g.elist[e]); } +template +std::size_t target(std::size_t e, Graph const&g) { return std::get<1>(g.elist[e]); } +template +Filtration_value get(vertex_filtration_t, Graph const&, Vertex_handle) { return 0; } +template +Filtration_value get(edge_filtration_t, Graph const&g, std::size_t e) { return std::get<2>(g.elist[e]); } +} // namespace rips_complex +} // namespace Gudhi +namespace boost { +template +struct graph_traits> { + typedef Gudhi::rips_complex::Graph G; + struct traversal_category : vertex_list_graph_tag, edge_list_graph_tag {}; + typedef Vertex_handle vertex_descriptor; + typedef typename G::vertex_iterator vertex_iterator; + typedef std::size_t vertices_size_type; + typedef std::size_t edge_descriptor; + typedef typename G::edge_iterator edge_iterator; + typedef std::size_t edges_size_type; + typedef directed_tag directed_category; + typedef disallow_parallel_edge_tag edge_parallel_category; +}; +// Etc, since we don't expose this graph to the world, we know we are not going to query property_traits. +} + namespace Gudhi { namespace rips_complex { @@ -45,13 +104,8 @@ template class Sparse_rips_complex { private: // TODO(MG): use a different graph where we know we can safely insert in parallel. - // Use a graph that lets us skip some vertices, for `mini` or redundant points. - typedef typename boost::adjacency_list, - boost::property> - Graph; - typedef int Vertex_handle; + typedef rips_complex::Graph Graph; public: /** \brief Sparse_rips_complex constructor from a list of points. @@ -137,13 +191,9 @@ class Sparse_rips_complex { const int n = boost::size(points); double cst = epsilon * (1 - epsilon) / 2; graph_.~Graph(); - new (&graph_) Graph(n); - // for(auto v : vertices(g)) // doesn't work :-( - typename boost::graph_traits::vertex_iterator v_i, v_e; - for (std::tie(v_i, v_e) = vertices(graph_); v_i != v_e; ++v_i) { - auto v = *v_i; - // This whole loop might not be necessary, leave it until someone investigates if it is safe to remove. - put(vertex_filtration_t(), graph_, v, 0); + new (&graph_) Graph(); + for (int i = 0; i < n; ++i) { + add_vertex(i, graph_); } // TODO(MG): -- cgit v1.2.3 From 71337179d95d1e330902b431907cb07698abcdc9 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 17 Apr 2021 17:31:23 +0200 Subject: Safely drop some vertices in sparse Rips --- .../include/gudhi/Sparse_rips_complex.h | 48 ++++++++++------------ src/python/test/test_rips_complex.py | 2 +- 2 files changed, 23 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h index 30afb1d0..28031e68 100644 --- a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h +++ b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h @@ -76,7 +76,7 @@ struct graph_traits> typedef directed_tag directed_category; typedef disallow_parallel_edge_tag edge_parallel_category; }; -// Etc, since we don't expose this graph to the world, we know we are not going to query property_traits. +// Etc, since we don't expose this graph to the world, we know we are not going to query property_traits for instance. } namespace Gudhi { @@ -113,8 +113,7 @@ class Sparse_rips_complex { * @param[in] points Range of points. * @param[in] distance Distance function that returns a `Filtration_value` from 2 given points. * @param[in] epsilon Approximation parameter. epsilon must be positive. - * @param[in] mini Not implemented yet, and broken in previous versions. Minimal filtration value. - * Ignore anything below this scale. This is a less efficient version of `Gudhi::subsampling::sparsify_point_set()`. + * @param[in] mini Minimal filtration value. Ignore anything below this scale. This is a less efficient version of `Gudhi::subsampling::sparsify_point_set()`. * @param[in] maxi Maximal filtration value. Ignore anything above this scale. * */ @@ -123,7 +122,7 @@ class Sparse_rips_complex { : epsilon_(epsilon) { GUDHI_CHECK(epsilon > 0, "epsilon must be positive"); auto dist_fun = [&](Vertex_handle i, Vertex_handle j) { return distance(points[i], points[j]); }; - // TODO: stop choose_n_farthest_points once it reaches mini? Then the graph vertices would not be [0, ..., n-1] which complicates things. + // TODO: stop choose_n_farthest_points once it reaches mini or 0? subsampling::choose_n_farthest_points(dist_fun, boost::irange(0, boost::size(points)), -1, -1, std::back_inserter(sorted_points), std::back_inserter(params)); compute_sparse_graph(dist_fun, epsilon, mini, maxi); @@ -165,10 +164,10 @@ class Sparse_rips_complex { complex.expansion(dim_max); return; } - const int n = boost::size(params); - std::vector lambda(n); + const Vertex_handle n = num_vertices(graph_); + std::vector lambda(max_v + 1); // lambda[original_order]=params[sorted_order] - for(int i=0;i void compute_sparse_graph(Distance& dist, double epsilon, Filtration_value mini, Filtration_value maxi) { const auto& points = sorted_points; // convenience alias - const int n = boost::size(points); + Vertex_handle n = boost::size(points); double cst = epsilon * (1 - epsilon) / 2; - graph_.~Graph(); - new (&graph_) Graph(); - for (int i = 0; i < n; ++i) { - add_vertex(i, graph_); + max_v = -1; // Useful for the size of the map lambda. + for (Vertex_handle i = 0; i < n; ++i) { + if ((params[i] < mini || params[i] <= 0) && i != 0) break; + // The parameter of the first point is not very meaningful, it is supposed to be infinite, + // but if the type does not support it... + // It would be better to do this reduction of the number of points earlier, around choose_n_farthest_points. + add_vertex(points[i], graph_); + max_v = std::max(max_v, points[i]); } + n = num_vertices(graph_); // TODO(MG): // - make it parallel // - only test near-enough neighbors - for (int i = 0; i < n; ++i) { + for (Vertex_handle i = 0; i < n; ++i) { auto&& pi = points[i]; auto li = params[i]; - // FIXME: see below about mini. It might be ok to uncomment just this one, but it requires a proof. - // if ((li < mini || li <= 0) && i != 0) break; - if (li <= 0 && i != 0) break; - // The parameter of the first point is not very meaningful, it is supposed to be infinite, - // but if the type does not support it... - // Points with multiplicity get connected to their first representative, no need to handle - // the redundant ones in the outer loop. - for (int j = i + 1; j < n; ++j) { + // If we inserted all the points, points with multiplicity would get connected to their first representative, + // no need to handle the redundant ones in the outer loop. + // if (li <= 0 && i != 0) break; + for (Vertex_handle j = i + 1; j < n; ++j) { auto&& pj = points[j]; auto d = dist(pi, pj); auto lj = params[j]; - // FIXME: It would make sense to ignore the points with low param completely, but the current graph type we are - // using implicitly inserts all the vertices 0 ... n-1, so this would create isolated vertices, which is bad. - // If we do end up ignoring those points, we should do it early, around choose_n_farthest_points. But be careful - // that the size of lambda should reflect the original number of points then. - // if (lj < mini) break; GUDHI_CHECK(lj <= li, "Bad furthest point sorting"); Filtration_value alpha; @@ -241,6 +236,7 @@ class Sparse_rips_complex { Graph graph_; double epsilon_; + Vertex_handle max_v; // Because of the arbitrary split between constructor and create_complex // sorted_points[sorted_order]=original_order std::vector sorted_points; diff --git a/src/python/test/test_rips_complex.py b/src/python/test/test_rips_complex.py index cae21435..a2f43a1b 100755 --- a/src/python/test/test_rips_complex.py +++ b/src/python/test/test_rips_complex.py @@ -152,5 +152,5 @@ def test_sparse_with_multiplicity(): ] rips = RipsComplex(points=points, sparse=0.01) simplex_tree = rips.create_simplex_tree(max_dimension=2) - assert simplex_tree.num_simplices() == 25 + assert simplex_tree.num_simplices() == 7 diag = simplex_tree.persistence() -- cgit v1.2.3 From 604b2cde0c7951c81d1c510f3038e2c65c19e6fe Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 20 Apr 2021 19:06:56 +0200 Subject: update doc and tests --- src/python/doc/wasserstein_distance_user.rst | 1 + src/python/test/test_wasserstein_distance.py | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index 091c9fd9..76eb1469 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -92,6 +92,7 @@ any matching has a cost +inf and thus can be considered to be optimal. In such a for j in dgm2_to_diagonal: print("point %s in dgm2 is matched to the diagonal" %j) + # An example where essential part cardinalities differ dgm3 = np.array([[1, 2], [0, np.inf]]) dgm4 = np.array([[1, 2], [0, np.inf], [1, np.inf]]) cost, matchings = gudhi.wasserstein.wasserstein_distance(dgm3, dgm4, matching=True, order=1, internal_p=2) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index df7acc91..121ba065 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -67,16 +67,25 @@ def test_handle_essential_parts(): def test_get_essential_parts(): - diag = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], + diag1 = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf], [-np.inf, 8], [-np.inf, 12], [-np.inf, -np.inf], [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) - res = _get_essential_parts(diag) + diag2 = np.array([[0, 1], [3, 5], [2, np.inf], [3, np.inf]]) + + res = _get_essential_parts(diag1) + res2 = _get_essential_parts(diag2) assert np.array_equal(res[0], [4, 5]) assert np.array_equal(res[1], [2, 3]) assert np.array_equal(res[2], [8, 9]) assert np.array_equal(res[3], [6] ) assert np.array_equal(res[4], [7] ) + assert np.array_equal(res2[0], [] ) + assert np.array_equal(res2[1], [2, 3]) + assert np.array_equal(res2[2], [] ) + assert np.array_equal(res2[3], [] ) + assert np.array_equal(res2[4], [] ) + def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_matching=True): diag1 = np.array([[2.7, 3.7], [9.6, 14.0], [34.2, 34.974]]) @@ -152,7 +161,7 @@ def pot_wrap(**extra): return fun def test_wasserstein_distance_pot(): - _basic_wasserstein(pot, 1e-15, test_infinity=False, test_matching=True) + _basic_wasserstein(pot, 1e-15, test_infinity=False, test_matching=True) # pot with its standard args _basic_wasserstein(pot_wrap(enable_autodiff=True, keep_essential_parts=False), 1e-15, test_infinity=False, test_matching=False) def test_wasserstein_distance_hera(): -- cgit v1.2.3 From e3865868cd36f27e57f75be64749429773a1734f Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 20 Apr 2021 21:54:35 +0200 Subject: Targeted include, more const --- src/Rips_complex/include/gudhi/Sparse_rips_complex.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h index 28031e68..9c5993c5 100644 --- a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h +++ b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include @@ -118,7 +118,7 @@ class Sparse_rips_complex { * */ template - Sparse_rips_complex(const RandomAccessPointRange& points, Distance distance, double epsilon, Filtration_value mini=-std::numeric_limits::infinity(), Filtration_value maxi=std::numeric_limits::infinity()) + Sparse_rips_complex(const RandomAccessPointRange& points, Distance distance, double const epsilon, Filtration_value const mini=-std::numeric_limits::infinity(), Filtration_value const maxi=std::numeric_limits::infinity()) : epsilon_(epsilon) { GUDHI_CHECK(epsilon > 0, "epsilon must be positive"); auto dist_fun = [&](Vertex_handle i, Vertex_handle j) { return distance(points[i], points[j]); }; @@ -139,7 +139,7 @@ class Sparse_rips_complex { * @param[in] maxi Maximal filtration value. Ignore anything above this scale. */ template - Sparse_rips_complex(const DistanceMatrix& distance_matrix, double epsilon, Filtration_value mini=-std::numeric_limits::infinity(), Filtration_value maxi=std::numeric_limits::infinity()) + Sparse_rips_complex(const DistanceMatrix& distance_matrix, double const epsilon, Filtration_value const mini=-std::numeric_limits::infinity(), Filtration_value const maxi=std::numeric_limits::infinity()) : Sparse_rips_complex(boost::irange(0, boost::size(distance_matrix)), [&](Vertex_handle i, Vertex_handle j) { return (i==j) ? 0 : (i - void create_complex(SimplicialComplexForRips& complex, int dim_max) { + void create_complex(SimplicialComplexForRips& complex, int const dim_max) { GUDHI_CHECK(complex.num_vertices() == 0, std::invalid_argument("Sparse_rips_complex::create_complex - simplicial complex is not empty")); @@ -185,7 +185,7 @@ class Sparse_rips_complex { private: // PointRange must be random access. template - void compute_sparse_graph(Distance& dist, double epsilon, Filtration_value mini, Filtration_value maxi) { + void compute_sparse_graph(Distance& dist, double const epsilon, Filtration_value const mini, Filtration_value const maxi) { const auto& points = sorted_points; // convenience alias Vertex_handle n = boost::size(points); double cst = epsilon * (1 - epsilon) / 2; -- cgit v1.2.3 From 2ca42207529f0f21c2cb1392ebfd2b5f41882b60 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 20 Apr 2021 22:39:41 +0200 Subject: Vertex_handle -> size_t --- src/Rips_complex/include/gudhi/Sparse_rips_complex.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h index 9c5993c5..8024f92d 100644 --- a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h +++ b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h @@ -164,10 +164,10 @@ class Sparse_rips_complex { complex.expansion(dim_max); return; } - const Vertex_handle n = num_vertices(graph_); + const std::size_t n = num_vertices(graph_); std::vector lambda(max_v + 1); // lambda[original_order]=params[sorted_order] - for(Vertex_handle i=0;i void compute_sparse_graph(Distance& dist, double const epsilon, Filtration_value const mini, Filtration_value const maxi) { const auto& points = sorted_points; // convenience alias - Vertex_handle n = boost::size(points); + std::size_t n = boost::size(points); double cst = epsilon * (1 - epsilon) / 2; max_v = -1; // Useful for the size of the map lambda. - for (Vertex_handle i = 0; i < n; ++i) { + for (std::size_t i = 0; i < n; ++i) { if ((params[i] < mini || params[i] <= 0) && i != 0) break; // The parameter of the first point is not very meaningful, it is supposed to be infinite, // but if the type does not support it... @@ -203,13 +203,13 @@ class Sparse_rips_complex { // TODO(MG): // - make it parallel // - only test near-enough neighbors - for (Vertex_handle i = 0; i < n; ++i) { + for (std::size_t i = 0; i < n; ++i) { auto&& pi = points[i]; auto li = params[i]; // If we inserted all the points, points with multiplicity would get connected to their first representative, // no need to handle the redundant ones in the outer loop. // if (li <= 0 && i != 0) break; - for (Vertex_handle j = i + 1; j < n; ++j) { + for (std::size_t j = i + 1; j < n; ++j) { auto&& pj = points[j]; auto d = dist(pi, pj); auto lj = params[j]; -- 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 0360f02ec1778daae53b50c50f223049fa294328 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Wed, 21 Apr 2021 10:26:05 +0200 Subject: typo corrected --- src/python/gudhi/wasserstein/wasserstein.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 8ccbe12e..a89c7efd 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -198,7 +198,7 @@ def _warn_infty(matching): warnings.warn('Cardinality of essential parts differs. Distance (cost) is +infty, and the returned matching is None.') return np.inf, None else: - warnings.warn('Cardinality of essential parts diffes. Distance (cost) is +infty.') + warnings.warn('Cardinality of essential parts differs. Distance (cost) is +infty.') return np.inf -- 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 bf4625f877aee83325812c6c479af4df36a2c7e9 Mon Sep 17 00:00:00 2001 From: Hind Date: Thu, 22 Apr 2021 16:14:43 +0200 Subject: Replace hardcoded PI with M_PI from cmath --- src/common/include/gudhi/random_point_generators.h | 39 +++++++++++----------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/common/include/gudhi/random_point_generators.h b/src/common/include/gudhi/random_point_generators.h index 9dd88ac4..e02c1ed2 100644 --- a/src/common/include/gudhi/random_point_generators.h +++ b/src/common/include/gudhi/random_point_generators.h @@ -18,6 +18,7 @@ #include // for CGAL_VERSION_NR #include // for vector<> +#include // for M_PI // Make compilation fail - required for external projects - https://github.com/GUDHI/gudhi-devel/issues/10 #if CGAL_VERSION_NR < 1041101000 @@ -164,11 +165,11 @@ std::vector generate_points_on_torus_3D(std::size_t nu if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 6.2832 * k1 / num_lines; - v = 6.2832 * k2 / num_lines; + u = 2 * M_PI * k1 / num_lines; + v = 2 * M_PI * k2 / num_lines; } else { - u = rng.get_double(0, 6.2832); - v = rng.get_double(0, 6.2832); + u = rng.get_double(0, 2 * M_PI); + v = rng.get_double(0, 2 * M_PI); } Point p = construct_point(k, (R + r * std::cos(u)) * std::cos(v), @@ -200,7 +201,7 @@ static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::si (100. + radius_noise_percentage) / 100.); } std::vector cp2 = current_point; - double alpha = 6.2832 * slice_idx / num_slices; + double alpha = 2 * M_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( @@ -234,7 +235,7 @@ std::vector generate_points_on_torus_d(std::size_t num std::vector pt; pt.reserve(dim * 2); for (int curdim = 0; curdim < dim; ++curdim) { - FT alpha = rng.get_double(0, 6.2832); + FT alpha = rng.get_double(0, 2 * M_PI); pt.push_back(radius_noise_ratio * std::cos(alpha)); pt.push_back(radius_noise_ratio * std::sin(alpha)); } @@ -370,7 +371,7 @@ std::vector generate_points_on_3sphere_and_circle(std: for (std::size_t i = 0; i < num_points;) { Point p_sphere = *generator++; // First 3 coords - FT alpha = rng.get_double(0, 6.2832); + FT alpha = rng.get_double(0, 2 * M_PI); std::vector pt(5); pt[0] = k_coord(p_sphere, 0); pt[1] = k_coord(p_sphere, 1); @@ -403,11 +404,11 @@ std::vector generate_points_on_klein_bottle_3D(std::si if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 6.2832 * k1 / num_lines; - v = 6.2832 * k2 / num_lines; + u = 2 * M_PI * k1 / num_lines; + v = 2 * M_PI * k2 / num_lines; } else { - u = rng.get_double(0, 6.2832); - v = rng.get_double(0, 6.2832); + u = rng.get_double(0, 2 * M_PI); + v = rng.get_double(0, 2 * M_PI); } double tmp = cos(u / 2) * sin(v) - sin(u / 2) * sin(2. * v); Point p = construct_point(k, @@ -439,11 +440,11 @@ std::vector generate_points_on_klein_bottle_4D(std::si if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 6.2832 * k1 / num_lines; - v = 6.2832 * k2 / num_lines; + u = 2 * M_PI * k1 / num_lines; + v = 2 * M_PI * k2 / num_lines; } else { - u = rng.get_double(0, 6.2832); - v = rng.get_double(0, 6.2832); + u = rng.get_double(0, 2 * M_PI); + v = rng.get_double(0, 2 * M_PI); } Point p = construct_point(k, (a + b * cos(v)) * cos(u) + (noise == 0. ? 0. : rng.get_double(0, noise)), @@ -478,11 +479,11 @@ generate_points_on_klein_bottle_variant_5D( if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 6.2832 * k1 / num_lines; - v = 6.2832 * k2 / num_lines; + u = 2 * M_PI * k1 / num_lines; + v = 2 * M_PI * k2 / num_lines; } else { - u = rng.get_double(0, 6.2832); - v = rng.get_double(0, 6.2832); + u = rng.get_double(0, 2 * M_PI); + v = rng.get_double(0, 2 * M_PI); } FT x1 = (a + b * cos(v)) * cos(u); FT x2 = (a + b * cos(v)) * sin(u); -- cgit v1.2.3 From 45917ecf17acacfede909994d7b3a78fc18355da Mon Sep 17 00:00:00 2001 From: Hind Date: Thu, 22 Apr 2021 17:08:17 +0200 Subject: Add random points generator on sphere in python, with an example --- src/python/CMakeLists.txt | 6 ++ .../alpha_complex_from_generated_points_example.py | 52 +++++++++++++++++ src/python/gudhi/random_point_generators.cc | 68 ++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 src/python/example/alpha_complex_from_generated_points_example.py create mode 100644 src/python/gudhi/random_point_generators.cc (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 73303a24..8baf0f02 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -43,6 +43,7 @@ endfunction( add_gudhi_debug_info ) if(PYTHONINTERP_FOUND) if(PYBIND11_FOUND) add_gudhi_debug_info("Pybind11 version ${PYBIND11_VERSION}") + set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'random_point_generators', ") 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', ") @@ -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}'random_point_generators', ") set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'bottleneck', ") set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'nerve_gic', ") endif () @@ -425,6 +427,10 @@ if(PYTHONINTERP_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") + add_test(NAME alpha_complex_from_generated_points_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_generated_points_example.py") add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" diff --git a/src/python/example/alpha_complex_from_generated_points_example.py b/src/python/example/alpha_complex_from_generated_points_example.py new file mode 100644 index 00000000..7a07ed42 --- /dev/null +++ b/src/python/example/alpha_complex_from_generated_points_example.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +from gudhi import random_point_generators +from gudhi import AlphaComplex, SimplexTree +from gudhi import plot_persistence_barcode, plot_persistence_diagram + +import matplotlib.pyplot as plt + + +""" 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 +""" + +__author__ = "Hind Montassif" +__copyright__ = "Copyright (C) 2021 Inria" +__license__ = "MIT" + +print("#####################################################################") +print("AlphaComplex creation from generated points") + + +# Generate a circle: 50 points; dim 2; radius 1 +points = random_point_generators.generate_points_on_sphere_d(50, 2, 1) + +# Plot the generated points (to uncomment if wished) +#plt.scatter(points[:,0], points[:,1]) +#plt.show() + +# Create an alpha complex +alpha_complex = AlphaComplex(points=points) +simplex_tree = alpha_complex.create_simplex_tree() + +result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ + repr(simplex_tree.num_simplices()) + ' simplices - ' + \ + repr(simplex_tree.num_vertices()) + ' vertices.' +print(result_str) + + +# Compute the persistence +diag = simplex_tree.persistence() + +# Plot the barcode and diagram (to uncomment if wished) +#plot_persistence_barcode(diag) +#plt.show() +#plot_persistence_diagram(diag) +#plt.show() diff --git a/src/python/gudhi/random_point_generators.cc b/src/python/gudhi/random_point_generators.cc new file mode 100644 index 00000000..39b09a6d --- /dev/null +++ b/src/python/gudhi/random_point_generators.cc @@ -0,0 +1,68 @@ +/* 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 + +namespace py = pybind11; + + +typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; + +template +py::array_t generate_points_on_sphere(py::object num_points, py::object dim, py::object radius) { + int npoints = num_points.cast(); + int d = dim.cast(); + double rad = radius.cast(); + + py::gil_scoped_release release; + + auto points_generated = Gudhi::generate_points_on_sphere_d(npoints, d, rad); + + py::gil_scoped_acquire acquire; + + py::array_t points({npoints, d}); + + py::buffer_info buf = points.request(); + + double *ptr = static_cast(buf.ptr); + + assert(npoints == buf.shape[0]); + assert(d == buf.shape[1]); + + + for (size_t i = 0; i < (size_t)npoints; i++) + for (size_t j = 0; j < (size_t)d; j++) + ptr[i*d+j] = points_generated.at(i).at(j); + + return points; +} + +PYBIND11_MODULE(random_point_generators, m) { + m.attr("__license__") = "LGPL v3"; + m.def("generate_points_on_sphere_d", &generate_points_on_sphere, + py::arg("num_points"), py::arg("dim"), py::arg("radius"), + R"pbdoc( + Generate points on a sphere + + :param num_points: The number of points to be generated. + :type num_points: integer + :param dim: The sphere dimension. + :type dim: integer + :param radius: The sphere radius. + :type radius: float + :rtype: numpy array of points + :returns: the generated points on a sphere. + )pbdoc"); +} -- cgit v1.2.3 From 33cb5826e62abf8dd84d2adb59d99fc1f54a2aa1 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 22 Apr 2021 22:16:33 +0200 Subject: Fix return type of source/target --- src/Rips_complex/include/gudhi/Sparse_rips_complex.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h index 8024f92d..7ae7b317 100644 --- a/src/Rips_complex/include/gudhi/Sparse_rips_complex.h +++ b/src/Rips_complex/include/gudhi/Sparse_rips_complex.h @@ -53,9 +53,9 @@ edges(Graph const&g) { return { I(0), I(g.elist.size()) }; } template -std::size_t source(std::size_t e, Graph const&g) { return std::get<0>(g.elist[e]); } +Vertex_handle source(std::size_t e, Graph const&g) { return std::get<0>(g.elist[e]); } template -std::size_t target(std::size_t e, Graph const&g) { return std::get<1>(g.elist[e]); } +Vertex_handle target(std::size_t e, Graph const&g) { return std::get<1>(g.elist[e]); } template Filtration_value get(vertex_filtration_t, Graph const&, Vertex_handle) { return 0; } template -- cgit v1.2.3 From 9df34f942df8417db11c324fb0c4e2c475a5211f Mon Sep 17 00:00:00 2001 From: Hind Date: Fri, 23 Apr 2021 09:41:29 +0200 Subject: Get pi constant from boost instead of cmath (to be replaced with the C++20 standard one eventually) --- src/common/include/gudhi/random_point_generators.h | 42 +++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/common/include/gudhi/random_point_generators.h b/src/common/include/gudhi/random_point_generators.h index e02c1ed2..25a10232 100644 --- a/src/common/include/gudhi/random_point_generators.h +++ b/src/common/include/gudhi/random_point_generators.h @@ -18,7 +18,7 @@ #include // for CGAL_VERSION_NR #include // for vector<> -#include // for M_PI +#include // for pi constant // Make compilation fail - required for external projects - https://github.com/GUDHI/gudhi-devel/issues/10 #if CGAL_VERSION_NR < 1041101000 @@ -27,6 +27,8 @@ namespace Gudhi { +constexpr double pi = boost::math::constants::pi(); + /////////////////////////////////////////////////////////////////////////////// // Note: All these functions have been tested with the CGAL::Epick_d kernel /////////////////////////////////////////////////////////////////////////////// @@ -165,11 +167,11 @@ std::vector generate_points_on_torus_3D(std::size_t nu if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * M_PI * k1 / num_lines; - v = 2 * M_PI * k2 / num_lines; + u = 2 * pi * k1 / num_lines; + v = 2 * pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * M_PI); - v = rng.get_double(0, 2 * M_PI); + u = rng.get_double(0, 2 * pi); + v = rng.get_double(0, 2 * pi); } Point p = construct_point(k, (R + r * std::cos(u)) * std::cos(v), @@ -201,7 +203,7 @@ static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::si (100. + radius_noise_percentage) / 100.); } std::vector cp2 = current_point; - double alpha = 2 * M_PI * slice_idx / num_slices; + double alpha = 2 * 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( @@ -235,7 +237,7 @@ std::vector generate_points_on_torus_d(std::size_t num std::vector pt; pt.reserve(dim * 2); for (int curdim = 0; curdim < dim; ++curdim) { - FT alpha = rng.get_double(0, 2 * M_PI); + FT alpha = rng.get_double(0, 2 * pi); pt.push_back(radius_noise_ratio * std::cos(alpha)); pt.push_back(radius_noise_ratio * std::sin(alpha)); } @@ -371,7 +373,7 @@ std::vector generate_points_on_3sphere_and_circle(std: for (std::size_t i = 0; i < num_points;) { Point p_sphere = *generator++; // First 3 coords - FT alpha = rng.get_double(0, 2 * M_PI); + FT alpha = rng.get_double(0, 2 * pi); std::vector pt(5); pt[0] = k_coord(p_sphere, 0); pt[1] = k_coord(p_sphere, 1); @@ -404,11 +406,11 @@ std::vector generate_points_on_klein_bottle_3D(std::si if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * M_PI * k1 / num_lines; - v = 2 * M_PI * k2 / num_lines; + u = 2 * pi * k1 / num_lines; + v = 2 * pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * M_PI); - v = rng.get_double(0, 2 * M_PI); + u = rng.get_double(0, 2 * pi); + v = rng.get_double(0, 2 * pi); } double tmp = cos(u / 2) * sin(v) - sin(u / 2) * sin(2. * v); Point p = construct_point(k, @@ -440,11 +442,11 @@ std::vector generate_points_on_klein_bottle_4D(std::si if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * M_PI * k1 / num_lines; - v = 2 * M_PI * k2 / num_lines; + u = 2 * pi * k1 / num_lines; + v = 2 * pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * M_PI); - v = rng.get_double(0, 2 * M_PI); + u = rng.get_double(0, 2 * pi); + v = rng.get_double(0, 2 * pi); } Point p = construct_point(k, (a + b * cos(v)) * cos(u) + (noise == 0. ? 0. : rng.get_double(0, noise)), @@ -479,11 +481,11 @@ generate_points_on_klein_bottle_variant_5D( if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * M_PI * k1 / num_lines; - v = 2 * M_PI * k2 / num_lines; + u = 2 * pi * k1 / num_lines; + v = 2 * pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * M_PI); - v = rng.get_double(0, 2 * M_PI); + u = rng.get_double(0, 2 * pi); + v = rng.get_double(0, 2 * pi); } FT x1 = (a + b * cos(v)) * cos(u); FT x2 = (a + b * cos(v)) * sin(u); -- cgit v1.2.3 From db7ce3487e526741c0408b00c2cffda0048b0026 Mon Sep 17 00:00:00 2001 From: Hind Date: Fri, 23 Apr 2021 11:27:59 +0200 Subject: Make adjustments according to the received reviews --- src/python/CMakeLists.txt | 2 +- src/python/gudhi/random_point_generators.cc | 45 +++++++++++++---------------- 2 files changed, 21 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 8baf0f02..87f10a1a 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -43,10 +43,10 @@ endfunction( add_gudhi_debug_info ) if(PYTHONINTERP_FOUND) if(PYBIND11_FOUND) add_gudhi_debug_info("Pybind11 version ${PYBIND11_VERSION}") - set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'random_point_generators', ") 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}'random_point_generators', ") endif() if(CYTHON_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'off_reader', ") diff --git a/src/python/gudhi/random_point_generators.cc b/src/python/gudhi/random_point_generators.cc index 39b09a6d..4306ba98 100644 --- a/src/python/gudhi/random_point_generators.cc +++ b/src/python/gudhi/random_point_generators.cc @@ -21,30 +21,25 @@ namespace py = pybind11; typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; template -py::array_t generate_points_on_sphere(py::object num_points, py::object dim, py::object radius) { - int npoints = num_points.cast(); - int d = dim.cast(); - double rad = radius.cast(); - - py::gil_scoped_release release; - - auto points_generated = Gudhi::generate_points_on_sphere_d(npoints, d, rad); - - py::gil_scoped_acquire acquire; - - py::array_t points({npoints, d}); +py::array_t generate_points_on_sphere(size_t num_points, int dim, double radius) { + + py::array_t points({(int)num_points, dim}); py::buffer_info buf = points.request(); - double *ptr = static_cast(buf.ptr); - assert(npoints == buf.shape[0]); - assert(d == buf.shape[1]); + assert(num_points == buf.shape[0]); + assert(dim == buf.shape[1]); - - for (size_t i = 0; i < (size_t)npoints; i++) - for (size_t j = 0; j < (size_t)d; j++) - ptr[i*d+j] = points_generated.at(i).at(j); + std::vector points_generated; + { + py::gil_scoped_release release; + points_generated = Gudhi::generate_points_on_sphere_d(num_points, dim, radius); + + for (size_t i = 0; i < num_points; i++) + for (size_t j = 0; j < (size_t)dim; j++) + ptr[i*dim+j] = points_generated[i][j]; + } return points; } @@ -52,17 +47,17 @@ py::array_t generate_points_on_sphere(py::object num_points, py::object PYBIND11_MODULE(random_point_generators, m) { m.attr("__license__") = "LGPL v3"; m.def("generate_points_on_sphere_d", &generate_points_on_sphere, - py::arg("num_points"), py::arg("dim"), py::arg("radius"), + py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, R"pbdoc( - Generate points on a sphere + Generate random i.i.d. points uniformly on a (d-1)-sphere in Rd :param num_points: The number of points to be generated. - :type num_points: integer - :param dim: The sphere dimension. + :type num_points: unsigned integer + :param dim: The dimension. :type dim: integer - :param radius: The sphere radius. + :param radius: The radius. :type radius: float - :rtype: numpy array of points + :rtype: numpy array of float :returns: the generated points on a sphere. )pbdoc"); } -- cgit v1.2.3 From 245354222ed6090f9828dba24b3db9ad17f8dfbf Mon Sep 17 00:00:00 2001 From: Hind Date: Fri, 23 Apr 2021 15:17:28 +0200 Subject: Use double_constants instead of templated constants Use the boost double_constants namespace in each function that needs two_pi --- src/common/include/gudhi/random_point_generators.h | 54 +++++++++++++--------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/common/include/gudhi/random_point_generators.h b/src/common/include/gudhi/random_point_generators.h index 25a10232..33fb182d 100644 --- a/src/common/include/gudhi/random_point_generators.h +++ b/src/common/include/gudhi/random_point_generators.h @@ -27,8 +27,6 @@ namespace Gudhi { -constexpr double pi = boost::math::constants::pi(); - /////////////////////////////////////////////////////////////////////////////// // Note: All these functions have been tested with the CGAL::Epick_d kernel /////////////////////////////////////////////////////////////////////////////// @@ -152,6 +150,8 @@ std::vector generate_points_on_moment_curve(std::size_ template std::vector generate_points_on_torus_3D(std::size_t num_points, double R, double r, bool uniform = false) { + using namespace boost::math::double_constants; + typedef typename Kernel::Point_d Point; typedef typename Kernel::FT FT; Kernel k; @@ -167,11 +167,11 @@ std::vector generate_points_on_torus_3D(std::size_t nu if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * pi * k1 / num_lines; - v = 2 * pi * k2 / num_lines; + u = two_pi * k1 / num_lines; + v = two_pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * pi); - v = rng.get_double(0, 2 * pi); + u = rng.get_double(0, two_pi); + v = rng.get_double(0, two_pi); } Point p = construct_point(k, (R + r * std::cos(u)) * std::cos(v), @@ -190,6 +190,8 @@ static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::si double radius_noise_percentage = 0., std::vector current_point = std::vector()) { + using namespace boost::math::double_constants; + CGAL::Random rng; int point_size = static_cast(current_point.size()); if (point_size == 2 * dim) { @@ -203,7 +205,7 @@ static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::si (100. + radius_noise_percentage) / 100.); } std::vector cp2 = current_point; - double alpha = 2 * pi * slice_idx / num_slices; + 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( @@ -215,6 +217,8 @@ static void generate_uniform_points_on_torus_d(const Kernel &k, int dim, std::si template std::vector generate_points_on_torus_d(std::size_t num_points, int dim, bool uniform = false, double radius_noise_percentage = 0.) { + using namespace boost::math::double_constants; + typedef typename Kernel::Point_d Point; typedef typename Kernel::FT FT; Kernel k; @@ -237,7 +241,7 @@ std::vector generate_points_on_torus_d(std::size_t num std::vector pt; pt.reserve(dim * 2); for (int curdim = 0; curdim < dim; ++curdim) { - FT alpha = rng.get_double(0, 2 * pi); + FT alpha = rng.get_double(0, two_pi); pt.push_back(radius_noise_ratio * std::cos(alpha)); pt.push_back(radius_noise_ratio * std::sin(alpha)); } @@ -360,6 +364,8 @@ std::vector generate_points_on_two_spheres_d(std::size template std::vector generate_points_on_3sphere_and_circle(std::size_t num_points, double sphere_radius) { + using namespace boost::math::double_constants; + typedef typename Kernel::FT FT; typedef typename Kernel::Point_d Point; Kernel k; @@ -373,7 +379,7 @@ std::vector generate_points_on_3sphere_and_circle(std: for (std::size_t i = 0; i < num_points;) { Point p_sphere = *generator++; // First 3 coords - FT alpha = rng.get_double(0, 2 * pi); + FT alpha = rng.get_double(0, two_pi); std::vector pt(5); pt[0] = k_coord(p_sphere, 0); pt[1] = k_coord(p_sphere, 1); @@ -391,6 +397,8 @@ std::vector generate_points_on_3sphere_and_circle(std: template std::vector generate_points_on_klein_bottle_3D(std::size_t num_points, double a, double b, bool uniform = false) { + using namespace boost::math::double_constants; + typedef typename Kernel::Point_d Point; typedef typename Kernel::FT FT; Kernel k; @@ -406,11 +414,11 @@ std::vector generate_points_on_klein_bottle_3D(std::si if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * pi * k1 / num_lines; - v = 2 * pi * k2 / num_lines; + u = two_pi * k1 / num_lines; + v = two_pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * pi); - v = rng.get_double(0, 2 * pi); + u = rng.get_double(0, two_pi); + v = rng.get_double(0, two_pi); } double tmp = cos(u / 2) * sin(v) - sin(u / 2) * sin(2. * v); Point p = construct_point(k, @@ -427,6 +435,8 @@ std::vector generate_points_on_klein_bottle_3D(std::si template std::vector generate_points_on_klein_bottle_4D(std::size_t num_points, double a, double b, double noise = 0., bool uniform = false) { + using namespace boost::math::double_constants; + typedef typename Kernel::Point_d Point; typedef typename Kernel::FT FT; Kernel k; @@ -442,11 +452,11 @@ std::vector generate_points_on_klein_bottle_4D(std::si if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * pi * k1 / num_lines; - v = 2 * pi * k2 / num_lines; + u = two_pi * k1 / num_lines; + v = two_pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * pi); - v = rng.get_double(0, 2 * pi); + u = rng.get_double(0, two_pi); + v = rng.get_double(0, two_pi); } Point p = construct_point(k, (a + b * cos(v)) * cos(u) + (noise == 0. ? 0. : rng.get_double(0, noise)), @@ -466,6 +476,8 @@ template std::vector generate_points_on_klein_bottle_variant_5D( std::size_t num_points, double a, double b, bool uniform = false) { + using namespace boost::math::double_constants; + typedef typename Kernel::Point_d Point; typedef typename Kernel::FT FT; Kernel k; @@ -481,11 +493,11 @@ generate_points_on_klein_bottle_variant_5D( if (uniform) { std::size_t k1 = i / num_lines; std::size_t k2 = i % num_lines; - u = 2 * pi * k1 / num_lines; - v = 2 * pi * k2 / num_lines; + u = two_pi * k1 / num_lines; + v = two_pi * k2 / num_lines; } else { - u = rng.get_double(0, 2 * pi); - v = rng.get_double(0, 2 * pi); + u = rng.get_double(0, two_pi); + v = rng.get_double(0, two_pi); } FT x1 = (a + b * cos(v)) * cos(u); FT x2 = (a + b * cos(v)) * sin(u); -- cgit v1.2.3 From e59b1cfd338a80a769c0e2b6d677b9474b07beb3 Mon Sep 17 00:00:00 2001 From: Hind Date: Mon, 26 Apr 2021 11:47:36 +0200 Subject: Replace assert with GUDHI_CHECK Make the function non-template Change typing and casting --- src/python/gudhi/random_point_generators.cc | 34 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/random_point_generators.cc b/src/python/gudhi/random_point_generators.cc index 4306ba98..6eb40429 100644 --- a/src/python/gudhi/random_point_generators.cc +++ b/src/python/gudhi/random_point_generators.cc @@ -12,6 +12,7 @@ #include #include +#include #include @@ -20,36 +21,33 @@ namespace py = pybind11; typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; -template py::array_t generate_points_on_sphere(size_t num_points, int dim, double radius) { - - py::array_t points({(int)num_points, dim}); - + + py::array_t points({num_points, (size_t)dim}); + py::buffer_info buf = points.request(); double *ptr = static_cast(buf.ptr); - assert(num_points == buf.shape[0]); - assert(dim == buf.shape[1]); - - std::vector points_generated; - { - py::gil_scoped_release release; - points_generated = Gudhi::generate_points_on_sphere_d(num_points, dim, radius); - - for (size_t i = 0; i < num_points; i++) - for (size_t j = 0; j < (size_t)dim; j++) - ptr[i*dim+j] = points_generated[i][j]; - } + GUDHI_CHECK(num_points == buf.shape[0], "Py array first dimension not matching num_points on sphere"); + GUDHI_CHECK(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(num_points, dim, radius); + + for (size_t i = 0; i < num_points; i++) + for (int j = 0; j < dim; j++) + ptr[i*dim+j] = points_generated[i][j]; return points; } PYBIND11_MODULE(random_point_generators, m) { m.attr("__license__") = "LGPL v3"; - m.def("generate_points_on_sphere_d", &generate_points_on_sphere, + m.def("generate_points_on_sphere_d", &generate_points_on_sphere, py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, R"pbdoc( - Generate random i.i.d. points uniformly on a (d-1)-sphere in Rd + Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d :param num_points: The number of points to be generated. :type num_points: unsigned integer -- cgit v1.2.3 From 154596a39b2b26c90e46ec851b8f05ea08fa47d4 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 27 Apr 2021 09:17:53 +0200 Subject: Remove make install target from python and rewrite documentation accordingly --- src/common/doc/installation.h | 4 ++++ src/python/CMakeLists.txt | 2 -- src/python/doc/installation.rst | 14 ++++---------- 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index c2e63a24..ce393c38 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -30,6 +30,10 @@ make \endverbatim * This action may require to be in the sudoer or administrator of the machine in function of the operating system and * of CMAKE_INSTALL_PREFIX. * + * \note Python module will be compiled by the `make` command, but `make install` will not install it. Please refer to + * the Python + * module installation documentation. + * * \subsection testsuites Test suites * To test your build, run the following command in a terminal: * \verbatim make test \endverbatim diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 73303a24..a1440cbc 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -274,8 +274,6 @@ if(PYTHONINTERP_FOUND) add_custom_target(python ALL DEPENDS gudhi.so COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") - install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/setup.py install)") - set(GUDHI_PYTHON_PATH_ENV "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:$ENV{PYTHONPATH}") # Documentation generation is available through sphinx - requires all modules # Make it first as sphinx test is by far the longest test which is nice when testing in parallel diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 66efe45a..2881055f 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -99,20 +99,14 @@ Or install it definitely in your Python packages folder: .. code-block:: bash cd /path-to-gudhi/build/python - # May require sudo or administrator privileges - make install + python setup.py install # add --user to the command if you do not have the permission + # Or 'pip install .' .. note:: - :code:`make install` is only a - `CMake custom targets `_ - to shortcut :code:`python setup.py install` command. It does not take into account :code:`CMAKE_INSTALL_PREFIX`. - But one can use :code:`python setup.py install ...` specific options in the python directory: - -.. code-block:: bash - - python setup.py install --prefix /home/gudhi # Install in /home/gudhi directory + But one can use + `alternate location installation `_. Test suites =========== -- cgit v1.2.3 From 44085e15a0ce83d8139db7da276d656bd6381026 Mon Sep 17 00:00:00 2001 From: Théo Lacombe Date: Tue, 27 Apr 2021 09:55:13 +0200 Subject: Typo correction - Update src/python/gudhi/wasserstein/wasserstein.py Co-authored-by: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> --- src/python/gudhi/wasserstein/wasserstein.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 8ccbe12e..926dec33 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -131,7 +131,7 @@ def _cost_and_match_essential_parts(X, Y, idX, idY, order, axis): :param Y: (n x 2) numpy.array (dgm points) :param idX: indices to consider for this one dimensional OT problem (in X) :param idY: indices to consider for this one dimensional OT problem (in Y) - :param order: exponent for Wasserstein distanc ecomputation + :param order: exponent for Wasserstein distance computation :param axis: must be 0 or 1, correspond to the coordinate which is finite. :returns: cost (float) and match for points with *one* infinite coordinate. -- cgit v1.2.3 From 29ffea359c52e2813c8e6887bda51874c36a56a5 Mon Sep 17 00:00:00 2001 From: Théo Lacombe Date: Tue, 27 Apr 2021 09:56:53 +0200 Subject: Typo - Update src/python/gudhi/wasserstein/wasserstein.py Co-authored-by: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> --- src/python/gudhi/wasserstein/wasserstein.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 926dec33..90988512 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -267,7 +267,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab # Check essential part and enable autodiff together if enable_autodiff and keep_essential_parts: warnings.warn('''enable_autodiff=True and keep_essential_parts=True are incompatible together. - keep_essential_parts is set to False: only points with finite coordiantes are considered + keep_essential_parts is set to False: only points with finite coordinates are considered in the following. ''') keep_essential_parts = False -- cgit v1.2.3 From c1ab7c43d4797da93aa74ba823dd1a6b28fb2cfd Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 27 Apr 2021 12:16:22 +0200 Subject: now consider (inf,inf) as belonging to the diagonal ; more tests --- src/python/gudhi/wasserstein/wasserstein.py | 18 ++++++++++---- src/python/test/test_wasserstein_distance.py | 36 +++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 3abecfe6..5095e672 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -106,6 +106,8 @@ def _get_essential_parts(a): .. note:: For instance, a[_get_essential_parts(a)[0]] returns the points in a of coordinates (-inf, x) for some finite x. Note also that points with (+inf, -inf) are not handled (points (x,y) in dgm satisfy by assumption (y >= x)). + + Finally, we consider that points with coordinates (-inf,-inf) and (+inf, +inf) belong to the diagonal. ''' if len(a): first_coord_finite = np.isfinite(a[:,0]) @@ -118,6 +120,7 @@ def _get_essential_parts(a): ess_first_type = np.where(second_coord_finite & first_coord_infinite_negative)[0] # coord (-inf, x) ess_second_type = np.where(first_coord_finite & second_coord_infinite_positive)[0] # coord (x, +inf) ess_third_type = np.where(first_coord_infinite_negative & second_coord_infinite_positive)[0] # coord (-inf, +inf) + ess_fourth_type = np.where(first_coord_infinite_negative & second_coord_infinite_negative)[0] # coord (-inf, -inf) ess_fifth_type = np.where(first_coord_infinite_positive & second_coord_infinite_positive)[0] # coord (+inf, +inf) return ess_first_type, ess_second_type, ess_third_type, ess_fourth_type, ess_fifth_type @@ -162,7 +165,7 @@ def _handle_essential_parts(X, Y, order): ess_parts_Y = _get_essential_parts(Y) # Treats the case of infinite cost (cardinalities of essential parts differ). - for u, v in zip(ess_parts_X, ess_parts_Y): + for u, v in list(zip(ess_parts_X, ess_parts_Y))[:3]: # ignore types 4 and 5 as they belong to the diagonal if len(u) != len(v): return np.inf, None @@ -174,9 +177,14 @@ def _handle_essential_parts(X, Y, order): c = c1 + c2 m = m1 + m2 - # Handle type >= 2 (both coordinates are infinite, so we essentially just align points) - for u, v in zip(ess_parts_X[2:], ess_parts_Y[2:]): - m += list(zip(u, v)) # cost is 0 + # Handle type3 (coordinates (-inf,+inf), so we just align points) + m += list(zip(ess_parts_X[2], ess_parts_Y[2])) + + # Handle type 4 and 5, considered as belonging to the diagonal so matched to (-1) with cost 0. + for z in ess_parts_X[3:]: + m += [(u, -1) for u in z] # points in X are matched to -1 + for z in ess_parts_Y[3:]: + m += [(-1, v) for v in z] # -1 is match to points in Y return c, np.array(m) @@ -334,7 +342,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab return ep.concatenate(dists).norms.lp(order).raw # We can also concatenate the 3 vectors to compute just one norm. - # Comptuation of the otcost using the ot.emd2 library. + # Comptuation of the ot cost using the ot.emd2 library. # Note: it is the Wasserstein distance to the power q. # The default numItermax=100000 is not sufficient for some examples with 5000 points, what is a good value? ot_cost = ot.emd2(a, b, M, numItermax=2000000) diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index 121ba065..3a004d77 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -10,6 +10,7 @@ """ from gudhi.wasserstein.wasserstein import _proj_on_diag, _finite_part, _handle_essential_parts, _get_essential_parts +from gudhi.wasserstein.wasserstein import _warn_infty from gudhi.wasserstein import wasserstein_distance as pot from gudhi.hera import wasserstein_distance as hera import numpy as np @@ -50,16 +51,17 @@ def test_handle_essential_parts(): [-np.inf, np.inf], [-np.inf, np.inf]]) diag3 = np.array([[0, 2], [3, 5], - [2, np.inf], [4, np.inf], + [2, np.inf], [4, np.inf], [6, np.inf], [-np.inf, 8], [-np.inf, 11], - [-np.inf, -np.inf], [-np.inf, -np.inf], + [-np.inf, -np.inf], [np.inf, np.inf], [-np.inf, np.inf], [-np.inf, np.inf]]) c, m = _handle_essential_parts(diag1, diag2, order=1) assert c == pytest.approx(2, 0.0001) # Note: here c is only the cost due to essential part (thus 2, not 3) # Similarly, the matching only corresponds to essential parts. - assert np.array_equal(m, [[4, 4], [5, 5], [2, 2], [3, 3], [8, 8], [9, 9], [6, 6], [7, 7]]) + # Note that (-inf,-inf) and (+inf,+inf) coordinates are matched to the diagonal. + assert np.array_equal(m, [[4, 4], [5, 5], [2, 2], [3, 3], [8, 8], [9, 9], [6, -1], [7, -1], [-1, 6], [-1, 7]]) c, m = _handle_essential_parts(diag1, diag3, order=1) assert c == np.inf @@ -87,6 +89,13 @@ def test_get_essential_parts(): assert np.array_equal(res2[4], [] ) +def test_warn_infty(): + assert _warn_infty(matching=False)==np.inf + c, m = _warn_infty(matching=True) + assert (c == np.inf) + assert (m is None) + + def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_matching=True): diag1 = np.array([[2.7, 3.7], [9.6, 14.0], [34.2, 34.974]]) diag2 = np.array([[2.8, 4.45], [9.5, 14.1]]) @@ -143,11 +152,29 @@ def _basic_wasserstein(wasserstein_distance, delta, test_infinity=True, test_mat if test_matching and test_infinity: diag7 = np.array([[0, 3], [4, np.inf], [5, np.inf]]) + diag8 = np.array([[0,1], [0, np.inf], [-np.inf, -np.inf], [np.inf, np.inf]]) + diag9 = np.array([[-np.inf, -np.inf], [np.inf, np.inf]]) + diag10 = np.array([[0,1], [-np.inf, -np.inf], [np.inf, np.inf]]) match = wasserstein_distance(diag5, diag6, matching=True, internal_p=2., order=2.)[1] assert np.array_equal(match, [[0, -1], [-1,0], [-1, 1], [1, 2]]) match = wasserstein_distance(diag5, diag7, matching=True, internal_p=2., order=2.)[1] assert (match is None) + cost, match = wasserstein_distance(diag7, emptydiag, matching=True, internal_p=2., order=2.3) + assert (cost == np.inf) + assert (match is None) + cost, match = wasserstein_distance(emptydiag, diag7, matching=True, internal_p=2.42, order=2.) + assert (cost == np.inf) + assert (match is None) + cost, match = wasserstein_distance(diag8, diag9, matching=True, internal_p=2., order=2.) + assert (cost == np.inf) + assert (match is None) + cost, match = wasserstein_distance(diag9, diag10, matching=True, internal_p=1., order=1.) + assert (cost == 1) + assert (match == [[0, -1],[1, -1],[-1, 0], [-1, 1], [-1, 2]]) # type 4 and 5 are match to the diag anyway. + cost, match = wasserstein_distance(diag9, emptydiag, matching=True, internal_p=2., order=2.) + assert (cost == 0.) + assert (match == [[0, -1], [1, -1]]) def hera_wrap(**extra): @@ -155,15 +182,18 @@ def hera_wrap(**extra): return hera(*kargs,**kwargs,**extra) return fun + def pot_wrap(**extra): def fun(*kargs,**kwargs): return pot(*kargs,**kwargs,**extra) return fun + def test_wasserstein_distance_pot(): _basic_wasserstein(pot, 1e-15, test_infinity=False, test_matching=True) # pot with its standard args _basic_wasserstein(pot_wrap(enable_autodiff=True, keep_essential_parts=False), 1e-15, test_infinity=False, test_matching=False) + def test_wasserstein_distance_hera(): _basic_wasserstein(hera_wrap(delta=1e-12), 1e-12, test_matching=False) _basic_wasserstein(hera_wrap(delta=.1), .1, test_matching=False) -- cgit v1.2.3 From b5fc64b23f8c92377a86111f75178abcc171050d Mon Sep 17 00:00:00 2001 From: tlacombe Date: Tue, 27 Apr 2021 14:57:04 +0200 Subject: changed infty to inf in doc --- src/python/gudhi/wasserstein/wasserstein.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 5095e672..61505d03 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -83,7 +83,7 @@ def _perstot(X, order, internal_p, enable_autodiff): :returns: float, the total persistence of the diagram (that is, its distance to the empty diagram). .. note:: - Can be +infty if the diagram has an essential part (points with infinite coordinates). + Can be +inf if the diagram has an essential part (points with infinite coordinates). ''' if enable_autodiff: import eagerpy as ep @@ -203,10 +203,10 @@ def _warn_infty(matching): `matching=True`) about the returned matching being `None`. ''' if matching: - warnings.warn('Cardinality of essential parts differs. Distance (cost) is +infty, and the returned matching is None.') + warnings.warn('Cardinality of essential parts differs. Distance (cost) is +inf, and the returned matching is None.') return np.inf, None else: - warnings.warn('Cardinality of essential parts differs. Distance (cost) is +infty.') + warnings.warn('Cardinality of essential parts differs. Distance (cost) is +inf.') return np.inf -- cgit v1.2.3 From 7573e67c8c6c1bb3cd21fd8b9ffb8aa0168eb7f7 Mon Sep 17 00:00:00 2001 From: Hind Date: Tue, 27 Apr 2021 15:13:25 +0200 Subject: Remove the commented graphic part from the example (to be added to tutorial notebooks) --- .../alpha_complex_from_generated_points_example.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'src') diff --git a/src/python/example/alpha_complex_from_generated_points_example.py b/src/python/example/alpha_complex_from_generated_points_example.py index 7a07ed42..c2562d8a 100644 --- a/src/python/example/alpha_complex_from_generated_points_example.py +++ b/src/python/example/alpha_complex_from_generated_points_example.py @@ -1,10 +1,7 @@ #!/usr/bin/env python from gudhi import random_point_generators -from gudhi import AlphaComplex, SimplexTree -from gudhi import plot_persistence_barcode, plot_persistence_diagram - -import matplotlib.pyplot as plt +from gudhi import AlphaComplex """ This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. @@ -28,10 +25,6 @@ print("AlphaComplex creation from generated points") # Generate a circle: 50 points; dim 2; radius 1 points = random_point_generators.generate_points_on_sphere_d(50, 2, 1) -# Plot the generated points (to uncomment if wished) -#plt.scatter(points[:,0], points[:,1]) -#plt.show() - # Create an alpha complex alpha_complex = AlphaComplex(points=points) simplex_tree = alpha_complex.create_simplex_tree() @@ -41,12 +34,3 @@ result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + repr(simplex_tree.num_vertices()) + ' vertices.' print(result_str) - -# Compute the persistence -diag = simplex_tree.persistence() - -# Plot the barcode and diagram (to uncomment if wished) -#plot_persistence_barcode(diag) -#plt.show() -#plot_persistence_diagram(diag) -#plt.show() -- cgit v1.2.3 From ce73a29d4fee67b7d20c213df81edf57b0de8770 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Tue, 27 Apr 2021 17:41:15 +0200 Subject: Doxygen documentation improvement --- .circleci/config.yml | 9 +- .../for_maintainers/new_gudhi_version_creation.md | 9 +- src/Alpha_complex/doc/Intro_alpha_complex.h | 14 +- .../doc/Intro_bottleneck_distance.h | 2 +- src/Cech_complex/doc/Intro_cech_complex.h | 6 +- src/Collapse/doc/intro_edge_collapse.h | 4 +- src/Doxyfile.in | 44 ++--- src/Nerve_GIC/doc/Intro_graph_induced_complex.h | 10 +- .../doc/Intro_persistent_cohomology.h | 14 +- src/Rips_complex/doc/Intro_rips_complex.h | 24 +-- src/Simplex_tree/doc/Intro_simplex_tree.h | 8 +- .../doc/Intro_spatial_searching.h | 2 +- src/Subsampling/doc/Intro_subsampling.h | 6 +- .../doc/Intro_tangential_complex.h | 4 +- src/Witness_complex/doc/Witness_complex_doc.h | 4 +- src/cmake/modules/GUDHI_doxygen_target.cmake | 47 +++++- src/cmake/modules/GUDHI_user_version_target.cmake | 11 +- src/common/doc/examples.h | 184 +++++++++++---------- src/common/doc/installation.h | 157 +++++++++--------- src/common/include/gudhi/Points_3D_off_io.h | 4 +- src/common/include/gudhi/Points_off_io.h | 4 +- 21 files changed, 302 insertions(+), 265 deletions(-) (limited to 'src') diff --git a/.circleci/config.yml b/.circleci/config.yml index 7fa9ae05..f6a875dd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -90,10 +90,15 @@ jobs: mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF -DUSER_VERSION_DIR=version .. + make user_version + cd version + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=OFF .. make doxygen 2>&1 | tee dox.log grep warning dox.log - cp dox.log version/doc/html/ - cp -R version/doc/html /tmp/doxygen + cp dox.log html/ + cp -R html /tmp/doxygen - store_artifacts: path: /tmp/doxygen diff --git a/.github/for_maintainers/new_gudhi_version_creation.md b/.github/for_maintainers/new_gudhi_version_creation.md index aadfae7d..d6c4cdd3 100644 --- a/.github/for_maintainers/new_gudhi_version_creation.md +++ b/.github/for_maintainers/new_gudhi_version_creation.md @@ -34,16 +34,21 @@ make -j 4 all && ctest -j 4 --output-on-failure ## Create the documentation ```bash mkdir gudhi.doc.@GUDHI_VERSION@ -make doxygen 2>&1 | tee dox.log && grep warning dox.log ``` ***[Check there are no error and the warnings]*** ```bash -cp -R gudhi.@GUDHI_VERSION@/doc/html gudhi.doc.@GUDHI_VERSION@/cpp cd gudhi.@GUDHI_VERSION@ rm -rf build; mkdir build; cd build cmake -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=/your/path/to/CGAL -DWITH_GUDHI_EXAMPLE=ON -DPython_ADDITIONAL_VERSIONS=3 .. +make doxygen 2>&1 | tee dox.log && grep warning dox.log +``` + +***[Check there are no error and the warnings]*** + +```bash +cp -R html ../../gudhi.doc.@GUDHI_VERSION@/cpp export LC_ALL=en_US.UTF-8 # cf. bug https://github.com/GUDHI/gudhi-devel/issues/111 make sphinx ``` diff --git a/src/Alpha_complex/doc/Intro_alpha_complex.h b/src/Alpha_complex/doc/Intro_alpha_complex.h index c068b268..f417ebb2 100644 --- a/src/Alpha_complex/doc/Intro_alpha_complex.h +++ b/src/Alpha_complex/doc/Intro_alpha_complex.h @@ -83,7 +83,7 @@ Table of Contents * * Then, it is asked to display information about the simplicial complex. * - * \include Alpha_complex/Alpha_complex_from_points.cpp + * \include Alpha_complex_from_points.cpp * * When launching: * @@ -92,7 +92,7 @@ Table of Contents * * the program output is: * - * \include Alpha_complex/alphaoffreader_for_doc_60.txt + * \include alphaoffreader_for_doc_60.txt * * \section createcomplexalgorithm Create complex algorithm * @@ -171,7 +171,7 @@ Table of Contents * * Then, it is asked to display information about the alpha complex. * - * \include Alpha_complex/Weighted_alpha_complex_from_points.cpp + * \include Weighted_alpha_complex_from_points.cpp * * When launching: * @@ -180,7 +180,7 @@ Table of Contents * * the program output is: * - * \include Alpha_complex/weightedalpha3dfrompoints_for_doc.txt + * \include weightedalpha3dfrompoints_for_doc.txt * * * \section offexample Example from OFF file @@ -190,7 +190,7 @@ Table of Contents * * Then, it is asked to display information about the alpha complex. * - * \include Alpha_complex/Alpha_complex_from_off.cpp + * \include Alpha_complex_from_off.cpp * * When launching: * @@ -199,7 +199,7 @@ Table of Contents * * the program output is: * - * \include Alpha_complex/alphaoffreader_for_doc_32.txt + * \include alphaoffreader_for_doc_32.txt * * * \section weighted3dexample 3d specific version @@ -215,7 +215,7 @@ Table of Contents * * Then, it is asked to display information about the alpha complex. * - * \include Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp + * \include Weighted_alpha_complex_3d_from_points.cpp * * The results will be the same as in \ref weightedversion . * diff --git a/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h b/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h index 2a988b4b..4f5a956c 100644 --- a/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h +++ b/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h @@ -64,7 +64,7 @@ int main() { * \section bottleneckbasicexample Basic example * * This other example computes the bottleneck distance from 2 persistence diagrams: - * \include Bottleneck_distance/bottleneck_basic_example.cpp + * \include bottleneck_basic_example.cpp * * \code Bottleneck distance = 0.75 diff --git a/src/Cech_complex/doc/Intro_cech_complex.h b/src/Cech_complex/doc/Intro_cech_complex.h index 80c88dc6..698f9749 100644 --- a/src/Cech_complex/doc/Intro_cech_complex.h +++ b/src/Cech_complex/doc/Intro_cech_complex.h @@ -71,7 +71,7 @@ namespace cech_complex { * \ref rips_complex but it offers more topological guarantees. * * If the Cech_complex interfaces are not detailed enough for your need, please refer to - * + * * cech_complex_step_by_step.cpp example, where the graph construction over the Simplex_tree is more detailed. * * \subsection cechpointscloudexample Example from a point cloud @@ -81,7 +81,7 @@ namespace cech_complex { * * Then, it is asked to display information about the simplicial complex. * - * \include Cech_complex/cech_complex_example_from_points.cpp + * \include cech_complex_example_from_points.cpp * * When launching (maximal enclosing ball radius is 1., is expanded until dimension 2): * @@ -90,7 +90,7 @@ namespace cech_complex { * * the program output is: * - * \include Cech_complex/cech_complex_example_from_points_for_doc.txt + * \include cech_complex_example_from_points_for_doc.txt * */ /** @} */ // end defgroup cech_complex diff --git a/src/Collapse/doc/intro_edge_collapse.h b/src/Collapse/doc/intro_edge_collapse.h index 81edd79f..fde39707 100644 --- a/src/Collapse/doc/intro_edge_collapse.h +++ b/src/Collapse/doc/intro_edge_collapse.h @@ -81,7 +81,7 @@ namespace collapse { * Then it collapses edges and displays a new list of `Filtered_edge` (with less edges) * that will preserve the persistence homology computation. * - * \include Collapse/edge_collapse_basic_example.cpp + * \include edge_collapse_basic_example.cpp * * When launching the example: * @@ -90,7 +90,7 @@ namespace collapse { * * the program output is: * - * \include Collapse/edge_collapse_example_basic.txt + * \include edge_collapse_example_basic.txt */ /** @} */ // end defgroup strong_collapse diff --git a/src/Doxyfile.in b/src/Doxyfile.in index 49e781bd..4784b915 100644 --- a/src/Doxyfile.in +++ b/src/Doxyfile.in @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "GUDHI" +PROJECT_NAME = "@CMAKE_PROJECT_NAME@" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -58,7 +58,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = "doc/" +OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -672,9 +672,9 @@ LAYOUT_FILE = # search path. Do not use file names with spaces, bibtex cannot handle them. See # also \cite for info how to create references. -CITE_BIB_FILES = biblio/bibliography.bib \ - biblio/how_to_cite_cgal.bib \ - biblio/how_to_cite_gudhi.bib +CITE_BIB_FILES = @CMAKE_SOURCE_DIR@/biblio/bibliography.bib \ + @CMAKE_SOURCE_DIR@/biblio/how_to_cite_cgal.bib \ + @CMAKE_SOURCE_DIR@/biblio/how_to_cite_gudhi.bib #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages @@ -745,7 +745,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = +INPUT = @CMAKE_SOURCE_DIR@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -780,13 +780,14 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = data/ \ - example/ \ - GudhUI/ \ - cmake/ \ - python/ \ - ext/ \ - README.md +EXCLUDE = @CMAKE_SOURCE_DIR@/data/ \ + @CMAKE_SOURCE_DIR@/ext/ \ + @CMAKE_SOURCE_DIR@/README.md \ + @CMAKE_SOURCE_DIR@/.github \ + @CMAKE_CURRENT_BINARY_DIR@/new_gudhi_version_creation.md \ + @GUDHI_DOXYGEN_SOURCE_PREFIX@/GudhUI/ \ + @GUDHI_DOXYGEN_SOURCE_PREFIX@/cmake/ \ + @GUDHI_DOXYGEN_SOURCE_PREFIX@/python/ \ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -802,7 +803,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = */utilities/*/*.md +EXCLUDE_PATTERNS = @GUDHI_DOXYGEN_SOURCE_PREFIX@/@GUDHI_DOXYGEN_UTILS_PATH@/*.md # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -819,10 +820,9 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = biblio/ \ - example/ \ - utilities/ \ - data/ +EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/biblio/ \ + @CMAKE_SOURCE_DIR@/data/ \ + @GUDHI_DOXYGEN_EXAMPLE_PATH@ # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -890,7 +890,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = doc/common/main_page.md +USE_MDFILE_AS_MAINPAGE = @GUDHI_DOXYGEN_COMMON_DOC_PATH@/main_page.md #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1046,7 +1046,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = doc/common/header.html +HTML_HEADER = @GUDHI_DOXYGEN_COMMON_DOC_PATH@/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1056,7 +1056,7 @@ HTML_HEADER = doc/common/header.html # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = doc/common/footer.html +HTML_FOOTER = @GUDHI_DOXYGEN_COMMON_DOC_PATH@/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of @@ -1068,7 +1068,7 @@ HTML_FOOTER = doc/common/footer.html # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_STYLESHEET = doc/common/stylesheet.css +HTML_STYLESHEET = @GUDHI_DOXYGEN_COMMON_DOC_PATH@/stylesheet.css # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- # defined cascading style sheet that is included after the standard style sheets diff --git a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h index f9441b24..a6098860 100644 --- a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h +++ b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h @@ -53,7 +53,7 @@ namespace cover_complex { * covering the height function (coordinate 2), * which are then refined into their connected components using the triangulation of the .OFF file. * - * \include Nerve_GIC/Nerve.cpp + * \include Nerve.cpp * * When launching: * @@ -62,7 +62,7 @@ namespace cover_complex { * * the program output is: * - * \include Nerve_GIC/Nerve.txt + * \include Nerve.txt * * The program also writes a file ../../data/points/human_sc.txt. The first three lines in this file are the location * of the input point cloud and the function used to compute the cover. @@ -96,7 +96,7 @@ namespace cover_complex { * comes from the triangulation of the human shape. Note that the resulting simplicial complex is in dimension 3 * in this example. * - * \include Nerve_GIC/VoronoiGIC.cpp + * \include VoronoiGIC.cpp * * When launching: * @@ -129,7 +129,7 @@ namespace cover_complex { * with automatic resolution and gain. Note that automatic threshold, resolution and gain * can be computed as well for the Nerve. * - * \include Nerve_GIC/CoordGIC.cpp + * \include CoordGIC.cpp * * When launching: * @@ -152,7 +152,7 @@ namespace cover_complex { * The function is now the first eigenfunction given by PCA, whose values * are written in a file (lucky_cat_PCA1). Threshold, resolution and gain are automatically selected as before. * - * \include Nerve_GIC/FuncGIC.cpp + * \include FuncGIC.cpp * * When launching: * diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h index b4f9fd2c..a3613d0d 100644 --- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h +++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h @@ -131,7 +131,7 @@ namespace persistent_cohomology { We provide several example files: run these examples with -h for details on their use, and read the README file. -\li +\li Rips_complex/rips_persistence.cpp computes the Rips complex of a point cloud and outputs its persistence diagram. \code $> ./rips_persistence ../../data/points/tore3D_1307.off -r 0.25 -m 0.5 -d 3 -p 3 \endcode @@ -144,11 +144,11 @@ diagram. More details on the Rips complex utilities dedicated page. -\li +\li Persistent_cohomology/rips_multifield_persistence.cpp computes the Rips complex of a point cloud and outputs its persistence diagram with a family of field coefficients. -\li +\li Rips_complex/rips_distance_matrix_persistence.cpp computes the Rips complex of a distance matrix and outputs its persistence diagram. @@ -158,7 +158,7 @@ Please refer to data/distance_matrix/lower_triangular_distance_matrix.csv for an More details on the Rips complex utilities dedicated page. -\li +\li Rips_complex/rips_correlation_matrix_persistence.cpp computes the Rips complex of a correlation matrix and outputs its persistence diagram. @@ -169,7 +169,7 @@ Please refer to data/correlation_matrix/lower_triangular_correlation_matrix.csv More details on the Rips complex utilities dedicated page. -\li +\li Alpha_complex/alpha_complex_3d_persistence.cpp computes the persistent homology with \f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file. \code $> ./alpha_complex_3d_persistence ../../data/points/tore3D_300.off -p 2 -m 0.45 \endcode @@ -235,7 +235,7 @@ Note that the lengths of the sides of the periodic cuboid have to be the same. +\li Alpha_complex/alpha_complex_persistence.cpp computes the persistent homology with \f$\mathbb{Z}/p\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file. \code $> ./alpha_complex_persistence -r 32 -p 2 -m 0.45 ../../data/points/tore3D_300.off \endcode @@ -248,7 +248,7 @@ Simplex_tree dim: 3 More details on the Alpha complex utilities dedicated page. -\li +\li Persistent_cohomology/plain_homology.cpp computes the plain homology of a simple simplicial complex without filtration values. diff --git a/src/Rips_complex/doc/Intro_rips_complex.h b/src/Rips_complex/doc/Intro_rips_complex.h index b2840686..3888ec8f 100644 --- a/src/Rips_complex/doc/Intro_rips_complex.h +++ b/src/Rips_complex/doc/Intro_rips_complex.h @@ -64,7 +64,7 @@ namespace rips_complex { * And so on for simplex (0,1,2,3). * * If the Rips_complex interfaces are not detailed enough for your need, please refer to - * + * * rips_persistence_step_by_step.cpp example, where the constructions of the graph and * the Simplex_tree are more detailed. * @@ -111,7 +111,7 @@ namespace rips_complex { * * Then, it is asked to display information about the simplicial complex. * - * \include Rips_complex/example_one_skeleton_rips_from_points.cpp + * \include example_one_skeleton_rips_from_points.cpp * * When launching (Rips maximal distance between 2 points is 12.0, is expanded * until dimension 1 - one skeleton graph in other words): @@ -121,7 +121,7 @@ namespace rips_complex { * * the program output is: * - * \include Rips_complex/one_skeleton_rips_for_doc.txt + * \include one_skeleton_rips_for_doc.txt * * \subsection ripsoffexample Example from OFF file * @@ -132,7 +132,7 @@ namespace rips_complex { * * Then, it is asked to display information about the Rips complex. * - * \include Rips_complex/example_rips_complex_from_off_file.cpp + * \include example_rips_complex_from_off_file.cpp * * When launching: * @@ -141,7 +141,7 @@ namespace rips_complex { * * the program output is: * - * \include Rips_complex/full_skeleton_rips_for_doc.txt + * \include full_skeleton_rips_for_doc.txt * * * \subsection sparseripspointscloudexample Example of a sparse Rips from a point cloud @@ -149,7 +149,7 @@ namespace rips_complex { * This example builds the full sparse Rips of a set of 2D Euclidean points, then prints some minimal * information about the complex. * - * \include Rips_complex/example_sparse_rips.cpp + * \include example_sparse_rips.cpp * * When launching: * @@ -172,7 +172,7 @@ namespace rips_complex { * * Then, it is asked to display information about the simplicial complex. * - * \include Rips_complex/example_one_skeleton_rips_from_distance_matrix.cpp + * \include example_one_skeleton_rips_from_distance_matrix.cpp * * When launching (Rips maximal distance between 2 points is 1.0, is expanded until dimension 1 - one skeleton graph * with other words): @@ -182,7 +182,7 @@ namespace rips_complex { * * the program output is: * - * \include Rips_complex/one_skeleton_rips_for_doc.txt + * \include one_skeleton_rips_for_doc.txt * * \subsection ripscsvdistanceexample Example from a distance matrix read in a csv file * @@ -192,7 +192,7 @@ namespace rips_complex { * * Then, it is asked to display information about the Rips complex. * - * \include Rips_complex/example_rips_complex_from_csv_distance_matrix_file.cpp + * \include example_rips_complex_from_csv_distance_matrix_file.cpp * * When launching: * @@ -201,7 +201,7 @@ namespace rips_complex { * * the program output is: * - * \include Rips_complex/full_skeleton_rips_for_doc.txt + * \include full_skeleton_rips_for_doc.txt * * * \section ripscorrelationematrix Correlation matrix @@ -213,7 +213,7 @@ namespace rips_complex { * * Then, it is asked to display information about the simplicial complex. * - * \include Rips_complex/example_one_skeleton_rips_from_correlation_matrix.cpp + * \include example_one_skeleton_rips_from_correlation_matrix.cpp * * When launching: * @@ -222,7 +222,7 @@ namespace rips_complex { * * the program output is: * - * \include Rips_complex/one_skeleton_rips_from_correlation_matrix_for_doc.txt + * \include one_skeleton_rips_from_correlation_matrix_for_doc.txt * * All the other constructions discussed for Rips complex for distance matrix can be also performed for Rips complexes * construction from correlation matrices. diff --git a/src/Simplex_tree/doc/Intro_simplex_tree.h b/src/Simplex_tree/doc/Intro_simplex_tree.h index 800879fe..ef8dec91 100644 --- a/src/Simplex_tree/doc/Intro_simplex_tree.h +++ b/src/Simplex_tree/doc/Intro_simplex_tree.h @@ -39,10 +39,10 @@ namespace Gudhi { * \subsubsection filteredcomplexessimplextreeexamples Examples * * Here is a list of simplex tree examples : - * \li + * \li * Simplex_tree/simple_simplex_tree.cpp - Simple simplex tree construction and basic function use. * - * \li + * \li * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp - Simplex tree construction from cliques of graph read in * a file. * @@ -54,11 +54,11 @@ Expand the simplex tree in 3.8e-05 s. Information of the Simplex Tree: Number of vertices = 10 Number of simplices = 98 \endcode * - * \li + * \li * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp - Simplex tree is computed and displayed * from a 3D alpha complex (Requires CGAL, GMP and GMPXX to be installed). * - * \li + * \li * Simplex_tree/graph_expansion_with_blocker.cpp - Simple simplex tree construction from a one-skeleton graph with * a simple blocker expansion method. * diff --git a/src/Spatial_searching/doc/Intro_spatial_searching.h b/src/Spatial_searching/doc/Intro_spatial_searching.h index 30805570..81c5a3aa 100644 --- a/src/Spatial_searching/doc/Intro_spatial_searching.h +++ b/src/Spatial_searching/doc/Intro_spatial_searching.h @@ -36,7 +36,7 @@ namespace spatial_searching { * * This example generates 500 random points, then performs all-near-neighbors searches, and queries for nearest and furthest neighbors using different methods. * - * \include Spatial_searching/example_spatial_searching.cpp + * \include example_spatial_searching.cpp * */ /** @} */ // end defgroup spatial_searching diff --git a/src/Subsampling/doc/Intro_subsampling.h b/src/Subsampling/doc/Intro_subsampling.h index 1c84fb2e..1c366fe6 100644 --- a/src/Subsampling/doc/Intro_subsampling.h +++ b/src/Subsampling/doc/Intro_subsampling.h @@ -32,20 +32,20 @@ namespace subsampling { * squared distance between any two points * is greater than or equal to 0.4. * - * \include Subsampling/example_sparsify_point_set.cpp + * \include example_sparsify_point_set.cpp * * \section farthestpointexamples Example: choose_n_farthest_points * * This example outputs a subset of 100 points obtained by González algorithm, * starting with a random point. * - * \include Subsampling/example_choose_n_farthest_points.cpp + * \include example_choose_n_farthest_points.cpp * * \section randompointexamples Example: pick_n_random_points * * This example outputs a subset of 100 points picked randomly. * - * \include Subsampling/example_pick_n_random_points.cpp + * \include example_pick_n_random_points.cpp */ /** @} */ // end defgroup subsampling diff --git a/src/Tangential_complex/doc/Intro_tangential_complex.h b/src/Tangential_complex/doc/Intro_tangential_complex.h index ce277185..cb8c6122 100644 --- a/src/Tangential_complex/doc/Intro_tangential_complex.h +++ b/src/Tangential_complex/doc/Intro_tangential_complex.h @@ -88,7 +88,7 @@ This example builds the Tangential complex of point set. Note that the dimension of the kernel here is dynamic, which is slower, but more flexible: the intrinsic and ambient dimensions does not have to be known at compile-time. -\include Tangential_complex/example_basic.cpp +\include example_basic.cpp \section example_with_perturb Example with perturbation @@ -97,7 +97,7 @@ by perturbing the positions of points involved in inconsistent simplices. Note that the dimension of the kernel here is static, which is the best choice when the dimensions are known at compile-time. -\include Tangential_complex/example_with_perturb.cpp +\include example_with_perturb.cpp */ /** @} */ // end defgroup tangential_complex diff --git a/src/Witness_complex/doc/Witness_complex_doc.h b/src/Witness_complex/doc/Witness_complex_doc.h index 202f4539..c66b106e 100644 --- a/src/Witness_complex/doc/Witness_complex_doc.h +++ b/src/Witness_complex/doc/Witness_complex_doc.h @@ -108,14 +108,14 @@ int main(int argc, char * const argv[]) { Here is an example of constructing a strong witness complex filtration and computing persistence on it: - \include Witness_complex/strong_witness_persistence.cpp + \include strong_witness_persistence.cpp \section witnessexample3 Example3: Computing relaxed witness complex persistence from a distance matrix In this example we compute the relaxed witness complex persistence from a given matrix of closest landmarks to each witness. Each landmark is given as the couple (index, distance). - \include Witness_complex/example_nearest_landmark_table.cpp + \include example_nearest_landmark_table.cpp */ diff --git a/src/cmake/modules/GUDHI_doxygen_target.cmake b/src/cmake/modules/GUDHI_doxygen_target.cmake index 7a84c4e0..0f80b187 100644 --- a/src/cmake/modules/GUDHI_doxygen_target.cmake +++ b/src/cmake/modules/GUDHI_doxygen_target.cmake @@ -8,14 +8,47 @@ if(DOXYGEN_FOUND) get_property(DOXYGEN_EXECUTABLE TARGET Doxygen::doxygen PROPERTY IMPORTED_LOCATION) endif() - add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${GUDHI_USER_VERSION_DIR}/Doxyfile - WORKING_DIRECTORY ${GUDHI_USER_VERSION_DIR} - COMMENT "Generating API documentation with Doxygen in ${GUDHI_USER_VERSION_DIR}/doc/html/" VERBATIM) - - if(TARGET user_version) - # In dev version, doxygen target depends on user_version target. Not existing in user version - add_dependencies(doxygen user_version) + message("++ Project = ${CMAKE_PROJECT_NAME}") + if (CMAKE_PROJECT_NAME STREQUAL "GUDHIdev") + # Set Doxyfile.in variables for the developer version + set(GUDHI_DOXYGEN_SOURCE_PREFIX "${CMAKE_SOURCE_DIR}/src") + foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) + if(EXISTS "${GUDHI_DOXYGEN_SOURCE_PREFIX}/${GUDHI_MODULE}/doc/") + set(GUDHI_DOXYGEN_IMAGE_PATH "${GUDHI_DOXYGEN_IMAGE_PATH} ${GUDHI_DOXYGEN_SOURCE_PREFIX}/${GUDHI_MODULE}/doc/ \\ \n") + endif() + if(EXISTS "${GUDHI_DOXYGEN_SOURCE_PREFIX}/${GUDHI_MODULE}/example/") + set(GUDHI_DOXYGEN_EXAMPLE_PATH "${GUDHI_DOXYGEN_EXAMPLE_PATH} ${GUDHI_DOXYGEN_SOURCE_PREFIX}/${GUDHI_MODULE}/example/ \\ \n") + endif() + if(EXISTS "${GUDHI_DOXYGEN_SOURCE_PREFIX}/${GUDHI_MODULE}/utilities/") + set(GUDHI_DOXYGEN_EXAMPLE_PATH "${GUDHI_DOXYGEN_EXAMPLE_PATH} ${GUDHI_DOXYGEN_SOURCE_PREFIX}/${GUDHI_MODULE}/utilities/ \\ \n") + endif() + endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) + set(GUDHI_DOXYGEN_COMMON_DOC_PATH "${GUDHI_DOXYGEN_SOURCE_PREFIX}/common/doc") + set(GUDHI_DOXYGEN_UTILS_PATH "*/utilities") + endif() + if (CMAKE_PROJECT_NAME STREQUAL "GUDHI") + # Set Doxyfile.in variables for the user version + set(GUDHI_DOXYGEN_SOURCE_PREFIX "${CMAKE_SOURCE_DIR}") + foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) + if(EXISTS "${GUDHI_DOXYGEN_SOURCE_PREFIX}/doc/${GUDHI_MODULE}") + set(GUDHI_DOXYGEN_IMAGE_PATH "${GUDHI_DOXYGEN_IMAGE_PATH} ${GUDHI_DOXYGEN_SOURCE_PREFIX}/doc/${GUDHI_MODULE}/ \\ \n") + endif() + if(EXISTS "${GUDHI_DOXYGEN_SOURCE_PREFIX}/example/${GUDHI_MODULE}") + set(GUDHI_DOXYGEN_EXAMPLE_PATH "${GUDHI_DOXYGEN_EXAMPLE_PATH} ${GUDHI_DOXYGEN_SOURCE_PREFIX}/example/${GUDHI_MODULE}/ \\ \n") + endif() + if(EXISTS "${GUDHI_DOXYGEN_SOURCE_PREFIX}/utilities/${GUDHI_MODULE}") + set(GUDHI_DOXYGEN_EXAMPLE_PATH "${GUDHI_DOXYGEN_EXAMPLE_PATH} ${GUDHI_DOXYGEN_SOURCE_PREFIX}/utilities/${GUDHI_MODULE}/ \\ \n") + endif() + endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) + set(GUDHI_DOXYGEN_COMMON_DOC_PATH "${GUDHI_DOXYGEN_SOURCE_PREFIX}/doc/common") + set(GUDHI_DOXYGEN_UTILS_PATH "utilities/*") endif() + + configure_file(${GUDHI_DOXYGEN_SOURCE_PREFIX}/Doxyfile.in "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" @ONLY) + + add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen in 'html' directory" VERBATIM) else() set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "cpp-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() diff --git a/src/cmake/modules/GUDHI_user_version_target.cmake b/src/cmake/modules/GUDHI_user_version_target.cmake index e4f39aae..9e76c3d9 100644 --- a/src/cmake/modules/GUDHI_user_version_target.cmake +++ b/src/cmake/modules/GUDHI_user_version_target.cmake @@ -14,14 +14,7 @@ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${GUDHI_USER_VERSION_DIR} COMMENT "user_version creation in ${GUDHI_USER_VERSION_DIR}") -foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) - set(GUDHI_DOXYGEN_IMAGE_PATH "${GUDHI_DOXYGEN_IMAGE_PATH} doc/${GUDHI_MODULE}/ \\ \n") -endforeach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) - -# Generate Doxyfile for Doxygen - cf. root CMakeLists.txt for explanation -configure_file(${CMAKE_SOURCE_DIR}/src/Doxyfile.in "${CMAKE_CURRENT_BINARY_DIR}/src/Doxyfile" @ONLY) -add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E - copy ${CMAKE_CURRENT_BINARY_DIR}/src/Doxyfile ${GUDHI_USER_VERSION_DIR}/Doxyfile) +file(COPY "${CMAKE_SOURCE_DIR}/src/Doxyfile.in" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") # Generate bib files for Doxygen - cf. root CMakeLists.txt for explanation string(TIMESTAMP GUDHI_VERSION_YEAR "%Y") @@ -48,6 +41,8 @@ add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/src/GUDHIConfig.cmake.in ${GUDHI_USER_VERSION_DIR}/GUDHIConfig.cmake.in) add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/CMakeGUDHIVersion.txt ${GUDHI_USER_VERSION_DIR}/CMakeGUDHIVersion.txt) +add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E + copy ${CMAKE_SOURCE_DIR}/src/Doxyfile.in ${GUDHI_USER_VERSION_DIR}/Doxyfile.in) # As cython generates .cpp files in source, we have to copy all except cpp files from python directory file(GLOB_RECURSE PYTHON_FILES ${CMAKE_SOURCE_DIR}/${GUDHI_PYTHON_PATH}/*) diff --git a/src/common/doc/examples.h b/src/common/doc/examples.h index 474f8699..b557727b 100644 --- a/src/common/doc/examples.h +++ b/src/common/doc/examples.h @@ -1,96 +1,98 @@ // 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 /*! @file Examples - * @example Alpha_complex/Alpha_complex_from_off.cpp - * @example Alpha_complex/Alpha_complex_from_points.cpp - * @example Bottleneck_distance/bottleneck_basic_example.cpp - * @example Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp - * @example Witness_complex/example_nearest_landmark_table.cpp - * @example Witness_complex/example_witness_complex_off.cpp - * @example Witness_complex/example_witness_complex_sphere.cpp - * @example Witness_complex/example_strong_witness_complex_off.cpp - * @example Simplex_tree/mini_simplex_tree.cpp - * @example Simplex_tree/graph_expansion_with_blocker.cpp - * @example Simplex_tree/simple_simplex_tree.cpp - * @example Simplex_tree/simplex_tree_from_cliques_of_graph.cpp - * @example Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp - * @example Simplex_tree/cech_complex_cgal_mini_sphere_3d.cpp - * @example Persistent_cohomology/plain_homology.cpp - * @example Persistent_cohomology/persistence_from_file.cpp - * @example Persistent_cohomology/rips_persistence_step_by_step.cpp - * @example Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp - * @example Persistent_cohomology/custom_persistence_sort.cpp - * @example Persistent_cohomology/persistence_from_simple_simplex_tree.cpp - * @example Persistent_cohomology/rips_multifield_persistence.cpp - * @example Skeleton_blocker/Skeleton_blocker_from_simplices.cpp - * @example Skeleton_blocker/Skeleton_blocker_iteration.cpp - * @example Skeleton_blocker/Skeleton_blocker_link.cpp - * @example Contraction/Garland_heckbert.cpp - * @example Contraction/Rips_contraction.cpp - * @example Bitmap_cubical_complex/Random_bitmap_cubical_complex.cpp - * @example common/example_CGAL_3D_points_off_reader.cpp - * @example common/example_vector_double_points_off_reader.cpp - * @example common/example_CGAL_points_off_reader.cpp - * @example Rips_complex/example_one_skeleton_rips_from_distance_matrix.cpp - * @example Rips_complex/example_one_skeleton_rips_from_points.cpp - * @example Rips_complex/example_rips_complex_from_csv_distance_matrix_file.cpp - * @example Rips_complex/example_rips_complex_from_off_file.cpp - * @example Persistence_representations/persistence_intervals.cpp - * @example Persistence_representations/persistence_vectors.cpp - * @example Persistence_representations/persistence_heat_maps.cpp - * @example Persistence_representations/persistence_landscape_on_grid.cpp - * @example Persistence_representations/persistence_landscape.cpp - * @example Tangential_complex/example_basic.cpp - * @example Tangential_complex/example_with_perturb.cpp - * @example Subsampling/example_custom_distance.cpp - * @example Subsampling/example_choose_n_farthest_points.cpp - * @example Subsampling/example_sparsify_point_set.cpp - * @example Subsampling/example_pick_n_random_points.cpp - * @example Nerve_GIC/CoordGIC.cpp - * @example Nerve_GIC/Nerve.cpp - * @example Nerve_GIC/FuncGIC.cpp - * @example Nerve_GIC/VoronoiGIC.cpp - * @example Spatial_searching/example_spatial_searching.cpp - * @example Alpha_complex/alpha_complex_3d_persistence.cpp - * @example Alpha_complex/alpha_complex_persistence.cpp - * @example Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp - * @example Bottleneck_distance/bottleneck_distance.cpp - * @example Witness_complex/weak_witness_persistence.cpp - * @example Witness_complex/strong_witness_persistence.cpp - * @example Bitmap_cubical_complex/cubical_complex_persistence.cpp - * @example Bitmap_cubical_complex/periodic_cubical_complex_persistence.cpp - * @example common/off_file_from_shape_generator.cpp - * @example Rips_complex/rips_distance_matrix_persistence.cpp - * @example Rips_complex/rips_persistence.cpp - * @example Persistence_representations/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp - * @example Persistence_representations/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp - * @example Persistence_representations/persistence_landscapes_on_grid/compute_scalar_product_of_landscapes_on_grid.cpp - * @example Persistence_representations/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp - * @example Persistence_representations/persistence_landscapes_on_grid/average_landscapes_on_grid.cpp - * @example Persistence_representations/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp - * @example Persistence_representations/persistence_intervals/compute_number_of_dominant_intervals.cpp - * @example Persistence_representations/persistence_intervals/plot_persistence_Betti_numbers.cpp - * @example Persistence_representations/persistence_intervals/plot_persistence_intervals.cpp - * @example Persistence_representations/persistence_intervals/plot_histogram_of_intervals_lengths.cpp - * @example Persistence_representations/persistence_intervals/compute_bottleneck_distance.cpp - * @example Persistence_representations/persistence_heat_maps/create_pssk.cpp - * @example Persistence_representations/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp - * @example Persistence_representations/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp - * @example Persistence_representations/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp - * @example Persistence_representations/persistence_heat_maps/compute_scalar_product_of_persistence_heat_maps.cpp - * @example Persistence_representations/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp - * @example Persistence_representations/persistence_heat_maps/average_persistence_heat_maps.cpp - * @example Persistence_representations/persistence_heat_maps/plot_persistence_heat_map.cpp - * @example Persistence_representations/persistence_heat_maps/create_persistence_heat_maps.cpp - * @example Persistence_representations/persistence_vectors/plot_persistence_vectors.cpp - * @example Persistence_representations/persistence_vectors/compute_distance_of_persistence_vectors.cpp - * @example Persistence_representations/persistence_vectors/average_persistence_vectors.cpp - * @example Persistence_representations/persistence_vectors/create_persistence_vectors.cpp - * @example Persistence_representations/persistence_vectors/compute_scalar_product_of_persistence_vectors.cpp - * @example Persistence_representations/persistence_landscapes/average_landscapes.cpp - * @example Persistence_representations/persistence_landscapes/compute_scalar_product_of_landscapes.cpp - * @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 + * \section Alpha_complex_examples Alpha complex + * @example Alpha_complex_from_off.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 mini_simplex_tree.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 + * @example rips_persistence_via_boundary_matrix.cpp + * @example custom_persistence_sort.cpp + * @example persistence_from_simple_simplex_tree.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 + * @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 rips_persistence.cpp + * @example persistence_landscapes_on_grid/create_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_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_p_h_m_weighted_by_distance_from_diagonal.cpp + * @example persistence_heat_maps/average_persistence_heat_maps.cpp + * @example persistence_heat_maps/plot_persistence_heat_map.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/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_landscapes/create_landscapes.cpp + * @example persistence_landscapes/compute_distance_of_landscapes.cpp + * @example persistence_landscapes/plot_landscapes.cpp */ diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index c2e63a24..313184b6 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -40,11 +40,8 @@ make \endverbatim * \subsection documentationgeneration Documentation * To generate the documentation, Doxygen is required. * Run the following command in a terminal: -\verbatim -make doxygen -# Documentation will be generated in the folder YYYY-MM-DD-hh-mm-ss_GUDHI_X.Y.Z/doc/html/ -# You can customize the directory name by calling `cmake -DUSER_VERSION_DIR=/my/custom/folder` -\endverbatim + * \verbatim make doxygen \endverbatim + * Documentation will be generated in a folder named html. * * \subsection helloworld Hello world ! * The Hello world for GUDHI @@ -57,7 +54,7 @@ make doxygen * * The following example requires the GNU Multiple Precision Arithmetic * Library (GMP) and will not be built if GMP is not installed: - * \li + * \li * Persistent_cohomology/rips_multifield_persistence.cpp * * Having GMP version 4.2 or higher installed is recommended. @@ -75,55 +72,55 @@ make doxygen * * The following examples/utilities require the Computational Geometry Algorithms * Library (CGAL \cite cgal:eb-19b) and will not be built if CGAL version 4.11.0 or higher is not installed: - * \li + * \li * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp - * \li + * \li * Witness_complex/strong_witness_persistence.cpp - * \li + * \li * Witness_complex/weak_witness_persistence.cpp - * \li + * \li * Witness_complex/example_strong_witness_complex_off.cpp - * \li + * \li * Witness_complex/example_witness_complex_off.cpp - * \li + * \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 + * \li * Alpha_complex/alpha_complex_persistence.cpp - * \li + * \li * Persistent_cohomology/custom_persistence_sort.cpp - * \li + * \li * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp - * \li + * \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 + * \li * Spatial_searching/example_spatial_searching.cpp - * \li + * \li * Subsampling/example_choose_n_farthest_points.cpp - * \li + * \li * Subsampling/example_pick_n_random_points.cpp - * \li + * \li * Subsampling/example_sparsify_point_set.cpp - * \li + * \li * Tangential_complex/example_basic.cpp - * \li + * \li * Tangential_complex/example_with_perturb.cpp - * \li + * \li * Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp - * \li + * \li * Alpha_complex/alpha_complex_3d_persistence.cpp * * \subsection eigen Eigen @@ -133,41 +130,41 @@ make doxygen * * 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 + * \li * Alpha_complex/alpha_complex_persistence.cpp - * \li + * \li * Alpha_complex/alpha_complex_3d_persistence.cpp - * \li + * \li * Alpha_complex/Weighted_alpha_complex_3d_from_points.cpp - * \li + * \li * Bottleneck_distance/alpha_rips_persistence_bottleneck_distance.cpp.cpp - * \li + * \li * Persistent_cohomology/custom_persistence_sort.cpp - * \li + * \li * Spatial_searching/example_spatial_searching.cpp - * \li + * \li * Subsampling/example_choose_n_farthest_points.cpp - * \li + * \li * Subsampling/example_pick_n_random_points.cpp - * \li + * \li * Subsampling/example_sparsify_point_set.cpp - * \li + * \li * Tangential_complex/example_basic.cpp - * \li + * \li * Tangential_complex/example_with_perturb.cpp - * \li + * \li * Witness_complex/strong_witness_persistence.cpp - * \li + * \li * Witness_complex/weak_witness_persistence.cpp - * \li + * \li * Witness_complex/example_strong_witness_complex_off.cpp - * \li + * \li * Witness_complex/example_witness_complex_off.cpp - * \li + * \li * Witness_complex/example_witness_complex_sphere.cpp * * \subsection tbb Threading Building Blocks @@ -178,67 +175,67 @@ make doxygen * 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 + * \li * Alpha_complex/alpha_complex_3d_persistence.cpp - * \li + * \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 + * \li * Simplex_tree/simple_simplex_tree.cpp - * \li + * \li * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp - * \li + * \li * Simplex_tree/simplex_tree_from_cliques_of_graph.cpp - * \li + * \li * Simplex_tree/graph_expansion_with_blocker.cpp - * \li + * \li * Persistent_cohomology/alpha_complex_3d_persistence.cpp - * \li + * \li * Persistent_cohomology/alpha_complex_persistence.cpp - * \li + * \li * Persistent_cohomology/rips_persistence_via_boundary_matrix.cpp - * \li + * \li * Persistent_cohomology/persistence_from_file.cpp - * \li + * \li * Persistent_cohomology/persistence_from_simple_simplex_tree.cpp - * \li + * \li * Persistent_cohomology/plain_homology.cpp - * \li + * \li * Persistent_cohomology/rips_multifield_persistence.cpp - * \li + * \li * Persistent_cohomology/rips_persistence_step_by_step.cpp - * \li + * \li * Persistent_cohomology/custom_persistence_sort.cpp - * \li + * \li * Rips_complex/example_one_skeleton_rips_from_points.cpp - * \li + * \li * Rips_complex/example_rips_complex_from_off_file.cpp - * \li + * \li * Rips_complex/rips_distance_matrix_persistence.cpp - * \li + * \li * Rips_complex/rips_persistence.cpp - * \li + * \li * Witness_complex/strong_witness_persistence.cpp - * \li + * \li * Witness_complex/weak_witness_persistence.cpp - * \li + * \li * Witness_complex/example_nearest_landmark_table.cpp * * \section Contributions Bug reports and contributions diff --git a/src/common/include/gudhi/Points_3D_off_io.h b/src/common/include/gudhi/Points_3D_off_io.h index 39b79c96..4f74fd4b 100644 --- a/src/common/include/gudhi/Points_3D_off_io.h +++ b/src/common/include/gudhi/Points_3D_off_io.h @@ -125,7 +125,7 @@ class Points_3D_off_visitor_reader { * This example loads points from an OFF file and builds a vector of CGAL points in dimension 3. * Then, it is asked to display the points. * - * @include common/example_CGAL_3D_points_off_reader.cpp + * @include example_CGAL_3D_points_off_reader.cpp * * When launching: * @@ -134,7 +134,7 @@ class Points_3D_off_visitor_reader { * * the program output is: * - * @include common/cgal3Doffreader_result.txt + * @include cgal3Doffreader_result.txt */ template class Points_3D_off_reader { diff --git a/src/common/include/gudhi/Points_off_io.h b/src/common/include/gudhi/Points_off_io.h index 9dc40568..3aa8afd8 100644 --- a/src/common/include/gudhi/Points_off_io.h +++ b/src/common/include/gudhi/Points_off_io.h @@ -107,7 +107,7 @@ class Points_off_visitor_reader { * This example loads points from an OFF file and builds a vector of points (vector of double). * Then, it is asked to display the points. * - * \include common/example_vector_double_points_off_reader.cpp + * \include example_vector_double_points_off_reader.cpp * * When launching: * @@ -116,7 +116,7 @@ class Points_off_visitor_reader { * * the program outputs a file ../../data/points/alphacomplexdoc.off.txt: * - * \include common/vectordoubleoffreader_result.txt + * \include vectordoubleoffreader_result.txt */ template class Points_off_reader { -- cgit v1.2.3 From df9daf64aa7623ac188a5842a90162d65a54b07e Mon Sep 17 00:00:00 2001 From: Hind Date: Tue, 27 Apr 2021 18:01:00 +0200 Subject: Rename and reorganize point generators module --- src/python/CMakeLists.txt | 10 ++-- .../alpha_complex_from_generated_points_example.py | 36 ------------- ...plex_from_generated_points_on_sphere_example.py | 36 +++++++++++++ src/python/gudhi/datasets/generators/__init__.py | 0 src/python/gudhi/datasets/generators/sphere.cc | 61 ++++++++++++++++++++++ src/python/gudhi/random_point_generators.cc | 61 ---------------------- 6 files changed, 103 insertions(+), 101 deletions(-) delete mode 100644 src/python/example/alpha_complex_from_generated_points_example.py create mode 100644 src/python/example/alpha_complex_from_generated_points_on_sphere_example.py create mode 100644 src/python/gudhi/datasets/generators/__init__.py create mode 100644 src/python/gudhi/datasets/generators/sphere.cc delete mode 100644 src/python/gudhi/random_point_generators.cc (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 87f10a1a..bcdd0741 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}'random_point_generators', ") + set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'datasets/generators', ") 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}'random_point_generators', ") + set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/sphere', ") set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'bottleneck', ") set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'nerve_gic', ") endif () @@ -264,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/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/datasets/generators") + # Some files for pip package file(COPY "introduction.rst" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") @@ -427,10 +429,10 @@ if(PYTHONINTERP_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") - add_test(NAME alpha_complex_from_generated_points_example_py_test + add_test(NAME alpha_complex_from_generated_points_on_sphere_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_generated_points_example.py") + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_generated_points_on_sphere_example.py") add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" diff --git a/src/python/example/alpha_complex_from_generated_points_example.py b/src/python/example/alpha_complex_from_generated_points_example.py deleted file mode 100644 index c2562d8a..00000000 --- a/src/python/example/alpha_complex_from_generated_points_example.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -from gudhi import random_point_generators -from gudhi import AlphaComplex - - -""" 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 -""" - -__author__ = "Hind Montassif" -__copyright__ = "Copyright (C) 2021 Inria" -__license__ = "MIT" - -print("#####################################################################") -print("AlphaComplex creation from generated points") - - -# Generate a circle: 50 points; dim 2; radius 1 -points = random_point_generators.generate_points_on_sphere_d(50, 2, 1) - -# Create an alpha complex -alpha_complex = AlphaComplex(points=points) -simplex_tree = alpha_complex.create_simplex_tree() - -result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ - repr(simplex_tree.num_simplices()) + ' simplices - ' + \ - repr(simplex_tree.num_vertices()) + ' vertices.' -print(result_str) - diff --git a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py new file mode 100644 index 00000000..2de9ec08 --- /dev/null +++ b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +from gudhi.datasets.generators import sphere +from gudhi import AlphaComplex + + +""" 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 +""" + +__author__ = "Hind Montassif" +__copyright__ = "Copyright (C) 2021 Inria" +__license__ = "MIT" + +print("#####################################################################") +print("AlphaComplex creation from generated points on sphere") + + +# Generate a circle: 50 points; dim 2; radius 1 +points = sphere.generate_random_points(50, 2, 1) + +# Create an alpha complex +alpha_complex = AlphaComplex(points=points) +simplex_tree = alpha_complex.create_simplex_tree() + +result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ + repr(simplex_tree.num_simplices()) + ' simplices - ' + \ + repr(simplex_tree.num_vertices()) + ' vertices.' +print(result_str) + 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/sphere.cc b/src/python/gudhi/datasets/generators/sphere.cc new file mode 100644 index 00000000..79392ef0 --- /dev/null +++ b/src/python/gudhi/datasets/generators/sphere.cc @@ -0,0 +1,61 @@ +/* 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_sphere(size_t num_points, int dim, double radius) { + + py::array_t points({num_points, (size_t)dim}); + + py::buffer_info buf = points.request(); + double *ptr = static_cast(buf.ptr); + + GUDHI_CHECK(num_points == buf.shape[0], "Py array first dimension not matching num_points on sphere"); + GUDHI_CHECK(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(num_points, dim, radius); + + for (size_t i = 0; i < num_points; i++) + for (int j = 0; j < dim; j++) + ptr[i*dim+j] = points_generated[i][j]; + + return points; +} + +PYBIND11_MODULE(sphere, m) { + m.attr("__license__") = "LGPL v3"; + m.def("generate_random_points", &generate_points_on_sphere, + py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, + R"pbdoc( + Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d + + :param num_points: The number of points to be generated. + :type num_points: unsigned integer + :param dim: The dimension. + :type dim: integer + :param radius: The radius. + :type radius: float + :rtype: numpy array of float + :returns: the generated points on a sphere. + )pbdoc"); +} diff --git a/src/python/gudhi/random_point_generators.cc b/src/python/gudhi/random_point_generators.cc deleted file mode 100644 index 6eb40429..00000000 --- a/src/python/gudhi/random_point_generators.cc +++ /dev/null @@ -1,61 +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_sphere(size_t num_points, int dim, double radius) { - - py::array_t points({num_points, (size_t)dim}); - - py::buffer_info buf = points.request(); - double *ptr = static_cast(buf.ptr); - - GUDHI_CHECK(num_points == buf.shape[0], "Py array first dimension not matching num_points on sphere"); - GUDHI_CHECK(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(num_points, dim, radius); - - for (size_t i = 0; i < num_points; i++) - for (int j = 0; j < dim; j++) - ptr[i*dim+j] = points_generated[i][j]; - - return points; -} - -PYBIND11_MODULE(random_point_generators, m) { - m.attr("__license__") = "LGPL v3"; - m.def("generate_points_on_sphere_d", &generate_points_on_sphere, - py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, - R"pbdoc( - Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d - - :param num_points: The number of points to be generated. - :type num_points: unsigned integer - :param dim: The dimension. - :type dim: integer - :param radius: The radius. - :type radius: float - :rtype: numpy array of float - :returns: the generated points on a sphere. - )pbdoc"); -} -- cgit v1.2.3 From e90121bf0c62de00e0d10548f833632f3dfdf799 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 28 Apr 2021 08:09:21 +0200 Subject: update Doxyfile --- src/Doxyfile.in | 457 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 311 insertions(+), 146 deletions(-) (limited to 'src') diff --git a/src/Doxyfile.in b/src/Doxyfile.in index 4784b915..ae8db1a3 100644 --- a/src/Doxyfile.in +++ b/src/Doxyfile.in @@ -1,4 +1,4 @@ -# Doxyfile 1.8.6 +# Doxyfile 1.8.13 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -46,10 +46,10 @@ PROJECT_NUMBER = "@GUDHI_VERSION@" PROJECT_BRIEF = "C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding." -# With the PROJECT_LOGO tag one can specify an logo or icon that is included in -# the documentation. The maximum height of the logo should not exceed 55 pixels -# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo -# to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = @@ -60,7 +60,7 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where @@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. @@ -85,14 +93,14 @@ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -127,7 +135,7 @@ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -153,7 +161,8 @@ STRIP_FROM_PATH = # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = include concept +STRIP_FROM_INC_PATH = include \ + concept # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -197,9 +206,9 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a -# new page for each member. If set to NO, the documentation of a member will be -# part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO @@ -261,11 +270,14 @@ OPTIMIZE_OUTPUT_VHDL = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # -# Note For files without extension you can use no_extension as a placeholder. +# Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. @@ -282,10 +294,19 @@ EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES @@ -325,13 +346,20 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent @@ -390,7 +418,7 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -400,35 +428,35 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = NO -# This flag is only useful for Objective-C code. When set to YES local methods, +# This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO only methods in the interface are +# included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. @@ -453,21 +481,21 @@ HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set -# to NO these classes will be included in the various overviews. This option has -# no effect if EXTRACT_ALL is enabled. +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO these declarations will be +# (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO these +# documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -481,7 +509,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES upper-case letters are also +# names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. @@ -490,12 +518,19 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES the +# their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -523,14 +558,14 @@ INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. Note that +# name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. @@ -575,27 +610,25 @@ SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the -# todo list. This list is created by putting \todo commands in the -# documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = NO -# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the -# test list. This list is created by putting \test commands in the -# documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = NO -# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = NO -# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. @@ -620,8 +653,8 @@ ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES the list -# will mention the files that were used to generate the documentation. +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES @@ -669,8 +702,7 @@ LAYOUT_FILE = # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. +# search path. See also \cite for info how to create references. CITE_BIB_FILES = @CMAKE_SOURCE_DIR@/biblio/bibliography.bib \ @CMAKE_SOURCE_DIR@/biblio/how_to_cite_cgal.bib \ @@ -688,7 +720,7 @@ CITE_BIB_FILES = @CMAKE_SOURCE_DIR@/biblio/bibliography.bib \ QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -696,7 +728,7 @@ QUIET = NO WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. @@ -713,12 +745,18 @@ WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO doxygen will only warn about wrong or incomplete parameter -# documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated @@ -742,7 +780,7 @@ WARN_LOGFILE = # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with -# spaces. +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @CMAKE_SOURCE_DIR@ @@ -758,14 +796,30 @@ INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank the -# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, -# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, -# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, -# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, -# *.qsf, *.as and *.js. - -#FILE_PATTERNS = +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.md \ + *.mm \ # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -780,14 +834,14 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = @CMAKE_SOURCE_DIR@/data/ \ - @CMAKE_SOURCE_DIR@/ext/ \ +EXCLUDE = @CMAKE_SOURCE_DIR@/data/ \ + @CMAKE_SOURCE_DIR@/ext/ \ @CMAKE_SOURCE_DIR@/README.md \ @CMAKE_SOURCE_DIR@/.github \ @CMAKE_CURRENT_BINARY_DIR@/new_gudhi_version_creation.md \ @GUDHI_DOXYGEN_SOURCE_PREFIX@/GudhUI/ \ - @GUDHI_DOXYGEN_SOURCE_PREFIX@/cmake/ \ - @GUDHI_DOXYGEN_SOURCE_PREFIX@/python/ \ + @GUDHI_DOXYGEN_SOURCE_PREFIX@/cmake/ \ + @GUDHI_DOXYGEN_SOURCE_PREFIX@/python/ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -821,7 +875,7 @@ EXCLUDE_SYMBOLS = # command). EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/biblio/ \ - @CMAKE_SOURCE_DIR@/data/ \ + @CMAKE_SOURCE_DIR@/data/ \ @GUDHI_DOXYGEN_EXAMPLE_PATH@ # If the value of the EXAMPLE_PATH tag contains directories, you can use the @@ -829,7 +883,7 @@ EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/biblio/ \ # *.h) to filter out the source-files in the directories. If left blank all # files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands @@ -858,6 +912,10 @@ IMAGE_PATH = @GUDHI_DOXYGEN_IMAGE_PATH@ # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. INPUT_FILTER = @@ -867,11 +925,15 @@ INPUT_FILTER = # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER ) will also be used to filter the input files that are used for +# INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. @@ -931,7 +993,7 @@ REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. @@ -978,6 +1040,25 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1008,7 +1089,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES @@ -1070,13 +1151,15 @@ HTML_FOOTER = @GUDHI_DOXYGEN_COMMON_DOC_PATH@/footer.html HTML_STYLESHEET = @GUDHI_DOXYGEN_COMMON_DOC_PATH@/stylesheet.css -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1092,7 +1175,7 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the stylesheet and background images according to +# will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 @@ -1123,8 +1206,9 @@ HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES @@ -1220,28 +1304,29 @@ GENERATE_HTMLHELP = NO CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# The GENERATE_CHI flag controls if a separate .chi index file is generated ( -# YES) or that it should be included in the master .chm file ( NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1354,7 +1439,7 @@ DISABLE_INDEX = YES # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has @@ -1382,7 +1467,7 @@ ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1411,7 +1496,7 @@ FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. @@ -1448,7 +1533,8 @@ MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2 # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +MATHJAX_EXTENSIONS = TeX/AMSmath \ + TeX/AMSsymbols # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site @@ -1481,11 +1567,11 @@ SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. @@ -1497,7 +1583,7 @@ SERVER_BASED_SEARCH = NO # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # @@ -1510,7 +1596,7 @@ EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. @@ -1548,7 +1634,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1579,7 +1665,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1597,13 +1683,18 @@ COMPACT_LATEX = NO PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. To get the times font for -# instance you can specify -# EXTRA_PACKAGES=times +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. -EXTRA_PACKAGES = amsfonts amsmath amssymb +EXTRA_PACKAGES = amsfonts \ + amsmath \ + amssymb # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the # generated LaTeX document. The header should contain everything until the first @@ -1613,23 +1704,36 @@ EXTRA_PACKAGES = amsfonts amsmath amssymb # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or @@ -1647,8 +1751,8 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1689,11 +1793,19 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -1708,7 +1820,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1745,11 +1857,21 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -1773,6 +1895,13 @@ MAN_OUTPUT = man MAN_EXTENSION = .3 +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without @@ -1786,7 +1915,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -1800,7 +1929,7 @@ GENERATE_XML = NO XML_OUTPUT = xml -# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -1813,7 +1942,7 @@ XML_PROGRAMLISTING = YES # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -1827,14 +1956,23 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen -# Definitions (see http://autogen.sf.net) file that captures the structure of -# the code including all documentation. Note that this feature is still -# experimental and incomplete at the moment. +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -1843,7 +1981,7 @@ GENERATE_AUTOGEN_DEF = NO # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -1851,7 +1989,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -1859,9 +1997,9 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO the +# understand what is going on. On the other hand, if this tag is set to NO, the # size of the Perl module output will be much smaller and Perl will parse it # just the same. # The default value is: YES. @@ -1881,14 +2019,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names -# in the source code. If set to NO only conditional compilation will be +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. @@ -1904,7 +2042,7 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES -# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1946,9 +2084,9 @@ PREDEFINED = protected=private EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1968,7 +2106,7 @@ SKIP_FUNCTION_MACROS = YES # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include +# Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. @@ -1980,20 +2118,21 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external class will be listed in the -# class index. If set to NO only the inherited external classes will be listed. +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. # The default value is: NO. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in -# the modules index. If set to NO, only the current project's groups will be +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. EXTERNAL_GROUPS = YES -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. @@ -2010,7 +2149,7 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more @@ -2035,7 +2174,7 @@ MSCGEN_PATH = DIA_PATH = -# If set to YES, the inheritance and collaboration graphs will hide inheritance +# If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2046,7 +2185,7 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: NO. +# The default value is: YES. HAVE_DOT = YES @@ -2060,7 +2199,7 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font n the dot files that doxygen +# When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by @@ -2108,7 +2247,7 @@ COLLABORATION_GRAPH = NO GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2160,7 +2299,8 @@ INCLUDED_BY_GRAPH = NO # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2171,7 +2311,8 @@ CALL_GRAPH = NO # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2194,11 +2335,17 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, jpg, gif and svg. +# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, +# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, +# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2241,6 +2388,24 @@ MSCFILE_DIRS = DIAFILE_DIRS = +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized @@ -2277,7 +2442,7 @@ MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support # this, this feature is disabled by default. @@ -2294,7 +2459,7 @@ DOT_MULTI_TARGETS = YES GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -- cgit v1.2.3 From e498bc8f838ab0cc433f9f67206088064b52b6fa Mon Sep 17 00:00:00 2001 From: tlacombe Date: Wed, 28 Apr 2021 10:54:55 +0200 Subject: enhancing the doc --- src/python/gudhi/wasserstein/wasserstein.py | 37 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 61505d03..5196b280 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -210,32 +210,37 @@ def _warn_infty(matching): return np.inf - def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enable_autodiff=False, keep_essential_parts=True): ''' - :param X: (n x 2) numpy.array encoding the first diagram. Can contain essential parts (points with infinite - coordinates). - :param Y: (m x 2) numpy.array encoding the second diagram. - :param matching: if True, computes and returns the optimal matching between X and Y, encoded as - a (n x 2) np.array [...[i,j]...], meaning the i-th point in X is matched to - the j-th point in Y, with the convention (-1) represents the diagonal. - Note that if the cost is +inf (essential parts have different number of points, - then the optimal matching will be set to `None`. - :param order: exponent for Wasserstein. Default value is 1. + Compute the Wasserstein distance between persistence diagram using Python Optimal Transport backend. + Diagrams can contain points with infinity coordinates (essential parts). + Points with (-inf,-inf) and (+inf,+inf) coordinates are considered as belonging to the diagonal. + If the distance between two diagrams is +inf (which happens if the cardinalities of essential + parts differ) and optimal matching is required, it will be set to ``None``. + + :param X: The first diagram. + :type X: n x 2 numpy.array + :param Y: The second diagram. + :type Y: m x 2 numpy.array + :param matching: if ``True``, computes and returns the optimal matching between X and Y, encoded as + a (n x 2) np.array [...[i,j]...], meaning the i-th point in X is matched to + the j-th point in Y, with the convention that (-1) represents the diagonal. + :param order: Wasserstein exponent W_q + :type order: float :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2). - Default value is `np.inf`. - :param enable_autodiff: If X and Y are torch.tensor or tensorflow.Tensor, make the computation + :type internal_p: float + :param enable_autodiff: If X and Y are ``torch.tensor`` or ``tensorflow.Tensor``, make the computation transparent to automatic differentiation. This requires the package EagerPy and is currently incompatible - with `matching=True` and with `keep_essential_parts=True`. + with ``matching=True`` and with ``keep_essential_parts=True``. .. note:: This considers the function defined on the coordinates of the off-diagonal finite points of X and Y and lets the various frameworks compute its gradient. It never pulls new points from the diagonal. :type enable_autodiff: bool - :param keep_essential_parts: If False, only considers the finite points in the diagrams. - Otherwise, computes the distance between the essential parts separately. + :param keep_essential_parts: If ``False``, only considers the finite points in the diagrams. + Otherwise, include essential parts in cost and matching computation. :type keep_essential_parts: bool - :returns: the Wasserstein distance of order q (1 <= q < infinity) between persistence diagrams with + :returns: The Wasserstein distance of order q (1 <= q < infinity) between persistence diagrams with respect to the internal_p-norm as ground metric. If matching is set to True, also returns the optimal matching between X and Y. If cost is +inf, any matching is optimal and thus it returns `None` instead. -- cgit v1.2.3 From 9e59ca4f4497969ae6d159407e913c31dba7d6c5 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Wed, 28 Apr 2021 10:56:45 +0200 Subject: enhancing the doc2 --- src/python/gudhi/wasserstein/wasserstein.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/wasserstein/wasserstein.py b/src/python/gudhi/wasserstein/wasserstein.py index 5196b280..dc18806e 100644 --- a/src/python/gudhi/wasserstein/wasserstein.py +++ b/src/python/gudhi/wasserstein/wasserstein.py @@ -226,7 +226,7 @@ def wasserstein_distance(X, Y, matching=False, order=1., internal_p=np.inf, enab :param matching: if ``True``, computes and returns the optimal matching between X and Y, encoded as a (n x 2) np.array [...[i,j]...], meaning the i-th point in X is matched to the j-th point in Y, with the convention that (-1) represents the diagonal. - :param order: Wasserstein exponent W_q + :param order: Wasserstein exponent q (1 <= q < infinity). :type order: float :param internal_p: Ground metric on the (upper-half) plane (i.e. norm L^p in R^2). :type internal_p: float -- cgit v1.2.3 From d68ddc94bd82c48a4433ae0b3b1b3f10c167ed0b Mon Sep 17 00:00:00 2001 From: Hind Date: Wed, 28 Apr 2021 14:05:03 +0200 Subject: Add points (dataset type) before the underlying model (sphere) as a module --- src/python/CMakeLists.txt | 6 +-- ...plex_from_generated_points_on_sphere_example.py | 2 +- src/python/gudhi/datasets/generators/__init__.py | 0 .../gudhi/datasets/generators/points/__init__.py | 0 .../gudhi/datasets/generators/points/sphere.cc | 61 ++++++++++++++++++++++ src/python/gudhi/datasets/generators/sphere.cc | 61 ---------------------- 6 files changed, 65 insertions(+), 65 deletions(-) delete mode 100644 src/python/gudhi/datasets/generators/__init__.py create mode 100644 src/python/gudhi/datasets/generators/points/__init__.py create mode 100644 src/python/gudhi/datasets/generators/points/sphere.cc delete mode 100644 src/python/gudhi/datasets/generators/sphere.cc (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index bcdd0741..ef9dc3ab 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', ") + 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', ") @@ -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/sphere', ") + set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/points/sphere', ") 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/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/datasets/generators") + file(COPY "gudhi/datasets/generators/points/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/datasets/generators/points") # Some files for pip package diff --git a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py index 2de9ec08..2b023bbe 100644 --- a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py +++ b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from gudhi.datasets.generators import sphere +from gudhi.datasets.generators.points import sphere from gudhi import AlphaComplex diff --git a/src/python/gudhi/datasets/generators/__init__.py b/src/python/gudhi/datasets/generators/__init__.py deleted file mode 100644 index e69de29b..00000000 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/sphere.cc b/src/python/gudhi/datasets/generators/points/sphere.cc new file mode 100644 index 00000000..79392ef0 --- /dev/null +++ b/src/python/gudhi/datasets/generators/points/sphere.cc @@ -0,0 +1,61 @@ +/* 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_sphere(size_t num_points, int dim, double radius) { + + py::array_t points({num_points, (size_t)dim}); + + py::buffer_info buf = points.request(); + double *ptr = static_cast(buf.ptr); + + GUDHI_CHECK(num_points == buf.shape[0], "Py array first dimension not matching num_points on sphere"); + GUDHI_CHECK(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(num_points, dim, radius); + + for (size_t i = 0; i < num_points; i++) + for (int j = 0; j < dim; j++) + ptr[i*dim+j] = points_generated[i][j]; + + return points; +} + +PYBIND11_MODULE(sphere, m) { + m.attr("__license__") = "LGPL v3"; + m.def("generate_random_points", &generate_points_on_sphere, + py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, + R"pbdoc( + Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d + + :param num_points: The number of points to be generated. + :type num_points: unsigned integer + :param dim: The dimension. + :type dim: integer + :param radius: The radius. + :type radius: float + :rtype: numpy array of float + :returns: the generated points on a sphere. + )pbdoc"); +} diff --git a/src/python/gudhi/datasets/generators/sphere.cc b/src/python/gudhi/datasets/generators/sphere.cc deleted file mode 100644 index 79392ef0..00000000 --- a/src/python/gudhi/datasets/generators/sphere.cc +++ /dev/null @@ -1,61 +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_sphere(size_t num_points, int dim, double radius) { - - py::array_t points({num_points, (size_t)dim}); - - py::buffer_info buf = points.request(); - double *ptr = static_cast(buf.ptr); - - GUDHI_CHECK(num_points == buf.shape[0], "Py array first dimension not matching num_points on sphere"); - GUDHI_CHECK(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(num_points, dim, radius); - - for (size_t i = 0; i < num_points; i++) - for (int j = 0; j < dim; j++) - ptr[i*dim+j] = points_generated[i][j]; - - return points; -} - -PYBIND11_MODULE(sphere, m) { - m.attr("__license__") = "LGPL v3"; - m.def("generate_random_points", &generate_points_on_sphere, - py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, - R"pbdoc( - Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d - - :param num_points: The number of points to be generated. - :type num_points: unsigned integer - :param dim: The dimension. - :type dim: integer - :param radius: The radius. - :type radius: float - :rtype: numpy array of float - :returns: the generated points on a sphere. - )pbdoc"); -} -- cgit v1.2.3 From 8cf6bbe7e2bd7c71cb44872aba772a1c4caf06a9 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 29 Apr 2021 11:23:43 +0200 Subject: numpy.take_along_axis used in knn requires numpy>=1.15.0 --- .github/build-requirements.txt | 5 ----- .github/test-requirements.txt | 15 --------------- src/python/doc/installation.rst | 2 +- src/python/setup.py.in | 4 ++-- 4 files changed, 3 insertions(+), 23 deletions(-) delete mode 100644 .github/build-requirements.txt delete mode 100644 .github/test-requirements.txt (limited to 'src') diff --git a/.github/build-requirements.txt b/.github/build-requirements.txt deleted file mode 100644 index 7de60d23..00000000 --- a/.github/build-requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -setuptools -wheel -numpy -Cython -pybind11 \ No newline at end of file diff --git a/.github/test-requirements.txt b/.github/test-requirements.txt deleted file mode 100644 index d0803574..00000000 --- a/.github/test-requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ -pytest -pytest-cov -sphinx -sphinxcontrib-bibtex==1.0.0 -sphinx-paramlinks -matplotlib -scipy -scikit-learn -POT -tensorflow -tensorflow-addons -torch<1.5 -pykeops -hnswlib -eagerpy diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 2881055f..9c16b04e 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -41,7 +41,7 @@ there. The library uses c++14 and requires `Boost `_ :math:`\geq` 1.56.0, `CMake `_ :math:`\geq` 3.5 to generate makefiles, -`NumPy `_, `Cython `_ and +`NumPy `_ :math:`\geq` 1.15.0, `Cython `_ and `pybind11 `_ to compile the GUDHI Python module. It is a multi-platform library and compiles on Linux, Mac OSX and Visual diff --git a/src/python/setup.py.in b/src/python/setup.py.in index 65f5446e..759ec8d8 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -85,7 +85,7 @@ setup( long_description_content_type='text/x-rst', long_description=long_description, ext_modules = ext_modules, - install_requires = ['numpy >= 1.9',], - setup_requires = ['cython','numpy >= 1.9','pybind11',], + install_requires = ['numpy >= 1.15.0',], + setup_requires = ['cython','numpy >= 1.15.0','pybind11',], package_data={"": ["*.dll"], }, ) -- 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 aeff21a712e488a2948d7c12f67f2f11b047ada8 Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Tue, 4 May 2021 10:40:03 +0200 Subject: Set Simplex_tree_interface_full_featured constructor name (Simplex_tree) to the class name --- src/python/gudhi/simplex_tree.pxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd index 000323af..3b8ea4f9 100644 --- a/src/python/gudhi/simplex_tree.pxd +++ b/src/python/gudhi/simplex_tree.pxd @@ -44,7 +44,7 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_interface_full_featured "Gudhi::Simplex_tree_interface": - Simplex_tree() nogil + Simplex_tree_interface_full_featured() nogil double simplex_filtration(vector[int] simplex) nogil void assign_simplex_filtration(vector[int] simplex, double filtration) nogil void initialize_filtration() nogil -- cgit v1.2.3 From 2b694f9beae0e5fa78ae5b8923e7f2905c58777f Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Wed, 5 May 2021 13:58:30 +0200 Subject: Add __init__ files at every level in modules Remove last modules level and add sample type argument Rename num_points to n_samples --- src/python/CMakeLists.txt | 7 +-- ...plex_from_generated_points_on_sphere_example.py | 7 +-- src/python/gudhi/datasets/__init__.py | 0 src/python/gudhi/datasets/generators/__init__.py | 0 src/python/gudhi/datasets/generators/points.cc | 68 ++++++++++++++++++++++ .../gudhi/datasets/generators/points/__init__.py | 0 .../gudhi/datasets/generators/points/sphere.cc | 61 ------------------- 7 files changed, 74 insertions(+), 69 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 delete mode 100644 src/python/gudhi/datasets/generators/points/__init__.py delete mode 100644 src/python/gudhi/datasets/generators/points/sphere.cc (limited to 'src') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index ef9dc3ab..8dd4ea5d 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/sphere', ") + 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,8 +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/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/datasets/generators/points") - + file(COPY "gudhi/datasets" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi" FILES_MATCHING PATTERN "*.py") # Some files for pip package file(COPY "introduction.rst" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") diff --git a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py index 2b023bbe..e73584d3 100644 --- a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py +++ b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from gudhi.datasets.generators.points import sphere +from gudhi.datasets.generators import points from gudhi import AlphaComplex @@ -22,11 +22,10 @@ print("#####################################################################") print("AlphaComplex creation from generated points on sphere") -# Generate a circle: 50 points; dim 2; radius 1 -points = sphere.generate_random_points(50, 2, 1) +gen_points = points.sphere(n_samples = 50, dim = 2, radius = 1, sample = "random") # Create an alpha complex -alpha_complex = AlphaComplex(points=points) +alpha_complex = AlphaComplex(points = gen_points) simplex_tree = alpha_complex.create_simplex_tree() result_str = 'Alpha complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \ 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..f02c7d73 --- /dev/null +++ b/src/python/gudhi/datasets/generators/points.cc @@ -0,0 +1,68 @@ +/* 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_sphere(size_t n_samples, int dim, double radius, std::string sample) { + + if (sample != "random") { + throw pybind11::value_error("sample type is not supported"); + } + + py::array_t points({n_samples, (size_t)dim}); + + py::buffer_info buf = points.request(); + double *ptr = static_cast(buf.ptr); + + GUDHI_CHECK(n_samples == buf.shape[0], "Py array first dimension not matching n_samples on sphere"); + GUDHI_CHECK(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, dim, radius); + + for (size_t i = 0; i < n_samples; i++) + for (int j = 0; j < dim; j++) + ptr[i*dim+j] = points_generated[i][j]; + + return points; +} + +PYBIND11_MODULE(points, m) { + m.attr("__license__") = "LGPL v3"; + m.def("sphere", &generate_points_on_sphere, + py::arg("n_samples"), py::arg("dim"), + py::arg("radius") = 1, py::arg("sample") = "random", + R"pbdoc( + Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d + + :param n_samples: The number of points to be generated. + :type n_samples: integer + :param dim: The ambient dimension d. + :type dim: integer + :param radius: The radius. + :type radius: float + :param sample: The sample type. + :type sample: string + :rtype: numpy array of float + :returns: the generated points on a sphere. + )pbdoc"); +} 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/sphere.cc b/src/python/gudhi/datasets/generators/points/sphere.cc deleted file mode 100644 index 79392ef0..00000000 --- a/src/python/gudhi/datasets/generators/points/sphere.cc +++ /dev/null @@ -1,61 +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_sphere(size_t num_points, int dim, double radius) { - - py::array_t points({num_points, (size_t)dim}); - - py::buffer_info buf = points.request(); - double *ptr = static_cast(buf.ptr); - - GUDHI_CHECK(num_points == buf.shape[0], "Py array first dimension not matching num_points on sphere"); - GUDHI_CHECK(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(num_points, dim, radius); - - for (size_t i = 0; i < num_points; i++) - for (int j = 0; j < dim; j++) - ptr[i*dim+j] = points_generated[i][j]; - - return points; -} - -PYBIND11_MODULE(sphere, m) { - m.attr("__license__") = "LGPL v3"; - m.def("generate_random_points", &generate_points_on_sphere, - py::arg("num_points"), py::arg("dim"), py::arg("radius") = 1, - R"pbdoc( - Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d - - :param num_points: The number of points to be generated. - :type num_points: unsigned integer - :param dim: The dimension. - :type dim: integer - :param radius: The radius. - :type radius: float - :rtype: numpy array of float - :returns: the generated points on a sphere. - )pbdoc"); -} -- 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 62510e70009ff2fc65028b88b56886fb53743e51 Mon Sep 17 00:00:00 2001 From: Hind Montassif Date: Mon, 10 May 2021 10:58:36 +0200 Subject: Rename dim to ambient_dim for sphere (to be consistent with dim in torus) --- ..._complex_from_generated_points_on_sphere_example.py | 2 +- src/python/gudhi/datasets/generators/points.cc | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py index e73584d3..267e6436 100644 --- a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py +++ b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py @@ -22,7 +22,7 @@ print("#####################################################################") print("AlphaComplex creation from generated points on sphere") -gen_points = points.sphere(n_samples = 50, dim = 2, radius = 1, sample = "random") +gen_points = points.sphere(n_samples = 50, ambient_dim = 2, radius = 1, sample = "random") # Create an alpha complex alpha_complex = AlphaComplex(points = gen_points) diff --git a/src/python/gudhi/datasets/generators/points.cc b/src/python/gudhi/datasets/generators/points.cc index f02c7d73..e2626b09 100644 --- a/src/python/gudhi/datasets/generators/points.cc +++ b/src/python/gudhi/datasets/generators/points.cc @@ -21,27 +21,27 @@ namespace py = pybind11; typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; -py::array_t generate_points_on_sphere(size_t n_samples, int dim, double radius, std::string sample) { +py::array_t generate_points_on_sphere(size_t n_samples, int ambient_dim, double radius, std::string sample) { if (sample != "random") { throw pybind11::value_error("sample type is not supported"); } - py::array_t points({n_samples, (size_t)dim}); + py::array_t points({n_samples, (size_t)ambient_dim}); py::buffer_info buf = points.request(); double *ptr = static_cast(buf.ptr); GUDHI_CHECK(n_samples == buf.shape[0], "Py array first dimension not matching n_samples on sphere"); - GUDHI_CHECK(dim == buf.shape[1], "Py array second dimension not matching the ambient space dimension"); + 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, dim, radius); + auto 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 < dim; j++) - ptr[i*dim+j] = points_generated[i][j]; + for (int j = 0; j < ambient_dim; j++) + ptr[i*ambient_dim+j] = points_generated[i][j]; return points; } @@ -49,15 +49,15 @@ py::array_t generate_points_on_sphere(size_t n_samples, int dim, double PYBIND11_MODULE(points, m) { m.attr("__license__") = "LGPL v3"; m.def("sphere", &generate_points_on_sphere, - py::arg("n_samples"), py::arg("dim"), + py::arg("n_samples"), py::arg("ambient_dim"), py::arg("radius") = 1, py::arg("sample") = "random", R"pbdoc( Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d :param n_samples: The number of points to be generated. :type n_samples: integer - :param dim: The ambient dimension d. - :type dim: integer + :param ambient_dim: The ambient dimension d. + :type ambient_dim: integer :param radius: The radius. :type radius: float :param sample: The sample type. -- 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 a571f198535b5ab5751eb55693371e9348aa1804 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Fri, 21 May 2021 17:32:43 +0200 Subject: Fix issue #489 RipsComplex out of bounds access --- ...ips_complex_diagram_persistence_from_distance_matrix_file_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py b/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py index 236d085d..9320d904 100755 --- a/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py +++ b/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py @@ -44,7 +44,7 @@ print("RipsComplex creation from distance matrix read in a csv file") message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length) print(message) -distance_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=args.file) +distance_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=args.file, separator=',') rips_complex = gudhi.RipsComplex( distance_matrix=distance_matrix, max_edge_length=args.max_edge_length ) -- cgit v1.2.3 From 8b3c55502718e4c184d828151ee6f75fd2cfc9eb Mon Sep 17 00:00:00 2001 From: Hind-M Date: Tue, 25 May 2021 18:01:54 +0200 Subject: Add a separator argument that goes with the rips_complex_diagram_persistence_from_distance_matrix_file_example input file Specify explicitly the separator when using a specific input file --- src/common/test/test_distance_matrix_reader.cpp | 2 +- src/python/CMakeLists.txt | 2 +- ..._complex_diagram_persistence_from_distance_matrix_file_example.py | 5 +++-- src/python/test/test_reader_utils.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/common/test/test_distance_matrix_reader.cpp b/src/common/test/test_distance_matrix_reader.cpp index 73be8104..92e899b8 100644 --- a/src/common/test/test_distance_matrix_reader.cpp +++ b/src/common/test/test_distance_matrix_reader.cpp @@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE( full_square_distance_matrix ) { Distance_matrix from_full_square; // Read full_square_distance_matrix.csv file where the separator is the default one ';' - from_full_square = Gudhi::read_lower_triangular_matrix_from_csv_file("full_square_distance_matrix.csv"); + from_full_square = Gudhi::read_lower_triangular_matrix_from_csv_file("full_square_distance_matrix.csv", ';'); for (auto& i : from_full_square) { for (auto j : i) { std::clog << j << " "; diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index a1440cbc..bc9a3b7b 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -457,7 +457,7 @@ if(PYTHONINTERP_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "${GUDHI_PYTHON_PATH_ENV}" ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -s , -e 12.0 -d 3) add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} diff --git a/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py b/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py index 9320d904..8a9cc857 100755 --- a/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py +++ b/src/python/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py @@ -21,11 +21,12 @@ parser = argparse.ArgumentParser( description="RipsComplex creation from " "a distance matrix read in a csv file.", epilog="Example: " "example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py " - "-f ../data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3" + "-f ../data/distance_matrix/lower_triangular_distance_matrix.csv -s , -e 12.0 -d 3" "- Constructs a Rips complex with the " "distance matrix from the given csv file.", ) parser.add_argument("-f", "--file", type=str, required=True) +parser.add_argument("-s", "--separator", type=str, required=True) parser.add_argument("-e", "--max_edge_length", type=float, default=0.5) parser.add_argument("-d", "--max_dimension", type=int, default=1) parser.add_argument("-b", "--band", type=float, default=0.0) @@ -44,7 +45,7 @@ print("RipsComplex creation from distance matrix read in a csv file") message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length) print(message) -distance_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=args.file, separator=',') +distance_matrix = gudhi.read_lower_triangular_matrix_from_csv_file(csv_file=args.file, separator=args.separator) rips_complex = gudhi.RipsComplex( distance_matrix=distance_matrix, max_edge_length=args.max_edge_length ) diff --git a/src/python/test/test_reader_utils.py b/src/python/test/test_reader_utils.py index 90da6651..e96e0569 100755 --- a/src/python/test/test_reader_utils.py +++ b/src/python/test/test_reader_utils.py @@ -30,7 +30,7 @@ def test_full_square_distance_matrix_csv_file(): test_file.write("0;1;2;3;\n1;0;4;5;\n2;4;0;6;\n3;5;6;0;") test_file.close() matrix = gudhi.read_lower_triangular_matrix_from_csv_file( - csv_file="full_square_distance_matrix.csv" + csv_file="full_square_distance_matrix.csv", separator=";" ) assert matrix == [[], [1.0], [2.0, 4.0], [3.0, 5.0, 6.0]] -- cgit v1.2.3 From ad1145bc4ac224954055f9b9ad955c2a53ceb687 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 26 May 2021 17:27:01 +0200 Subject: Change some output messages and documentation to me more explicit --- src/python/gudhi/datasets/generators/points.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/points.cc b/src/python/gudhi/datasets/generators/points.cc index e2626b09..d658946b 100644 --- a/src/python/gudhi/datasets/generators/points.cc +++ b/src/python/gudhi/datasets/generators/points.cc @@ -24,7 +24,7 @@ typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern; py::array_t generate_points_on_sphere(size_t n_samples, int ambient_dim, double radius, std::string sample) { if (sample != "random") { - throw pybind11::value_error("sample type is not supported"); + throw pybind11::value_error("This sample type is not supported"); } py::array_t points({n_samples, (size_t)ambient_dim}); @@ -50,7 +50,7 @@ PYBIND11_MODULE(points, m) { m.attr("__license__") = "LGPL v3"; m.def("sphere", &generate_points_on_sphere, py::arg("n_samples"), py::arg("ambient_dim"), - py::arg("radius") = 1, py::arg("sample") = "random", + py::arg("radius") = 1., py::arg("sample") = "random", R"pbdoc( Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d @@ -58,9 +58,9 @@ PYBIND11_MODULE(points, m) { :type n_samples: integer :param ambient_dim: The ambient dimension d. :type ambient_dim: integer - :param radius: The radius. + :param radius: The radius. Default value is `1.`. :type radius: float - :param sample: The sample type. + :param sample: The sample type. Default and only available value is `"random"`. :type sample: string :rtype: numpy array of float :returns: the generated points on a sphere. -- 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 01d62172c54b258a1072a42d25a39fd21a38c284 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 24 Jun 2021 16:15:02 +0200 Subject: Use python_docs_theme. Dependency added in gudhi-deploy --- src/python/doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/doc/conf.py b/src/python/doc/conf.py index b06baf9c..46debd87 100755 --- a/src/python/doc/conf.py +++ b/src/python/doc/conf.py @@ -120,7 +120,7 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'classic' +html_theme = 'python_docs_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the -- cgit v1.2.3 From b32f61a66d52a25be177dd96de469420e5b4a980 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 25 Jun 2021 07:07:32 +0200 Subject: add sphinx-paramlinks and python-docs-theme in installation guide --- src/python/doc/installation.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 9c16b04e..451ae020 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -194,8 +194,10 @@ A complete configuration would be : Documentation ============= -To build the documentation, `sphinx-doc `_ and -`sphinxcontrib-bibtex `_ are +To build the documentation, `sphinx-doc `_, +`sphinxcontrib-bibtex `_, +`sphinxcontrib-paramlinks `_ and +`python-docs-theme `_ are required. As the documentation is auto-tested, `CGAL`_, `Eigen`_, `Matplotlib`_, `NumPy`_, `POT`_, `Scikit-learn`_ and `SciPy`_ are also mandatory to build the documentation. -- cgit v1.2.3 From c0cca8dbd60e3da5147517f6f8f37d9bdeefe511 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 25 Jun 2021 16:26:55 +0200 Subject: update headers, conf.py for the new theme and bottleneck image to be smaller --- src/Bottleneck_distance/doc/perturb_pd.png | Bin 20864 -> 15532 bytes src/common/doc/header.html | 1 + src/python/doc/_templates/layout.html | 1 + src/python/doc/conf.py | 3 --- 4 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Bottleneck_distance/doc/perturb_pd.png b/src/Bottleneck_distance/doc/perturb_pd.png index be638de0..eabf3c8c 100644 Binary files a/src/Bottleneck_distance/doc/perturb_pd.png and b/src/Bottleneck_distance/doc/perturb_pd.png differ diff --git a/src/common/doc/header.html b/src/common/doc/header.html index 9da20bbc..7c20478b 100644 --- a/src/common/doc/header.html +++ b/src/common/doc/header.html @@ -49,6 +49,7 @@ $extrastylesheet
      • Related projects
      • They are talking about us
      • GUDHI in action
      • +
      • Etymology
    • diff --git a/src/python/doc/_templates/layout.html b/src/python/doc/_templates/layout.html index cd40a51b..e074b6c7 100644 --- a/src/python/doc/_templates/layout.html +++ b/src/python/doc/_templates/layout.html @@ -194,6 +194,7 @@
    • Related projects
    • They are talking about us
    • GUDHI in action
    • +
    • Etymology
    • diff --git a/src/python/doc/conf.py b/src/python/doc/conf.py index 46debd87..e69e2751 100755 --- a/src/python/doc/conf.py +++ b/src/python/doc/conf.py @@ -126,9 +126,6 @@ html_theme = 'python_docs_theme' # further. For a list of options available for each theme, see the # documentation. html_theme_options = { - "sidebarbgcolor": "#A1ADCD", - "sidebartextcolor": "black", - "sidebarlinkcolor": "#334D5C", "body_max_width": "100%", } -- cgit v1.2.3 From 50d7eb5bc89900dd90f7f2d97ca8bc3c19c8a057 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 25 Jun 2021 17:02:54 +0200 Subject: Fix #486 --- .../modules/GUDHI_third_party_libraries.cmake | 2 + src/python/CMakeLists.txt | 116 ++++++++++++--------- 2 files changed, 69 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index e1566877..023061f1 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -156,6 +156,8 @@ if( PYTHONINTERP_FOUND ) find_python_module("eagerpy") find_python_module_no_version("hnswlib") find_python_module("tensorflow") + find_python_module("sphinx_paramlinks") + find_python_module_no_version("python_docs_theme") endif() if(NOT GUDHI_PYTHON_PATH) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 98f2b85f..f534fc2a 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -107,6 +107,16 @@ if(PYTHONINTERP_FOUND) if(TENSORFLOW_FOUND) add_gudhi_debug_info("TensorFlow version ${TENSORFLOW_VERSION}") endif() + if(SPHINX_FOUND) + add_gudhi_debug_info("Sphinx version ${SPHINX_VERSION}") + endif() + if(SPHINX_PARAMLINKS_FOUND) + add_gudhi_debug_info("Sphinx-paramlinks version ${SPHINX_PARAMLINKS_VERSION}") + endif() + if(PYTHON_DOCS_THEME_FOUND) + # Does not have a version number... + add_gudhi_debug_info("python_docs_theme found") + endif() set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") @@ -281,62 +291,70 @@ if(PYTHONINTERP_FOUND) # Documentation generation is available through sphinx - requires all modules # Make it first as sphinx test is by far the longest test which is nice when testing in parallel if(SPHINX_PATH) - if(MATPLOTLIB_FOUND) - if(NUMPY_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") + if(SPHINX_PARAMLINKS_FOUND) + if(PYTHON_DOCS_THEME_FOUND) + if(MATPLOTLIB_FOUND) + if(NUMPY_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") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(PYBIND11_FOUND) + 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") - 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") + endif(OT_FOUND) + else(SKLEARN_FOUND) + message("++ Python documentation module will not be compiled because scikit-learn was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(PYBIND11_FOUND) - else(OT_FOUND) - message("++ Python documentation module will not be compiled because POT was not found") + endif(SKLEARN_FOUND) + else(SCIPY_FOUND) + message("++ Python documentation module will not be compiled because scipy was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(OT_FOUND) - else(SKLEARN_FOUND) - message("++ Python documentation module will not be compiled because scikit-learn was not found") + endif(SCIPY_FOUND) + else(NUMPY_FOUND) + message("++ Python documentation module will not be compiled because numpy was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(SKLEARN_FOUND) - else(SCIPY_FOUND) - message("++ Python documentation module will not be compiled because scipy was not found") + endif(NUMPY_FOUND) + else(MATPLOTLIB_FOUND) + message("++ Python documentation module will not be compiled because matplotlib was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(SCIPY_FOUND) - else(NUMPY_FOUND) - message("++ Python documentation module will not be compiled because numpy was not found") + endif(MATPLOTLIB_FOUND) + else(PYTHON_DOCS_THEME_FOUND) + message("++ Python documentation module will not be compiled because python-docs-theme was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(NUMPY_FOUND) - else(MATPLOTLIB_FOUND) - message("++ Python documentation module will not be compiled because matplotlib was not found") + endif(PYTHON_DOCS_THEME_FOUND) + else(SPHINX_PARAMLINKS_FOUND) + message("++ Python documentation module will not be compiled because sphinxcontrib-paramlinks was not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") - endif(MATPLOTLIB_FOUND) + endif(SPHINX_PARAMLINKS_FOUND) else(SPHINX_PATH) message("++ Python documentation module will not be compiled because sphinx and sphinxcontrib-bibtex were not found") set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") -- cgit v1.2.3 From 68031184fb94cf19c8b3c6f0de122db447693847 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Tue, 29 Jun 2021 11:48:28 +0200 Subject: Fix issue #502: check homology_coeff_field primality before computing persistence --- src/python/include/Persistent_cohomology_interface.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/python/include/Persistent_cohomology_interface.h b/src/python/include/Persistent_cohomology_interface.h index e5a3dfba..6877f190 100644 --- a/src/python/include/Persistent_cohomology_interface.h +++ b/src/python/include/Persistent_cohomology_interface.h @@ -43,6 +43,21 @@ persistent_cohomology::Persistent_cohomology 1; + if ((n % 2 == 0) || (n % 3 == 0)) + return false; + int i = 5; + while (i*i <= n) { + if ((n % i == 0) || (n % (i + 2) == 0)) + return false; + i += 6; + } + return true; + } + public: Persistent_cohomology_interface(FilteredComplex* stptr, bool persistence_dim_max=false) : Base(*stptr, persistence_dim_max), @@ -50,6 +65,11 @@ persistent_cohomology::Persistent_cohomology Date: Thu, 1 Jul 2021 15:56:11 +0200 Subject: Move primality test to Field_Zp::init Throw exception when not prime Add tests --- src/Persistent_cohomology/example/CMakeLists.txt | 2 +- .../include/gudhi/Persistent_cohomology/Field_Zp.h | 19 ++++++++++++++++++- .../test/persistent_cohomology_unit_test.cpp | 22 +++++++++++++++++++++- src/python/gudhi/cubical_complex.pyx | 2 +- src/python/gudhi/periodic_cubical_complex.pyx | 2 +- src/python/gudhi/simplex_tree.pxd | 2 +- .../include/Persistent_cohomology_interface.h | 20 -------------------- 7 files changed, 43 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index c68c6524..3e7e9369 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -11,7 +11,7 @@ if (TBB_FOUND) target_link_libraries(persistence_from_simple_simplex_tree ${TBB_LIBRARIES}) endif() add_test(NAME Persistent_cohomology_example_from_simple_simplex_tree COMMAND $ - "1" "0") + "2" "0") if(TARGET Boost::program_options) add_executable(rips_persistence_step_by_step rips_persistence_step_by_step.cpp) diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h index 0673625c..4bfd95c0 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h @@ -13,6 +13,8 @@ #include #include +#include +#include namespace Gudhi { @@ -34,15 +36,30 @@ class Field_Zp { void init(int charac) { assert(charac > 0); // division by zero + non negative values + Prime = charac; + + // Check for primality + if ((Prime == 0) || (Prime == 1) || ((Prime > 3) && ((Prime % 2 == 0) || (Prime % 3 == 0)))) + throw std::invalid_argument("homology_coeff_field must be a prime number"); + inverse_.clear(); inverse_.reserve(charac); inverse_.push_back(0); for (int i = 1; i < Prime; ++i) { int inv = 1; - while (((inv * i) % Prime) != 1) + int mult = inv * i; + while ( (mult % Prime) != 1) { ++inv; + if(mult == Prime) + throw std::invalid_argument("homology_coeff_field must be a prime number"); + mult = inv * i; + } inverse_.push_back(inv); + if ( (i <= std::sqrt(Prime)) && (((i-5)%6) == 0) ) { + if ((Prime % i == 0) || (Prime % (i + 2) == 0)) + throw std::invalid_argument("homology_coeff_field must be a prime number"); + } } } diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index fe3f8517..9559b842 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -146,9 +146,14 @@ 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_CHECK_THROW(test_rips_persistence_in_dimension(0), std::invalid_argument); +} + BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_1 ) { - test_rips_persistence_in_dimension(1); + BOOST_CHECK_THROW(test_rips_persistence_in_dimension(1), std::invalid_argument); } BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_2 ) @@ -161,11 +166,26 @@ BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_3 ) test_rips_persistence_in_dimension(3); } +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_4 ) +{ + BOOST_CHECK_THROW(test_rips_persistence_in_dimension(4), std::invalid_argument); +} + BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_5 ) { test_rips_persistence_in_dimension(5); } +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_11 ) +{ + test_rips_persistence_in_dimension(11); +} + +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_13 ) +{ + test_rips_persistence_in_dimension(13); +} + // TODO(VR): not working from 6 // std::string str_rips_persistence = test_rips_persistence(6, 0); // TODO(VR): division by zero diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index 28fbe3af..adc40499 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -35,7 +35,7 @@ cdef extern from "Cubical_complex_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Cubical_complex_persistence_interface "Gudhi::Persistent_cohomology_interface>": Cubical_complex_persistence_interface(Bitmap_cubical_complex_base_interface * st, bool persistence_dim_max) nogil - void compute_persistence(int homology_coeff_field, double min_persistence) nogil + void compute_persistence(int homology_coeff_field, double min_persistence) nogil except+ vector[pair[int, pair[double, double]]] get_persistence() nogil vector[vector[int]] cofaces_of_cubical_persistence_pairs() nogil vector[int] betti_numbers() nogil diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index d353d2af..0eaa5867 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -32,7 +32,7 @@ cdef extern from "Cubical_complex_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Periodic_cubical_complex_persistence_interface "Gudhi::Persistent_cohomology_interface>>": Periodic_cubical_complex_persistence_interface(Periodic_cubical_complex_base_interface * st, bool persistence_dim_max) nogil - void compute_persistence(int homology_coeff_field, double min_persistence) nogil + void compute_persistence(int homology_coeff_field, double min_persistence) nogil except + vector[pair[int, pair[double, double]]] get_persistence() nogil vector[vector[int]] cofaces_of_cubical_persistence_pairs() nogil vector[int] betti_numbers() nogil diff --git a/src/python/gudhi/simplex_tree.pxd b/src/python/gudhi/simplex_tree.pxd index 3b8ea4f9..006a24ed 100644 --- a/src/python/gudhi/simplex_tree.pxd +++ b/src/python/gudhi/simplex_tree.pxd @@ -78,7 +78,7 @@ cdef extern from "Simplex_tree_interface.h" namespace "Gudhi": cdef extern from "Persistent_cohomology_interface.h" namespace "Gudhi": cdef cppclass Simplex_tree_persistence_interface "Gudhi::Persistent_cohomology_interface>": Simplex_tree_persistence_interface(Simplex_tree_interface_full_featured * st, bool persistence_dim_max) nogil - void compute_persistence(int homology_coeff_field, double min_persistence) nogil + void compute_persistence(int homology_coeff_field, double min_persistence) nogil except + vector[pair[int, pair[double, double]]] get_persistence() nogil vector[int] betti_numbers() nogil vector[int] persistent_betti_numbers(double from_value, double to_value) nogil diff --git a/src/python/include/Persistent_cohomology_interface.h b/src/python/include/Persistent_cohomology_interface.h index 6877f190..e5a3dfba 100644 --- a/src/python/include/Persistent_cohomology_interface.h +++ b/src/python/include/Persistent_cohomology_interface.h @@ -43,21 +43,6 @@ persistent_cohomology::Persistent_cohomology 1; - if ((n % 2 == 0) || (n % 3 == 0)) - return false; - int i = 5; - while (i*i <= n) { - if ((n % i == 0) || (n % (i + 2) == 0)) - return false; - i += 6; - } - return true; - } - public: Persistent_cohomology_interface(FilteredComplex* stptr, bool persistence_dim_max=false) : Base(*stptr, persistence_dim_max), @@ -65,11 +50,6 @@ persistent_cohomology::Persistent_cohomology Date: Mon, 12 Jul 2021 11:25:57 +0200 Subject: Limit homology_coeff_field value to max allowed Add test with first prime outside the allowed range --- .../include/gudhi/Persistent_cohomology/Field_Zp.h | 7 +++++-- .../test/persistent_cohomology_unit_test.cpp | 8 ++++---- src/python/gudhi/simplex_tree.pyx | 6 +++--- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h index 4bfd95c0..7ecc9a80 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h @@ -14,7 +14,6 @@ #include #include #include -#include namespace Gudhi { @@ -39,6 +38,10 @@ class Field_Zp { Prime = charac; + // Check that the provided prime is less than the maximum allowed as int and calculation below : 46337 ; i.e (max_prime-1)**2 <= INT_MAX + if(Prime > 46337) + throw std::invalid_argument("Maximum homology_coeff_field allowed value is 46337"); + // Check for primality if ((Prime == 0) || (Prime == 1) || ((Prime > 3) && ((Prime % 2 == 0) || (Prime % 3 == 0)))) throw std::invalid_argument("homology_coeff_field must be a prime number"); @@ -56,7 +59,7 @@ class Field_Zp { mult = inv * i; } inverse_.push_back(inv); - if ( (i <= std::sqrt(Prime)) && (((i-5)%6) == 0) ) { + if ( (i*i <= Prime) && (((i-5)%6) == 0) ) { if ((Prime % i == 0) || (Prime % (i + 2) == 0)) throw std::invalid_argument("homology_coeff_field must be a prime number"); } diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 9559b842..35bb5988 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -186,10 +186,10 @@ BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_13 ) test_rips_persistence_in_dimension(13); } -// 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); +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_46349 ) +{ + BOOST_CHECK_THROW(test_rips_persistence_in_dimension(46349), std::invalid_argument); +} /** SimplexTree minimal options to test the limits. * diff --git a/src/python/gudhi/simplex_tree.pyx b/src/python/gudhi/simplex_tree.pyx index be08a3a1..9c51cb46 100644 --- a/src/python/gudhi/simplex_tree.pyx +++ b/src/python/gudhi/simplex_tree.pyx @@ -412,7 +412,7 @@ cdef class SimplexTree: """This function retrieves good values for extended persistence, and separate the diagrams into the Ordinary, Relative, Extended+ and Extended- subdiagrams. - :param homology_coeff_field: The homology coefficient field. Must be a prime number. Default value is 11. + :param homology_coeff_field: The homology coefficient field. Must be a prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int :param min_persistence: The minimum persistence value (i.e., the absolute value of the difference between the persistence diagram point coordinates) to take into account (strictly greater than min_persistence). @@ -449,7 +449,7 @@ cdef class SimplexTree: """This function computes and returns the persistence of the simplicial complex. :param homology_coeff_field: The homology coefficient field. Must be a - prime number. Default value is 11. + prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is @@ -472,7 +472,7 @@ cdef class SimplexTree: when you do not want the list :func:`persistence` returns. :param homology_coeff_field: The homology coefficient field. Must be a - prime number. Default value is 11. + prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is -- cgit v1.2.3 From df4e209fb0d2dba662fa755f9d049372f3fc2c53 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Fri, 23 Jul 2021 00:56:48 +0200 Subject: Remove bad attribute maybe_unused `CGAL_UNUSED` or `[[maybe_unused]]` is useful if we name the argument but don't use it. If we don't name it, the attribute is wrong as it would apply to the type and not the variable. --- src/Spatial_searching/include/gudhi/Kd_tree_search.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Spatial_searching/include/gudhi/Kd_tree_search.h b/src/Spatial_searching/include/gudhi/Kd_tree_search.h index a50a8537..6fb611f2 100644 --- a/src/Spatial_searching/include/gudhi/Kd_tree_search.h +++ b/src/Spatial_searching/include/gudhi/Kd_tree_search.h @@ -139,7 +139,7 @@ class Kd_tree_search { } template - bool contains_point_given_as_coordinates(Coord_iterator pi, Coord_iterator CGAL_UNUSED) const { + bool contains_point_given_as_coordinates(Coord_iterator pi, Coord_iterator) const { FT distance = 0; auto ccci = traits.construct_cartesian_const_iterator_d_object(); auto ci = ccci(c); -- cgit v1.2.3 From f78e5e3c6df6f7e6e899d5846fff785a4ed3313c Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sat, 24 Jul 2021 17:08:03 +0200 Subject: Avoid v[0] for persistence of empty complex It was reported by some debug mode while I was working on something else --- src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index d34ee07d..d428e497 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -100,7 +100,7 @@ class Persistent_cohomology { ds_rank_(num_simplices_), // union-find ds_parent_(num_simplices_), // union-find ds_repr_(num_simplices_, NULL), // union-find -> annotation vectors - dsets_(&ds_rank_[0], &ds_parent_[0]), // union-find + dsets_(ds_rank_.data(), ds_parent_.data()), // union-find cam_(), // collection of annotation vectors zero_cocycles_(), // union-find -> Simplex_key of creator for 0-homology transverse_idx_(), // key -> row -- cgit v1.2.3 From a93e26976e5898b267d8b743e080e8869ff41b4f Mon Sep 17 00:00:00 2001 From: Hind-M Date: Tue, 27 Jul 2021 11:01:31 +0200 Subject: Remove unnecessary checks for primality Document homology_coeff_field values in cubical --- .../include/gudhi/Persistent_cohomology/Field_Zp.h | 8 ++------ .../test/persistent_cohomology_unit_test.cpp | 5 +++++ src/python/gudhi/cubical_complex.pyx | 4 ++-- src/python/gudhi/periodic_cubical_complex.pyx | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h index 7ecc9a80..8ec89e41 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h @@ -38,12 +38,12 @@ class Field_Zp { Prime = charac; - // Check that the provided prime is less than the maximum allowed as int and calculation below : 46337 ; i.e (max_prime-1)**2 <= INT_MAX + // Check that the provided prime is less than the maximum allowed as int, calculation below, and 'plus_times_equal' function : 46337 ; i.e (max_prime-1)*max_prime <= INT_MAX if(Prime > 46337) throw std::invalid_argument("Maximum homology_coeff_field allowed value is 46337"); // Check for primality - if ((Prime == 0) || (Prime == 1) || ((Prime > 3) && ((Prime % 2 == 0) || (Prime % 3 == 0)))) + if (Prime <= 1) throw std::invalid_argument("homology_coeff_field must be a prime number"); inverse_.clear(); @@ -59,10 +59,6 @@ class Field_Zp { mult = inv * i; } inverse_.push_back(inv); - if ( (i*i <= Prime) && (((i-5)%6) == 0) ) { - if ((Prime % i == 0) || (Prime % (i + 2) == 0)) - throw std::invalid_argument("homology_coeff_field must be a prime number"); - } } } diff --git a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp index 35bb5988..041cb0fd 100644 --- a/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp +++ b/src/Persistent_cohomology/test/persistent_cohomology_unit_test.cpp @@ -176,6 +176,11 @@ BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_5 ) test_rips_persistence_in_dimension(5); } +BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_6 ) +{ + BOOST_CHECK_THROW(test_rips_persistence_in_dimension(6), std::invalid_argument); +} + BOOST_AUTO_TEST_CASE( rips_persistent_cohomology_single_field_dim_11 ) { test_rips_persistence_in_dimension(11); diff --git a/src/python/gudhi/cubical_complex.pyx b/src/python/gudhi/cubical_complex.pyx index adc40499..97c69a2d 100644 --- a/src/python/gudhi/cubical_complex.pyx +++ b/src/python/gudhi/cubical_complex.pyx @@ -147,7 +147,7 @@ cdef class CubicalComplex: :func:`persistence` returns. :param homology_coeff_field: The homology coefficient field. Must be a - prime number + prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int. :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is @@ -169,7 +169,7 @@ cdef class CubicalComplex: """This function computes and returns the persistence of the complex. :param homology_coeff_field: The homology coefficient field. Must be a - prime number + prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int. :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is diff --git a/src/python/gudhi/periodic_cubical_complex.pyx b/src/python/gudhi/periodic_cubical_complex.pyx index 0eaa5867..ef1d3080 100644 --- a/src/python/gudhi/periodic_cubical_complex.pyx +++ b/src/python/gudhi/periodic_cubical_complex.pyx @@ -148,7 +148,7 @@ cdef class PeriodicCubicalComplex: :func:`persistence` returns. :param homology_coeff_field: The homology coefficient field. Must be a - prime number + prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int. :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is @@ -170,7 +170,7 @@ cdef class PeriodicCubicalComplex: """This function computes and returns the persistence of the complex. :param homology_coeff_field: The homology coefficient field. Must be a - prime number + prime number. Default value is 11. Max is 46337. :type homology_coeff_field: int. :param min_persistence: The minimum persistence value to take into account (strictly greater than min_persistence). Default value is -- cgit v1.2.3 From a91e3bc16d511ef66bb296da6a990a0723100657 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 5 Aug 2021 18:00:40 +0200 Subject: mailing lists migration and rephrase contributions in installation guides --- .github/for_maintainers/new_gudhi_version_creation.md | 4 ++-- src/common/doc/installation.h | 8 +++++--- src/python/doc/installation.rst | 9 +++++---- src/python/setup.py.in | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/.github/for_maintainers/new_gudhi_version_creation.md b/.github/for_maintainers/new_gudhi_version_creation.md index d6c4cdd3..3e5295c5 100644 --- a/.github/for_maintainers/new_gudhi_version_creation.md +++ b/.github/for_maintainers/new_gudhi_version_creation.md @@ -128,5 +128,5 @@ docker image on docker hub. ## Mail sending Send version mail to the following lists : -* gudhi-devel@lists.gforge.inria.fr -* gudhi-users@lists.gforge.inria.fr (not for release candidate) +* gudhi-devel@inria.fr +* gudhi-users@inria.fr (not for release candidate) diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index 610aa17e..5d40a48e 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -243,10 +243,12 @@ make \endverbatim * Witness_complex/example_nearest_landmark_table.cpp * * \section Contributions Bug reports and contributions - * Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to: - * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim + * Please help us improving the quality of the GUDHI library. + * You may report bugs or + * contact us for any suggestions. * - * GUDHI is open to external contributions. If you want to join our development team, please contact us. + * GUDHI is open to external contributions. If you want to join our development team, please take some time to read our + * contributing guide. * */ diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 9c16b04e..56f27b21 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -396,8 +396,9 @@ TensorFlow Bug reports and contributions ***************************** -Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to: +Please help us improving the quality of the GUDHI library. +You may `report bugs `_ or +`contact us `_ for any suggestions. - Contact: gudhi-users@lists.gforge.inria.fr - -GUDHI is open to external contributions. If you want to join our development team, please contact us. +GUDHI is open to external contributions. If you want to join our development team, please take some time to read our +`contributing guide `_. diff --git a/src/python/setup.py.in b/src/python/setup.py.in index 759ec8d8..c400b601 100644 --- a/src/python/setup.py.in +++ b/src/python/setup.py.in @@ -71,7 +71,7 @@ setup( name = 'gudhi', packages=find_packages(), # find_namespace_packages(include=["gudhi*"]) author='GUDHI Editorial Board', - author_email='gudhi-contact@lists.gforge.inria.fr', + author_email='gudhi-contact@inria.fr', version='@GUDHI_VERSION@', url='https://gudhi.inria.fr/', project_urls={ -- 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 eddb7b935e21bac41caace7b9efedf9df58bd2b9 Mon Sep 17 00:00:00 2001 From: VincentRouvreau Date: Wed, 22 Sep 2021 10:45:08 +0200 Subject: Simplex tree example README was not up to date, and bunny can be removed --- src/Simplex_tree/example/README | 73 ----------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 src/Simplex_tree/example/README (limited to 'src') diff --git a/src/Simplex_tree/example/README b/src/Simplex_tree/example/README deleted file mode 100644 index a9498173..00000000 --- a/src/Simplex_tree/example/README +++ /dev/null @@ -1,73 +0,0 @@ -To build the example, run in a Terminal: - -cd /path-to-gudhi/ -cmake . -cd /path-to-example/ -make - - -Example of use : - -*** Simple simplex tree construction - -./Simplex_tree_example_simple_simplex_tree - -******************************************************************** -EXAMPLE OF SIMPLE INSERTION - * INSERT 0 - + 0 INSERTED - * INSERT 1 - + 1 INSERTED - * INSERT (0,1) - + (0,1) INSERTED - * INSERT 2 - + 2 INSERTED - * INSERT (2,0) - + (2,0) INSERTED - * INSERT (2,1) - + (2,1) INSERTED - * INSERT (2,1,0) - + (2,1,0) INSERTED - * INSERT 3 - + 3 INSERTED - * INSERT (3,0) - + (3,0) INSERTED - * INSERT 0 (already inserted) - - 0 NOT INSERTED - * INSERT (2,1,0) (already inserted) - - (2,1,0) NOT INSERTED -******************************************************************** -* The complex contains 9 simplices - - dimension 2 - filtration 0.4 -* Iterator on Simplices in the filtration, with [filtration value]: - [0.1] 0 - [0.1] 1 - [0.1] 2 - [0.1] 3 - [0.2] 1 0 - [0.2] 2 0 - [0.2] 2 1 - [0.2] 3 0 - [0.3] 2 1 0 - -*** Simplex tree construction with Z/2Z coefficients on weighted graph Klein bottle file: - -./Simplex_tree_example_from_cliques_of_graph ../../../data/points/Klein_bottle_complex.txt 2 -Insert the 1-skeleton in the simplex tree in 0 s. -Expand the simplex tree in 0 s. -Information of the Simplex Tree: - Number of vertices = 10 Number of simplices = 82 - -with Z/3Z coefficients: - -./Simplex_tree_example_from_cliques_of_graph ../../../data/points/Klein_bottle_complex.txt 3 - -Insert the 1-skeleton in the simplex tree in 0 s. -Expand the simplex tree in 0 s. -Information of the Simplex Tree: - Number of vertices = 10 Number of simplices = 106 - -*** Simplex_tree computed and displayed from a 3D alpha complex: - [ Requires CGAL, GMP and GMPXX to be installed] - -./Simplex_tree_example_alpha_shapes_3_from_off ../../../data/points/bunny_5000 -- cgit v1.2.3 From e0edac45736201ce76bf71428e8fc9d41943d872 Mon Sep 17 00:00:00 2001 From: VincentRouvreau Date: Wed, 22 Sep 2021 11:39:06 +0200 Subject: Remove bunny --- data/persistence_diagram/PD1.pers | 3 - data/persistence_diagram/PD2.pers | 2 - data/points/bunny.COPYRIGHT | 6 - data/points/bunny_5000.off | 5002 ---------------------- src/Persistent_cohomology/example/CMakeLists.txt | 4 +- src/Simplex_tree/example/CMakeLists.txt | 2 +- 6 files changed, 3 insertions(+), 5016 deletions(-) delete mode 100644 data/persistence_diagram/PD1.pers delete mode 100644 data/persistence_diagram/PD2.pers delete mode 100644 data/points/bunny.COPYRIGHT delete mode 100644 data/points/bunny_5000.off (limited to 'src') diff --git a/data/persistence_diagram/PD1.pers b/data/persistence_diagram/PD1.pers deleted file mode 100644 index 404199b4..00000000 --- a/data/persistence_diagram/PD1.pers +++ /dev/null @@ -1,3 +0,0 @@ -2.7 3.7 -9.6 14 -34.2 34.974 \ No newline at end of file diff --git a/data/persistence_diagram/PD2.pers b/data/persistence_diagram/PD2.pers deleted file mode 100644 index 125d8e4b..00000000 --- a/data/persistence_diagram/PD2.pers +++ /dev/null @@ -1,2 +0,0 @@ -2.8 4.45 -9.5 14.1 \ No newline at end of file diff --git a/data/points/bunny.COPYRIGHT b/data/points/bunny.COPYRIGHT deleted file mode 100644 index e8c47dd9..00000000 --- a/data/points/bunny.COPYRIGHT +++ /dev/null @@ -1,6 +0,0 @@ -The bunny pointsets comes from the Stanford Computer Graphics Laboratory. -http://graphics.stanford.edu/data/3Dscanrep/ - -Please acknowledge... - -Please be sure to acknowledge the source of the bunny data set. You are welcome to use the bunny data and models for research purposes. You are also welcome to mirror or redistribute them for free. Finally, you may publish images made using these models, or the images on this web site, in a scholarly article or book - as long as credit is given to the Stanford Computer Graphics Laboratory. However, such models or images are not to be used for commercial purposes, nor should they appear in a product for sale (with the exception of scholarly journals or books), without our permission. diff --git a/data/points/bunny_5000.off b/data/points/bunny_5000.off deleted file mode 100644 index 12ec0c68..00000000 --- a/data/points/bunny_5000.off +++ /dev/null @@ -1,5002 +0,0 @@ -OFF -5000 0 0 --0.0164722 0.0382453 0.0209318 --0.0641407 0.171114 -0.0471776 -0.023086 0.119339 0.0317977 -0.00506037 0.0347021 0.0393176 --0.066143 0.143958 0.0413147 --0.0445017 0.163753 0.00542301 --0.0689729 0.181022 -0.0546459 --0.0931085 0.131006 0.0192314 -0.000506827 0.0489752 0.0512269 --0.0615935 0.160001 -0.0315914 --0.0245032 0.0960169 0.0442753 --0.0258992 0.0891655 0.049535 --0.000499367 0.0456802 0.0470389 --0.0171808 0.0654583 0.0528522 -0.00116916 0.131228 0.00582139 --0.0356565 0.122935 -0.00798984 --0.0701892 0.156285 0.021569 --0.0173569 0.038443 0.0259817 --0.0716413 0.0763478 -0.0132577 -0.0528545 0.0568172 0.0288563 --0.0325067 0.0732308 0.0407775 --0.0760686 0.150008 -0.00987485 --0.030561 0.0774145 0.0410957 --0.0833901 0.0762729 0.00451303 --0.000492618 0.0925258 0.0556594 --0.0358778 0.159506 0.00240863 -0.0115111 0.114076 0.0384616 --0.0877889 0.0887187 0.00347532 --0.0261028 0.115949 -0.0147279 --0.0682913 0.165205 -0.0539869 --0.0225512 0.0933694 -0.0331106 --0.0538783 0.0999149 -0.0214389 -0.0435587 0.0959151 0.0211557 --0.0167991 0.0388632 -0.0107644 --0.0569142 0.0548839 0.00364185 -0.00749229 0.091015 0.0542708 --0.065316 0.0625169 -0.002419 --0.00749647 0.119689 0.0375376 --0.0772165 0.0934484 -0.0125951 --0.029008 0.0478606 -0.0250513 -0.00934189 0.0553527 -0.0303034 --0.0578677 0.104042 -0.0186102 -0.0405495 0.0999198 -0.00379356 --0.0894314 0.137929 0.0371779 -0.00710731 0.126603 -0.00643182 -0.058913 0.070492 0.0108657 --0.0922485 0.120133 0.0292903 -0.0395325 0.105566 0.0221621 --0.0376065 0.0365426 0.0444186 --0.0550158 0.128128 -0.00563226 --0.0561672 0.0336533 0.0186553 -0.0123436 0.0351165 0.0296251 --0.0899184 0.131005 0.0413145 -0.0065365 0.100373 0.0469448 --0.0502879 0.133796 0.0278403 --0.0716838 0.0351362 0.00880221 -0.0579126 0.0523842 0.0101848 --0.0639212 0.154791 0.00385831 --0.0654795 0.0384216 -0.00684663 --0.0615513 0.0624603 0.0259481 --0.0368013 0.0842007 -0.0223672 -0.0522757 0.0574291 -0.0035048 --0.0764972 0.123179 0.0527664 -0.0302998 0.0694384 -0.019812 --0.0334269 0.0486094 0.0413091 --0.00450651 0.0689184 0.0565193 -0.0425976 0.0887597 -0.00680771 --0.0707351 0.156208 0.0228366 -0.0548799 0.0492406 0.0202107 --0.00962948 0.168316 -0.023669 --0.0313363 0.11605 -0.0148117 --0.0225249 0.125571 0.0012278 -0.0122871 0.124953 0.0313975 --0.0343047 0.125361 0.0205265 --0.038499 0.0747376 0.0420783 -0.0292349 0.0759579 -0.0220376 --0.0255784 0.0477093 -0.0263526 --0.0750958 0.151313 -0.0258791 -0.0057743 0.0347896 0.0375885 --0.0926124 0.120126 0.0272917 --0.0366664 0.175138 -0.00407486 --0.00549337 0.088417 0.0570387 --0.0711473 0.17507 -0.0540267 --0.0776118 0.0739521 0.0284675 -0.0376746 0.104662 0.0282621 --0.0634881 0.121359 0.0469409 -0.0233296 0.0564006 -0.0254415 --0.0399361 0.123254 0.0259269 --0.000577398 0.0341134 -0.0181551 --0.000496894 0.0520342 0.0541515 --0.0701023 0.177167 -0.0478719 --0.0641167 0.143926 0.0389732 --0.0679369 0.165269 -0.0197719 --0.0681029 0.138305 0.0455026 --0.00280426 0.0384802 0.0198949 --0.0628273 0.0924874 -0.0189476 -0.0084946 0.0869435 0.0558386 -0.00910286 0.0348066 0.0183719 --0.0195983 0.126231 0.0213862 --0.0584949 0.143878 0.0330085 --0.0218343 0.0553077 0.0451067 --0.0645685 0.147457 -0.0230581 -0.0426227 0.0691122 -0.00279622 --0.035813 0.0842739 -0.0225525 --0.0819685 0.0791215 0.0284136 -0.0328852 0.113087 -0.00384394 --0.0677123 0.168615 -0.0283035 --0.0556635 0.140996 0.0299986 --0.0764958 0.131682 0.0526442 -0.0421796 0.0832522 0.0293553 --0.0848653 0.0855483 0.0264341 --0.0329445 0.121338 0.0269922 --0.0320197 0.058187 -0.0133973 --0.0322785 0.0421631 -0.0296986 -0.0401757 0.067497 -0.00878165 --0.0904989 0.148452 0.0245146 --0.00947974 0.0561444 0.0530127 --0.0310333 0.0383692 -0.000250742 --0.0780713 0.150403 0.0367551 --0.0872126 0.146051 0.00824907 --0.0735722 0.148626 -0.0268487 --0.00548676 0.116904 0.0394711 --0.0599006 0.132533 0.037981 --0.093479 0.129659 0.0212406 --0.0639063 0.120904 -0.00875525 --0.028606 0.0356961 0.0524615 --0.0652024 0.153998 -0.041972 --0.0262134 0.0765572 0.0473962 --0.0774721 0.155387 0.0234212 --0.0628707 0.0345025 0.0358026 -0.0434964 0.0555926 0.0322399 --0.0618022 0.142496 0.0370478 --0.0638273 0.0910291 -0.0188305 --0.0636286 0.0672101 0.0337087 --0.0842132 0.092522 0.0298256 -0.0185123 0.115397 0.0365584 --0.0666269 0.131204 0.0458398 --0.0653475 0.165775 -0.0260007 --0.0182573 0.181629 -0.0177335 --0.0142757 0.185348 -0.0257883 -0.0485082 0.0624718 0.0300814 --0.0254927 0.0974122 0.0441083 --0.0446561 0.0349999 0.0427486 --0.0616719 0.0410515 0.0160296 --0.0179307 0.0931593 -0.0348763 --0.00828798 0.130102 0.00662088 --0.0525878 0.149334 0.020403 --0.0102534 0.128943 0.0232512 -0.0445378 0.0959706 0.0101622 --0.0465291 0.0335268 -0.00814027 -0.00437534 0.131145 0.0198749 --0.0394369 0.03436 0.0321562 --0.0107155 0.127812 0.0260097 --0.0273383 0.17123 -0.0098418 --0.0037118 0.0655569 -0.0347446 --0.0630689 0.150547 -0.0265942 --0.0776846 0.16386 -0.0329461 --0.0728796 0.151218 -0.0388899 -0.038172 0.0967289 0.0325586 --0.058907 0.0983413 -0.0195805 --0.00549542 0.0965711 0.0536823 -0.00650609 0.0503877 0.0517539 --0.0847722 0.113367 0.0459387 -0.0309512 0.0822193 0.0430727 --0.0159859 0.0984773 0.0464357 -0.0361586 0.0781359 0.0382445 -0.0417308 0.0422749 0.000248643 --0.0631435 0.175042 -0.061564 --0.0251041 0.0945178 -0.0276305 -0.018776 0.122594 -0.0061273 -0.0173125 0.0726566 0.0514253 --0.0377229 0.0724783 -0.0174913 -0.0173872 0.0432828 -0.0228623 -0.0416262 0.0912615 0.0286616 --0.050567 0.0474222 -0.00850865 --0.0150865 0.162585 -0.00969001 -0.0143357 0.0566765 -0.0290221 --0.0309078 0.065095 -0.0224325 -0.045522 0.0805737 0.00219452 --0.0725374 0.138625 0.0483183 --0.0476365 0.150675 0.00992423 --0.0799103 0.125126 -0.00560703 --0.051025 0.159915 -0.00453945 -0.00139766 0.0419298 -0.0244976 --0.0664219 0.0352675 0.015055 --0.00832508 0.130422 0.0138058 --0.00366678 0.0481589 -0.0301707 --0.0738566 0.161044 -0.0339379 -0.0319703 0.0475137 0.0318758 -0.0188215 0.126955 0.00377584 --0.0309617 0.044825 -0.0281993 -0.0456484 0.0875951 0.00518134 --0.0521074 0.0583062 0.0285239 --0.0171825 0.0382402 0.011747 --0.0692976 0.0615474 0.00912978 --0.0232044 0.175652 -0.0207635 --0.0406662 0.0592305 -0.0118049 -0.0572429 0.0508905 0.0121849 --0.0488285 0.0416917 0.0446681 -0.0455301 0.0677752 0.0254231 --0.0846369 0.110251 0.00429821 --0.0754652 0.163196 -0.0162299 --0.0247271 0.0564997 0.0408849 --0.0639975 0.0601011 0.00610183 --0.0741599 0.155538 0.00126713 --0.0728899 0.122329 -0.00823917 -0.010861 0.0360066 0.0447493 -0.0150176 0.0355797 0.04239 --0.0437155 0.0710509 -0.0175901 -0.0271589 0.093209 -0.0206672 --0.00592646 0.12418 0.0336126 --0.0810295 0.0895599 -0.00769505 --0.0920663 0.121362 0.00826874 --0.0862277 0.0832671 0.00749085 --0.085371 0.127983 -0.0026626 --0.081815 0.108922 0.02836 --0.0491537 0.135503 0.0034228 -0.00885847 0.0887054 -0.0320419 --0.0673146 0.0446682 0.00602001 -0.0152697 0.128852 0.0195703 -0.0231834 0.0422122 0.040252 --0.0286261 0.0463451 -0.0269667 -0.0449154 0.0763231 0.00019353 --0.0387296 0.0739178 -0.0177449 -0.0212191 0.0819428 -0.0266321 --0.00126307 0.039726 0.0470556 --0.0261021 0.0379463 0.0228342 --0.0448562 0.101383 -0.0214692 --0.0014827 0.0390261 -0.00225591 --0.0648948 0.103911 -0.0165942 --0.0624902 0.155293 -0.0145941 -0.000436968 0.130385 0.0227651 --0.0219738 0.059501 0.0451263 --0.0502789 0.129408 -0.00267456 --0.0216757 0.065257 0.0474751 --0.0621482 0.16155 -0.0395978 -0.0427418 0.0916392 0.0261768 -0.00967962 0.127274 0.0289934 --0.0728707 0.168003 -0.0450202 --0.0305611 0.179398 -0.00755573 -0.0341402 0.0902832 0.0407178 --0.0491119 0.0361611 0.0459929 -0.0392087 0.0739776 0.0338431 --0.0897017 0.151503 0.0171224 -0.0407967 0.105643 0.0101649 --0.023633 0.0478399 -0.0272396 --0.0504958 0.0862332 0.0455716 --0.0451092 0.153606 0.00834539 --0.0616087 0.146812 0.0373554 -0.0280342 0.0346822 0.009507 -0.0565861 0.0685555 0.00335277 --0.027568 0.0674298 0.0392602 --0.0926576 0.117463 0.0373027 --0.0334278 0.124984 0.0208436 --0.0602518 0.034678 0.0430709 --0.0574989 0.107052 0.0398301 --0.091226 0.128161 0.00727002 -0.0400022 0.0913669 0.0315547 --0.0656743 0.138242 0.0419702 --0.0852141 0.0805923 0.0204766 --0.0444957 0.111173 0.0370595 --0.044489 0.0803636 0.042222 --0.00648998 0.122405 0.0354776 -0.00602348 0.111527 -0.0200414 --0.0860119 0.132159 0.00027761 -0.0521231 0.0734583 0.0172399 --0.0155403 0.0446621 0.0510487 --0.0397503 0.0768521 -0.0186787 --0.0682155 0.0787029 0.0404793 --0.0813927 0.0758934 0.0225084 --0.010188 0.0386565 4.14997e-05 --0.00149609 0.0912323 -0.0347548 --0.0294974 0.111128 0.0367729 --0.0503924 0.0501648 0.0186468 --0.0104698 0.070299 0.0557764 -0.0327323 0.0809002 0.0421262 --0.0328911 0.122131 -0.00712262 --0.0861948 0.1005 0.0258994 --0.0319282 0.178722 -0.00808101 --0.050675 0.140101 0.0024044 --0.0346788 0.0636729 -0.0139354 --0.00820144 0.0344928 -0.0181278 --0.0830162 0.0939316 0.0314035 -0.0438286 0.0611702 -0.00330591 --0.0162799 0.127645 0.0211086 --0.0615233 0.0354132 0.043881 --0.0755937 0.0809959 -0.0116148 --0.0632393 0.166259 -0.0385929 --0.0156738 0.0511142 -0.0317767 -0.000751147 0.0339678 -0.0215355 --0.0534027 0.0336932 0.022744 -0.0102837 0.0348658 -0.0091814 --0.0285082 0.0874866 -0.0336017 --0.0849712 0.111906 0.0292041 --0.0732162 0.169408 -0.0460252 --0.00746424 0.110009 0.0430329 --0.0587154 0.0723411 -0.016523 --0.00333145 0.0968513 -0.0305901 -0.0385608 0.0713011 0.0346329 --0.0463734 0.133247 0.0130756 --0.0474986 0.104275 0.0408376 --0.0714849 0.147284 -0.0260827 --0.0404433 0.0461446 -0.0193164 -0.000709469 0.125628 -0.00726116 -0.028516 0.117882 -0.00302906 --0.00249354 0.0746702 0.0587588 -0.0463101 0.0806468 0.00818141 --0.0245515 0.114015 0.0358596 --0.0396488 0.0563195 -0.0111963 --0.0236961 0.0607746 0.0425604 --0.0336359 0.0548461 -0.0105101 --0.0585033 0.0337545 0.0163089 -0.0212208 0.126407 0.0160623 --0.0729862 0.15207 0.0354642 --0.085378 0.128494 0.0496125 -0.00429457 0.122356 -0.0118056 -0.0203517 0.0672611 0.0487139 --0.0452845 0.0395903 -0.0182935 --0.0211124 0.182965 -0.0210132 --0.0295465 0.0819132 0.0441437 --0.0777488 0.07493 0.029356 -0.00824435 0.0966482 -0.0263491 --0.0588066 0.0854157 -0.0208208 --0.0718999 0.113582 -0.00821597 --0.0893735 0.0901981 0.0104595 -0.032603 0.0835706 0.0419526 --0.0230608 0.0594124 0.0433799 -0.0284544 0.121423 0.0116324 --0.0832785 0.12444 0.0504652 --0.0396241 0.0520021 -0.0108773 -0.00721225 0.0837864 -0.0330068 --0.046713 0.131987 0.00556897 --0.0663702 0.157999 -0.00906779 --0.067736 0.0779793 -0.0166569 --0.0508692 0.102779 -0.0209206 --0.0828958 0.151378 0.00422572 --0.0346622 0.118788 -0.0116368 --0.0726425 0.0716156 -0.00744076 --0.059725 0.0469427 0.0326718 --0.0468444 0.033579 -0.0045851 --0.0384976 0.100064 0.0415702 --0.050989 0.121022 -0.0119137 --0.0624226 0.152205 -0.0125757 --0.085741 0.151793 0.0266482 --0.0826468 0.144713 0.0407672 --0.0685649 0.0705046 -0.00966184 --0.0734033 0.167233 -0.0217479 --0.0455099 0.155064 0.0077969 -0.022652 0.0862116 0.0486888 -0.043364 0.0547822 -0.00644446 --0.054457 0.14621 0.0274041 --0.0639777 0.155958 0.0237716 --0.0882347 0.0861347 0.011472 -0.00545294 0.1216 -0.0129959 --0.0334673 0.174268 -0.00177832 --0.00402179 0.129762 0.0240423 --0.0185051 0.0711438 0.0540217 --0.0872329 0.150111 0.00920897 --0.090033 0.147105 0.0269347 --0.0141936 0.0419832 0.0511586 --0.0335873 0.154463 -0.00838872 -0.0441357 0.083266 -0.000805736 --0.0528842 0.102762 -0.0205636 --0.0125091 0.0815143 0.0575917 -0.0197435 0.125962 0.0226458 --0.067993 0.0619274 0.01978 --0.0216083 0.039391 -0.0287125 --0.0767116 0.165247 -0.022942 --0.0861936 0.111308 0.0401352 --0.0238165 0.0854111 -0.0376407 --0.0442161 0.123225 0.0243959 --0.0175443 0.0460366 0.0510389 --0.0272334 0.0902723 -0.0326005 --0.0459359 0.168402 -0.00594095 -0.0355423 0.0512597 0.0315836 -0.0451079 0.0636949 -0.00183531 --0.0368834 0.125578 -0.00482073 -0.0196258 0.0457587 -0.0217227 --0.00773224 0.109619 -0.0221011 --0.0514957 0.0876341 0.0455102 --0.00269376 0.0613003 -0.0344696 --0.0512049 0.147808 0.0143958 -0.0266901 0.106496 -0.0148024 -0.0383861 0.0476151 -0.00591592 --0.0136895 0.0952904 -0.0330103 -0.0368491 0.0767795 0.0374896 --0.029592 0.0522946 -0.0203629 -0.0482309 0.0500295 -0.00369862 -0.0381363 0.0794306 0.0358549 --0.0677271 0.155796 -0.00229118 -0.026043 0.0392404 0.0305576 -0.0208388 0.126564 0.0173475 -0.0159735 0.0448127 0.0438765 --0.0681757 0.118633 0.0523539 --0.065068 0.136793 0.0410949 --0.0454458 0.168254 0.00168996 --0.0715222 0.142818 0.0455702 --0.0604912 0.112522 0.03629 --0.00074702 0.0712329 -0.0350931 --0.0894331 0.150114 0.0121902 --0.0185746 0.0381525 0.0151621 -0.0291213 0.0348096 0.00960912 -0.0404448 0.0985503 0.0271661 -0.0134712 0.0936014 0.0511282 --0.021496 0.103017 0.0435858 -0.00918856 0.0342345 -0.00132638 --0.0508332 0.0956285 -0.0221275 --0.0613646 0.0394268 0.0439671 -0.0264379 0.0968548 0.0436578 --0.0646669 0.0405364 0.0387423 -0.0125029 0.0475354 0.045933 -0.0412949 0.104257 0.00416372 --0.00222052 0.117102 -0.0161156 --0.00995662 0.169734 -0.0198047 -0.0200755 0.0399795 -0.0157069 --0.0839165 0.110514 0.0395089 --0.0546435 0.116042 -0.0146857 -0.0268767 0.0854059 -0.022529 --0.0543926 0.0337363 0.0224962 --0.049781 0.0841032 -0.0216622 -0.0431463 0.100109 0.00616795 -0.0393814 0.0780345 0.0341058 --0.0162612 0.17862 -0.0260128 --0.0335093 0.0676035 0.0406399 --0.0176483 0.0352702 -0.0188352 --0.031463 0.0519033 0.0373773 --0.0803572 0.0803552 0.0319871 --0.0320868 0.159267 -0.0129293 -0.0132853 0.0589897 0.0507165 --0.0103631 0.180289 -0.0277342 --0.0144925 0.0559441 0.0511232 --0.0246444 0.0381166 0.0247786 -0.0170669 0.0871276 -0.028336 -0.00372554 0.105196 -0.0213905 --0.0777857 0.156925 -0.0179137 -0.0578227 0.0710073 0.0178627 --0.0582482 0.0336534 0.0128901 --0.0520861 0.0545712 0.0266312 -0.0269849 0.113053 -0.00983991 -0.0429421 0.0467386 0.030224 -0.00548112 0.11414 0.0405028 -0.0607975 0.0637336 0.0101416 --0.0895137 0.135181 0.0391853 --0.0822803 0.139383 0.0462108 -0.00350363 0.0883757 0.0563643 --0.0599112 0.109712 -0.0163845 --0.0699244 0.107994 -0.0118147 --0.073438 0.145781 -0.0138542 --0.0702694 0.156361 0.0186365 -0.0365208 0.0713424 0.036933 --0.0764811 0.141399 0.0471717 --0.0338378 0.0943788 -0.02372 --0.0185768 0.055451 0.0489119 --0.0294962 0.107041 0.0398129 -0.0351663 0.0783387 -0.0157415 --0.0823976 0.095314 0.0321564 -0.0458052 0.08902 0.00916777 -0.00466954 0.0341296 0.0180802 -0.012258 0.0751733 -0.0308354 --0.0176564 0.0480544 -0.0295902 --0.0487658 0.0811872 -0.020682 --0.0375125 0.045091 0.0407522 -0.00960807 0.0375632 0.0322947 -0.0522688 0.0462249 0.00921199 --0.0452834 0.0395877 -0.019291 --0.0396931 0.126183 0.0200311 --0.0903381 0.144712 0.0141544 --0.0430213 0.0450576 -0.0153284 --0.0539191 0.129665 -0.00510771 --0.0384876 0.108386 0.0375357 --0.0496388 0.0605583 -0.0113235 --0.034501 0.115223 0.0328885 --0.0540284 0.131061 -0.00500164 --0.0147028 0.0389017 0.0333119 --0.0207376 0.0641563 -0.0358205 -0.00590682 0.131658 0.0132863 --0.0819436 0.154696 0.0145801 -0.0526661 0.0660937 -0.000184776 --0.0526201 0.14007 0.0244025 --0.0752504 0.177839 -0.0529463 --0.0574955 0.0946379 0.0447737 -0.0456129 0.0904097 0.00518194 --0.0282629 0.122524 0.022734 --0.0680338 0.142566 0.0438693 --0.0643033 0.0426016 0.0312522 --0.0314971 0.102929 0.041974 --0.00589664 0.0980966 0.0519993 --0.0542782 0.132533 0.0338047 --0.0911122 0.11473 0.0343167 --0.0493972 0.140141 0.00739907 --0.0577664 0.0485104 0.00767417 --0.0629684 0.139576 0.0370615 --0.0122087 0.128137 0.0240139 -0.00116984 0.129366 -0.00128907 --0.039496 0.0634667 0.0415276 --0.0427066 0.0696149 -0.0170299 --0.0721201 0.149786 -0.0402916 --0.0637423 0.168365 -0.0426884 --0.0228169 0.0383283 0.0285633 --0.0894925 0.143336 0.0131803 --0.0408822 0.128708 0.0107294 --0.043783 0.147719 0.00491206 -0.00912223 0.0833108 0.0554277 --0.0543042 0.0335497 0.00301212 --0.0544171 0.0333785 -0.00775516 -0.0295237 0.0727272 0.042682 --0.0504982 0.112495 0.0358796 --0.0240218 0.119915 -0.0108978 --0.0535232 0.0556038 0.0117195 --0.0480175 0.133707 0.00490199 -0.00583381 0.129313 0.0261699 --0.0405566 0.149165 -0.00293165 --0.0286765 0.0690744 -0.0314836 -0.0453693 0.0693828 0.00245115 -0.0581659 0.056561 0.00517446 -0.0192888 0.0651078 -0.0282476 --0.0228892 0.0739252 0.0512281 --0.0217183 0.113234 -0.017904 -0.0365187 0.0526805 0.0315096 -0.0490482 0.0539975 0.0303486 -0.0175085 0.114012 0.0373101 --0.0328107 0.126843 0.0122027 --0.0687814 0.0336983 0.00353162 -0.0220892 0.0906332 -0.0239505 --0.0460528 0.122513 0.026245 -0.0381409 0.109688 0.00657231 -0.0368421 0.0742334 -0.0127504 --0.0657975 0.0340784 0.0127357 --0.0706216 0.146831 -0.0255714 --0.0468292 0.091298 -0.0217206 --0.0914681 0.144718 0.0171554 --0.0624908 0.0343254 0.0238098 -0.0543739 0.0477987 0.0161989 --0.0195403 0.1757 -0.0161256 -0.0224671 0.0343921 0.00678503 --0.0654707 0.155271 0.00728456 --0.0897135 0.12265 0.00431103 --0.0501651 0.0361307 0.0461721 --0.0901888 0.139114 0.0151891 --0.0726107 0.156829 -0.0349095 --0.0334964 0.0718545 0.0411869 -0.0106165 0.0644536 0.0539383 -0.0274263 0.0491525 0.0376576 --0.0157908 0.169796 -0.0160148 --0.0608326 0.17151 -0.0610901 -0.0136156 0.126814 -0.00267762 -0.0293325 0.0535401 0.0386956 --0.0652579 0.153012 -0.0402459 -0.0264019 0.036087 0.0225582 -0.0101281 0.105858 -0.0202342 --0.0674046 0.0833115 0.0429955 --0.0312435 0.0538841 -0.0143722 -0.0424267 0.0441756 -0.00158684 --0.0305089 0.0760274 0.0408429 --0.0849899 0.127963 -0.0030064 --0.0223249 0.0386602 -0.0135496 -0.0216012 0.112963 -0.0137495 --0.0224297 0.0552774 0.0442986 --0.093152 0.121537 0.0362834 --0.0384463 0.166779 0.00239389 -0.0317419 0.0667553 -0.0187125 --0.0127135 0.100022 -0.0239701 -0.0204112 0.0371925 -0.00568428 -0.0383001 0.0969495 -0.00880451 --0.0500528 0.150184 -0.0037815 --0.0578783 0.106898 -0.0179862 -0.0485378 0.0682762 0.00156381 --0.0708965 0.0341323 0.00629169 --0.0871174 0.110466 0.0103621 --0.0235739 0.0944939 0.0470656 --0.0164815 0.0515035 0.0485835 -0.0325428 0.0380502 1.57112e-05 -0.0385774 0.0888011 0.0348199 --0.0628692 0.0445185 0.0382675 --0.0572856 0.125533 0.0399888 --0.0780066 0.0940671 0.0362827 --0.0361012 0.160724 -0.0132118 -0.0200495 0.124902 -0.000599563 -0.0101263 0.107276 -0.0197522 -0.0224877 0.0961643 0.0466342 --0.077715 0.0852782 -0.0115916 --0.0164955 0.105778 0.0423459 --0.0725318 0.101313 0.038599 --0.0663565 0.0783826 0.0411592 --0.0644378 0.17995 -0.0588828 --0.0645973 0.171184 -0.0458828 -0.0111199 0.129735 0.0223368 --0.018333 0.172741 -0.0161594 --0.0864925 0.10492 0.00639597 --0.0144943 0.0500942 0.0487331 --0.0855601 0.095177 0.0282718 -1.67787e-05 0.0386604 0.0239291 -0.0109499 0.0344084 0.00259617 --0.0270041 0.168274 -0.00938266 --0.0378811 0.107099 -0.0200653 -0.060304 0.0664655 0.0101406 --0.0478845 0.108472 -0.0188663 -0.0181085 0.0591163 0.0489014 --0.0260899 0.0522789 0.0395517 -0.0049437 0.0984176 -0.0242128 --0.0623314 0.0357831 0.0433788 -0.0110403 0.0725847 0.0546235 --0.0864956 0.084691 0.0204775 --0.00849993 0.0787667 0.0579153 --0.0260008 0.0382709 0.000860974 --0.06937 0.145758 -0.0234859 --0.0314168 0.117929 -0.0127586 --0.0261669 0.0378674 0.0174813 --0.0832309 0.120353 0.049216 --0.0617814 0.16156 -0.0355923 --0.0779669 0.165862 -0.0278956 --0.0698398 0.0922797 -0.0162924 -0.0483255 0.0503286 -0.00380134 -0.0451716 0.0889782 0.0181643 -0.0329815 0.112282 -0.00498623 -0.0279206 0.0916217 -0.0209795 -0.0155 0.11402 0.0377783 --0.0105379 0.0431327 0.0497176 -0.0606167 0.0609422 0.00915424 --0.0181983 0.18599 -0.0174024 -0.0189716 0.115037 -0.0139804 --0.0590849 0.0644137 0.0318252 --0.0819254 0.12582 0.0519232 --0.0588398 0.0954803 -0.0203334 --0.0674426 0.148384 -0.0326115 -0.0387628 0.10462 0.0262683 -0.00841723 0.129272 0.0256623 --0.0196119 0.0364667 -0.0278852 --0.0376923 0.162356 -0.000243841 -1.88808e-05 0.115368 -0.0182789 -0.0393962 0.0505525 -0.00668347 --0.0116788 0.0555838 -0.0339192 -0.0363865 0.0713868 -0.0138007 --0.0821651 0.110069 0.034903 -0.022728 0.117081 -0.0101857 --0.0515389 0.0417461 -0.0105815 -0.0219588 0.123501 -0.00109075 -0.00735928 0.0960033 -0.0276522 --0.00349428 0.119696 0.0379021 --0.0470844 0.151656 -0.00519447 --0.0242296 0.0941248 -0.0298734 -0.0152433 0.0658912 0.0518711 --0.021804 0.0376594 -0.0181241 --0.0133966 0.121962 -0.00916065 -0.0365536 0.108655 0.0265769 --0.0668098 0.0880715 -0.0180091 --0.0665181 0.171112 -0.0407548 -0.0493343 0.0532247 -0.0043679 -0.0423933 0.0901635 -0.00682346 --0.0624126 0.150651 -0.0115734 -0.0373944 0.0505276 -0.00658166 --0.0411461 0.162173 -0.0113613 --0.065916 0.0662086 0.0305519 --0.0289729 0.083488 0.0456837 --0.000642523 0.0347913 0.0398677 --0.0738147 0.065744 0.00631032 -0.00351431 0.0938625 0.0544725 --0.0467733 0.12389 0.0269319 -0.0246632 0.123785 0.00595837 --0.0715256 0.0958228 0.0413941 -0.00252922 0.0362636 0.0463395 -0.00948792 0.0963424 0.0500581 -0.0292035 0.0400739 0.0286474 --0.0309481 0.0706991 -0.0284733 --0.054091 0.152763 0.0215579 -0.0118527 0.105542 -0.0197545 --0.0404793 0.0832528 0.0431634 --0.0448438 0.0985036 -0.0215544 --0.032014 0.0567822 -0.0123897 -0.00040853 0.0356817 0.00488121 -0.0447245 0.0861403 0.0231669 --0.0426307 0.0338188 -0.00946517 --0.0710495 0.141325 -0.00813095 --0.0255896 0.182763 -0.0105092 --0.0838169 0.107636 0.0253505 --0.0796245 0.0859561 0.0353266 -0.0240034 0.0449703 0.0396985 -0.00450108 0.0716864 0.0560951 --0.0676894 0.0750921 -0.0153176 --0.0466572 0.0369109 -0.0172699 --0.016529 0.0558872 0.0508401 --0.087831 0.103641 0.0093887 -0.0272256 0.10745 0.0377741 --0.0670064 0.0337953 0.0073865 --0.0866888 0.0833263 0.0124872 -0.0152687 0.0779357 -0.0299953 --0.0851819 0.152725 0.0105454 -0.000352424 0.0511166 -0.0306262 -0.0518495 0.0464359 0.0201911 -0.0554005 0.0553511 0.0254886 --0.0886141 0.0928486 0.00844707 -0.0129712 0.130228 0.0115965 --0.085549 0.104961 0.0233427 -0.0515991 0.0496316 0.0251833 -0.0131946 0.0878791 -0.0305989 --0.0693376 0.131255 0.0489674 --0.0660205 0.167997 -0.0305503 --0.0666146 0.174697 -0.0480375 --0.0293346 0.0347045 0.0427947 --0.0553259 0.126836 -0.00601308 --0.058583 0.0460291 0.0113967 --0.0416277 0.0337441 -0.014735 --0.0446642 0.0621749 -0.0132201 -0.0295862 0.120365 0.0134787 --0.0697163 0.064282 0.022673 --0.0805487 0.0789662 0.0306236 --0.0787564 0.154933 0.00983696 --0.0662707 0.14708 -0.0258685 --0.0248167 0.0949702 -0.0267501 --0.0407693 0.0826515 -0.0208197 -0.000514101 0.0346343 0.00952105 --0.0533361 0.138123 0.0280776 --0.0689277 0.115103 -0.00892086 --0.0865224 0.0913375 0.0024428 -0.0232602 0.0790529 -0.0256674 -0.0296786 0.0679688 -0.0198342 --0.0331127 0.123309 0.0239558 -0.0276403 0.118218 0.0284429 -0.00238303 0.0449286 -0.0261957 --0.0928278 0.124236 0.0382657 --0.0868685 0.11045 0.00936714 --0.0254875 0.0959781 0.0438332 -0.0132252 0.0808221 -0.0308314 -0.035265 0.0591791 0.0368077 --0.00944135 0.168135 -0.0197365 -0.0011864 0.12951 0.0259323 --0.0139593 0.0967237 -0.0305143 --0.00848922 0.0385737 0.0258802 -0.0562981 0.0619429 0.0011209 -0.0322546 0.0987343 -0.0145759 --0.0268707 0.103016 -0.0234914 --0.00655639 0.0384205 0.0209905 --0.0296666 0.0774462 0.0418826 --0.0626586 0.0676213 -0.0103966 -0.0374569 0.0904362 -0.0137042 --0.0712181 0.161 -0.0439365 -0.0243668 0.0889213 0.0476805 --0.0336134 0.0408899 -0.0298935 --0.0404969 0.0916505 0.0425962 -0.0443454 0.0903358 0.0221636 --0.0435232 0.163746 0.00524284 --0.0649943 0.0623954 0.0235277 --0.0613093 0.0593276 0.0181457 --0.0717978 0.155398 -0.0409076 --0.00868753 0.0584178 -0.0339256 --0.0904383 0.119966 0.00529664 --0.0601615 0.0333995 -0.00165181 --0.0612252 0.0407891 0.0437895 --0.0537348 0.0738508 -0.0172852 --0.0709057 0.10512 -0.0125462 --0.00333997 0.039253 0.0353398 --0.0469903 0.145002 0.00194161 --0.0250386 0.0659034 -0.0335362 --0.023273 0.0382876 0.00502865 -0.0111228 0.0960826 -0.0257288 -0.0198113 0.0954368 -0.0230239 -0.038476 0.104075 -0.00282883 --0.0843581 0.0883713 0.0286614 --0.0930341 0.118841 0.0362969 --0.0646767 0.146003 -0.0179612 -0.0284626 0.102127 0.0395666 --0.0435018 0.113907 0.034675 --0.0604863 0.0790224 0.042794 --0.089042 0.112536 0.0205154 --0.0524675 0.0344946 0.0345461 --0.0848716 0.119101 -0.00207765 --0.0120923 0.11442 -0.0172013 --0.079929 0.151371 0.00121035 --0.0920085 0.116136 0.0393096 -0.0361533 0.112569 0.0130564 --0.0196629 0.125034 -0.00230889 -0.000499429 0.115573 0.0406664 --0.0560183 0.147198 -0.00168648 --0.0873616 0.110481 0.0113565 --0.0416844 0.0636674 -0.0137203 --0.0651889 0.153592 -0.00278678 -0.0471599 0.07398 0.0153485 -0.0404106 0.0873775 0.0321991 --0.019434 0.184905 -0.0153275 --0.0438294 0.0913555 -0.0224139 --0.0527613 0.0797578 -0.020501 --0.0314155 0.0651435 -0.021432 -0.00948509 0.0950229 0.0512669 -0.0346346 0.107297 -0.007625 --0.0870053 0.0954387 0.00242783 --0.0617312 0.142927 -0.00565867 --0.0538929 0.14622 0.0244012 -0.0339044 0.115273 0.00366751 -0.049575 0.0693171 0.00251779 --0.0861009 0.106274 0.00635995 --0.00751182 0.075985 0.0578234 --0.0761849 0.0933719 -0.0135017 -0.0266626 0.0672707 0.0437593 --0.0314925 0.0932138 0.0444288 -0.0112937 0.0680868 -0.0307505 --0.086045 0.141863 0.00720055 -0.000490707 0.111422 0.0424934 --0.0516022 0.0502173 -0.00741774 --0.0709386 0.131124 -0.00852217 --0.0291841 0.125368 0.0164845 --0.0012258 0.095852 -0.0315171 --0.000697567 0.0641196 -0.0342689 --0.0797379 0.0738711 0.0228323 --0.0705682 0.0382102 0.00943236 --0.0558807 0.102663 -0.0193944 -0.0262875 0.0835737 0.0468767 --0.0206175 0.0364922 -0.0281092 -0.0306136 0.0779431 -0.0207534 -0.037492 0.0983062 -0.0097724 --0.0861064 0.0806138 0.0174966 --0.0488748 0.105594 -0.0196597 --0.0499497 0.0724883 0.0409516 --0.060435 0.131107 0.0389542 --0.0197383 0.108898 -0.0213322 --0.0328414 0.0943934 -0.0238538 -0.0071329 0.104451 -0.0211019 --0.0904392 0.125398 0.00528343 -0.0579573 0.0676391 0.00414749 --0.0890486 0.0915916 0.0214249 -0.0544885 0.0716156 0.00618127 -0.037936 0.0901639 0.0356574 --0.0631289 0.155254 0.0269868 -0.0280038 0.120349 0.024295 -0.00325461 0.0697315 -0.0336623 -0.0198002 0.0768324 0.0515324 -0.0135718 0.0504901 0.0475195 --0.0220331 0.041681 0.0538782 --0.0322365 0.126297 0.00653811 --0.020497 0.0855906 0.0563403 -0.0100844 0.123139 0.0340691 --0.0917617 0.141982 0.0191718 --0.00665267 0.0526646 -0.0325345 -0.0325469 0.0922927 -0.0176842 --0.00490321 0.0383839 0.0141185 -0.0393963 0.049102 -0.00636122 --0.0468295 0.0927337 -0.0216687 -0.0393484 0.0561243 -0.00568756 -0.0381042 0.0392738 0.00134927 --0.02061 0.0653432 0.0492306 --0.0644858 0.152894 -0.00250698 -0.0316363 0.118365 0.0113851 --0.0625842 0.162383 -0.0563311 --0.0126137 0.180121 -0.0236267 --0.0562637 0.142432 0.0309288 -0.0389203 0.10838 0.0161659 -0.0468209 0.0708789 0.021127 -0.0153317 0.060873 -0.028643 --0.067208 0.0447917 0.00368814 --0.0638714 0.15469 -0.0385902 --0.0624126 0.161536 -0.0416011 --0.011049 0.124435 -0.00785173 -0.0143712 0.0493733 -0.0267066 --0.0374862 0.0931566 0.0438456 --0.0278525 0.0807805 0.0474761 -0.0573848 0.0670309 0.00292365 --0.0304938 0.0960556 0.0449536 -0.0182602 0.127523 0.0192457 -0.0182204 0.080645 -0.0282763 --0.00275795 0.0740872 -0.0359501 --0.072697 0.155649 0.00759319 --0.0857527 0.0792184 0.0135098 --0.0604443 0.0456013 0.0296807 --0.0528198 0.0927332 -0.0219739 --0.0457202 0.0709417 -0.0164642 --0.054497 0.0889964 0.0448823 --0.0541353 0.147754 0.0254132 -0.05074 0.0503045 -0.00171178 --0.0926993 0.124215 0.0352716 -0.00850767 0.0786 0.0556334 --0.0141847 0.0405865 0.0511605 --0.0500491 0.0345412 0.0367666 --0.0744234 0.156022 0.0128056 --0.0148381 0.0386367 -0.0157684 --0.0896535 0.0916031 0.0184402 --0.0279306 0.125506 0.00666413 --0.0249827 0.0918474 0.0485489 --0.0247746 0.0385687 -0.0102357 --0.0718755 0.10648 -0.0114758 -0.0303733 0.115414 -0.00438737 -0.0390771 0.099844 -0.00681802 --0.0601235 0.0447437 0.0425684 -0.0559507 0.0508031 0.00520531 --0.087948 0.102288 0.00840013 --0.0802939 0.0732789 0.00250413 --0.00347452 0.114725 -0.0175669 --0.0780015 0.155773 0.018849 --0.0868392 0.0873072 0.00147849 -0.0114304 0.0346172 0.0371012 --0.0154945 0.0925097 0.0555061 -0.0207547 0.10431 -0.0184628 --0.0805113 0.153427 0.0283513 --0.0133702 0.0343611 -0.0190243 -0.045363 0.0932019 0.00717004 --0.0517619 0.079747 -0.0203928 --0.011137 0.171308 -0.0197957 --0.0797359 0.0706327 0.0105539 --0.0435047 0.116629 0.0323741 -0.0461192 0.0786876 0.0190773 -0.0257679 0.0349257 0.0180133 --0.0377436 0.127354 0.000111554 -0.0455391 0.0875946 0.0141649 --0.0115776 0.0962625 -0.032007 --0.0304054 0.0580102 -0.0194062 --0.0519213 0.118323 0.0336042 --0.0615165 0.15114 0.0355512 --0.0268549 0.175688 -0.00910606 -0.0291872 0.0462618 0.034893 --0.0828817 0.143196 0.00216401 --0.0229243 0.0972075 0.044901 --0.0420606 0.0344689 0.0332688 -0.00840712 0.0404044 -0.0234014 --0.0584986 0.100161 0.0428821 -0.0267286 0.0521731 -0.0207566 --0.0343564 0.043282 -0.028737 -0.035312 0.0840703 -0.0177861 -0.0167493 0.0874098 0.0506847 --0.0706375 0.156126 0.0126907 -0.0395317 0.0596774 0.0306966 -0.0160357 0.0807986 0.0531419 --0.0719071 0.105086 -0.0120336 -0.057752 0.0523416 0.0181873 --0.0705862 0.166615 -0.0490027 --0.069998 0.157611 -0.0031485 --0.0629727 0.118457 0.044154 --0.0098895 0.107351 -0.0224128 --0.0668287 0.169972 -0.0351376 --0.0538607 0.152062 0.0231076 -0.0286155 0.0795328 0.044942 -0.00747725 0.131195 0.0181386 -0.0525355 0.0678367 0.0261828 --0.069983 0.033931 0.00665746 --0.00449526 0.10588 0.044033 --0.0647467 0.143415 -0.011401 --0.0242451 0.0337053 -0.0224295 -0.0405945 0.102819 0.0221712 --0.0253936 0.106122 -0.0223873 --0.031866 0.126076 0.00521848 --0.0903832 0.132413 0.0312232 -0.0270423 0.0648893 -0.0216756 --0.0416036 0.125525 0.0208631 --0.0642885 0.148287 -0.0250747 -0.043249 0.0705728 -0.00179391 -0.00750831 0.0772509 0.056126 --0.0360471 0.125746 -0.0036679 --0.0534999 0.0820142 0.0450601 --0.0268076 0.0782799 -0.0366273 --0.0630392 0.0336157 0.00836468 -0.00450283 0.0924607 0.0546761 --0.0794816 0.0846149 0.0352279 --0.0354976 0.116636 0.0319301 -0.0590094 0.0552651 0.0101755 -0.0177618 0.100614 -0.0224544 -0.0141872 0.0347155 0.0357788 --0.0626395 0.0644043 -0.00619313 --0.0472223 0.168222 -0.000777409 --0.0688709 0.156258 0.0147705 --0.00209707 0.130745 0.0203917 -0.0438165 0.0959355 0.0191615 -0.0272253 0.120021 -0.000250724 --0.0623918 0.152158 -0.026581 --0.0619803 0.153737 -0.02558 --0.0110119 0.122536 -0.00980812 --0.00845767 0.100229 0.0476033 --0.053626 0.1255 0.0365054 -0.029243 0.0872327 -0.0208644 --0.0561028 0.133503 -0.00512832 --0.0536146 0.150855 0.0243962 --0.0729449 0.0805494 0.0386997 --0.0113093 0.0384672 0.00547553 -0.013929 0.0392001 0.0444158 --0.0743245 0.179234 -0.0539852 --0.0670834 0.168031 -0.0569976 -0.0269196 0.0418157 0.0333163 --0.0261604 0.114813 -0.0155316 -0.054979 0.06227 -0.000302264 -0.0447631 0.0931576 0.00318223 --0.028552 0.159576 0.000695282 --0.0196334 0.0906851 0.0545345 --0.0681661 0.173216 -0.0428508 --0.0670035 0.166617 -0.0570134 --0.00170857 0.0641356 -0.0344906 --0.0302923 0.115032 -0.0157497 --0.017789 0.0998203 0.0439009 -0.0575984 0.0711737 0.0088801 --0.0559485 0.119826 0.0383628 --0.0508832 0.106998 -0.0191626 --0.0856518 0.096702 -0.000561949 -0.0433856 0.0475038 -0.0047769 --0.0141839 0.177168 -0.0206609 --0.0318261 0.0623615 -0.0184459 --0.0694684 0.158126 -0.0509379 --0.059088 0.0445923 -0.00517311 --0.0680469 0.0887699 0.043444 -0.0413366 0.0588699 -0.00449648 --0.0108613 0.16611 -0.0209706 --0.0810695 0.111472 -0.000645954 -0.0236683 0.0535376 0.0428398 --0.0525009 0.104252 0.0406803 -0.0178265 0.128119 0.0148069 --0.0833287 0.0817012 -0.000498118 --0.0582078 0.148218 0.0334722 -0.0469627 0.0735494 0.00823046 -0.0348898 0.0889372 0.0400127 -0.0544139 0.0478718 0.0102055 --0.0519767 0.0343446 0.0277664 --0.0526872 0.144684 0.0193835 --0.0654577 0.0403952 0.0367257 --0.0632766 0.146612 -0.0147592 --0.0756638 0.0968147 0.0380937 --0.0121766 0.169774 -0.0245851 --0.0313173 0.115081 -0.0157968 -0.00550009 0.105744 0.0419393 -0.0170456 0.0808203 0.0528345 -0.00997537 0.129323 0.0247881 --0.000565033 0.0348667 0.0451983 --0.0170398 0.124093 -0.00535053 -0.0359746 0.112738 0.007259 --0.0264982 0.112519 0.0362632 --0.0108141 0.0841239 -0.038537 --0.0464922 0.097353 0.0431423 -0.0456344 0.0820067 0.0201819 --0.00765915 0.0388225 0.0294318 -0.00952232 0.057476 0.0527668 --0.0114724 0.180094 -0.0295969 --0.0324762 0.0778813 -0.0295332 --0.0515001 0.0465582 0.0417907 --0.0716564 0.0639047 0.0190638 --0.00648988 0.10728 0.0440126 -0.0517118 0.048146 0.0235716 --0.00973422 0.0712867 -0.0371391 --0.0311873 0.0499402 0.0418672 --0.0652548 0.0380623 0.0267185 --0.0353491 0.0346157 0.0221204 --0.00455763 0.115688 -0.0165869 --0.0158711 0.0941172 -0.0338261 --0.0307264 0.0510087 -0.0163552 --0.0674749 0.0861001 0.0436947 --0.00549495 0.0456998 0.0471564 --0.0127624 0.0742651 -0.0384156 --0.0667813 0.0354951 0.0323861 --0.0650934 0.040468 0.0377689 -0.00949782 0.11825 0.0371477 -0.042476 0.0986857 0.0211679 -0.0134353 0.0833572 0.0528968 --0.006265 0.0381462 0.0486516 -0.019505 0.108463 0.0397034 --0.0531501 0.13113 0.0336749 --0.0169066 0.174228 -0.0176024 --0.0877346 0.144562 0.0345528 --0.0620052 0.131132 -0.00795604 -0.00350354 0.0967589 -0.0284524 --0.0379926 0.15214 0.00278328 --0.0250008 0.0678945 0.0436439 -0.013488 0.120719 -0.0120957 --0.0546814 0.0342953 0.0289953 --0.0493523 0.128134 -0.0033313 --0.00536457 0.0387134 0.026395 --0.0301008 0.162274 -0.0148279 --0.0520761 0.153139 -0.00390728 --0.0312974 0.120401 0.0276066 --0.072708 0.173064 -0.0373345 --0.0634981 0.0847405 0.0443851 --0.00748204 0.123738 0.0339317 -0.0398166 0.0726016 0.0329349 --0.0204571 0.159751 -0.0120682 --0.0398664 0.104215 -0.0203975 -0.006345 0.0351555 0.0445736 --0.0295025 0.0974144 0.0445077 --0.00148646 0.0489421 0.0507365 --0.0158009 0.0813621 -0.039398 --0.0661715 0.0383371 0.0290301 --0.0520592 0.0517918 0.0296489 -0.0132683 0.0765435 -0.0305058 -0.0357248 0.113154 0.00859849 -0.0452751 0.0847797 0.0211588 -0.0408906 0.0942563 -0.00676992 --0.0621992 0.16466 -0.0525894 --0.0704991 0.101365 0.0396906 --0.0514936 0.0959907 0.0439844 --0.0738976 0.0662178 0.00410027 --0.0308753 0.104365 -0.0222089 --0.0454852 0.0411575 0.0440424 -0.0264018 0.0591975 -0.0228202 --0.0372554 0.154082 -0.00855912 --0.0104302 0.175693 -0.0238578 --0.0581296 0.0583212 0.0178996 --0.0237002 0.0610797 -0.032726 --0.0366248 0.127943 0.00786237 --0.00749367 0.0605601 0.0556586 --0.0317091 0.0749949 -0.0294856 --0.0617882 0.138121 0.0352393 --0.0764283 0.117143 0.0518912 --0.0476607 0.120291 -0.0131944 --0.0617261 0.158412 -0.0335949 --0.0794782 0.106106 0.0317497 --0.00127622 0.127442 0.029403 --0.0850735 0.0819457 0.0214598 --0.088151 0.137836 0.0407884 --0.0622605 0.152178 -0.0225796 --0.0896207 0.132365 0.0409732 --0.0392773 0.153597 0.0044688 --0.0477636 0.0797421 -0.0198355 -0.0475024 0.06248 0.0300852 -0.0137309 0.0344041 -0.00431645 --0.0864106 0.136323 0.00223079 --0.0622483 0.0470201 0.00467011 --0.0218601 0.0893132 0.0539604 --0.0404866 0.0390699 -0.027317 --0.0563767 0.0650155 0.0336358 --0.022785 0.0727991 -0.0382731 -0.00745846 0.0952014 -0.0287983 --0.0728877 0.143976 -0.0119757 --0.0485361 0.130681 1.6802e-05 --0.08227 0.0830732 0.0310042 --0.0458007 0.0884477 -0.0220772 --0.0674901 0.102816 0.040307 --0.0295082 0.0987895 0.0437091 -0.0266247 0.0591987 0.0436528 --0.0166425 0.0970062 0.0498004 --0.0754488 0.151352 -0.0128993 --0.0561187 0.04231 0.0196965 --0.0125561 0.107483 -0.0218463 --0.0258638 0.0987461 -0.0241399 --0.0150968 0.0965608 -0.0303463 -0.0403869 0.0505617 -0.00671315 --0.0618596 0.135275 0.0369058 --0.00853806 0.120181 -0.0133625 -0.0152242 0.123558 0.0310525 --0.0669104 0.112326 -0.011534 --0.00121369 0.0389243 -0.000247464 -0.0599261 0.0581121 0.0171753 --0.0104999 0.0842933 0.0575891 -0.0236959 0.120687 0.0298434 -0.0407626 0.105627 0.00616707 --0.0204813 0.10165 0.0438784 --0.0497999 0.0884036 -0.0217208 -0.0455191 0.0847794 0.00419259 --0.0113995 0.128605 0.00179072 --0.0808762 0.0733317 0.00350919 --0.0634956 0.0804499 0.0432131 --0.0737877 0.170302 -0.0290826 --0.00649113 0.0718493 0.0579775 --0.0445186 0.0533636 0.0386768 -0.0320623 0.104555 -0.0127247 --0.0491177 0.138604 0.00740359 -0.0459251 0.0848195 0.0121712 -0.0423718 0.0547731 -0.00653415 --0.0505603 0.0417939 -0.0107632 --0.0551112 0.0477166 -0.00539308 --0.0492183 0.150688 0.0111503 --0.0868019 0.0886457 0.00149241 --0.0414982 0.166749 0.00369508 --0.00533161 0.123249 -0.0106624 -0.00612795 0.107304 -0.0203065 -0.023391 0.0605296 0.0460187 --0.0778945 0.102117 0.0345146 --0.0177322 0.108689 -0.0211068 --0.0341359 0.168185 -0.0152479 --0.0364811 0.0931828 0.0441998 --0.0645148 0.15586 0.0250316 --0.0133496 0.124356 0.0309811 --0.053528 0.131291 -0.0047694 -0.0236875 0.0373106 0.0299772 -0.00806894 0.0972917 -0.0250353 -0.0518069 0.0518147 -0.00170668 --0.0580149 0.0675718 0.0363481 --0.0916942 0.124053 0.00727726 -0.0143227 0.0344255 0.0215932 --0.0828034 0.0762521 0.011522 --0.0523769 0.119775 0.034728 --0.0380638 0.174118 -0.00995608 --0.0515288 0.0559219 0.0167726 --0.0665225 0.10009 0.04154 -0.0449219 0.0497223 0.0313654 --0.00374083 0.069852 -0.0355987 --0.0448162 0.12956 0.0195798 -0.00318984 0.0852564 -0.0341139 --0.0901249 0.125637 0.04453 -0.0248625 0.12099 -0.00239034 --0.0357073 0.03405 0.0117511 --0.0461509 0.05879 0.0381434 -0.0389649 0.108275 0.00542368 --0.0857362 0.141867 0.00617644 --0.0755097 0.135846 0.0506323 -0.0384382 0.0954258 0.0328906 -0.00385238 0.131766 0.0125385 --0.0277181 0.0382234 0.00237012 -0.0554262 0.0714159 0.00640835 --0.0707971 0.168292 -0.02371 --0.0131917 0.169758 -0.0239616 --0.0344904 0.0661905 0.0406967 --0.00154364 0.130277 0.00186507 --0.0647696 0.148087 -0.0261392 --0.0577571 0.0334518 0.000595927 --0.0334995 0.0618586 0.0392638 --0.0657123 0.171986 -0.0448274 --0.0254896 0.049863 0.0466034 --0.0207287 0.058287 -0.0332963 --0.040488 0.088839 0.0428058 -0.00826686 0.0681716 -0.0316571 --0.0382076 0.0431174 -0.0263315 --0.0192007 0.0392753 0.0392298 -0.0446778 0.0701888 0.00161208 --0.0681688 0.0340999 0.0104427 --0.0891956 0.099693 0.0183885 -0.00250408 0.0856622 0.0573274 -0.00673484 0.0364109 -0.0131882 --0.0273112 0.0917698 0.0451953 -0.0360152 0.072737 0.038003 --0.0174841 0.0910963 0.0554741 --0.0882831 0.114383 0.0443189 --0.0562701 0.0534697 0.00668599 -0.0184737 0.104403 0.0439338 -0.0591195 0.067343 0.0203999 --0.0464971 0.107057 0.0400682 -0.0224712 0.125479 0.00796738 --0.00281596 0.0896133 -0.0355773 --0.0892259 0.113441 0.0323782 --0.0532781 0.0476794 0.0246524 -0.00120832 0.0811183 -0.0353756 --0.0820812 0.0748515 0.0115294 --0.0344414 0.153644 0.000910386 --0.0915313 0.147463 0.0171482 --0.0778811 0.12224 -0.00662917 -0.00275904 0.130985 0.0207146 -0.0333375 0.115599 0.0220283 --0.0925663 0.116874 0.0234322 --0.0461657 0.168264 0.000998904 --0.0608088 0.148246 0.0367611 --0.0740333 0.13404 0.0510058 -0.046183 0.0806404 0.0141758 --0.0177485 0.0700027 -0.0382786 --0.05252 0.0490121 0.0379722 --0.0142459 0.168321 -0.0155387 --0.0894247 0.0996886 0.0153976 --0.0654783 0.0861634 0.0444498 -0.0323217 0.116577 0.0230638 --0.0676059 0.141897 -0.00935244 --0.0514978 0.10289 0.0412322 --0.00575874 0.0741425 -0.036638 --0.0913439 0.11607 0.03131 --0.0313824 0.0877015 -0.0265568 -0.0373688 0.102607 -0.00785264 --0.0106393 0.169838 -0.0190633 --0.0716387 0.0675256 0.0265031 --0.0396636 0.0340515 0.0270767 --0.0779219 0.0717107 0.00150831 -0.0451585 0.0670735 0.000845212 --0.045692 0.126639 0.0237789 --0.0914166 0.131046 0.0292353 --0.0845601 0.0832447 0.0254813 --0.00465613 0.0540645 -0.0324247 --0.0573264 0.15429 0.0261567 --0.0776607 0.0817583 -0.0102119 --0.0614708 0.165833 -0.0590275 --0.0866007 0.129822 0.0479412 --0.0751026 0.155922 -0.00200459 -0.0292911 0.0364248 0.021021 -0.0168648 0.0958851 -0.0235234 -0.0566532 0.0608369 0.0255651 --0.0447794 0.128887 0.00190497 --0.024583 0.0635737 0.0419612 --0.0534745 0.0360014 0.0464895 --0.0488506 0.0999451 -0.0218934 -0.00224668 0.0740592 -0.0351433 --0.0223056 0.126998 0.0101726 --0.0907871 0.14608 0.0151486 --0.0506704 0.0680761 0.0375114 --0.0689054 0.113678 -0.00975253 --0.032497 0.0917926 0.0443017 -0.0282492 0.102359 -0.0164093 -0.0375206 0.0540908 0.0314327 --0.00566586 0.0555015 -0.0328252 --0.0896969 0.139298 0.033185 --0.0707473 0.127025 0.0521985 --0.0455052 0.162274 0.00622301 --0.0188243 0.0868874 -0.0382929 -0.00890069 0.0988547 -0.0226736 -0.0103725 0.130878 0.016344 --0.0568151 0.142191 -0.00256359 --0.0576833 0.0660478 -0.00944709 --0.0394154 0.128541 0.00978788 --0.0112757 0.0392934 0.0501019 --0.0875442 0.11045 0.0133403 -0.0108543 0.128955 0.0251156 --0.0306705 0.0692801 -0.0274547 -0.0193368 0.0460939 -0.0219388 -0.0280428 0.0928381 -0.0202889 -0.0101954 0.0879315 -0.0314901 --0.0425303 0.153621 0.00682011 -0.046342 0.0671736 0.000660587 -0.0133755 0.0508647 -0.0275026 --0.0815821 0.0803018 0.0303913 --0.059075 0.137911 -0.00597298 -0.0419587 0.0958192 0.0261617 -0.0444321 0.0482656 0.0306384 --0.0444939 0.0519693 0.038747 -0.0141421 0.107244 -0.018655 --0.0258198 0.0880859 -0.0357275 -0.0511643 0.0525875 0.0281258 --0.0838035 0.0884157 -0.00457068 --0.0075843 0.111951 -0.0206051 -0.020155 0.0344845 0.00437508 --0.0141697 0.038751 -0.00641336 -0.0160515 0.039741 -0.0214719 --0.0627129 0.161593 -0.024579 --0.0329051 0.0359381 0.0496011 --0.0738068 0.0892836 -0.0151913 -0.0299737 0.0934986 -0.0189639 --0.0618436 0.129703 0.0404325 -0.0117043 0.110341 -0.0188996 -0.013386 0.0576661 0.0508541 --0.0636966 0.117092 0.044917 --0.0634835 0.0890243 0.0452141 --0.0874124 0.136542 0.0428952 --0.0391888 0.168166 -0.0121398 -0.0376532 0.101954 -0.00791483 --0.0708338 0.143978 -0.0149516 --0.0135013 0.0687469 0.0541774 --0.0671166 0.134015 0.0451603 --0.0645196 0.148285 0.0383203 --0.0216796 0.18469 -0.0188168 --0.00148992 0.070365 0.0570874 --0.0291401 0.0875323 -0.0325902 -0.0251009 0.122815 0.00327552 --0.0111221 0.0980696 -0.0279124 --0.0635024 0.0918143 0.0447779 --0.0887995 0.0901451 0.00746775 -0.0164935 0.0962515 0.0477962 -0.046272 0.0806446 0.00718674 -0.038459 0.094268 -0.00974763 -0.0100793 0.0873522 0.0550703 -0.0183745 0.0874107 0.0495162 --0.0547819 0.0840722 -0.0215429 -0.0249849 0.0576546 -0.0237943 -0.0262469 0.11849 0.0293617 -0.0187045 0.0462587 0.0425837 --0.0433933 0.123406 -0.0104784 --0.0615139 0.0385816 -0.00827445 --0.0234882 0.104381 0.0428298 -0.0334188 0.115464 0.00204907 --0.0251305 0.0810774 0.0532367 --0.0661661 0.0431586 -0.00127362 --0.0689806 0.138464 -0.0078252 -0.0324954 0.0484967 0.0321634 --0.0650217 0.154743 0.00396393 --0.0615004 0.0818818 0.0435978 -0.0289072 0.10744 0.0367037 --0.0720417 0.156813 -0.0379146 --0.0232564 0.171248 -0.0127378 -0.0211195 0.109025 -0.0155233 --0.0668614 0.150018 -0.036632 -0.0204284 0.122662 -0.00423372 --0.0628194 0.162004 -0.0576316 --0.0641553 0.168532 -0.0413683 -0.0278158 0.0649933 -0.0208789 --0.0788364 0.0742331 0.0262211 -0.0527925 0.0505032 0.000257908 --0.0738772 0.107826 -0.00969763 --0.0819791 0.08171 0.030761 --0.0904343 0.136488 0.021207 --0.0584473 0.145323 0.0330944 -0.00225674 0.0697235 -0.0336823 --0.0228155 0.081267 -0.0385568 -0.0290261 0.106116 0.036871 -0.0121361 0.105839 -0.0196306 --0.0365486 0.12125 -0.0102225 --0.070219 0.146984 -0.026659 -0.00749947 0.122404 0.035106 --0.0234912 0.107132 0.0414501 -0.0116034 0.0355849 -0.021581 --0.0896067 0.0902304 0.0134498 -0.0274272 0.0781922 -0.0230908 --0.0228318 0.114095 -0.016802 --0.0510675 0.0598803 0.0316706 -0.0525281 0.0730706 0.0188626 --0.0503624 0.128323 -0.00347306 --0.0758088 0.0906346 -0.0139136 -0.0428831 0.0902351 0.0261862 --0.00171604 0.131316 0.0104838 --0.0845537 0.143232 0.00516668 -0.0183451 0.0551894 -0.0280076 --0.0914715 0.128331 0.0382421 --0.0654644 0.148292 0.0388168 -0.025254 0.122206 0.00192061 -0.0102154 0.0850922 -0.0315035 --0.0913446 0.12833 0.0392393 --0.0282035 0.125211 0.0168448 -0.0435793 0.0677809 0.0261624 --0.014506 0.114132 0.0394731 -0.0146525 0.0927004 0.0511905 --0.0777124 0.0900603 0.0375253 -0.0426104 0.0723991 0.0281081 --0.0165087 0.10859 0.0417725 --0.0293809 0.118905 0.0298455 --0.0747355 0.161794 -0.0126957 --0.0194977 0.103001 0.0433214 --0.0774975 0.111156 0.045792 --0.0235187 0.0551838 0.0425567 -0.00826699 0.0696219 -0.0321852 --0.0671246 0.042281 0.0101216 -0.0443577 0.0547836 -0.00632411 --0.0771697 0.152833 -0.00289126 --0.0455143 0.0335109 0.00302189 --0.0154906 0.0744572 0.0558178 -0.0390604 0.0575755 -0.00514174 --0.0300453 0.0861604 -0.0315778 -0.0243112 0.0999667 -0.0198415 -0.0337476 0.0534432 0.0345417 --0.0207506 0.0685447 -0.0377382 --0.0883977 0.0983242 0.022387 --0.043533 0.162269 0.00566221 --0.0580451 0.047259 0.00941407 --0.0435244 0.129538 0.0127129 --0.0129572 0.163516 -0.016687 --0.018238 0.0985224 -0.0244062 --0.0468429 0.132502 0.00641278 --0.012834 0.128656 0.00349339 --0.00949586 0.0938956 0.0554931 -0.0405174 0.0829825 -0.0107762 --0.0306755 0.0409906 0.0514223 --0.0887381 0.139163 0.03848 --0.0639163 0.105371 -0.0163736 -0.0319159 0.0876168 0.0427503 --0.0165553 0.128252 0.0064647 --0.0695817 0.168848 -0.0261289 --0.0702082 0.141157 0.0460159 -0.0179624 0.0489942 0.0433049 -0.0363477 0.102053 0.0316389 --0.029898 0.0385093 -0.0112051 --0.0687619 0.169445 -0.0540038 --0.0726588 0.143932 -0.0130219 -0.0162319 0.0849386 -0.0291053 --0.0620358 0.136971 -0.00707833 -0.0166416 0.0740317 0.0522091 -0.0213347 0.0607071 -0.0262571 --0.0576194 0.143675 -0.00218012 --0.0913297 0.148826 0.016141 --0.0751782 0.152724 -0.0149145 --0.062838 0.153641 -0.0115615 --0.0579073 0.152669 0.031812 --0.0401847 0.173392 -0.00391542 -0.0166876 0.0475243 0.0432195 --0.0393167 0.0432044 -0.0243027 -0.00658649 0.0945677 -0.0301242 --0.00883076 0.130134 0.0179537 --0.0248377 0.0867614 -0.0367865 -0.0135609 0.0343729 -0.0176058 --0.0367327 0.0739624 -0.0182558 --0.0891756 0.088886 0.0174542 --0.0869535 0.131154 0.0468504 -0.00298644 0.131511 0.0079308 --0.0116778 0.0541503 -0.0336719 --0.00992638 0.128404 -5.81123e-05 --0.0544374 0.131586 -0.00508481 --0.0384968 0.104212 0.0394832 --0.074384 0.0726496 -0.00763941 --0.0530656 0.150158 -0.00286677 --0.0166345 0.0465837 -0.0289175 -0.0567453 0.0707667 0.0204115 -0.0381172 0.0659142 -0.0117557 -0.00256341 0.131601 0.00920655 -0.0391019 0.106936 0.00217583 --0.0480338 0.0685335 0.039429 --0.0794876 0.0745597 -0.0035364 --0.0248661 0.101609 -0.0237851 --0.0647841 0.0448471 0.00913709 --0.0446647 0.117939 -0.0147658 --0.0152743 0.180101 -0.0270399 --0.0859599 0.106341 0.0203569 -0.0111873 0.0893276 -0.0308633 --0.0922566 0.126816 0.00926569 --0.0618365 0.166237 -0.0545929 -0.0181719 0.0795251 0.0527143 --0.0684871 0.120374 0.0527878 --0.0476953 0.0723623 -0.0159721 --0.0472614 0.125357 0.0280089 --0.0494961 0.113894 0.0347794 --0.0374992 0.0847101 0.0439351 --0.0404923 0.0620428 0.0412639 -0.0609826 0.0637492 0.0111528 --0.0849504 0.136625 0.0461206 -0.0337121 0.104741 0.0331059 --0.00864132 0.0907031 -0.0362798 -0.00988706 0.0373676 0.0450724 --0.024511 0.0782394 0.0527049 --0.0716377 0.0368114 0.00909586 --0.0832904 0.111663 0.0440643 --0.0156647 0.109623 -0.0201068 --0.0766606 0.163806 -0.0339802 -0.0165486 0.0631544 0.0502063 --0.0753023 0.155004 0.00375308 -0.039051 0.0380783 0.00858362 -0.0420573 0.0943632 -0.00379153 --0.0924935 0.124207 0.0332695 --0.0745678 0.155931 0.022959 --0.0348878 0.0336855 0.0122448 --0.0755817 0.14859 -0.0148673 --0.0712419 0.0628661 0.0147709 --0.0722512 0.170824 -0.0490235 --0.044945 0.146638 -0.00064718 --0.0327132 0.0383899 -0.00426549 --0.0656128 0.0626699 -0.00283823 --0.0615924 0.156857 -0.0275883 --0.0306139 0.051126 0.0398517 --0.0552831 0.0478834 0.0286656 --0.0825962 0.0869865 -0.00556699 --0.0743429 0.0777095 0.0359578 --0.00912413 0.125328 0.0309758 --0.0877256 0.112462 0.0226926 --0.0624682 0.148372 0.0373168 --0.0772099 0.0954309 0.0368548 --0.0657805 0.04031 0.0356744 -0.0390337 0.102562 -0.00454148 --0.0218167 0.0770677 -0.0388569 --0.013694 0.165443 -0.0129401 --0.0242656 0.0588495 -0.0313753 --0.0201769 0.16108 -0.00474531 --0.0746468 0.151291 -0.0288803 --0.0870878 0.147265 0.0324302 --0.0667973 0.0823343 -0.0181512 --0.0894818 0.137913 0.0311948 -0.0410937 0.100015 0.0241739 -0.0260496 0.0420955 0.0353242 --0.0497977 0.134944 0.0250398 --0.0824554 0.0748386 0.00652396 --0.0420037 0.0449364 -0.0183222 --0.00587956 0.107379 -0.0226761 --0.0298783 0.0719759 -0.0315267 --0.0649016 0.118019 -0.00923352 --0.0461849 0.131841 0.0072241 --0.0384968 0.066293 0.0418062 --0.0375363 0.128085 0.0104763 --0.0684218 0.173931 -0.0443685 --0.0921191 0.131045 0.0262423 --0.0269088 0.0720784 0.0425891 --0.0318614 0.109962 -0.0183828 --0.0576346 0.139576 0.0324737 --0.0582272 0.151065 0.033498 --0.0824187 0.0788859 0.0267668 --0.0386191 0.0474546 -0.0163861 -0.0266281 0.0902434 0.0456585 --0.00674435 0.0340208 -0.0192827 -0.0167681 0.0348096 -0.0116543 -0.00555478 0.102979 0.0445124 -0.0101351 0.0346886 0.0403762 --0.0715049 0.147007 0.0421623 -0.0583177 0.0551766 0.00716644 --0.0774854 0.142838 0.0458543 --0.0630637 0.0343143 0.0307056 --0.00979508 0.122843 -0.0101629 --0.0497184 0.0723081 -0.0156401 -0.0463136 0.0660623 -0.000202599 --0.0455839 0.0490621 -0.0101677 --0.0746807 0.110131 0.0436879 --0.0107636 0.0728162 -0.0377336 --0.0155087 0.105817 0.0426846 --0.0419504 0.0338103 -0.0111665 -0.0243299 0.0661738 -0.0239819 -0.0195943 0.041435 -0.0196763 -0.0590873 0.0566489 0.0191831 --0.0828908 0.120639 -0.00384458 -0.0299951 0.111426 0.0329993 --0.0685146 0.033856 -0.00470573 --0.0492135 0.140151 0.00839688 --0.0489146 0.121146 0.0309679 --0.00870224 0.0627847 -0.0356447 --0.086772 0.140601 0.0407491 --0.0293203 0.0381642 0.0309659 --0.0330003 0.0497903 -0.0153502 --0.0425517 0.127843 -0.00110505 -0.0328934 0.0381571 -2.41096e-05 --0.0525195 0.0426931 0.0456595 -0.021748 0.0349954 0.0225893 -0.00827474 0.123868 -0.00945393 --0.029563 0.0377844 -0.01791 --0.0370175 0.163827 -0.00102436 --0.0664999 0.101466 0.0412188 -0.0064937 0.048929 0.05087 -0.0287604 0.121079 0.0103057 -0.0252285 0.11379 -0.0106368 --0.0599544 0.0581084 0.014112 --0.062196 0.154993 0.0273195 --0.0901963 0.136492 0.0222062 -0.0243441 0.0535282 0.0420575 --0.0779175 0.0954136 0.0361479 -0.0233436 0.112218 -0.0129499 --0.0707139 0.0721775 0.0349299 --0.0640765 0.0658063 0.0313225 --0.012499 0.112778 0.04085 -0.00184795 0.0345666 0.017115 --0.0706528 0.0621972 0.0100461 --0.0885678 0.139164 0.0111992 --0.0188224 0.0347384 0.0467634 --0.0867734 0.103584 0.00638913 -0.0585617 0.0692487 0.0195963 --0.0597919 0.0868174 -0.0202685 -0.00547344 0.0964656 -0.0281399 -0.0206378 0.123881 0.0271063 --0.0699457 0.0641869 0.00125597 --0.0625615 0.156051 0.017016 --0.0417544 0.0339701 -0.0279962 --0.0649712 0.129694 -0.00875388 --0.0862104 0.107661 0.0103578 --0.0932554 0.121405 0.0112928 --0.0354965 0.0533413 0.0383699 --0.0288938 0.0821008 0.0456772 --0.0504899 0.115263 0.0337703 -0.0589314 0.0635744 0.022157 --0.0186162 0.0391183 0.0377018 --0.00206852 0.0346139 0.0433223 --0.0274904 0.108416 0.0392888 -0.0114791 0.0353993 0.0291949 -0.0231094 0.1217 -0.00313916 --0.0577454 0.0767844 -0.0191155 --0.00909377 0.175718 -0.0267745 -0.0517415 0.0673755 0.000499527 --0.0128851 0.164546 -0.0183954 --0.0673534 0.170861 -0.0570311 --0.0929853 0.13101 0.0212315 -0.0234643 0.0889079 0.0481435 --0.088271 0.126713 0.00126975 --0.0657845 0.0809163 -0.0181411 --0.0623578 0.139562 0.0361839 -0.0537838 0.0608937 0.0284739 --0.0417084 0.0681156 -0.0160245 -0.0391698 0.101249 -0.00580082 -0.0314319 0.059214 0.0400505 --0.0609535 0.135292 0.0364528 --0.000337321 0.0338454 -0.0216338 --0.0194278 0.169807 -0.0142312 --0.0348191 0.0886631 -0.024431 -0.0343015 0.0925788 -0.0159761 --0.0484766 0.166987 4.90724e-06 --0.0665297 0.149283 -0.0337543 --0.0801184 0.0845811 0.0344552 --0.0728936 0.109289 -0.00959602 --0.0631344 0.177233 -0.0567528 --0.0405211 0.16525 0.00379284 --0.0231365 0.166757 -0.0180638 -0.00733914 0.0539337 -0.0304234 --0.0448725 0.105637 -0.0203982 --0.0120489 0.177175 -0.0228491 --0.0935183 0.117402 0.0193034 --0.0218743 0.178667 -0.0141782 -0.0371376 0.0728556 -0.0127896 -0.00251304 0.0828672 0.0572444 --0.0659599 0.128235 -0.00885739 -0.0572369 0.0523165 0.0201815 -0.00234985 0.1177 -0.0168004 -0.0136405 0.0534411 0.0494225 -0.0440001 0.081852 -0.00180195 --0.0352323 0.0337248 0.00491425 --0.0852903 0.152844 0.0238067 --0.0841107 0.0938743 -0.00455389 --0.0327087 0.156604 0.00170747 --0.0136478 0.0384232 0.0249573 -0.0203982 0.126887 0.0157559 --0.0256832 0.0878506 0.050771 --0.0859766 0.117044 0.000228439 --0.0275277 0.0660102 0.0388181 -0.0386899 0.0941002 0.0332667 --0.0072203 0.0994662 -0.0253456 --0.0387089 0.068094 -0.0155018 --0.0447414 0.149173 0.00704529 --0.037003 0.126393 0.0195465 --0.0691196 0.118603 0.052746 -0.0126876 0.0376693 0.0445214 -0.00235997 0.0496442 -0.0301148 --0.0852421 0.0804972 0.00551565 --0.0315104 0.105689 0.0403731 -0.045017 0.0410596 0.00889517 --0.0645229 0.0335011 -0.00443342 --0.0237309 0.092173 -0.0338912 --0.0696939 0.158144 -0.0499358 --0.00649106 0.116924 0.0392844 -0.0203532 0.0579488 -0.0270415 -0.0454669 0.0761165 0.0216249 --0.0776599 0.103464 0.0342449 --0.0732 0.113624 0.050147 --0.0760799 0.147225 -0.00886324 -0.0300894 0.118197 0.0250757 -0.0134949 0.103141 0.0462202 --0.0890108 0.142042 0.0341592 --0.0804084 0.0719394 0.00662383 --0.0695221 0.143851 -0.0150076 --0.0608967 0.108264 -0.0166058 -0.024601 0.0954054 -0.0210454 --0.022965 0.108799 -0.0212234 --0.0611808 0.060116 0.0210055 -0.0302694 0.104198 -0.014346 --0.0556068 0.119255 -0.0119973 -0.0521834 0.0709362 0.0231159 --0.0314011 0.159502 0.00180977 --0.0393243 0.172677 -0.00992732 --0.0273795 0.0859709 -0.0356537 --0.0158141 0.084157 -0.0391976 --0.0748503 0.150353 0.0378605 --0.0898842 0.145774 0.0282412 --0.0830081 0.135296 -0.00152379 -0.00239673 0.0404932 -0.0244502 -0.0427154 0.0482477 0.0316879 --0.0266384 0.166791 -0.00886205 -0.0140069 0.0433574 0.0445182 --0.0554949 0.102938 0.0419937 --0.0535677 0.121244 0.0365515 --0.091536 0.147482 0.0221363 --0.0926871 0.118696 0.0103064 --0.0944412 0.121464 0.0182801 --0.0562674 0.0521079 0.00770249 -0.0268173 0.0563551 0.0421393 -0.0126767 0.102031 -0.0220157 --0.0753389 0.14722 -0.0108566 --0.0856054 0.119006 0.0487694 --0.0533885 0.122494 -0.00938247 -0.0431078 0.0438619 0.0262578 --0.0605291 0.0337655 0.01588 --0.0126252 0.045057 -0.0279244 --0.045035 0.131096 0.00921538 --0.0885624 0.127032 0.0457658 -0.040497 0.0569389 0.0314027 -0.0364907 0.111851 0.00455337 --0.0834729 0.144593 0.00316535 -0.0433385 0.080395 -0.00378638 --0.0318429 0.0944059 -0.023975 --0.0484939 0.0747239 0.0424157 --0.0110217 0.175722 -0.0231509 -0.000137104 0.104495 -0.0221519 --0.0521218 0.0553341 0.025863 -0.0390662 0.103279 0.0267541 --0.0365034 0.105591 0.0389607 -0.0135363 0.0347941 0.0319644 --0.0857201 0.113489 0.0456231 --0.0225205 0.114038 0.037332 --0.0424861 0.107068 0.0398635 --0.0498903 0.161248 0.00701432 --0.0261589 0.0660162 -0.0325063 --0.061193 0.167783 -0.0585846 --0.0153476 0.186173 -0.0245951 --0.0220085 0.0386415 -0.0116054 --0.0746541 0.0660086 0.0112783 --0.0857094 0.107615 0.00636703 --0.000110081 0.106984 -0.0213197 --0.0293764 0.039648 0.0531021 -0.028771 0.0495105 -0.0157345 --0.0168713 0.184583 -0.0192109 --0.0517714 0.14934 0.0163945 --0.059475 0.0776368 0.0428908 --0.0109445 0.0385116 0.00732721 --0.0636281 0.177112 -0.0556446 --0.074576 0.0901236 0.0400162 -0.0161292 0.0604031 0.0495734 -0.022982 0.114019 0.0351746 -0.0259399 0.098006 -0.0197455 --0.0097165 0.0698878 -0.0366754 --0.069561 0.132665 0.0486469 --0.0530949 0.0350628 -0.012244 --0.0680607 0.153823 -0.0498908 --0.0135439 0.125168 0.0294386 --0.00340282 0.12679 -0.00651364 --0.0391911 0.149452 0.000405422 --0.0764653 0.177807 -0.0519745 --0.0287178 0.121983 -0.00700749 --0.0619687 0.155933 0.0215789 --0.0411389 0.0448599 -0.0213399 --0.0553956 0.0560936 -0.00341211 --0.0930152 0.116045 0.0163142 --0.0538732 0.0634525 0.0320061 --0.0265911 0.123944 0.0203778 -0.0521155 0.073659 0.0142686 --0.0733241 0.158247 -0.0319134 --0.0109096 0.167211 -0.0224966 --0.0387656 0.0459335 -0.0222844 --0.0438685 0.104239 -0.0209341 --0.0404958 0.0464911 0.0408136 --0.0546568 0.133929 0.033262 --0.0875345 0.0914089 0.00446769 -0.0213976 0.0505253 -0.0237217 -0.00734362 0.0524803 -0.0298755 -0.0300864 0.0686462 0.0416997 -0.0343005 0.110021 0.028645 -0.0541591 0.0648613 0.0272743 --0.0267629 0.124714 0.018819 --0.084006 0.130916 -0.00261237 --0.032464 0.126152 0.0167563 -0.0411083 0.0816433 -0.00876203 -0.0569799 0.0538694 0.0224893 --0.0104937 0.0502816 0.0505289 --0.0809192 0.0899278 0.0336764 --0.0706578 0.10688 0.0373417 --0.0634399 0.160562 -0.0195565 --0.0491873 0.165537 -0.00392571 --0.0506864 0.137014 0.00141591 -0.0414602 0.0985756 -0.00280597 --0.0725308 0.161023 -0.0389355 --0.0593508 0.0339548 0.0212701 --0.0724089 0.155986 0.0106072 -0.0454654 0.0819915 0.0211715 --0.0231673 0.169718 -0.0195033 -0.014393 0.129494 0.0163965 --0.0185111 0.0499058 0.0467842 --0.0180519 0.128104 0.0102643 --0.0161793 0.169751 -0.0220442 -0.0178585 0.0957539 -0.0234025 -0.0277062 0.122023 0.0113437 --0.0356288 0.0533886 -0.010251 --0.00862621 0.0394649 0.0376552 --0.0708134 0.0624523 0.0134268 --0.0338786 0.104305 -0.0212068 --0.0471517 0.160622 -0.00754132 --0.0925898 0.124211 0.034269 --0.0584616 0.0717087 0.039721 --0.0146591 0.0511639 -0.0318396 --0.0607891 0.0597911 0.00342454 -0.0222547 0.0819067 -0.0260667 -0.0230644 0.109683 -0.0142211 --0.0844174 0.110829 0.0409213 --0.0687289 0.0779401 -0.0161359 --0.0752643 0.0941545 0.0391883 --0.0876028 0.105024 0.0163629 --0.077844 0.114867 -0.00473455 --0.0325542 0.0341026 -0.0206973 --0.0589604 0.0340153 0.0230639 --0.00211759 0.125578 0.0320366 -0.0126989 0.0342761 -0.010037 -0.013184 0.0740073 0.0542309 --0.0477691 0.130137 0.000614804 --0.0718381 0.155405 -0.0399144 --0.0622568 0.148888 -0.00391238 --0.0159434 0.0385311 0.027994 -0.0373005 0.103362 0.0294506 --0.02276 0.093942 -0.0316991 --0.0520122 0.14159 0.0203687 --0.082015 0.110886 0.0432009 --0.0745865 0.0720219 0.0307608 --0.00953059 0.096141 -0.0318625 --0.0495789 0.046041 -0.00928879 --0.00423381 0.0382248 0.0479393 --0.0382126 0.169665 -0.0124129 -0.0318584 0.0981802 0.0392129 --0.0314643 0.126198 0.0141678 --0.0622546 0.152185 -0.0195775 --0.0424907 0.0831788 0.0422885 --0.0205087 0.18589 -0.0190712 --0.00369262 0.0366899 0.0482034 --0.0197122 0.0583602 -0.0339067 --0.0106092 0.0434444 -0.026227 -0.0245832 0.0562081 -0.0237654 --0.0891532 0.121635 0.0465292 --0.0629277 0.161435 -0.0535909 -0.047295 0.0711844 0.0046334 --0.0417522 0.0782987 -0.0193601 --0.000496629 0.0828922 0.0574621 --0.0320822 0.0335961 -0.0276233 --0.0571072 0.154583 -0.000558004 -0.0584978 0.0634546 0.0229811 --0.0581231 0.149655 0.0336366 --0.0619701 0.160031 -0.0245798 --0.0800787 0.0980611 0.0339873 --0.0219645 0.0403079 0.0539432 --0.0699065 0.110817 -0.0106385 --0.0725366 0.154032 -0.0369032 --0.0224974 0.0498852 0.046496 -0.00485548 0.0339942 -0.0207847 --0.0614772 0.0338873 0.0155724 -0.00946392 0.0472926 0.0483305 --0.019502 0.109944 0.0407387 --0.0539465 0.0486826 0.012352 --0.0355502 0.175589 -0.0109785 --0.0784832 0.155333 0.0128492 -0.0266099 0.122879 0.0123678 --0.0472066 0.134653 0.0142236 --0.0078767 0.103255 -0.023393 --0.0504989 0.101536 0.0421291 --0.0266231 0.0450263 -0.028096 --0.0916243 0.131038 0.0282288 -0.0125747 0.0445985 0.0442752 --0.0196537 0.0480066 -0.0290701 -0.0172432 0.108764 -0.0171862 --0.0295071 0.0635474 -0.0264265 --0.0620034 0.040777 0.0431481 --0.00243593 0.113721 -0.0185019 --0.0630177 0.135513 -0.00745136 -0.0433285 0.0874073 -0.00479371 --0.0154888 0.0688106 0.054717 --0.0882956 0.116235 0.0458325 --0.0494969 0.0946343 0.044743 --0.0619637 0.147832 -0.00431835 --0.092816 0.124239 0.0392636 --0.0629366 0.147438 -0.0146052 --0.0782928 0.163856 -0.0319501 --0.064798 0.174285 -0.0502768 --0.0112267 0.038611 -0.000125945 --0.0820175 0.148708 0.00217249 -0.0401192 0.0979552 0.0282751 --0.0877344 0.132461 0.0447656 --0.050513 0.143196 0.0143929 -0.0136958 0.0672461 0.0531523 --0.0608764 0.033777 0.0140174 -0.00552563 0.0813962 0.0561869 --0.0768476 0.148423 0.040238 --0.0306152 0.0552238 -0.0173804 --0.0567885 0.123073 -0.00794084 --0.0255089 0.119394 0.0308336 -0.0223261 0.116663 0.0342169 --0.0475261 0.0335634 -0.00837623 --0.0582936 0.157998 0.00361947 -0.0051303 0.105879 -0.0208781 --0.00896496 0.0383664 0.01874 --0.0444005 0.0336982 -0.00787213 --0.00659427 0.0391448 -0.0257394 --0.0414965 0.0424145 0.0425934 --0.0846517 0.135301 0.0472783 --0.0634992 0.0973124 0.0426152 --0.0488679 0.135513 0.00441971 -0.037597 0.0883595 -0.0147642 --0.00186878 0.0388962 0.0287527 --0.028023 0.0380941 0.0277005 --0.0474992 0.0718408 0.0410603 --0.0899231 0.113261 0.00935255 -0.044663 0.094574 0.0141596 --0.0613242 0.174126 -0.0596453 -0.0131192 0.0913894 0.0524895 -0.0569982 0.0642691 0.00177262 -0.029911 0.120086 0.0121698 --0.0341992 0.124637 -0.00378015 --0.0714932 0.121802 0.0535223 --0.060211 0.120578 -0.00928669 -0.0514409 0.0718132 0.00596213 --0.0055446 0.0384588 0.0102869 -0.0401137 0.0933035 -0.00871241 --0.077868 0.12372 -0.00684832 --0.0438994 0.148485 -0.00356582 --0.0478093 0.0898718 -0.0219802 --0.050356 0.0501549 0.0156949 --0.044116 0.168361 -0.0078879 -0.0274031 0.12156 0.0212208 --0.0198084 0.119865 -0.0108751 --0.00808629 0.0392239 0.0361848 --0.074679 0.177203 -0.0452121 --0.0717079 0.162415 -0.0429474 --0.0817249 0.153192 0.027965 --0.0830361 0.0952877 0.0313817 --0.0410879 0.12806 0.000341883 --0.0268762 0.104433 -0.0231038 --0.028867 0.0620809 -0.0264195 -0.0400441 0.0834026 0.0333734 -0.00148401 0.0427923 0.0460657 --0.021597 0.124211 0.0236359 --0.0493581 0.0389276 0.0456407 --0.0251636 0.119759 -0.0107128 --0.0305455 0.0776911 -0.0335901 -0.0434944 0.0719976 -0.00179535 --0.0730641 0.148297 -0.027137 --0.0403032 0.0335749 -0.0236075 --0.0838696 0.117633 -0.00194246 --0.0183958 0.0360837 -0.0274195 -0.0306925 0.119003 0.0181751 --0.0287719 0.0876257 0.045371 --0.0150862 0.116786 -0.0157023 --0.0226105 0.0393974 -0.0288175 --0.00549593 0.114185 0.0409403 -0.0172148 0.0820814 -0.0286624 -0.0204946 0.0878829 0.0490965 -0.0144377 0.119508 -0.0127985 -0.0084105 0.0389663 -0.0233493 -0.042717 0.0705281 -0.00378792 --0.0721585 0.0349122 0.00711943 --0.0700117 0.176166 -0.0463861 --0.0559881 0.0594067 0.0225062 --0.0934924 0.121416 0.0122906 -0.0386755 0.101225 -0.00680717 --0.00386806 0.105937 -0.0224388 --0.0104995 0.091174 0.0564817 --0.0012394 0.131315 0.00922853 --0.0497873 0.0855205 -0.0216876 --0.0168713 0.104463 -0.0227606 -0.0101956 0.0865002 -0.0314726 --0.0534959 0.108443 0.038977 --0.0548951 0.0610993 0.0270145 --0.0755046 0.137255 0.0498073 --0.0485754 0.0489523 -0.00913959 --0.0331264 0.163719 -0.0148995 --0.00945074 0.100225 0.0471086 --0.0342862 0.0340473 0.0246456 --0.0294128 0.0335741 -0.023325 --0.026685 0.0349864 0.0500364 --0.061923 0.12237 -0.00883821 -0.0501668 0.0567787 0.0302284 --0.011856 0.127622 0.0255897 --0.0429498 0.0338754 -0.00590515 --0.000398209 0.131157 0.00667235 --0.0163397 0.112374 -0.0190184 --0.0651151 0.138224 0.0409979 -0.0355326 0.0544702 -0.00765701 -0.0264528 0.0348348 0.00531809 --0.0438555 0.101385 -0.0214526 --0.0234974 0.0498976 0.0468652 --0.0436816 0.0651561 -0.0146099 --0.00750789 0.0386054 0.00429878 --0.0494719 0.0643044 0.0356628 --0.0857911 0.0847131 0.0234468 -0.0202388 0.0735294 -0.0276011 --0.0826135 0.153724 0.024657 -0.0377117 0.0799594 -0.0137509 --0.0629014 0.0384346 0.017326 --0.0564952 0.112508 0.0359017 --0.00450514 0.0647631 0.0563697 -0.0228849 0.0849076 0.049031 --0.0136101 0.17129 -0.0181213 --0.0659308 0.168025 -0.05906 -0.00616007 0.130231 0.0233995 -0.0200475 0.0355684 0.0326031 -0.0207235 0.0355731 0.0309275 --0.0914203 0.133738 0.0192152 --0.0894168 0.0942943 0.0184246 --0.0486795 0.137079 0.00840446 --0.0268516 0.0981872 -0.024073 --0.0296061 0.0499557 0.0431146 --0.0645444 0.136771 0.0400377 -0.00960463 0.0369501 0.029234 --0.0077992 0.0826766 -0.0378216 --0.0705096 0.145613 0.0431794 -0.038042 0.109981 0.0137429 --0.0323904 0.0346717 0.0421656 -0.0166765 0.12456 0.0286792 -0.0496183 0.0673428 0.0005193 --0.0256005 0.175695 -0.0107936 --0.0178219 0.0896296 -0.0373512 --0.010186 0.0339025 -0.0217341 --0.047823 0.0912927 -0.0217091 -0.0214379 0.121585 -0.00505488 --0.063535 0.0741856 0.0400495 --0.0175015 0.119559 0.0348485 -0.0378045 0.0701003 -0.0128173 --0.06064 0.140962 -0.00527103 --0.0745647 0.162191 -0.0132518 -0.0175747 0.0931801 -0.024649 --0.0413443 0.159411 0.00325579 --0.0692325 0.161954 -0.0115912 --0.0598828 0.104039 -0.0184233 --0.0275135 0.111195 0.0372083 -0.017284 0.0435398 0.0440147 --0.043478 0.0633766 0.0405033 -0.0234516 0.0389975 0.0363054 --0.0705331 0.144185 0.0442754 --0.00248752 0.0897873 0.0564419 --0.0728742 0.149812 -0.0379734 -0.0462595 0.0834414 0.00917612 -0.00549045 0.0459551 0.048539 -0.038562 0.0568882 0.0311978 --0.0404973 0.10005 0.041322 --0.0633155 0.125546 0.0454063 --0.0425091 0.0520201 0.0393163 -0.00748602 0.041302 0.0454759 --0.0652746 0.0378654 0.0394026 --0.0208078 0.081314 -0.039065 -0.00735987 0.131518 0.0123881 --0.0507686 0.0812185 -0.0210302 -0.0289317 0.0369927 0.000264038 --0.0895362 0.119938 0.00329723 -0.0339261 0.0564017 0.0366181 -0.0387571 0.0780554 0.0349576 --0.00249465 0.111426 0.042426 -0.0312166 0.0814571 -0.0197537 -0.00710696 0.112707 -0.0194319 -0.0182552 0.0736117 -0.028651 --0.0747384 0.149908 -0.0288721 --0.0142729 0.16729 -0.0212151 --0.0796554 0.0776931 0.0301108 --0.0308995 0.0385461 -0.0114399 --0.0135011 0.162185 -0.0138332 --0.062358 0.172308 -0.0618736 --0.0779551 0.131028 -0.00606492 -0.0053093 0.0610791 -0.0314051 --0.0622044 0.163118 -0.0415929 --0.0875561 0.0900472 0.00346813 --0.0693763 0.0627096 0.00438827 -0.0577316 0.0594186 0.0235899 --0.076964 0.0686471 0.0102516 --0.068516 0.156454 -0.00263594 --0.0116226 0.0389602 0.0338935 --0.053617 0.0500325 0.0119809 -0.0600963 0.059514 0.00816569 --0.0667396 0.168684 -0.03081 -0.0461456 0.0820314 0.0061875 --0.0433217 0.0391871 0.0438385 -0.0426589 0.0598822 -0.00401987 --0.0496436 0.132456 0.0281905 -0.0526393 0.0635217 0.0285801 -0.0276786 0.107363 -0.0137282 -0.0429561 0.100122 0.0141624 -0.0420203 0.102869 0.0111608 -0.0352633 0.113355 0.0198926 --0.0527821 0.0840792 -0.0215781 --0.0731314 0.179106 -0.0550054 --0.0772542 0.116219 0.0507045 --0.0448961 0.131042 0.0121815 --0.0659423 0.149401 -0.0328697 --0.00381497 0.0882175 -0.036071 --0.00434542 0.130565 0.019581 -0.0267602 0.0365817 2.43485e-05 -0.0169695 0.107204 -0.0175448 --0.062502 0.0625858 0.0256444 --0.00350098 0.0815126 0.05747 -0.000251433 0.0712294 -0.0349609 --0.0113059 0.174226 -0.0217772 --0.0348319 0.0943645 -0.0236767 --0.0786972 0.0940445 0.0355566 -0.0177903 0.112808 -0.0155711 --0.0318198 0.0887354 -0.0251772 --0.0198038 0.0827175 -0.0390158 --0.0190696 0.126125 0.000571573 --0.0793168 0.102079 0.0331119 -0.021502 0.109802 0.0384228 --0.0927296 0.124224 0.0362665 --0.0209485 0.0682779 0.0508919 -0.041224 0.101389 -0.000814438 --0.0468126 0.0898791 -0.022022 --0.0348994 0.124334 -0.00549397 --0.0341879 0.127198 0.0131711 --0.049291 0.131272 -0.000642386 --0.0359021 0.0337218 0.00658675 --0.0837824 0.091132 -0.00556609 --0.0335134 0.101547 0.0420338 -0.0210931 0.0429808 -0.0187308 -0.0424902 0.0555855 0.0321183 --0.0557185 0.0570014 0.011057 --0.0194912 0.112675 0.0392933 --0.025189 0.156576 -0.00769163 -0.0400265 0.10701 0.00816505 --0.0540901 0.153118 -0.00271435 --0.00486253 0.101638 -0.0232055 --0.0436472 0.0338067 0.00674466 --0.0211436 0.168262 -0.0193322 --0.0763578 0.141673 -0.00573846 -0.0465682 0.041911 0.0139236 --0.0534989 0.109802 0.0378386 --0.0811057 0.0748245 0.0195385 -0.0366496 0.0848209 0.0372394 -0.0520606 0.0608742 0.0294954 --0.0810176 0.109646 0.0372868 -0.0260062 0.121547 0.0249766 --0.0134941 0.0773082 0.0569169 --0.0759274 0.108411 0.0376421 -0.0131577 0.0548631 0.0504935 --0.0556243 0.0335264 0.0117574 --0.0445311 0.119183 -0.0140568 --0.0651138 0.155569 0.0262833 -0.0254608 0.100767 0.0422505 --0.0354939 0.101471 0.0414493 --0.0526525 0.152155 0.0150192 --0.0578899 0.111162 -0.0167182 --0.050471 0.0571806 0.032579 --0.0881725 0.103664 0.0113862 --0.0124346 0.0985527 -0.0264295 -0.0459022 0.0876188 0.00817319 --0.0598831 0.0337324 0.0142605 -0.0420206 0.092566 0.0274869 --0.0622887 0.152203 -0.0145776 --0.0483961 0.150684 0.0105827 -0.00023463 0.0985537 -0.0263753 --0.0719091 0.107919 -0.010771 -0.0379248 0.0575872 0.0318029 --0.0684803 0.169194 -0.0285889 --0.0388617 0.099995 -0.0218283 --0.0776097 0.0796169 0.0342011 -0.00633113 0.0553726 -0.0306713 -0.0163088 0.048977 0.0444188 --0.0838449 0.0817176 0.00149669 --0.0216263 0.0341828 -0.0204844 --0.0187634 0.0728738 -0.0388715 --0.0626025 0.0388129 0.0247151 --0.0373475 0.0347779 0.0107604 --0.00558664 0.0376733 -0.0253626 -0.0599615 0.0678313 0.0171716 --0.0295401 0.0904607 -0.0275932 -0.0284451 0.114053 0.0325229 -0.0418253 0.0830818 -0.00779351 -0.00746772 0.0343056 0.0166757 --0.0865698 0.0833108 0.0104907 --0.0729271 0.151083 0.037025 --0.0781924 0.155673 0.0158655 --0.0788514 0.116332 -0.0048797 -0.00512317 0.107303 -0.0203142 --0.0103272 0.0383585 0.0166568 --0.0348025 0.040194 -0.0297923 --0.000491404 0.0814979 0.0573536 --0.0290382 0.16386 -0.00530596 --0.0694805 0.121794 0.053195 --0.0704544 0.150585 -0.0434585 --0.0639717 0.0459278 0.00771742 --0.03056 0.124009 -0.00164624 -0.0144021 0.0780973 0.054252 --0.0808546 0.140749 0.0461596 -0.0103353 0.0581557 -0.0299403 --0.00949578 0.084298 0.0576062 --0.0249013 0.0382346 0.0282196 --0.0316389 0.0409999 0.051064 -0.0387381 0.0381712 0.0065938 --0.0580729 0.0345066 0.0402882 --0.0663198 0.150167 -0.0356652 --0.064292 0.168172 -0.0605879 --0.0314424 0.0679449 -0.0244554 -0.0603913 0.0595429 0.0161691 -0.0102649 0.129908 0.00205228 --0.0440813 0.0336392 -0.0114358 -0.0309277 0.0497348 -0.00874 --0.0267697 0.0750695 0.0452054 --0.0791015 0.170034 -0.0382691 --0.0864283 0.0954013 0.00141653 -0.00852849 0.0646614 0.0551736 -0.0473561 0.0503594 -0.00438005 -0.039601 0.107391 0.00564087 --0.0861267 0.0833147 0.0194823 --0.0786738 0.10815 0.0335843 -0.043481 0.0832455 0.0271768 -0.0281352 0.0915776 0.0443357 --0.0298099 0.0677811 -0.0284707 --0.0229012 0.115018 -0.0157633 --0.0270064 0.0808968 0.0494715 -0.0404227 0.0885874 -0.0107894 --0.087216 0.0937177 0.0257149 --0.0690509 0.0654544 -0.0025414 --0.0695527 0.04187 0.00402445 -0.00429234 0.0668529 -0.0329804 --0.046755 0.0336866 -0.0157033 -0.0576125 0.0580597 0.0234109 --0.000994561 0.129288 -0.0011666 -0.0454245 0.0904044 0.0131633 --0.0438081 0.0899046 -0.0222231 -0.0199328 0.127154 0.0141603 -0.0114882 0.0963254 0.0495798 -0.0218142 0.117368 -0.0105004 --0.0438465 0.0359346 0.00839642 --0.0714426 0.0632696 0.00712846 --0.0759079 0.150006 -0.00888842 --0.06794 0.126772 -0.00890268 --0.0343726 0.127227 0.0072164 -0.0578211 0.0537494 0.00717652 --0.0483087 0.135537 0.00740851 --0.0568342 0.0666429 0.0356476 -0.0481112 0.0431114 0.00725444 --0.0425043 0.117982 0.0312159 -0.0144699 0.0976455 0.0479677 -0.0563061 0.0508424 0.00620646 --0.0300578 0.163895 -0.00500569 -0.0102245 0.0823018 -0.0318649 -0.0598453 0.0608733 0.0191849 --0.0620027 0.172528 -0.0545971 --0.0197571 0.0971344 0.046022 --0.0611783 0.167226 -0.0592729 --0.00613038 0.0999315 0.0488982 -0.0488619 0.047436 -0.000620948 --0.0208111 0.118967 -0.0119295 -0.00352005 0.0786345 0.0561775 --0.071061 0.15959 -0.0439233 --0.0765957 0.161076 -0.0289322 -0.0259255 0.123359 0.0149571 --0.0746094 0.14858 -0.0188631 -0.0569296 0.058069 0.024171 --0.0338241 0.152569 -0.00489392 --0.0455023 0.0615609 0.0388319 --0.0654625 0.143948 0.0405383 --0.0560519 0.0345032 0.0407254 --0.0709341 0.162789 -0.0122264 --0.078067 0.144487 -0.00381208 --0.094099 0.121442 0.0152795 --0.00327736 0.0410332 0.0476549 --0.0500433 0.165539 -0.00195268 --0.0774288 0.0712256 0.0238415 --0.00725841 0.0408714 0.048906 --0.0833667 0.142023 0.0429747 --0.0692361 0.153199 0.0337122 --0.0360543 0.0398378 -0.0294769 --0.0403231 0.0344611 0.0371557 --0.0207576 0.069984 -0.0381379 -0.0122374 0.0737871 -0.031159 --0.0241603 0.0665253 0.044272 -0.0399369 0.0860773 0.0331939 --0.0809073 0.123633 -0.00507492 --0.00964827 0.166616 -0.0197629 --0.00664529 0.1307 0.0129838 --0.0209361 0.0381808 0.0128466 --0.0538563 0.0970443 -0.0219059 --0.0662078 0.0723697 0.0374848 --0.0398566 0.099981 -0.0216989 --0.0494761 0.0600183 0.034326 --0.0157667 0.0742966 -0.0389627 --0.0875711 0.0977385 0.0245274 --0.0529166 0.0566407 0.0191372 -0.000745542 0.0955759 -0.0312149 --0.0688619 0.10089 -0.0150284 --0.0130273 0.178658 -0.0225027 --0.00548585 0.118301 0.0387556 --0.063934 0.169417 -0.04458 -0.00224686 0.131192 0.0191047 --0.0526917 0.0662141 -0.0112413 -0.0316126 0.104759 0.0353509 -0.0222548 0.0776918 -0.0264111 --0.0685061 0.105552 0.0384458 --0.0576201 0.135609 -0.00546838 --0.00760577 0.128788 -0.000526473 --0.0262755 0.0383516 -0.00662702 -0.0096904 0.0344726 -0.0051827 -0.0183649 0.0355244 -0.0106716 --0.0892922 0.0996701 0.0134013 --0.0748707 0.116421 -0.00675171 --0.054019 0.0333099 0.015848 --0.0927402 0.125562 0.0292626 --0.00859312 0.0384098 0.0205847 --0.0574617 0.0399955 0.0466824 --0.0890962 0.0996533 0.0114017 --0.0393675 0.120945 -0.0119262 --0.0498057 0.144755 0.010389 --0.0800056 0.108388 0.0313605 --0.0694061 0.153071 -0.0482738 --0.0529002 0.0701503 0.0387731 --0.00979568 0.178776 -0.0277733 --0.0749384 0.177982 -0.0467773 --0.080224 0.0913049 0.0343483 -0.0274404 0.0399547 -0.00370609 -0.0064659 0.11274 0.0407332 --0.0218179 0.0350986 -0.0195001 --0.0723907 0.151114 -0.0412874 -0.00590733 0.0340449 -0.020637 -0.0460177 0.0800284 0.0189631 --0.0576496 0.0629466 -0.00612077 --0.0519433 0.0503866 0.0326949 -0.0377573 0.0757194 -0.0117756 -0.0434133 0.0930689 -0.00182579 --0.0445007 0.165214 0.00483168 --0.0196553 0.063928 0.0497256 --0.0766812 0.154876 -0.00631355 --0.0344859 0.0335245 -0.0299041 -0.0132509 0.0349689 -0.0195966 --0.0264467 0.0459901 0.0505652 --0.00131456 0.122836 -0.0102349 -0.0122169 0.129551 0.00276868 --0.0137494 0.0383366 0.00873382 --0.0445005 0.116602 0.0322264 --0.0346258 0.0408721 -0.0296689 --0.0706305 0.0401508 0.00122659 --0.0765009 0.0716493 0.0271716 --0.0708234 0.155869 0.0257344 --0.0311277 0.0566897 -0.0153882 --0.0896944 0.133694 0.0395953 -0.000231967 0.0783204 -0.0356621 -0.0338144 0.115724 0.00791606 --0.0300912 0.15662 0.000215848 -0.0464982 0.0677769 0.0257597 --0.0214151 0.0595466 0.0459898 --0.0572298 0.0696188 0.0382761 -0.0366123 0.064635 0.0370437 --0.0264937 0.0973851 0.0437224 -0.0404949 0.0513767 0.0324659 --0.0350844 0.107815 -0.0201106 --0.0205025 0.0486482 0.0489372 --0.0610181 0.13697 -0.00676267 --0.0906044 0.135075 0.015212 --0.0194066 0.174211 -0.0159442 --0.0394983 0.0719214 0.0419294 --0.0883414 0.120307 0.04718 --0.00748928 0.0978336 0.0520944 --0.0846404 0.107661 0.0233457 --0.0214945 0.10716 0.0418366 -0.0181073 0.0398088 -0.0196993 -0.0190777 0.0384168 -0.0157069 --0.0636502 0.159498 -0.051954 -0.0283128 0.0754542 0.0444772 --0.054074 0.15164 -0.0027148 --0.083614 0.154208 0.0184012 --0.056485 0.0343785 0.0390076 -0.0337482 0.102096 0.0349353 --0.0782584 0.1764 -0.0490322 -0.0136057 0.0460076 0.0440344 --0.00550326 0.0801395 0.0576107 -0.0334132 0.0849144 0.041374 --0.0113988 0.126257 0.0287047 --0.0655972 0.169628 -0.0389928 --0.0832568 0.154212 0.0141255 --0.0820934 0.0898659 0.0320222 --0.067283 0.17966 -0.0595334 --0.062529 0.150617 -0.0195776 --0.0299377 0.0847457 -0.0326018 -0.0607552 0.0664989 0.0131533 --0.0228597 0.101618 -0.023963 --0.0618668 0.165619 -0.0600772 --0.081854 0.0937329 -0.00756112 --0.0679516 0.170855 -0.0560296 --0.0295118 0.108456 0.0388793 -0.0482509 0.0539799 0.0309574 -0.00823122 0.079605 -0.0335706 --0.0526044 0.041455 0.0460966 --0.0496802 0.165544 -0.00294037 --0.0910152 0.129688 0.0372352 --0.0404973 0.0972715 0.0419896 -0.00850648 0.0772375 0.0559821 --0.0717922 0.153989 -0.0428988 --0.0507334 0.147965 -0.00270623 -0.0127323 0.0860509 0.0536553 -0.0565626 0.0508082 0.0192018 --0.047499 0.10845 0.0392246 --0.00917487 0.0875708 -0.0370938 --0.0783316 0.0788746 0.032897 --0.0896787 0.135012 0.00721892 -0.00550113 0.0883518 0.0561015 --0.0423419 0.0335706 -0.0240051 -0.0405574 0.104219 0.0191648 -0.00286437 0.130486 0.00148286 --0.0643911 0.133918 0.0402655 --0.0620868 0.139878 -0.00655442 --0.0557051 0.12209 -0.00891575 -0.0589396 0.0566475 0.0201757 -0.0386112 0.0603508 -0.0077511 --0.0806595 0.0855046 -0.00754297 --0.0718229 0.0965348 -0.0152102 -0.0459498 0.0806271 0.0191734 --0.0515557 0.141366 0.000880581 --0.0859779 0.0910726 0.0273961 --0.0194809 0.0757644 0.0547346 --0.0526104 0.0335154 0.00699108 --0.080479 0.155159 0.0180021 --0.0500595 0.117739 -0.014504 --0.0638596 0.0939187 -0.018635 --0.0469776 0.034208 0.0289371 -0.0315208 0.0994913 0.038731 -0.0444927 0.0610909 0.0304355 -0.0212529 0.1262 0.0189269 --0.0254692 0.0509386 0.0434079 -0.0476579 0.0715472 0.019969 -0.022698 0.118017 -0.00920048 --0.0384222 0.125448 0.0219859 --0.038314 0.170034 -0.0122167 --0.0530543 0.14469 0.0223994 --0.00492317 0.0389099 -0.00470281 -0.0373499 0.0533605 -0.00643641 --0.0696712 0.171569 -0.0347594 -0.0436954 0.0959268 0.0201595 -0.0285253 0.065965 0.0429423 --0.0466394 0.0345455 0.0392313 -0.0412883 0.0886287 0.0299331 --0.0251747 0.0383636 -0.0175696 --0.0674763 0.168038 -0.0560148 --0.0634115 0.166723 -0.0396505 --0.0443984 0.0671335 0.0404051 --0.0524987 0.100127 0.0423619 --0.0837023 0.110333 0.0361338 --0.0757541 0.0819089 0.037226 --0.0475033 0.0973719 0.0436212 --0.0418104 0.0899475 -0.0227382 --0.0308563 0.174216 -0.00433975 --0.00771604 0.130016 0.0212618 --0.0691125 0.156051 0.011784 --0.049655 0.0664173 -0.0130805 -0.0212145 0.0401172 -0.0107008 --0.0418108 0.128972 0.0103834 --0.0623408 0.164683 -0.0455908 --0.0776167 0.145877 -0.00384676 -0.0294578 0.079544 0.0444105 --0.052057 0.15088 0.0153954 -0.0551015 0.0521065 0.00221795 --0.0568769 0.116868 -0.0135067 --0.0856284 0.151402 0.00824006 --0.0512523 0.116429 -0.0151143 --0.0568623 0.0941345 -0.0215512 --0.0153943 0.099814 0.0443638 -0.0368805 0.101462 -0.00941022 --0.0293998 0.0355494 -0.0195486 --0.040872 0.105663 -0.0204372 --0.0279821 0.0821961 0.0475971 --0.0106963 0.176084 -0.0292514 --0.00933224 0.038323 0.0168951 --0.0792032 0.10313 -0.00756064 --0.0540718 0.118333 0.0357708 -0.00450074 0.0938217 0.0540732 --0.0746595 0.15617 0.0170913 --0.0708414 0.0994113 -0.0147342 --0.0516111 0.0530832 -0.00753985 --0.0486234 0.0532712 -0.0094518 --0.031704 0.172718 -0.00384226 --0.00272576 0.130091 0.00149765 --0.092388 0.120024 0.00928585 --0.037643 0.153612 0.00331291 -0.0356049 0.0577583 0.0355158 --0.0668801 0.103821 -0.0153002 -0.0379456 0.10977 0.0171703 -0.0191769 0.0959952 -0.0230407 -0.0391807 0.0658814 0.0336832 --0.0690863 0.0666121 0.0278101 --0.089106 0.114375 0.0298659 --0.0216155 0.0436703 -0.028439 --0.0266188 0.0490904 -0.0254391 -0.000108091 0.0340814 -0.0198793 --0.0171613 0.159788 -0.00903074 -0.041574 0.0397142 0.0168995 -0.019656 0.0347604 0.000281692 -0.00764804 0.128583 -0.00254334 --0.0553782 0.151032 0.0287496 --0.0528315 0.0558373 -0.00742005 -0.0115037 0.109883 0.0397133 -0.03545 0.105907 -0.00815474 --0.0629114 0.115341 -0.0117985 --0.0234208 0.172725 -0.0129655 --0.0890673 0.101028 0.0173829 -0.0236359 0.056409 0.0445932 --0.0187325 0.0374026 0.0529482 --0.0394792 0.105608 0.0388858 -0.0151319 0.0603601 0.0498992 --0.080949 0.137599 -0.00280806 --0.0546196 0.0345652 0.0426785 --0.0465281 0.033544 -0.0026564 -0.0395657 0.0998694 -0.00580754 -0.0101223 0.108705 -0.0195083 --0.0104988 0.09255 0.056119 -0.0330296 0.116688 0.0147767 --0.0910722 0.141959 0.0151878 --0.00849613 0.0703395 0.0565554 --0.0574961 0.0904385 0.0452768 --0.0530142 0.0490552 0.0256583 --0.0294931 0.0717523 0.039896 --0.0311676 0.0348856 0.0474529 --0.00876366 0.0347363 0.0436201 --0.0666703 0.0612745 0.0188657 -0.0173575 0.0940342 0.0480767 -0.0284806 0.111435 0.0343318 --0.0468308 0.0941893 -0.021914 --0.0265985 0.0562164 -0.027412 --0.0871843 0.135176 0.0441499 --0.063207 0.06374 0.0280276 --0.0345021 0.0647803 0.0405279 -0.0597837 0.0567045 0.0121686 --0.0474843 0.0818872 0.0439119 --0.0589237 0.11399 -0.014753 --0.0490056 0.122549 0.0307687 -0.0548584 0.0611516 -0.00113589 --0.0458004 0.0353434 -0.021332 -0.00134052 0.0539375 -0.0306386 --0.0278278 0.177181 -0.00696301 --0.0427537 0.0783105 -0.0194623 -0.00651372 0.089712 0.0551929 --0.0494951 0.0819134 0.044146 -0.0305588 0.055351 -0.0157687 -0.0297469 0.0929269 0.0431563 -0.0125099 0.0519837 0.0495237 -0.0459653 0.0806289 0.018177 --0.053548 0.149321 0.0244145 --0.0317948 0.0651814 -0.020436 --0.019834 0.0868717 -0.0379507 --0.0119886 0.038466 0.00715809 --0.0770198 0.170132 -0.03325 --0.0269539 0.17866 -0.00745161 --0.0756616 0.0695139 0.0239361 --0.0474944 0.116586 0.0319739 --0.0671319 0.0355924 0.0145398 --0.0783661 0.108548 -0.00557568 --0.0284012 0.0860445 -0.0346283 -0.0257301 0.0379057 0.0280361 -0.00740689 0.0389878 -0.0235836 --0.0629696 0.131105 0.0405653 --0.0380606 0.157756 -0.011216 --0.0361107 0.0459963 0.0412564 --0.053455 0.0625326 0.0304805 --0.0731839 0.178324 -0.0475338 -0.0137018 0.0888713 -0.0301465 --0.0894038 0.140678 0.0331776 --0.0114925 0.06602 0.0547394 --0.0853984 0.0872002 -0.00151975 --0.00957697 0.128995 0.00181181 -0.0571986 0.0536922 0.00517882 -0.0181761 0.0974249 -0.0228373 -0.0414526 0.0425673 -0.000513932 --0.0423634 0.121318 -0.0123099 --0.0854479 0.0898939 -0.00155092 --0.0136017 0.0392183 -0.0267222 --0.0353577 0.174409 -0.00212011 --0.0930586 0.122743 0.0102788 -0.0208421 0.0882147 -0.0254487 -0.000267595 0.0697483 -0.0342392 -0.0443612 0.0458824 -0.00271937 --0.0794062 0.147442 0.0402641 -0.0285362 0.120755 0.0202147 --0.0354498 0.0346389 0.0415402 -0.0189212 0.0875932 -0.0268145 --0.0326685 0.0478014 -0.0229356 -0.0213046 0.0374522 0.0382518 -0.0119628 0.111848 -0.018535 --0.0754368 0.114522 0.050709 --0.0575342 0.0415089 -0.00843308 --0.0289002 0.0348381 0.0445217 --0.0558188 0.0336396 0.0205147 --0.0294901 0.0946648 0.0450535 -0.0140142 0.0519753 0.0481823 --0.0499383 0.162625 -0.0047964 --0.0285131 0.111188 0.0369648 --0.0777024 0.176292 -0.0501047 --0.0458377 0.0970756 -0.021885 --0.0647866 0.167644 -0.0344082 --0.08472 0.111015 0.033569 --0.0624074 0.1491 -0.0095736 -0.0455563 0.078849 0.0217954 -0.0386173 0.0673644 -0.0117551 --0.0516941 0.147804 0.0164166 --0.0638593 0.0953482 -0.0183667 --0.0887889 0.117194 0.003272 --0.0667452 0.0342007 0.0124321 --0.0921816 0.132336 0.0152245 --0.0790475 0.168047 -0.0349702 --0.0445079 0.0424992 0.043443 --0.0914924 0.12135 0.00727423 -0.00205109 0.0347195 0.0440743 --0.0757523 0.0687815 0.0210323 -0.0254197 0.0394349 0.0320923 -0.0445209 0.095967 0.011159 -0.00418461 0.0908826 -0.0329329 --0.0447434 0.0753343 -0.0181391 -0.0465277 0.0497043 0.0301725 --0.0231678 0.124994 -0.000333927 --0.0261386 0.0359205 -0.0192491 -0.000314733 0.0597904 -0.0332055 --0.0664067 0.0336797 0.00582425 --0.0179785 0.068344 0.053543 -0.0128834 0.035495 0.00385056 --0.064012 0.0432207 0.0306772 -0.0356112 0.0942094 0.0375896 -0.0433586 0.0589158 -0.00469925 --0.0741431 0.153026 0.0335308 --0.0366764 0.0421455 0.0447176 --0.0616357 0.158429 -0.0245888 --0.0777899 0.164478 -0.0251991 --0.0774203 0.177255 -0.0472003 --0.0723466 0.0663158 0.0221054 --0.00945876 0.0366145 -0.0165831 --0.00782909 0.0896438 -0.0364286 --0.0483458 0.0338972 -0.0143683 --0.0548931 0.111218 -0.0174922 -0.0263272 0.0545944 -0.0208638 --0.078467 0.147461 0.0407301 -0.0472196 0.0430325 0.00527833 -0.0313294 0.118714 0.0127065 --0.00880796 0.0868775 -0.037347 --0.054028 0.0344996 0.0411656 --0.00639115 0.121199 -0.012466 -0.0300864 0.0564003 0.0398351 --0.0790124 0.0782686 0.0315155 --0.0134683 0.0964232 0.0523159 --0.0763221 0.159003 -0.0110053 --0.0600876 0.0367271 0.0456071 -0.0364957 0.049851 0.0316154 -0.00849848 0.0402756 0.0453316 -0.0205837 0.0754832 0.0508919 --0.071014 0.148895 -0.037822 -0.0170761 0.115474 -0.0144429 --0.063767 0.0615586 0.0227478 -0.0437965 0.0987467 0.00816432 --0.0513326 0.0542594 0.0137993 --0.0414552 0.0341096 -0.00949275 -0.0395669 0.101281 -0.00480928 --0.0918243 0.128307 0.0322434 --0.0474749 0.0945717 0.0440635 --0.0704486 0.16924 -0.0264473 -0.027192 0.101376 -0.017349 --0.0895884 0.114751 0.0258504 --0.0713206 0.156784 -0.042915 -0.0384501 0.0914717 0.0346309 -0.0214747 0.0996539 -0.0214946 --0.0106582 0.0527176 -0.0332954 -0.00773558 0.128847 0.0268569 -0.0202904 0.0912514 -0.02462 -0.00332905 0.0553943 -0.0309954 --0.0921247 0.116117 0.0353113 --0.0146765 0.0526113 -0.0325234 --0.0657759 0.0410192 0.0130518 -0.0587274 0.0538199 0.013179 -0.0291394 0.102042 -0.0160578 --0.0701142 0.0625797 0.0062174 -0.0457389 0.0876049 0.0111625 -0.00224905 0.118538 -0.0156887 -0.0520156 0.0596733 -0.00368903 --0.0891532 0.136419 0.0102028 --0.0400348 0.0344619 0.0337052 --0.0461887 0.0335082 0.00469546 --0.0923435 0.115998 0.0113188 --0.00713141 0.127357 0.0287426 -0.0252624 0.0747714 -0.0251152 --0.0453044 0.0587827 0.038737 -0.03635 0.0368836 0.00917982 --0.0527446 0.0753599 -0.0182797 --0.0728584 0.132623 0.0509226 --0.00672844 0.0698676 -0.0361675 -0.0413912 0.0459759 -0.00421898 --0.0201655 0.0348026 0.0446658 --0.0641545 0.0391804 0.0263583 --0.00246627 0.111608 -0.0202454 --0.0134033 0.110892 -0.0194483 -0.043074 0.0401669 0.0073914 -0.0192967 0.0693907 -0.0288221 --0.0619039 0.16157 -0.0305885 -0.00333358 0.0341967 0.0104872 -0.0421258 0.100042 0.000179811 --0.0386776 0.11516 -0.0158482 --0.00807178 0.0386982 0.0276584 --0.0756134 0.163772 -0.0350068 --0.0672387 0.155112 0.00519073 -0.0276118 0.053509 0.0397341 --0.0779406 0.158305 -0.0189233 --0.00470743 0.0627772 -0.0352137 -0.0325643 0.0981766 0.0384761 -0.0296733 0.0481683 -0.00874324 -0.0113105 0.059545 -0.0296135 --0.0653574 0.0733073 0.0386226 --0.0120884 0.101067 0.0439606 --0.0268179 0.0735627 0.0438663 --0.0513902 0.0530791 0.0216216 --0.0678614 0.042287 0.00944731 --0.0899071 0.133806 0.0352156 --0.0122404 0.0385117 0.0269697 --0.0719375 0.16298 -0.0125698 -0.0473212 0.0533258 -0.00537345 --0.030503 0.0588732 0.0373493 --0.0905557 0.120241 0.0451196 -0.0219406 0.0388423 0.0393076 --0.0672891 0.178209 -0.0595336 -0.0302182 0.0535528 0.0382346 --0.0815406 0.110006 0.0333062 --0.0477684 0.0811966 -0.0205178 --0.048671 0.138621 0.0113976 --0.0562999 0.0506286 -0.00237306 --0.0854189 0.0791501 0.00750351 -0.000105856 0.117482 -0.0165473 --0.0624071 0.149633 -0.00268499 --0.0682914 0.172271 -0.0560251 --0.0642448 0.0333797 -0.00245942 -0.0203456 0.053671 -0.0267089 --0.0711203 0.163576 -0.0137477 --0.0126641 0.0511309 -0.0317686 --0.066211 0.180426 -0.0565833 -0.0266688 0.0892152 -0.0224539 -0.01736 0.128384 0.0132094 --0.0541813 0.154195 0.0142529 --0.0799749 0.0710714 0.0163832 --0.0379044 0.0336424 -0.0213286 --0.0747588 0.0669346 0.0175421 --0.0221189 0.12668 0.005878 --0.0623544 0.152149 -0.0255836 -0.0137867 0.0377633 0.0443361 -0.0469104 0.0589185 -0.00506663 --0.0188119 0.0964492 -0.0282644 --0.000384494 0.130522 0.00237337 --0.0647338 0.0418755 0.0296857 --0.0418518 0.0999485 -0.0214177 --0.0135206 0.0432479 0.0507363 -0.0314548 0.113206 0.0298812 -0.0211096 0.0343656 0.00467028 -0.0493524 0.0516707 -0.00371978 -0.0324504 0.0916248 0.0417895 --0.0405477 0.118695 -0.0135582 --0.0421609 0.128746 0.00435225 -0.00852878 0.034888 0.0362651 --0.0599768 0.12527 -0.00809043 --0.0624255 0.16468 -0.0465913 -0.0305387 0.114047 0.0302625 --0.0209297 0.158088 -0.00822134 --0.00449554 0.0633716 0.0561592 -0.00751849 0.0440876 0.0454461 --0.0617319 0.160008 -0.0275856 --0.00111302 0.130629 0.0207594 --0.000792652 0.0894877 -0.0349748 --0.0534886 0.0862338 0.0454573 -0.0102426 0.0752832 -0.032327 --0.0866178 0.151117 0.0269024 -0.00586712 0.0991316 -0.0229749 --0.018487 0.0772258 0.0557066 --0.0220963 0.0623062 0.0451655 --0.0263156 0.124827 0.00142734 -0.00449781 0.0519669 0.0532713 --0.0318681 0.105727 -0.021166 --0.034171 0.0822565 -0.0245355 --0.0160192 0.104518 -0.0227486 --0.0336086 0.0394857 -0.0301589 -0.0179261 0.0900567 0.048881 -0.028994 0.0915879 0.0438177 -0.0419459 0.0625408 -0.0027477 --0.0623435 0.161536 -0.0425937 -0.0521127 0.0595383 0.0295528 -0.00603967 0.0344425 -0.0152712 --0.0200036 0.0384998 -0.0166705 -0.0335055 0.0549395 0.0359782 -0.0413899 0.0475369 -0.00516876 -0.0571049 0.0594437 0.0244408 --0.0642323 0.124186 0.0475964 --0.0104933 0.0952299 0.0545267 -0.0183283 0.0593891 -0.0275077 -0.0556724 0.0698728 0.00398853 -0.02895 0.086199 0.0437135 --0.00575467 0.1008 0.0460186 --0.0117555 0.0969094 -0.0306933 --0.0570352 0.129621 -0.00626418 --0.06396 0.034704 0.0249317 --0.0269668 0.0674701 -0.0325423 -0.00372222 0.0941665 -0.0317421 --0.0708312 0.0951391 -0.0158707 -0.0351494 0.0633173 0.038442 -0.0303372 0.119206 0.0194646 --0.0174811 0.118153 0.0357243 --0.0928105 0.116053 0.0203106 --0.012498 0.078722 0.0572931 -0.0102589 0.100444 -0.0223447 -0.0311369 0.0982118 0.0399163 --0.0870966 0.0995146 0.0044219 -0.0372771 0.100696 0.0312566 --0.0464652 0.16842 -0.00496016 --0.0340766 0.172586 -0.0145127 --0.0632966 0.144361 -0.00960502 --0.00396533 0.128634 -0.00247998 --0.0810179 0.0964125 -0.00756981 --0.0296304 0.159454 -0.0131553 -0.0323433 0.0592178 0.0396143 -0.0171685 0.0490344 0.0439112 --0.0798847 0.0706373 0.0145533 -0.00550249 0.0758881 0.0564988 --0.0285046 0.0588067 0.036767 --0.054422 0.152991 0.0228754 --0.0663081 0.150341 0.0377708 --0.0409099 0.173193 -0.0056112 --0.00259587 0.0391262 -0.0253465 -0.0394316 0.0807401 0.0342345 -0.048793 0.049707 0.0281736 --0.0225905 0.0365035 -0.0286129 --0.0185117 0.0387718 -0.0147573 --0.0889514 0.121274 0.00229944 -0.0255827 0.034587 0.0128177 --0.0258582 0.100162 -0.023852 --0.0317095 0.0382098 0.0512104 --0.0608875 0.104029 -0.0182853 --0.0577034 0.0591273 0.0216745 --0.0316861 0.0553325 -0.0133983 --0.0579004 0.0336435 0.0147513 --0.050636 0.0604891 -0.0105672 --0.0484979 0.101507 0.0419588 --0.0735846 0.159652 -0.032921 --0.0596849 0.136693 0.0347693 --0.0527883 0.0490273 0.0246529 --0.00587038 0.038496 0.0083708 -0.0443161 0.095966 0.0141619 --0.0355281 0.0832646 0.0432735 --0.0552893 0.160933 0.00328411 --0.0694051 0.177621 -0.0490523 -0.0553162 0.0608807 0.0271604 --0.0115038 0.082913 0.0576973 -0.00149573 0.118307 0.0388892 --0.0643923 0.178295 -0.0607754 --0.0696234 0.0702067 -0.00731499 --0.0684446 0.156174 0.0134711 --0.0631402 0.158352 -0.0425984 --0.028277 0.0807444 0.0465032 --0.0851037 0.143224 0.00618561 --0.0701909 0.171451 -0.0335218 --0.0542038 0.149302 0.0263885 --0.0230864 0.0416339 0.0540702 --0.0848397 0.124371 0.0492354 --0.0509437 0.0349503 0.0448676 -0.0147035 0.0490065 0.0456198 --0.059742 0.156334 0.00641085 --0.07522 0.0688188 0.0015368 --0.0196569 0.0390707 0.0375255 -0.0459174 0.0834201 0.0141703 --0.0785236 0.0894249 -0.0105705 --0.0200463 0.0893341 0.0549931 --0.0173075 0.11558 -0.0164072 -0.000516136 0.0760027 0.0580883 -0.042165 0.0859172 -0.00778247 -0.0203197 0.0664896 -0.0280597 --0.0604906 0.0959808 0.043977 --0.00180047 0.0840422 -0.0369301 -0.0106204 0.119324 -0.014581 -0.000242427 0.128645 -0.00250259 --0.0544918 0.0876045 0.0451014 --0.081252 0.0993542 0.0322994 -0.0225815 0.0632207 0.0466294 --0.0528036 0.129718 0.0341858 -0.0388075 0.10554 0.0251669 --0.071237 0.156366 0.0212013 --0.0419921 0.0349859 0.0415962 -0.0319555 0.0413937 0.028007 --0.0465003 0.112564 0.0357108 -0.00310161 0.111606 -0.0202814 -0.0306552 0.102095 0.0374778 -0.0158981 0.0576764 0.0492073 --0.036508 0.127508 0.00348399 -0.0403284 0.0574912 -0.00511853 --0.06805 0.157495 -0.00534926 --0.0870566 0.0847034 0.0124776 --0.0785035 0.127443 0.053282 -0.0093755 0.0479282 -0.0271091 --0.00151782 0.111398 -0.0200294 --0.0386619 0.0336282 0.00792475 --0.0321818 0.0666221 -0.0204419 --0.0516478 0.0334795 -0.00363494 --0.0505323 0.0346392 0.0434961 --0.0871097 0.129792 0.0470428 --0.00115829 0.0378141 0.0044798 -0.00250327 0.0351261 0.00210209 -0.0232927 0.0720269 -0.0262872 -0.0386441 0.0772022 -0.0107761 -0.00730214 0.0624461 -0.0313742 --0.0601285 0.0334799 -0.007174 --0.0311809 0.165241 -0.0158459 --0.0456556 0.126096 -0.00729728 -0.01482 0.0920349 -0.0274402 --0.0578658 0.154169 0.0274197 --0.0766831 0.148629 -0.00786722 --0.0548976 0.0574275 -0.00541424 --0.0213746 0.0936314 -0.0333712 --0.0795038 0.127439 0.0531413 --0.0719602 0.0381531 0.00797803 -0.0465231 0.0539629 0.0319545 --0.0327551 0.126411 0.00489661 --0.0907403 0.135093 0.0162106 --0.0798437 0.119249 -0.00499812 --0.0195891 0.186548 -0.0163318 --0.0336818 0.0474202 0.0430149 -0.0387003 0.0847793 0.034951 -0.005123 0.108732 -0.0201833 --0.0355723 0.127236 0.00383072 --0.0593755 0.0706339 0.0387044 --0.0701237 0.0337481 0.00141754 --0.0596389 0.0645563 -0.0073211 --0.0247044 0.0349045 0.050534 --0.0698349 0.155896 0.010068 --0.00664542 0.0496313 -0.030799 --0.0560508 0.049202 -0.00336342 --0.0846449 0.0777798 0.00851725 -0.0428444 0.0958802 0.0241636 -0.0226208 0.0505695 0.0412719 --0.0421939 0.165153 -0.0106292 --0.0530779 0.153128 -0.00337034 --0.0183995 0.128105 0.0144964 -0.0110096 0.125946 -0.00574203 -0.0135498 0.109816 -0.0183273 -0.0246987 0.1167 0.0323736 --0.0323986 0.169744 -0.00487272 -0.0414995 0.0513848 0.032599 --0.0820948 0.0748388 0.0105311 --0.0771842 0.102138 0.0352151 --0.0627985 0.161541 -0.0235962 -0.0203907 0.0490438 0.0415331 --0.0284862 0.120462 -0.00941436 -0.00850898 0.0990197 0.0481875 -0.0181919 0.0781799 0.0527467 --0.0323958 0.0383608 -0.00233468 --0.0198811 0.121697 -0.00881459 --0.0289402 0.154865 -0.00285823 --0.055522 0.0600566 -0.00554029 --0.0446949 0.0680713 -0.0159309 --0.0505296 0.0657745 0.0361047 -0.0251595 0.0995713 -0.0194056 -0.0456643 0.0876028 0.0121678 --0.0533672 0.143136 0.0253913 --0.05283 0.138085 0.0270749 --0.0324865 0.0974182 0.0443398 -0.00543862 0.118556 -0.0157347 --0.0704807 0.1602 -0.00768602 -0.00476485 0.0378127 -0.0129945 -0.0453303 0.0875809 0.0171699 -0.00844159 0.109753 0.0403226 -0.0199305 0.0645206 0.0480779 --0.0865012 0.0967606 0.00143514 -0.0239407 0.0433254 -0.00969837 --0.0464991 0.0818806 0.0436011 --0.0365053 0.0832925 0.043701 --0.0511539 0.144707 0.0143676 --0.0354688 0.0973337 0.0432864 -0.0315086 0.0361416 0.0180806 --0.0620392 0.152203 -0.0175795 --0.00174908 0.0726707 -0.0356483 -0.0482658 0.0482112 0.0273759 -0.0205204 0.0686316 0.0489712 -0.0055446 0.129937 0.0246284 --0.0509363 0.126898 0.0333376 -0.0503401 0.0525815 0.0286903 --0.0663805 0.0356243 0.0152158 --0.0631059 0.039729 0.0160762 --0.0794629 0.0702542 0.0118898 --0.0440204 0.0437247 -0.0153148 --0.0258047 0.0811626 -0.0373791 --0.0654527 0.156561 -0.05302 --0.0801896 0.0926573 0.034266 --0.0226625 0.0493576 -0.0281762 --0.076512 0.15561 -0.00689633 --0.0316228 0.0384779 -0.00967109 -0.0073096 0.0609801 -0.0307365 --0.036779 0.0827886 -0.0223365 --0.0454595 0.0846983 0.0440929 --0.0310517 0.0636961 -0.0214339 -0.044971 0.0748214 0.0226935 --0.0245671 0.182966 -0.016053 --0.0343794 0.125292 -0.00246071 -0.0260218 0.0493062 -0.0196675 -0.00451349 0.0786214 0.0559314 --0.0272596 0.0409813 0.0537728 --0.0865558 0.105007 0.0203641 --0.0427952 0.0347556 0.00787321 --0.0294944 0.0889496 0.044252 --0.0691615 0.0832998 0.0419252 --0.077704 0.175863 -0.0450747 --0.0595653 0.0407951 0.0449735 --0.0118194 0.129824 0.0125318 --0.0304269 0.169744 -0.0072967 -0.00750596 0.0674413 0.055134 --0.0895098 0.0942825 0.014433 -0.0566953 0.0550372 0.00319006 -0.0358581 0.0995241 -0.0113664 --0.0541815 0.15229 0.0244282 --0.0924737 0.125588 0.0362608 --0.0750911 0.110634 0.0449752 --0.0272685 0.0368017 0.0538626 --0.0614955 0.104283 0.0410789 --0.0721148 0.067315 0.0248191 -0.034236 0.094243 0.0391072 --0.0724407 0.178857 -0.0487083 --0.06691 0.033448 -0.00125687 --0.0660379 0.0349778 0.0329828 --0.0701097 0.156012 0.00122102 --0.0157478 0.0352634 0.050467 --0.0465076 0.160794 0.0071118 --0.0156218 0.0365183 -0.0177136 --0.00687536 0.0389886 0.0330493 -0.0201949 0.0959886 -0.0227072 -0.00536718 0.125777 0.0317922 --0.0689036 0.105186 -0.0135662 --0.0576505 0.0508003 0.0036576 --0.0372877 0.0353832 0.0246264 --0.0766222 0.0824671 -0.0115781 --0.0570813 0.0344654 0.0405363 -0.0284042 0.0431456 -0.00552671 --0.078005 0.151454 -0.00188508 -0.00274784 0.0953419 -0.0309592 --0.0764328 0.147234 -0.00786196 --0.0187399 0.0656914 -0.0372373 --0.0626784 0.0670893 0.0340154 --0.066213 0.0377522 0.0375383 -0.00946024 0.0346841 0.0420404 --0.00763703 0.046711 -0.0299661 -0.0217664 0.106013 0.0404033 -0.0159395 0.0900955 0.0512828 --0.0714939 0.126019 0.0527835 --0.035368 0.122868 0.0260927 -0.0397669 0.0885289 -0.0117744 --0.0235296 0.159196 -0.00227474 --0.0299919 0.0383903 -0.00556396 -0.00840449 0.0360838 -0.0229864 --0.0688351 0.0951745 -0.0162656 -0.0188202 0.124811 0.0265908 --0.0542034 0.0477679 0.0266683 --0.00718512 0.0384992 0.0226001 -0.0191993 0.0352366 0.0345338 --0.0486962 0.13553 0.00541025 -0.0065027 0.0533154 0.0528127 --0.064997 0.0410349 0.013689 -0.0235192 0.107033 0.0392433 --0.0526101 0.0632972 -0.0100113 -0.0288769 0.120252 0.0217702 --0.00882418 0.0896578 -0.0365764 --0.0563459 0.0335397 0.00260276 -0.0287652 0.114389 -0.00726895 -0.0564669 0.0577845 0.00118215 --0.0623836 0.163016 -0.0556039 --0.0235351 0.118111 0.0331575 -0.0443232 0.0889197 0.0231574 -0.0349753 0.114037 0.00545779 -0.0269837 0.108749 0.0374141 --0.000496913 0.056284 0.0547664 --0.0889882 0.115854 0.0042936 --0.0688144 0.0851338 -0.0175228 --0.0304795 0.0746468 0.0405648 --0.0616784 0.0692367 -0.0132074 --0.0554108 0.0334149 -0.00799207 --0.0610813 0.0342293 0.0311986 --0.0655517 0.155937 0.0246661 --0.0767597 0.163153 -0.0191399 --0.0140741 0.0388251 0.0317136 --0.02858 0.0731702 0.040795 --0.0480086 0.134685 0.0198054 --0.00949027 0.107257 0.0434611 --0.0224071 0.0510134 0.0440995 -0.0026516 0.0341771 0.00670019 --0.00282121 0.086807 -0.0363939 -0.00461042 0.092806 -0.0323339 -0.0444404 0.0425371 0.0222477 --0.0251232 0.0838362 0.0531591 --0.0711154 0.155676 0.00670049 --0.0144639 0.0977101 -0.0275565 --0.0176152 0.0407641 -0.0279656 --0.0273216 0.038344 -0.00129213 --0.0781679 0.14865 -0.00288263 --0.071113 0.171733 -0.033865 --0.0362701 0.0365605 0.0458807 --0.0245074 0.0384654 -0.0082311 --0.0768529 0.106269 -0.00826114 -0.0173624 0.088714 0.0498122 --0.0872512 0.106353 0.0133638 --0.0647985 0.124215 0.0485 -0.0274255 0.0686124 0.0431235 --0.0275944 0.0717748 -0.0345689 --0.00449702 0.0590031 0.0543234 --0.00869265 0.0598566 -0.0344628 --0.0624896 0.106999 0.0393995 -0.00296819 0.0986498 -0.0244883 --0.0716108 0.0701594 -0.00639514 --0.0454969 0.0733342 0.042072 -0.0217583 0.0505253 0.0417779 -0.0599479 0.0692188 0.0141571 -0.0159709 0.0859869 -0.0291978 -0.0474137 0.0671743 0.000684928 -0.045537 0.0890033 0.0131643 -0.025235 0.0690602 -0.0242719 --0.0140104 0.117853 -0.0148385 --0.0417786 0.156522 0.00614116 -0.0529468 0.0608894 0.0290245 --0.0623778 0.167137 -0.0608155 --0.043781 0.0422821 -0.0183128 -0.0194047 0.0727279 0.0509389 --0.025431 0.180214 -0.00870569 -0.00163035 0.0962275 -0.0299038 --0.0609057 0.119508 -0.00974426 --0.0265539 0.180361 -0.00771033 --0.00586693 0.104511 -0.0229142 --0.0446124 0.0534121 -0.0108089 --0.0607974 0.125499 0.0419374 --0.0676844 0.160922 -0.0559942 --0.0718937 0.0376106 0.00231258 --0.0769618 0.103489 0.0349575 --0.0136243 0.0450811 -0.0280269 --0.0656393 0.145367 0.0403005 --0.067848 0.0994807 -0.015636 --0.0674005 0.156127 0.0138467 --0.0814089 0.141772 -0.000809353 -0.0343092 0.113032 0.0252402 --0.0378129 0.0900392 -0.0237743 -0.0410972 0.0779427 0.031296 --0.0594968 0.104294 0.0413247 --0.045045 0.0657131 0.0396946 -0.0424943 0.0569701 0.0318321 -0.0380924 0.0618152 0.0338774 --0.0181385 0.038277 0.0223668 --0.0680503 0.114246 0.0489904 --0.089636 0.0902445 0.0164491 --0.0259323 0.124597 0.000115117 --0.0341212 0.124555 0.022076 --0.0117695 0.075665 -0.0382916 --0.0666005 0.156329 0.0184798 -0.0143467 0.0580862 -0.0289605 -0.00620145 0.0832401 0.0564613 --0.07299 0.158232 -0.0339184 -0.0179038 0.0866718 -0.0278625 --0.0447879 0.085543 -0.0216723 -0.0240528 0.0347605 0.00303304 -0.0471472 0.0437632 0.0216364 --0.0254743 0.105723 0.0415881 --0.0914335 0.120003 0.00730918 --0.0381624 0.035793 0.0434599 --0.0470742 0.127422 -0.00463291 -0.000501079 0.0620074 0.0565701 --0.0488714 0.104198 -0.020417 --0.00949444 0.063336 0.0558203 --0.0227837 0.0742285 -0.0385317 --0.00949145 0.115547 0.0400498 --0.0665386 0.0804536 0.042224 -0.00148883 0.121012 0.0365952 --0.024281 0.069418 0.0457102 -0.019893 0.114777 -0.0136897 --0.0904011 0.115144 0.0307537 --0.00370938 0.0627709 -0.0350699 --0.00367406 0.0555102 -0.0326331 --0.0125077 0.0773203 0.0572074 --0.0574951 0.093265 0.0451928 --0.0942113 0.120123 0.0212925 --0.0213358 0.165379 -0.00997448 --0.0615068 0.0789665 0.042503 -0.00239149 0.0343213 0.0156312 --0.0639126 0.11101 -0.0139478 -0.0381439 0.103967 -0.00387277 --0.0816033 0.101897 -0.00556882 --0.0582639 0.12123 0.0402958 --0.0729322 0.156105 0.0220745 --0.0514974 0.086244 0.0456131 --0.0876158 0.137864 0.0416648 -0.0120082 0.0967361 -0.024421 -0.0147782 0.0929392 -0.0263979 --0.0510555 0.150177 -0.00351578 --0.0165661 0.163924 -0.0100865 --0.00519498 0.0390091 -0.00671136 --0.021716 0.0641363 -0.0354017 --0.0523357 0.136679 0.027812 -0.0335961 0.0633113 0.0397473 --0.0384865 0.0492045 0.0394845 --0.0339969 0.152567 -0.000573454 -0.0175453 0.0645325 0.0499023 --0.0895247 0.139293 0.0351741 --0.0870044 0.115772 0.00228167 --0.0852267 0.0792333 0.0184927 --0.0927665 0.116031 0.013321 --0.0240588 0.111793 -0.0183639 -0.0191819 0.123133 0.0296014 -0.0163312 0.0767998 0.0535416 --0.0834123 0.0856961 -0.00454328 --0.0614974 0.0904473 0.0454009 --0.0648003 0.0370671 0.0164284 --0.0102366 0.125327 0.0306172 --0.0512935 0.0556822 0.0305914 --0.0674962 0.0930678 0.0426016 --0.0707247 0.156767 -0.045914 --0.0611468 0.0584317 0.0117762 -0.0152753 0.0680849 -0.0302874 --0.0638387 0.163409 -0.0592654 -0.030267 0.0496887 -0.0107252 --0.0227695 0.0684387 -0.0367377 -0.0216497 0.065881 0.0470485 --0.0849335 0.125015 -0.00321773 --0.0364959 0.0562316 0.0392716 --0.0132153 0.0406258 0.0508237 -0.00695506 0.0982177 -0.0239936 -0.00047843 0.12713 -0.00487855 -0.0354045 0.046148 -0.00604177 --0.0913848 0.129679 0.0322355 --0.0924762 0.124198 0.0322659 --0.0057025 0.12744 -0.00517306 -0.032332 0.110047 0.0311032 --0.0374975 0.0662835 0.0416878 --0.0306651 0.155159 -0.000638202 -0.0161 0.12839 0.0198796 --0.0392376 0.124806 0.0231803 -0.00131504 0.0597888 -0.0330641 --0.0445007 0.0931064 0.043109 --0.0174373 0.0336888 -0.022956 --0.0536509 0.0343311 0.0291848 -0.0348249 0.110986 -0.0028353 -0.0280633 0.100998 -0.0169482 -0.0423903 0.0490515 -0.00589339 -0.0306614 0.119205 0.0153072 --0.0604957 0.0876028 0.045161 --0.0137303 0.0699989 -0.0380502 --0.00750341 0.130405 0.00835201 --0.0494799 0.116621 0.0323892 --0.058737 0.075302 -0.0183386 --0.0518764 0.0550741 0.0228473 --0.0293899 0.118762 -0.0116358 --0.0743199 0.158257 -0.0279194 --0.0265758 0.0533991 -0.0263925 --0.047508 0.0903548 0.0442194 --0.0104972 0.0815462 0.0580111 --0.0356136 0.0408304 -0.0293778 --0.0622824 0.159968 -0.0396048 --0.0727292 0.0730957 -0.00887693 -0.0252321 0.0889244 0.0471615 -0.0362811 0.0443655 0.0298564 --0.0583717 0.138143 0.0331568 -0.0516174 0.0711387 0.00464104 -0.00649466 0.0427198 0.0454361 --0.0187116 0.0598792 -0.0350421 --0.0603468 0.0339987 0.0210215 -0.0310626 0.107429 0.0345663 --0.0153967 0.0384283 -0.000805549 -0.0390675 0.0617702 -0.00778266 --0.0718188 0.0907915 -0.0158595 --0.0066784 0.0569449 -0.0331859 -0.00738229 0.0448872 -0.0251556 -0.0193881 0.0506007 -0.0247336 --0.0171345 0.165288 -0.0183426 -0.0172728 0.0694422 -0.0295359 -0.0518225 0.072596 0.0200635 --0.085483 0.140457 0.00319222 --0.049383 0.140141 0.0133936 --0.076884 0.155644 0.0221655 --0.0584972 0.111135 0.0367864 --0.0264895 0.102963 0.0427118 --0.016526 0.0387631 -0.00875803 --0.060493 0.107007 0.0395303 --0.0133132 0.0385196 -0.000466347 -0.027107 0.0406036 0.0313674 --0.0852773 0.137655 0.00128094 --0.0776954 0.16804 -0.0399638 --0.0465214 0.0505047 0.038174 --0.0251912 0.178602 -0.0188241 --0.0524991 0.101502 0.0417298 --0.0142894 0.184628 -0.0268303 -0.00710791 0.110158 -0.019992 --0.0766628 0.155608 -0.00789132 --0.0814761 0.0734707 0.0145404 --0.0644951 0.0789605 0.0422031 -0.0403539 0.105584 0.00317596 --0.0633486 0.0371336 0.0178291 --0.0808831 0.117721 -0.00384392 --0.0265027 0.10847 0.0397156 -0.0236097 0.121674 0.028372 --0.0623736 0.164689 -0.0415928 --0.0495545 0.0404082 -0.0113965 --0.0562131 0.054804 -0.00139993 --0.0418518 0.098529 -0.0215916 -0.0133351 0.058103 -0.0291864 --0.0594448 0.063179 0.0293052 -0.0113019 0.0652847 -0.0308368 --0.0783582 0.0994351 0.0350546 --0.0715439 0.0376425 0.00026118 --0.0154996 0.112736 0.0400881 -0.0417289 0.0704356 -0.00679567 --0.0406463 0.127804 0.0152535 --0.0627661 0.170921 -0.0616075 --0.0923057 0.12017 0.0426167 --0.00727442 0.0422617 0.0488857 -0.0350851 0.0848737 -0.0178837 --0.01578 0.128598 0.00819831 --0.03217 0.0735917 -0.0275208 --0.0673634 0.110954 0.0392365 --0.0271001 0.0779439 0.0468281 --0.0765081 0.156243 -0.00790412 -0.0277565 0.117474 -0.00457839 --0.0113381 0.0986434 -0.0265191 --0.0330823 0.0695155 -0.0204574 --0.0652177 0.144322 -0.0140816 --0.0094303 0.0379372 -0.0159242 --0.0245144 0.0945317 -0.028309 --0.05375 0.0560385 0.0116204 --0.0679678 0.0383221 0.0123903 -0.00399334 0.0399971 0.0458959 --0.0841715 0.0870272 0.0285556 --0.0274573 0.0734015 0.0426855 --0.0626773 0.153684 -0.0325991 --0.0741408 0.105214 0.0369385 --0.0134986 0.081495 0.0573009 -0.0463327 0.0421886 0.017365 --0.0644937 0.108375 0.0384047 --0.0653695 0.151233 0.0366147 --0.018937 0.178659 -0.0169738 --0.0820692 0.0748107 0.00351555 --0.0841353 0.146019 0.0379782 --0.0148578 0.163977 -0.0174595 --0.0817263 0.0747702 0.00249857 -0.000235601 0.0740952 -0.0356038 -0.000940682 0.0357179 -0.0155776 --0.0719363 0.129668 -0.0086833 -0.0301411 0.102934 -0.0150039 --0.0651961 0.0334974 -0.00275965 --0.0185844 0.16399 -0.00948536 --0.0592125 0.042121 0.0445708 -7.57538e-05 0.0369473 0.00366537 -0.0152945 0.0666369 -0.0299356 -0.0410157 0.0739041 0.031202 --0.0577153 0.0344512 0.0421091 --0.0920793 0.129683 0.0282033 --0.0497426 0.0753235 -0.0177986 --0.0484934 0.047761 0.0395051 --0.0809803 0.104706 0.0304576 --0.0746935 0.111142 -0.00760178 -0.0204806 0.109788 0.0388648 --0.0734977 0.128836 0.0522844 --0.0426178 0.0520018 -0.0109441 -0.0112198 0.0932651 -0.0287439 --0.0119274 0.182669 -0.0262872 -0.0145534 0.0347576 0.0376203 --0.0810222 0.100509 -0.00657927 --0.0033633 0.038102 0.0128662 --0.0937861 0.128264 0.0182441 -0.0084061 0.0949783 -0.0285638 --0.0695902 0.113495 0.0492959 -0.000169576 0.131258 0.0183392 --0.0931626 0.117374 0.0143043 --0.0195343 0.112367 -0.0190097 --0.0524215 0.162453 0.00456363 -0.0184901 0.0879016 0.0492476 --0.0685433 0.170852 -0.0550244 --0.087182 0.130813 0.00128919 -0.00130454 0.0641388 -0.0343264 --0.000757317 0.075519 -0.0359212 -0.0308776 0.0902792 0.0430757 --0.00578939 0.0386518 0.00278679 --0.076212 0.155059 0.00635026 --0.0248315 0.0881388 -0.0362597 --0.0222598 0.160103 -0.0129456 --0.00877699 0.0770434 -0.0377883 --0.06674 0.0383979 0.0141071 --0.00350265 0.0689326 0.0566398 --0.0295614 0.0861399 -0.0326125 --0.0286647 0.125711 0.0122564 --0.0699648 0.0791315 0.0398469 -0.0142764 0.128727 0.0220636 --0.0638003 0.110914 0.037425 --0.0719625 0.135504 -0.00769556 --0.0527869 0.124083 0.0359567 --0.0467161 0.0738381 -0.0169211 --0.0117423 0.070003 -0.0378791 --0.0517809 0.138537 0.023394 --0.00482205 0.130969 0.0150835 -0.034711 0.0383001 0.0222555 --0.00127486 0.120883 -0.0121504 -0.0112227 0.0850587 -0.0310098 --0.0506063 0.0369029 -0.0119734 -0.0433147 0.0831895 0.0275132 -0.0112941 0.127457 0.0281604 -0.0151622 0.122267 0.032438 -0.0400834 0.082061 0.0334038 --0.0745622 0.152707 -0.0248951 --0.0528479 0.141625 0.0244146 -0.0245482 0.035172 0.0211866 --0.0325075 0.11115 0.0364446 -0.0417109 0.0957641 -0.00380547 --0.00538241 0.130597 0.0192035 --0.0649174 0.0364897 0.025021 --0.0770334 0.158982 -0.013085 --0.0760388 0.148613 -0.0118618 -0.0283559 0.116347 0.030146 --0.088594 0.121257 0.00130017 --0.0268076 0.122539 -0.00562189 --0.0346629 0.0607102 -0.0125376 -0.0413795 0.0505691 -0.00672382 --0.0906746 0.1365 0.0201946 -0.00951942 0.100425 0.0477045 --0.0642867 0.172466 -0.0611328 --0.0242433 0.172722 -0.0123976 -0.00950564 0.0990636 0.0482467 -0.0101664 0.120462 0.0359466 --0.0187755 0.107692 -0.0220397 -0.0335012 0.0795469 0.0414506 --0.0834882 0.14321 0.00316117 --0.0530161 0.141613 0.0254095 --0.0395373 0.172163 -0.000837254 -0.0387477 0.0589461 -0.0057234 --0.0647673 0.0795072 -0.0181104 --0.00140393 0.0361018 0.00962515 --0.00524162 0.0395598 0.0483202 -0.0236373 0.103743 -0.0178545 --0.000477761 0.0760312 0.0584165 --0.0210492 0.0348694 0.0496408 --0.00244654 0.131114 0.00878185 --0.033711 0.0384262 -0.00450177 --0.0745333 0.152696 -0.0258905 -0.055409 0.0509629 0.0218922 --0.0134774 0.127753 0.000758007 --0.0120362 0.0388366 0.0321214 --0.0278604 0.0487672 0.0470543 -0.0327952 0.0713854 0.0403707 --0.0728362 0.0979301 -0.0143404 --0.0367225 0.125751 0.02112 -0.0198232 0.0385183 -0.0126921 --0.0377749 0.150712 0.00133662 --0.0665966 0.180807 -0.0581921 --0.0215095 0.114043 0.0376946 --0.0620515 0.035927 0.0204607 --0.0584945 0.150006 -0.0011129 --0.0335992 0.1188 -0.0116562 -0.0196457 0.116633 0.0356159 -0.0248522 0.0685926 0.0446792 --0.0164926 0.0544756 0.0504072 --0.051136 0.140067 0.0203692 --0.089139 0.139182 0.0122002 -0.0163249 0.0580554 -0.0285 --0.0621816 0.0342254 0.0257179 --0.0188821 0.0387745 -0.0111028 --0.053388 0.034491 0.0395762 --0.000472072 0.130948 0.0195451 --0.0634988 0.173693 -0.0615446 --0.054487 0.0452173 0.0438312 --0.0202902 0.0906146 -0.0362948 --0.0725702 0.17984 -0.0501722 --0.0707759 0.162402 -0.0459559 --0.0463694 0.113628 -0.0162147 --0.0523573 0.0345285 0.0397607 --0.0136632 0.0511316 -0.0317578 --0.00948303 0.0703233 0.0561585 --0.0852113 0.0869359 0.026743 --0.0745333 0.0805197 0.0374668 -0.00349251 0.118288 0.0385113 -0.0493697 0.0693787 0.0250272 -0.029581 0.0736246 -0.0217333 --0.0400646 0.156235 -0.00986121 --0.0818113 0.136716 0.048659 --0.0809364 0.129495 -0.00494346 --0.0875459 0.110452 0.0143395 -0.0253164 0.112728 0.0350367 --0.0852858 0.0845126 -0.000515374 -0.00212883 0.120316 -0.0135831 --0.0192664 0.0381478 0.0114056 -0.0493315 0.0589269 -0.00474568 --0.0183092 0.162495 -0.00732366 --0.00730789 0.12834 -0.00208974 --0.0286194 0.180015 -0.014033 -0.0255963 0.0648009 -0.0228004 --0.00925832 0.177251 -0.027731 --0.0485485 0.0432385 -0.0107358 --0.0600861 0.14609 -0.00280453 --0.026172 0.174158 -0.0190728 --0.059111 0.0686528 0.0369372 --0.0434854 0.0944868 0.0426487 --0.0216341 0.038095 0.0200103 --0.0670537 0.071446 0.0363402 --0.0348255 0.0915164 -0.024068 --0.0202598 0.174222 -0.0154191 -0.0344662 0.114921 0.00815778 --0.0686919 0.0750175 -0.0147112 -0.026272 0.0789381 -0.0240124 -0.0202522 0.0805604 -0.0270674 --0.0432329 0.156565 0.00586077 --0.00650833 0.0787624 0.0577507 --0.0335034 0.0774945 0.0414157 --0.0606769 0.0676671 -0.0113119 --0.0656284 0.162324 -0.0174746 -0.00729944 0.0639619 -0.0320669 --0.00448657 0.0898027 0.0567005 --0.0584972 0.0918588 0.045399 -0.00218731 0.0852799 -0.0344916 --0.0417916 0.0869783 -0.0214259 -0.0463392 0.0489694 -0.00446687 --0.0389761 0.128486 0.00847309 -0.00727028 0.11232 0.040519 --0.0234564 0.0680424 0.0463484 --0.0797185 0.0803984 0.0327643 -0.0232549 0.0645506 0.0458531 -0.0198821 0.0449543 0.0425235 --0.0394974 0.0902763 0.0431118 --0.0662858 0.172388 -0.0591199 -0.0259452 0.0364961 0.0239139 --0.0714148 0.0386609 0.00057855 --0.0638254 0.0924713 -0.0188016 --0.0584874 0.112515 0.0360801 --0.0623619 0.166253 -0.047591 -0.0452758 0.0875665 0.00218329 --0.0244115 0.0379996 0.0159179 -0.0452209 0.0659646 -0.000116442 --0.0707693 0.176767 -0.0466577 --0.0650223 0.156803 -0.0519494 -0.0354173 0.0414682 -0.003097 --0.0416808 0.0622091 -0.0130274 -0.0326595 0.114633 -0.00147403 --0.0495274 0.14168 0.00739502 -0.0388579 0.0970015 -0.00784 --0.00249575 0.0389742 0.0303561 -0.0070795 0.101453 -0.021277 -0.0291938 0.0754716 0.043989 -0.00502464 0.126695 -0.00649713 --0.016158 0.0884114 -0.0380198 -0.0115883 0.102988 -0.0210311 -0.0576451 0.0661396 0.0235216 -0.0317192 0.118031 0.0171382 --0.0116954 0.175688 -0.0223293 -0.00121183 0.0853285 -0.0350521 --0.0158308 0.0883117 -0.038067 --0.0686258 0.0846974 0.0427491 -0.00833511 0.0595736 -0.0302453 -0.0450509 0.0423962 0.0206492 --0.027467 0.0793682 0.0471485 --0.0679777 0.0716192 0.0360049 --0.0718018 0.158195 -0.0399213 --0.0114987 0.0856547 0.0572923 -0.0131441 0.0346685 0.0356066 --0.0620328 0.156862 -0.0185851 --0.0607717 0.113836 0.03657 --0.0764751 0.146968 0.0421376 --0.0207673 0.117009 -0.0138783 -0.0416942 0.0655359 -0.00371801 --0.0306051 0.0524133 -0.0153638 -0.0107636 0.130209 0.0207729 --0.0902734 0.133771 0.0282153 --0.0235934 0.0383252 0.00311252 --0.012672 0.0526484 -0.0327744 --0.0309385 0.0622798 -0.0204312 --0.0337803 0.122942 0.0251825 --0.0598823 0.146825 0.0363335 --0.0447526 0.0336781 0.00121434 --0.0540428 0.0334293 -0.000440359 -0.0119421 0.123166 0.0332435 -0.0105328 0.103079 0.0462759 --0.00696577 0.0389018 -0.00510709 --0.033478 0.0632761 0.0395519 --0.0386238 0.0519962 -0.0107523 --0.0778526 0.159695 -0.0239243 --0.0154805 0.109966 0.0416657 --0.0688005 0.087996 -0.0171065 --0.0428494 0.0999447 -0.0214282 -0.02441 0.101163 -0.0191142 --0.0630974 0.160042 -0.0195595 --0.0591899 0.154851 0.0254882 --0.0694874 0.100005 0.0406788 --0.063101 0.150495 -0.0266018 --0.000774843 0.0783346 -0.0358957 --0.0335129 0.112536 0.0351002 -0.00348618 0.11278 0.041408 -0.0454091 0.0918015 0.00517469 --0.030521 0.0636541 -0.0224277 --0.0564983 0.108415 0.0389345 --0.0454982 0.045182 0.0420491 -0.0366564 0.089932 -0.0151793 --0.00318743 0.0350129 0.0463208 -0.0397193 0.0787183 -0.00974279 --0.0456155 0.165496 -0.00783315 --0.0401614 0.110268 -0.0187071 --0.0607836 0.171276 -0.0609166 --0.0849643 0.0885105 -0.00254627 -0.000663768 0.131541 0.0142252 --0.0773558 0.163115 -0.0213545 --0.00442024 0.118937 -0.0140576 -0.029367 0.1045 -0.0146741 --0.0767078 0.176155 -0.0445645 --0.087862 0.117151 0.00226309 --0.0674561 0.1652 -0.0559896 -0.0417828 0.101446 0.0181564 --0.0504972 0.0465484 0.0414292 -0.0334855 0.0808915 0.0414362 --0.0640951 0.0700461 0.0364211 --0.0500004 0.121197 0.0329094 --0.0640156 0.0344353 0.0303981 -0.0161688 0.0407187 0.0441528 --0.0175288 0.165418 -0.0114925 --0.0156111 0.0407209 -0.0274801 --0.0136265 0.129395 0.0133241 --0.060628 0.0588072 0.00794551 -0.0064803 0.0977098 0.0499318 -0.0439772 0.079046 -0.00278888 -0.0418428 0.0986036 -0.00180869 --0.0225444 0.178667 -0.0133919 --0.0606264 0.0336734 0.0105944 --0.0434 0.0336807 -0.00215159 --0.0886031 0.143176 0.0340326 --0.0849284 0.107666 0.0223625 -0.0592303 0.0580467 0.0201933 --0.0540206 0.147182 -0.0016614 --0.00601913 0.126314 0.0306279 --0.0686207 0.149674 -0.0393499 --0.0919325 0.130933 0.0102425 --0.0568299 0.143897 0.0319274 --0.0354984 0.115235 0.0327878 --0.0174958 0.0701523 0.0542792 -0.0270421 0.0862601 0.0462384 --0.0488595 0.101383 -0.02158 --0.0733679 0.152652 -0.0338969 --0.0750934 0.159541 -0.00936327 --0.0374543 0.155389 -0.00975319 --0.0381729 0.166677 -0.0130206 --0.087877 0.0990467 0.0233782 --0.00160432 0.0405525 -0.0251988 --0.0903048 0.139241 0.0221876 --0.00139541 0.0385701 0.0219096 --0.0221672 0.0839099 0.0558332 --0.000827607 0.0389424 0.0289209 --0.0177093 0.0385258 -0.00321073 --0.0221552 0.169733 -0.0198584 --0.0574718 0.156359 0.0101234 -0.0162407 0.0793143 -0.0294472 -0.0309621 0.0953572 -0.0169293 --0.0167051 0.126576 2.44266e-05 --0.0210968 0.161053 -0.00432438 --0.0244887 0.100244 0.0443393 --0.0637376 0.15365 0.0326508 -0.0154945 0.115387 0.0371086 --0.0110238 0.098585 0.0502027 --0.0466991 0.122484 0.0270727 -0.015569 0.110589 -0.0172093 --0.0540772 0.146211 0.0253916 -0.0117081 0.0589891 0.0519593 --0.0289244 0.033884 -0.0216457 --0.08784 0.105023 0.0143674 -0.0262802 0.123151 0.0136687 -0.0122982 0.128768 0.0241985 -0.0428587 0.0803554 -0.00479839 --0.0249679 0.0851951 0.0529639 -0.0259953 0.123127 0.0078705 --0.000612836 0.0356605 0.0156316 -0.0462948 0.0820457 0.00817944 --0.0179779 0.15947 -0.0103936 --0.0237993 0.184341 -0.0145966 --0.0300075 0.0337589 -0.0217484 -0.0233024 0.124378 0.00401489 --0.0457643 0.0811616 -0.0200148 --0.0786005 0.174957 -0.0470491 -0.00992987 0.0806149 0.0548353 --0.036507 0.0464425 0.0402005 --0.0229776 0.0681076 0.0472951 -0.0359077 0.111056 0.0244077 --0.0691331 0.0612207 0.0112337 --0.0653605 0.174136 -0.0490346 --0.0246777 0.0366811 0.0541279 -0.00549638 0.115538 0.0397987 --0.0512593 0.128575 -0.00377835 --0.0227541 0.0889021 -0.0365754 --0.052801 0.144689 0.0203903 --0.0373724 0.0344314 0.0325332 -0.0302609 0.0461225 0.032895 --0.0668934 0.119448 -0.00885989 --0.0781478 0.107183 -0.00659237 --0.0262448 0.109573 -0.0200299 --0.0930011 0.116069 0.0193086 -0.0199447 0.104671 0.0430468 --0.0902973 0.114585 0.00733567 --0.0597131 0.0708022 -0.0154129 -0.011503 0.0909852 0.0534706 --0.0601621 0.0433793 -0.00606772 --0.0690356 0.068492 0.0314599 --0.0662201 0.0390045 0.0360529 -0.0111444 0.104428 -0.02004 --0.0620602 0.155611 0.00849054 -0.038029 0.105425 -0.00179734 -0.00952421 0.0346423 -0.0128865 --0.0475328 0.0338333 0.0273813 -0.0275059 0.121239 0.00414409 --0.0713739 0.162409 -0.0439557 --0.0388285 0.0339925 0.000319116 -0.0209713 0.0966458 -0.0223043 --0.0117867 0.0798822 -0.0383021 --0.00231276 0.123919 -0.0094032 --0.0623035 0.158393 -0.0375989 --0.0498834 0.108435 -0.0190271 --0.0450959 0.122461 0.0255697 --0.086583 0.1077 0.0153543 --0.0640141 0.128346 0.0443555 --0.0910616 0.140621 0.0211716 -0.0222184 0.122028 -0.00352468 --0.0197563 0.0685528 -0.0378978 --0.0747315 0.0809443 -0.0125955 -0.0381487 0.056188 -0.00571384 -0.0310862 0.0808926 0.0432566 --0.0418955 0.0336683 0.02694 -0.0454971 0.0861837 0.00419421 --0.0515955 0.0575054 -0.00888629 --0.0923422 0.120143 0.0302906 --0.0388134 0.0900157 -0.0235053 --0.0678286 0.139237 -0.00787376 --0.0500776 0.136736 0.0219567 --0.0524826 0.132311 -0.00383544 --0.0725073 0.154019 -0.0378993 --0.0164965 0.114086 0.0389356 --0.0266334 0.0505574 -0.0257305 -0.0285947 0.0646316 0.0430307 --0.050498 0.10288 0.0412159 --0.0147348 0.0348101 0.0475803 --0.0147627 0.0728806 -0.0387608 --0.0425799 0.160887 0.00499665 --0.0516371 0.0334814 0.00180973 --0.0574972 0.0973516 0.04313 --0.0294813 0.179959 -0.00726258 --0.0696084 0.159782 -0.00738408 --0.00175707 0.0783385 -0.0360812 --0.0778906 0.0797955 -0.00863863 -0.0383322 0.0928141 0.0344469 --0.0459579 0.0368224 -0.0202942 -0.0126438 0.130236 0.0157508 -0.0370668 0.109719 0.0231776 --0.0650007 0.0600171 0.0167571 --0.0294928 0.0931993 0.044345 --0.0849548 0.0952071 0.0290738 --0.0314917 0.0660582 0.0391556 -0.0283827 0.10475 0.0376855 -0.0125555 0.034405 -0.0178251 -0.0407099 0.0684593 0.0306869 --0.0321086 0.163743 -0.0150961 -0.00529533 0.064011 -0.0326857 -0.0428516 0.0972538 0.000192155 -0.0475361 0.0451237 0.0241502 --0.0188094 0.0382725 0.0240343 --0.0242622 0.0650295 0.043001 --0.0247852 0.0783802 -0.0377363 -0.0104929 0.0923225 0.0529394 --0.0684671 0.140894 -0.00832284 --0.013606 0.0435021 -0.0266802 --0.0324058 0.05963 -0.0134049 --0.0709313 0.156768 -0.044906 --0.0794975 0.113845 0.0467655 -0.0215945 0.126233 0.0147739 --0.0653369 0.0416124 0.0352199 -0.0546053 0.0733755 0.0137165 --0.0893171 0.0996957 0.0173941 --0.0835863 0.0817078 0.00050138 -0.029436 0.039931 -0.00313898 --0.0614917 0.0661812 0.0332998 --0.0923901 0.114734 0.0183133 -0.030053 0.0567138 -0.0167759 --0.00342912 0.0915905 -0.0351346 --0.0758824 0.100651 -0.0113429 --0.0457293 0.0348843 0.042622 -0.00615023 0.0385922 -0.00780619 --0.0547458 0.0768339 -0.0193157 --0.0356142 0.0493225 -0.0125317 -0.024593 0.0345639 0.00705834 --0.0892328 0.114145 0.0245988 -0.0348936 0.0586201 -0.0127038 --0.0828513 0.138047 0.046826 -0.0569539 0.0508846 0.00918952 --0.0797103 0.0711205 0.00752586 --0.092065 0.118755 0.0273051 --0.0103683 0.0388061 0.0306894 --0.0431813 0.165147 -0.00997877 --0.0813565 0.109598 0.0300528 -0.0477122 0.0511499 0.0301456 --0.0678831 0.155252 0.000581516 -0.0349362 0.113582 0.0211925 -0.0280387 0.0549866 0.0403705 --0.0615433 0.125505 0.042614 -0.0450739 0.0427888 0.00232236 --0.0544975 0.121335 -0.0101688 -0.0117318 0.0833298 0.0539432 --0.0144997 0.103011 0.0432504 --0.0752992 0.149965 -0.0228671 -0.0196742 0.0686359 0.0495084 --0.0394722 0.107013 0.0383007 --0.0321381 0.0435397 -0.0289857 -0.0231687 0.0915577 0.0477207 --0.0480905 0.156132 -0.00685995 -0.00882114 0.0589209 0.053036 -0.000540453 0.0731645 0.0574875 --0.0842824 0.0818436 0.0235004 --0.072066 0.0353469 0.00817017 --0.0548518 0.122696 0.0382478 --0.0283817 0.123518 -0.00261643 --0.0178271 0.0855379 -0.0388455 --0.00772146 0.0656018 -0.0354736 -0.0230836 0.12416 0.0238853 --0.0125037 0.0730609 0.0559849 -0.0551355 0.0581678 0.0268835 --0.0288448 0.124881 0.0180835 --0.0566945 0.126945 0.0390945 --0.0491155 0.0337431 -0.0125383 --0.0100076 0.130157 0.0146359 --0.0114787 0.0934019 -0.0350786 --0.012503 0.0856552 0.057236 --0.00822614 0.0384527 0.0224267 --0.0288615 0.0353967 0.01735 --0.035527 0.115134 -0.015836 --0.085501 0.0791776 0.00851156 -0.0457594 0.0890174 0.0101642 --0.0775133 0.126 0.0528602 --0.0598229 0.0911123 -0.0198104 -0.0349018 0.0698502 -0.0158378 --0.00371064 0.0641813 -0.0350983 --0.0232497 0.0336668 -0.0221987 --0.0337721 0.121485 -0.00843946 -0.0123855 0.0603174 0.0511841 --0.0454994 0.0804154 0.0426755 -0.00893209 0.124393 0.0330753 --0.00403191 0.0987119 0.0511654 --0.0481285 0.0573264 0.0358964 --0.0166099 0.0407431 -0.0277394 --0.0440479 0.169839 -0.00695693 -0.0412738 0.0872408 -0.00977382 --0.0604546 0.071762 0.0392488 -0.0529297 0.0581906 0.02898 --0.0521631 0.138551 0.0244099 --0.0366167 0.15106 0.000396988 -0.0417493 0.0611977 -0.0033567 --0.070996 0.0683351 -0.00354604 --0.0356709 0.0621736 -0.0130441 --0.0170991 0.0383232 0.0225362 --0.0487856 0.0573034 0.0351442 -0.022412 0.0372285 0.0333476 --0.0249633 0.0931679 0.047071 -0.018008 0.0349409 0.0291289 --0.0796085 0.154132 0.0271276 --0.0406237 0.0336557 -0.0200198 -0.0169165 0.123099 -0.00667688 -0.0210051 0.0618768 0.0478546 --0.0427644 0.0812202 -0.0203472 --0.0672645 0.175508 -0.0482636 --0.0639988 0.121381 0.0479339 --0.0622266 0.158391 -0.0366041 --0.0261802 0.161053 -0.0142499 -0.0186318 0.0821747 0.0516425 --0.00531922 0.0961442 -0.0318294 -0.00250665 0.0341604 -0.0175888 -0.0167477 0.0563074 0.0486799 --0.0106808 0.0555967 -0.0338825 -0.00925016 0.0724976 -0.0328208 -0.0123553 0.0552818 -0.0294499 -0.0212602 0.0735043 -0.0271352 --0.0845249 0.129883 0.0501389 --0.0764965 0.154899 -0.0050946 --0.0621627 0.163132 -0.0395927 --0.0144955 0.0701698 0.0547379 --0.0084766 0.0489124 0.0500846 --0.000135712 0.0381648 -0.0142912 --0.0503963 0.1183 0.0322871 --0.0761087 0.083292 0.0375324 --0.0736943 0.094184 0.0404336 --0.0691138 0.0763852 0.0387083 --0.0290376 0.038297 0.000217512 --0.0348553 0.0342935 0.020715 --0.0220444 0.0384934 -0.0170721 --0.0114987 0.0471911 0.0478612 -0.0375264 0.0714822 -0.0127977 --0.0282394 0.087664 0.0462444 --0.0757136 0.107486 0.0366393 --0.0610115 0.134041 -0.00711168 --0.0797372 0.0717415 0.00518109 --0.0658978 0.147832 -0.0279808 --0.00653882 0.110902 -0.0214831 -0.0296673 0.0591775 0.0410177 --0.0217889 0.0696447 0.0502694 -0.0234089 0.0418644 -0.00766906 --0.0364935 0.0888766 0.0431732 -0.0306541 0.0520995 0.0370911 --0.060098 0.0687043 0.0366734 -0.0187338 0.0862153 -0.0273821 --0.0839692 0.148747 0.00414299 --0.0354821 0.0561791 0.038801 --0.0481382 0.0376145 0.0455768 --0.0676248 0.117206 0.0513943 --0.0281854 0.174153 -0.0178233 -0.0359289 0.0386712 0.0221633 --0.0256851 0.0824232 0.052338 --0.0145953 0.0363242 -0.0264317 --0.0303622 0.055196 -0.0183802 --0.00165167 0.0525486 -0.0310164 --0.0132125 0.168083 -0.022507 --0.00949762 0.078776 0.0580091 --0.0361357 0.127268 0.00216052 -0.048778 0.0525636 0.0299433 --0.0256526 0.0520956 -0.0269974 --0.0603733 0.0335628 0.0071663 --0.0426157 0.035917 -0.0271302 --0.0144999 0.162187 -0.0103051 --0.0384864 0.0548303 0.0394681 --0.0831442 0.107611 0.0263767 --0.00111933 0.100971 -0.0229536 --0.0548742 0.10693 -0.0184788 --0.0218282 0.127027 0.00889322 --0.0174982 0.111166 -0.0197324 --0.0652616 0.0722487 0.0377992 --0.0576238 0.145329 0.032529 --0.0184507 0.117417 -0.0143314 --0.081937 0.128034 -0.00496911 -0.0195332 0.12729 0.0154357 --0.0293484 0.0705264 -0.0315108 --0.00525979 0.0409541 0.0483014 -0.0555717 0.0706847 0.00515518 --0.048428 0.0531039 0.036022 --0.00279611 0.0826469 -0.0371795 --0.0287124 0.0382592 0.00213562 --0.0574984 0.0959784 0.0439666 --0.091525 0.133725 0.0172151 --0.016864 0.128415 0.0107007 --0.0636978 0.164648 -0.0286005 --0.0829735 0.127181 0.0515051 --0.0488321 0.0956358 -0.0221459 -0.0400863 0.0899903 -0.0108207 --0.0619683 0.12268 0.0437909 -0.0605435 0.0650981 0.0101416 --0.0665542 0.169448 -0.0580509 --0.0891009 0.0902275 0.0204481 --0.0825815 0.112383 0.0454387 -0.0104883 0.0936688 0.0521003 -0.0142529 0.0765304 -0.0302113 -0.0165164 0.126586 0.0257514 --0.0283423 0.118847 0.030216 -0.0142697 0.034212 -0.000289798 --0.0478723 0.105599 -0.0198923 --0.0739256 0.098177 0.0391323 --0.049674 0.141672 0.0123895 --0.0475977 0.15214 0.0100027 --0.0424553 0.128377 0.00131486 -0.0224361 0.0645464 0.046427 --0.0885609 0.087538 0.0184581 -0.0147132 0.0897404 -0.0290836 --0.054132 0.143048 0.0274248 -0.00550441 0.0575487 0.0534334 --0.0772682 0.155563 -0.0118971 --0.0677628 0.079419 -0.0170759 --0.0464924 0.159333 0.00779524 -0.0261579 0.0768253 0.0466356 --0.0552963 0.0473377 0.0123212 --0.0298441 0.0972531 -0.0235715 --0.00563259 0.0974901 -0.0292726 --0.0261993 0.095287 -0.0250572 --0.0716941 0.0684125 -0.00254325 -0.00127365 0.0682996 -0.0335875 -0.0575871 0.0523587 0.0191771 --0.00134429 0.0361889 0.0150058 --0.0715096 0.1041 0.0379435 --0.0921823 0.117455 0.0412015 --0.0384872 0.0337149 -0.0296051 --0.0287365 0.0475545 0.0479663 --0.0257999 0.0422849 0.0537317 --0.0230963 0.124618 -0.00175855 --0.0924128 0.11471 0.0173177 --0.00492025 0.0362041 0.048453 --0.0186551 0.184576 -0.0164922 --0.0802253 0.0772741 0.0285988 -0.0463015 0.0806481 0.0121762 --0.0304105 0.0861968 -0.0305753 --0.0346214 0.0348242 0.0450553 --0.0652339 0.0355811 0.0395373 --0.0788426 0.0825957 -0.0096075 --0.0127163 0.038878 -0.00996632 --0.0624916 0.166267 -0.0445898 --0.0746075 0.156859 -0.0239292 --0.0773753 0.161145 -0.0179242 --0.0883931 0.1336 0.00326444 --0.0661323 0.162373 -0.0581655 --0.0510928 0.12386 -0.00885828 --0.0384971 0.0705176 0.0419076 --0.0723264 0.176481 -0.0540086 --0.0271072 0.11707 -0.0138992 --0.0591735 0.11954 -0.0102201 -0.0222809 0.11936 0.0323905 --0.0302503 0.17123 -0.00702025 --0.0809167 0.107332 -0.00361395 --0.0627188 0.046051 0.00845692 --0.00639449 0.0347093 0.0459249 --0.0877048 0.0873692 0.00346654 --0.0410427 0.15478 -0.00878846 --0.069373 0.0655009 0.0252048 --0.0270649 0.0689032 -0.0335294 -0.00976243 0.126251 0.030462 --0.002483 0.114172 0.0414823 --0.0532846 0.152692 0.0160461 --0.0190668 0.12797 0.0127969 --0.0645056 0.0818668 0.0436415 --0.0144784 0.0645279 0.0535035 --0.0598098 0.08825 -0.0201729 --0.0614957 0.105649 0.0403113 --0.0278003 0.174225 -0.00868668 --0.0525152 0.0439969 0.0448982 --0.00749319 0.0503553 0.0512463 --0.0786706 0.0853441 -0.0105854 --0.0447185 0.0709976 -0.0171011 --0.0635722 0.0753573 0.0407707 --0.0124985 0.0603974 0.0541523 -0.0344134 0.0655586 -0.0158419 -0.0196499 0.124334 0.0268969 --0.0627763 0.0614875 0.0230054 -0.0416143 0.102832 0.00217563 --0.0552881 0.147721 0.0283494 --0.0143864 0.174216 -0.0192271 -0.0144149 0.0343798 -0.00603429 --0.0101902 0.177186 -0.0254506 -0.0284808 0.120403 0.0230436 --0.0149461 0.0384961 0.0282276 --0.0778803 0.0710945 0.0220932 --0.042083 0.168351 -0.00985967 --0.056782 0.043535 0.0167171 -0.0143083 0.122234 -0.00973054 --0.0266054 0.0916781 -0.031606 --0.00249278 0.121064 0.0370013 --0.0199096 0.0382242 0.00758286 --0.0135056 0.0842656 0.0572305 --0.0720125 0.148777 -0.0357596 -0.0251623 0.118606 -0.00580398 --0.0618325 0.0334319 -0.000212632 --0.0855476 0.136296 0.00125685 --0.032605 0.0408975 -0.030074 -0.0426847 0.0986805 0.020158 --0.00736899 0.0366982 -0.0162506 -0.00250252 0.0590979 0.0551087 --0.0674921 0.106947 0.0382762 --0.0289938 0.16114 -0.00164375 --0.0509402 0.0584984 0.0315938 --0.0350845 0.124972 -0.00417237 --0.0686385 0.0435335 0.00569826 -0.0441509 0.0959467 0.0161545 -0.0131317 0.10725 -0.0189993 -0.0358259 0.0928903 0.0378885 --0.0154981 0.060248 0.0524646 -0.0276762 0.118315 -0.00350857 --0.0683312 0.0833327 0.042485 -0.033847 0.106899 -0.00922375 -0.048317 0.0466984 0.0256626 --0.0570131 0.128126 -0.00643112 --0.0788672 0.111379 -0.00271807 -0.0115311 0.122019 -0.0114981 -0.0275945 0.106191 -0.0144774 --0.0591334 0.0584459 0.00677121 --0.0780191 0.149419 0.0383262 --0.0559631 0.0464314 -0.00541258 --0.0192836 0.0894928 -0.0371367 --0.033131 0.166707 -0.0157536 --0.0495065 0.107045 0.0392662 --0.073496 0.147014 0.0424214 --0.0404833 0.111172 0.036485 -0.0284708 0.0565571 -0.0188308 -0.0511996 0.0711486 0.0227866 --0.0681397 0.0738079 0.0376094 --0.0905331 0.135117 0.0212107 --0.0733037 0.155556 0.00591793 -0.0500217 0.0446984 0.00624267 --0.00949805 0.0815484 0.0580308 -0.0211117 0.124199 0.0260136 --0.0611133 0.149657 0.036321 --0.0635959 0.153475 0.00125628 -0.0344187 0.0994578 0.0359067 --0.0734442 0.163812 -0.0389777 --0.0852938 0.0858468 -0.00152115 --0.0559297 0.13815 0.0313829 --0.0870302 0.13217 0.00132034 -0.0204036 0.0474506 -0.0212729 --0.076548 0.0954614 0.0376104 --0.0855527 0.153551 0.0192298 --0.0729125 0.0928513 0.0411123 --0.0404958 0.0478428 0.0400733 --0.0121854 0.0980546 -0.0279084 --0.0464966 0.108432 0.0393098 --0.0177034 0.0569685 -0.0340386 --0.0908687 0.135097 0.0172074 --0.0862565 0.0846802 0.0214754 --0.0297808 0.0348722 0.0494682 --0.0764922 0.155931 0.0149956 --0.0618119 0.115344 0.0386033 --0.0487475 0.0767781 -0.0183253 --0.0907804 0.150219 0.0191245 --0.0524535 0.0335708 0.023045 --0.0384946 0.0577019 0.0400515 --0.074873 0.151297 -0.0278802 -0.00653661 0.120619 -0.0139577 --0.0483957 0.0389613 0.0452757 --0.0779524 0.165292 -0.0269536 --0.0536531 0.0334694 0.00682116 --0.0561549 0.118392 0.0380484 --0.0201622 0.0337128 -0.0216346 --0.0794073 0.0772395 -0.00557672 --0.0135947 0.071631 0.0548042 --0.0382622 0.0335792 -0.0232089 --0.0183288 0.115615 -0.0164437 --0.0507515 0.0768088 -0.0186854 --0.0176367 0.181628 -0.0186063 -0.001434 0.0980064 0.0516014 -0.00449684 0.131467 0.00706378 --0.0839655 0.111209 0.0317911 --0.0769529 0.128149 -0.00749249 -0.0471199 0.0728094 0.00697834 -0.0460243 0.0737836 0.00392327 --0.00149572 0.0505531 0.0529099 --0.0431936 0.0363833 0.0440447 --0.054345 0.151005 0.0266856 -0.00514071 0.12498 -0.00862525 --0.0729614 0.112778 0.0490933 -0.0152498 0.0348445 0.0304622 --0.0111539 0.0386404 0.0270766 --0.0431779 0.113636 -0.0162215 --0.0754447 0.164601 -0.0189193 --0.0685657 0.0346013 0.0116976 -0.036686 0.110763 0.0218417 --0.058015 0.128168 -0.00680186 --0.0805084 0.121673 0.0499202 --0.0750852 0.174913 -0.0410877 --0.0394764 0.081876 0.0433844 --0.01065 0.0383969 0.0147482 --0.0236788 0.0551648 -0.029679 --0.0207747 0.0728486 -0.0387932 -0.00733312 0.0553775 -0.0306811 --0.0497252 0.137033 0.00342407 --0.0650198 0.154365 0.0307072 -0.00051428 0.0383337 0.0225142 --0.0625323 0.1568 -0.0366082 --0.00383551 0.130671 0.00539431 -0.0310854 0.118732 0.00690653 --0.0699388 0.131128 -0.00863643 --0.023911 0.123885 -0.00309916 --0.0495628 0.0402984 0.0453668 --0.0639487 0.168098 -0.0606895 --0.0706835 0.155594 0.0053992 --0.0686442 0.156175 0.0235781 --0.0572185 0.0575347 0.00867749 --0.0788442 0.154658 0.0259054 --0.0721793 0.15961 -0.0389315 --0.0545051 0.119806 0.0369329 --0.0254081 0.182912 -0.0140439 --0.0729406 0.0676849 0.0243239 --0.0353285 0.0851433 -0.0237512 --0.0478735 0.104217 -0.0205651 --0.0558395 0.0589131 -0.0044052 -0.0448613 0.0903726 0.0191701 -0.0576189 0.0719687 0.0133447 --0.0511061 0.129858 -0.00316533 --0.00880359 0.113633 -0.0183799 --0.0618121 0.09105 -0.0190303 -0.0313027 0.114101 -0.00492854 --0.042497 0.0874008 0.0424798 --0.0508473 0.0970748 -0.0222124 --0.0654906 0.102864 0.0410679 --0.00458022 0.0347745 -0.0240516 -0.0553581 0.0524903 0.0236336 -0.00626754 0.071137 -0.0337471 --0.0135115 0.118298 0.0374588 --0.0604029 0.0342918 0.0295439 -0.0406411 0.0462159 0.0309092 --0.0278584 0.0385169 -0.0108032 -0.0266728 0.0713177 0.0438181 -0.0101968 0.116422 0.0377394 -0.0446411 0.0959729 0.00816419 --0.0597937 0.0334415 0.000190139 --0.0210999 0.0811322 0.0562803 --0.0474593 0.0559824 0.0367034 -0.0340242 0.115407 0.0165889 -0.0416569 0.0832977 0.0303966 -0.0340782 0.100772 0.035418 --0.0604756 0.0747304 0.0414998 -0.0147905 0.128825 0.0208219 --0.00109958 0.115152 -0.0180337 --0.0237291 0.0650733 0.0438813 --0.0261862 0.17712 -0.0185723 --0.0381348 0.0338853 -0.0178771 --0.0323789 0.115075 -0.0157884 -0.0168479 0.0856792 -0.0288312 -0.0383914 0.0390949 0.00219016 -0.0192558 0.0721931 -0.0285132 --0.0837506 0.0776431 0.00349824 -0.00549734 0.0937843 0.053579 -0.0381875 0.10978 0.0131678 --0.0707773 0.0822058 -0.016572 --0.0623556 0.0337533 -0.00969501 --0.0657944 0.0348418 0.0348835 -0.029813 0.0605585 0.0412449 --0.067274 0.142559 0.0431983 --0.00437946 0.039206 0.0351678 --0.091267 0.130919 0.00823808 -0.056791 0.0717301 0.0086079 --0.088725 0.0942104 0.00844208 --0.0527517 0.076824 -0.0190661 --0.075716 0.071204 0.0277224 --0.0296574 0.175524 -0.0164728 -0.0201633 0.0535759 0.04656 -0.00320624 0.036422 0.0229702 -0.0192058 0.0834241 -0.02764 --0.0918136 0.129556 0.00925121 -0.0276788 0.117119 0.0298812 --0.0251464 0.0824617 0.0532115 --0.0728771 0.154609 0.0294193 -0.00904539 0.03456 0.0402645 --0.0534903 0.102908 0.0413848 -0.00940878 0.0389595 -0.0232113 --0.0859627 0.109007 0.009354 --0.0484951 0.0903851 0.0445307 -0.00263147 0.0345612 0.0425417 --0.0770465 0.161776 -0.0174081 -0.0134975 0.104436 0.0449316 --0.0388918 0.123217 0.0263098 --0.0364947 0.112507 0.0349484 --0.0629025 0.103986 -0.017642 --0.0678178 0.0923118 -0.0167386 --0.0689104 0.122371 -0.00889897 --0.0255023 0.125351 0.00317915 --0.000607228 0.0419595 -0.0248688 -0.0460131 0.0820178 0.0051921 --0.0223034 0.0381733 0.0107634 --0.0861005 0.10314 0.0243088 --0.0674874 0.0958602 0.0421807 --0.0538319 0.138205 -0.00152003 --0.0199623 0.0624791 0.0486773 --0.0187732 0.0946942 0.0521396 -0.0415957 0.0859827 0.0303559 --0.0405006 0.0562797 0.0399754 --0.0396087 0.0392284 -0.0278507 --0.0203015 0.124709 0.0241059 --0.0667178 0.127063 0.0492263 --0.0727925 0.0893223 -0.0156729 -0.0370031 0.104683 0.029035 -0.0279524 0.103456 0.0388242 --0.0186121 0.038597 0.0291868 --0.0776508 0.152845 -0.000892884 --0.0334818 0.0987718 0.0435747 -0.0329891 0.092935 0.0408139 -0.0391956 0.0712805 0.0337887 --0.0631802 0.0590341 0.0144269 --0.0537547 0.143134 0.0264016 --0.0301924 0.153974 -0.00357072 --0.0448379 0.0970765 -0.0217835 -0.00941817 0.0340541 0.000745803 --0.0432126 0.168352 -0.00885275 -0.0554664 0.0549257 0.00120797 --0.0225677 0.0932815 0.0503229 --0.0524989 0.157892 0.00946562 -0.0390425 0.0953983 0.0320312 -0.04296 0.0817702 -0.00479044 -0.00635062 0.0510121 -0.0292209 --0.0543105 0.149562 0.0267072 -0.0221931 0.100779 0.0445472 -0.0329366 0.0724958 -0.0177814 -0.0248886 0.114037 0.0344109 --0.0550232 0.14424 -0.00134547 -0.0163915 0.04625 -0.0239163 -0.0177475 0.036867 -0.0166881 --0.0617992 0.0867358 -0.0192812 --0.0893599 0.133717 0.0406984 --0.039718 0.0695625 -0.0162922 --0.0089161 0.0389771 0.0326408 --0.0245194 0.0879123 0.052427 --0.0855508 0.0883229 0.0270467 --0.0419398 0.0356984 0.00899705 --0.0715816 0.0791203 0.0388191 --0.0444898 0.0690526 0.0411578 --0.070025 0.173518 -0.0406121 --0.0628508 0.0981808 -0.0176907 --0.0750322 0.144421 -0.00688246 --0.0499825 0.0544896 0.033589 --0.065333 0.177827 -0.0606985 --0.0316114 0.123192 0.0229888 --0.0760927 0.0805105 0.0361956 --0.0370838 0.0486029 -0.013278 --0.0785283 0.124553 0.0522615 --0.0708435 0.0731956 0.0357937 --0.0403104 0.0336344 -0.0180813 --0.0609885 0.0628534 0.0274979 --0.0323315 0.0624018 -0.0174393 --0.0368547 0.100015 -0.0221726 --0.0783796 0.172116 -0.0450441 --0.0633655 0.139636 -0.00706655 -0.00173262 0.13137 0.0174841 --0.0105091 0.0646847 0.0553841 -0.0266795 0.122765 0.0152477 --0.0360635 0.034528 0.0238485 --0.0541027 0.122637 0.0375656 --0.0544908 0.0344999 0.0341095 -0.0176998 0.103348 0.0450658 --0.0685644 0.145677 -0.0229009 --0.0356468 0.0577276 -0.0110125 --0.0696054 0.110911 0.0424293 --0.0584669 0.0577494 0.0129387 --0.0398029 0.0870085 -0.0218621 --0.00967624 0.104885 -0.0231041 -0.00669982 0.0383228 -0.00932299 --0.0609169 0.109692 -0.0160089 --0.0646221 0.122809 0.0487379 -0.0174813 0.0865744 0.0503122 --0.0067878 0.0386876 0.00254936 --0.0628956 0.119461 -0.00917238 --0.0404347 0.128451 0.0123721 -0.0304082 0.04464 -0.00596234 -0.00950687 0.0785812 0.0553914 --0.0185636 0.161122 -0.00592394 --0.0407009 0.066639 -0.0151117 --0.0638844 0.0392942 0.0408356 -0.00208256 0.0392848 0.0328214 --0.0891635 0.0901786 0.00945748 --0.0714603 0.0390724 0.00325296 -0.0396909 0.105526 0.00119339 --0.092918 0.118828 0.0342968 --0.0809093 0.0912865 0.0336272 -0.0106278 0.12033 -0.0136749 --0.079254 0.149169 0.0379325 --0.0700516 0.177913 -0.0570165 --0.0584973 0.0875674 0.0446281 -0.0363875 0.037641 0.0177175 --0.0266625 0.178341 -0.0176816 --0.0257516 0.0380733 0.00834253 --0.0514727 0.147804 0.0154008 --0.0475605 0.047528 -0.00960427 -0.0464078 0.0756596 0.0165703 --0.0659757 0.132606 -0.00839654 --0.0795255 0.0953936 0.0349279 --0.0512091 0.118302 0.0328718 --0.00441308 0.12096 -0.0123131 --0.0322918 0.0358193 0.0288559 --0.0907178 0.142015 0.0241681 --0.0555193 0.152453 0.0283051 --0.044345 0.152142 0.00768226 -0.0241695 0.0809229 0.0490966 --0.0528659 0.0999263 -0.0216782 --0.0669331 0.125307 -0.0088761 --0.0303567 0.119073 0.029499 -0.025846 0.107916 -0.0143268 --0.0617056 0.1325 0.0388812 --0.0185965 0.0364224 -0.0275796 --0.0207908 0.0384714 -0.00378381 --0.0617181 0.0598008 0.019418 --0.0474373 0.120726 0.0283448 -0.0366967 0.103968 -0.00783268 -0.0303183 0.0797251 -0.0205953 --0.0317074 0.0436869 0.0496355 --0.0623412 0.156794 -0.0356173 --0.0765015 0.121776 0.0527715 --0.0184879 0.122208 0.0309285 -0.0230909 0.103393 0.0423419 -0.0609018 0.0651278 0.0131549 -0.00916248 0.0355108 0.0268151 -0.0313289 0.0554154 -0.0147753 --0.0025035 0.108652 0.0433127 -0.0546992 0.0478618 0.0141962 --0.0620154 0.0689049 0.0360997 --0.0388626 0.102809 -0.0208006 --0.0555708 0.142434 0.0301615 --0.0688026 0.146519 -0.0258522 -0.0194777 0.0878818 0.0491927 --0.0228793 0.110931 -0.0194728 --0.0324125 0.0849398 -0.0275574 --0.0438855 0.03574 0.0440005 --0.0917791 0.117463 0.0421754 --0.0690116 0.129833 0.0494501 --0.0743362 0.15411 -0.0219057 --0.0638117 0.0867138 -0.0190744 --0.045027 0.168395 -0.00690925 -0.0270479 0.080882 0.0462053 --0.0114995 0.164138 -0.0150087 --0.0325011 0.058955 0.0382451 --0.0606931 0.0692955 -0.0138548 --0.0566913 0.0572662 0.0137312 --0.00649633 0.0488329 0.050181 -0.0223101 0.120965 0.030775 --0.0805231 0.0993639 0.0329828 --0.0644795 0.0959078 0.0429389 --0.075154 0.17882 -0.048244 -0.00607351 0.0358936 0.0456569 --0.035492 0.0648204 0.0410644 --0.0576415 0.155076 0.0216791 --0.0762945 0.152787 -0.0118902 --0.00761327 0.0434711 -0.0261832 --0.0814624 0.13163 0.0517276 --0.0743185 0.067053 0.0192856 --0.0842709 0.104792 0.000381661 --0.0374161 0.12162 -0.0106267 -0.0282004 0.082909 -0.0218038 --0.0538885 0.131144 0.0343613 -0.0268226 0.046511 -0.0137061 --0.0500801 0.151654 -0.00422617 --0.0843259 0.153929 0.0166903 --0.0840259 0.124392 0.0498267 --0.0906893 0.11752 0.0439252 --0.0636773 0.162484 -0.0225185 -0.0362915 0.0534119 -0.00658438 --0.0733102 0.0700068 0.0292571 -0.0432125 0.0858656 0.0273897 -0.0392299 0.108358 0.0101653 --0.0357967 0.0383351 -0.00483874 --0.0645865 0.0628123 -0.00359236 --0.0838768 0.108986 0.0253683 --0.0538875 0.139905 -0.00121756 -0.0463511 0.0764838 0.0150474 -0.0180384 0.119266 -0.0105437 --0.0812898 0.0735018 0.0165324 --0.0437426 0.076832 -0.018848 --0.0489995 0.126854 0.0308899 -0.00913686 0.107291 -0.0199257 -0.0413467 0.0718054 -0.00779903 --0.0407607 0.126285 -0.00553285 --0.0564807 0.113914 0.0357075 --0.0477527 0.149202 0.00972608 --0.0737025 0.144377 -0.00986626 --0.0237128 0.058121 -0.0313582 --0.0884618 0.142054 0.0361609 --0.00450592 0.0661541 0.056364 --0.0448888 0.108464 -0.0189265 --0.0531399 0.13506 -0.0028018 -0.0308728 0.114122 0.0296728 --0.0120858 0.0382274 0.0182274 -0.045976 0.0820209 0.01617 --0.0474955 0.0344671 0.0303636 -0.0116443 0.129846 0.0210966 -0.0429126 0.0775596 -0.00475805 --0.0639176 0.122377 -0.00881224 --0.0219078 0.0581082 0.0451165 --0.0185957 0.118181 -0.0131167 --0.0381658 0.165183 -0.0131497 --0.0445045 0.0438483 0.042919 --0.0464974 0.074738 0.042075 --0.0819901 0.133862 -0.00285904 --0.0633534 0.0445301 0.031682 --0.0314905 0.0960436 0.0448087 --0.0575997 0.0574661 0.0133658 --0.0303698 0.154176 -0.00601441 -0.0133009 0.0666579 -0.0304883 -0.0108109 0.0819726 0.0543646 --0.068057 0.178404 -0.0514469 --0.0806807 0.0760273 -0.00253172 -0.0394926 0.0541437 0.0318453 --0.00450121 0.0675415 0.056336 --0.019491 0.0387907 0.0342254 -0.0147818 0.0631153 0.0511723 --0.0291704 0.172664 -0.0174314 -0.0262968 0.070421 -0.0238548 --0.0421212 0.159153 -0.0103433 --0.0367588 0.172073 -0.0125043 --0.0196292 0.117165 -0.0140584 --0.042525 0.149193 0.00498605 --0.0175612 0.186044 -0.0184493 -0.0221884 0.0973608 -0.0216774 --0.0197019 0.0568866 -0.0331333 --0.045504 0.0832988 0.0437099 --0.0212803 0.0387041 -0.0133833 --0.0770943 0.154164 -0.0118975 --0.0484907 0.0833394 0.0445457 --0.0238036 0.0798229 -0.0381557 --0.0372926 0.0394674 -0.0291193 --0.00273038 0.0683735 -0.0347173 --0.0659296 0.14253 0.0416232 -0.0452769 0.0467388 0.0283148 --0.0898014 0.11587 0.00528404 -0.0263587 0.0577877 0.0432503 --0.0486968 0.067904 -0.0141574 --0.0893812 0.113196 0.0217139 --0.0841444 0.110242 0.00330414 --0.0631329 0.17411 -0.0535854 -0.0348962 0.0387881 -4.46661e-05 -0.0431163 0.0888383 0.0261767 --0.0444887 0.166716 0.00379579 --0.0235591 0.0953745 -0.0271663 -0.0455985 0.0918132 0.00816712 --0.0917403 0.12555 0.0418871 --0.0890224 0.136404 0.0092064 --0.0364114 0.175555 -0.00996795 --0.0345906 0.0727451 -0.0199624 -0.0429111 0.040977 0.0196984 -0.00148534 0.0385845 0.0464325 --0.0585016 0.0973698 0.0431908 --0.0484982 0.0819185 0.0441136 -0.00821862 0.116409 0.0384227 -0.0456517 0.0413562 0.00923967 --0.0769167 0.0873975 0.0382106 --0.061867 0.101123 -0.0184855 -0.0202898 0.124676 0.0257091 --0.0101432 0.130124 0.0117041 --0.0138894 0.183111 -0.0237643 --0.0707552 0.0792696 -0.0152786 -0.0465284 0.0761532 0.0136843 --0.0888827 0.140531 0.0122011 --0.0659605 0.110851 0.0377691 --0.0638988 0.109582 -0.0144399 -0.0445103 0.0541956 0.0324876 --0.0545376 0.0335773 0.0172858 -0.0156666 0.0726831 0.0525311 --0.0224929 0.0448955 0.0530527 -0.00250097 0.0897336 0.0558646 --0.0427601 0.128938 0.0129983 --0.0749067 0.100837 0.0372176 -0.0100662 0.0792875 0.0550109 -0.031592 0.0738009 -0.0197207 --0.0295595 0.111353 -0.0178807 --0.0265381 0.155425 -0.00506198 -0.0110253 0.0793101 0.0546505 -0.0455932 0.0834007 0.019176 --0.00963497 0.0389293 -0.00939263 --0.0740278 0.157006 -0.00316778 -0.026879 0.121193 0.00250168 --0.0840153 0.1376 0.000355984 -0.00144074 0.0344391 0.0153316 --0.062494 0.0746373 0.0407954 --0.0714338 0.100882 0.0394174 --0.0511894 0.0558131 0.0154354 -0.0142545 0.0887312 0.0523539 --0.0217647 0.0699552 -0.0378816 -0.042865 0.0958458 -0.000810373 --0.0225278 0.18149 -0.0200273 --0.0516224 0.0545433 -0.00792825 --0.0894416 0.0943032 0.0194238 --0.0450754 0.033637 -0.0171737 --0.0189216 0.122512 -0.00768052 --0.0278603 0.101566 -0.0234492 -0.0273313 0.094554 -0.020088 --0.0568394 0.145329 0.0319256 -0.0299199 0.11779 -0.000781916 -0.0345811 0.0368089 0.0162808 -0.0130795 0.0927597 -0.0282037 -0.0239979 0.0768543 0.0488301 --0.0560741 0.15232 0.0295584 --0.0713082 0.165213 -0.0459899 -0.0214853 0.0948038 0.0473574 --0.0124976 0.0472007 0.0479814 -0.0101747 0.096292 -0.0259611 --0.0424942 0.0916602 0.0426604 --0.000674255 0.10997 -0.0204918 --0.0731036 0.0721584 0.0326952 --0.0863191 0.0806349 0.0164939 --0.0174959 0.0984963 0.0451272 --0.0516134 0.0334804 0.007228 -0.0210892 0.0521114 0.044364 --0.0767842 0.155599 0.0119802 --0.0737106 0.0699801 -0.00251138 -0.0277999 0.0727164 0.0436883 -0.0605691 0.0637105 0.0171755 --0.0720961 0.156364 0.000513559 --0.0818934 0.154016 0.0102104 --0.0184806 0.169783 -0.0146335 --0.073631 0.173473 -0.03767 --0.0385075 0.0888951 0.0435504 --0.056184 0.0374619 -0.0105738 --0.0164629 0.0616668 0.0525376 --0.0214965 0.0525299 0.044709 --0.0324599 0.0722556 -0.0254696 --0.0781568 0.167257 -0.0305864 --0.0633087 0.117017 0.0436447 --0.084428 0.138004 0.0455627 -0.0287818 0.0480764 -0.0117305 --0.0706135 0.175903 -0.0451833 --0.0430742 0.0335089 -0.0222312 -0.0203664 0.0506236 -0.0244327 --0.0807714 0.153393 0.00628177 --0.0784635 0.138605 0.0489019 --0.0754126 0.068174 0.019879 --0.0105025 0.0773598 0.0576687 --0.0399608 0.0418525 -0.0253044 --0.0880973 0.137764 0.00820327 --0.0862825 0.106347 0.0193454 --0.0114851 0.123708 0.0326887 --0.00700917 0.0348727 0.042072 --0.0760973 0.0851761 -0.013541 -0.0421377 0.0912242 0.0276147 -0.0298218 0.119509 0.00500708 --0.0550443 0.148674 -0.00204704 --0.0107558 0.0386486 -0.0149703 -0.00849857 0.118254 0.0373924 -0.0373294 0.0848074 0.0364738 -0.0506886 0.0511228 0.0274131 --0.0538924 0.106961 -0.0186698 --0.0735555 0.105459 0.0371635 --0.0532563 0.0343869 0.0309731 --0.015483 0.0938222 0.0546278 -0.0454513 0.052559 0.0321398 -0.032601 0.100801 0.0367685 --0.0688527 0.142579 0.0444582 --0.0908832 0.150197 0.0161314 --0.0811312 0.129963 0.0524484 -0.00846909 0.111301 0.0401143 --0.0622744 0.0344133 0.0342699 --0.0343155 0.0340522 0.0192395 --0.0869096 0.111745 0.0223587 -0.0507656 0.0446256 0.0152142 --0.0767707 0.151403 -0.00690852 --0.00150011 0.103045 0.0440564 --0.051019 0.147224 -0.00224048 --0.025918 0.122982 0.0235755 --0.0527617 0.0461943 0.0216742 --0.0178184 0.0841429 -0.0390768 --0.0345091 0.0461323 0.043875 --0.0623881 0.149093 -0.0125752 --0.0809179 0.0761444 0.0241516 --0.00945917 0.175708 -0.0257473 --0.0334992 0.0704401 0.0410454 --0.0886682 0.141939 0.0121971 --0.0120612 0.0383071 0.0127308 --0.0853843 0.0980412 -0.000554198 --0.0325205 0.0646875 0.0393461 -0.0503466 0.0615208 -0.00363326 -0.00449283 0.103624 -0.0217086 --0.0698084 0.085099 -0.0171261 -0.0438316 0.0832073 0.0263179 --0.0486418 0.0576652 -0.0108452 -0.0123248 0.0609207 -0.0293142 -0.0429772 0.0902337 -0.00478341 --0.0619824 0.166238 -0.0535924 -0.0140441 0.0406072 0.0445814 -0.00249558 0.116934 0.0396534 -0.018473 0.0989902 0.0468145 --0.0169827 0.0385945 -0.00497776 -0.0309161 0.0955754 0.0413413 --0.0735982 0.110276 0.0438156 --0.0903629 0.11521 0.0252935 --0.0566835 0.124286 -0.00724626 --0.0620082 0.134045 -0.00734981 -0.00521493 0.0852237 -0.0334342 --0.0903999 0.124268 0.0448512 -0.0114719 0.1182 0.0365719 -0.0344326 0.0414166 -0.00330414 --0.0403754 0.124077 -0.00919956 -0.0484547 0.0702338 0.00359645 --0.0285016 0.113902 0.0349068 --0.0526285 0.0596472 0.0276152 --0.0325191 0.174119 -0.0148634 --0.0204902 0.108532 0.041306 -0.010276 0.076623 0.0552854 -0.0133781 0.0537725 -0.0285433 -0.0402901 0.0698645 0.0318359 -0.0401742 0.0671588 0.0316675 --0.0866887 0.120341 0.0484058 -0.0245253 0.0875975 0.0479106 --0.050498 0.0890212 0.0452499 --0.0598028 0.0853759 -0.0202992 -0.0354525 0.106753 -0.0069512 -0.0111874 0.0630268 0.0529412 --0.0416003 0.12872 0.00602836 -0.0443487 0.0533892 -0.00643258 --0.0229394 0.0985982 0.0448104 --0.0678177 0.0894605 -0.0172539 --0.0826703 0.0762102 0.00250991 --0.0152189 0.172708 -0.0246075 --0.0748382 0.0978559 -0.0133191 -0.0284295 0.0955564 0.0430179 --0.04802 0.136068 0.0153684 --0.0475691 0.0489734 -0.00936479 --0.0813576 0.0734641 0.0155425 --0.07594 0.14997 -0.0178724 --0.0649871 0.152354 -0.0372683 --0.0229947 0.122243 0.0275866 --0.0108296 0.0855471 -0.0384547 --0.0447583 0.0336472 -0.00973579 --0.041838 0.0942787 -0.0228038 --0.038857 0.101401 -0.0214118 -0.00839351 0.0342854 -0.0184828 -0.0436422 0.0748109 -0.00280304 -0.00409443 0.101828 -0.021842 --0.0194474 0.054231 0.0477027 -0.0410346 0.0752467 0.03121 -0.0588047 0.0677091 0.00614939 -0.021598 0.10091 -0.0208238 --0.0696323 0.156261 0.0232204 --0.086966 0.0846591 0.00747852 --0.0660124 0.176151 -0.0507054 -0.0425261 0.101486 0.00616657 -0.0305131 0.0418181 0.0291512 --0.0554982 0.113948 0.0354054 --0.0763852 0.108818 0.0389983 --0.0785959 0.152697 0.00118419 -0.0184567 0.127794 0.00934393 -0.0105917 0.043143 0.0448676 --0.0719858 0.0346482 0.00381826 --0.0341243 0.0335931 -0.0280196 --0.0564439 0.115317 0.036137 --0.0928438 0.126838 0.0112559 --0.0661071 0.164936 -0.0219713 --0.0665376 0.142546 0.0425061 --0.0167827 0.0388081 0.0329676 --0.0614351 0.156032 0.020314 -0.0388231 0.106965 0.0221712 -0.0247856 0.0449735 0.0390757 --0.0324984 0.0788891 0.0412743 --0.068331 0.155325 0.0280685 -0.0267262 0.114038 0.0335472 --0.0888783 0.111909 0.0103621 --0.0772308 0.0920788 -0.012603 -0.0457689 0.0431024 0.0219801 -0.0474981 0.0737139 0.0139878 --0.061487 0.0746791 0.0411579 --0.0861526 0.148758 0.00721004 -0.0341879 0.0913684 -0.0166968 --0.0200728 0.100101 -0.0240875 --0.0286491 0.125506 0.0152069 --0.0268606 0.0378639 0.0137313 --0.0352216 0.0346633 0.0327857 --0.0444613 0.12936 0.0182577 -0.0373383 0.0740435 0.0363986 -0.00751373 0.0869673 0.0561316 --0.0888328 0.0942898 0.0224093 -0.00897858 0.127106 -0.00499333 -0.0363106 0.0994119 0.033375 --0.0448194 0.0913346 -0.0221278 -0.000368669 0.0466323 -0.0286891 --0.0606782 0.0639978 0.0300882 --0.0735086 0.078138 -0.0125733 --0.0358361 0.11045 -0.0189078 -0.0300578 0.0632721 0.0416198 -0.0173543 0.0349384 0.0362289 --0.0104845 0.10863 0.0429333 --0.0265155 0.115287 0.0336658 -0.0257868 0.0967214 -0.0203669 -0.0255714 0.119263 0.0291067 --0.0404457 0.119913 -0.0128413 --0.0596429 0.0622343 0.0265494 --0.0522074 0.122732 -0.00965468 -0.00419216 0.0340885 -0.0190827 --0.0614977 0.108395 0.0385563 --0.0154933 0.0392591 0.0382209 -0.0568425 0.0592039 0.0011688 -0.033494 0.0619462 0.0395497 -0.0378948 0.0699732 0.0354084 --0.0643687 0.155314 0.00767719 --0.017163 0.124753 -0.00408239 --0.0892062 0.128127 0.00426293 --0.058497 0.101559 0.0426268 --0.00170163 0.130406 0.0219933 -0.0258358 0.123453 0.0120756 -0.0200283 0.102079 0.0449293 --0.0034976 0.0965806 0.0535793 --0.0805988 0.090913 -0.0086158 -0.0307316 0.091606 0.0428217 -0.0293141 0.095566 0.0425395 -0.011103 0.0779768 0.0547588 --0.0912353 0.14886 0.0211316 -0.0484812 0.0443317 0.021366 --0.00581925 0.0868408 -0.0369183 --0.0454559 0.0902978 0.0432333 --0.0346794 0.119765 -0.0106544 --0.00349323 0.113677 -0.0184484 --0.0434907 0.101526 0.0420227 --0.0385061 0.0986889 0.0419871 --0.0599081 0.112539 -0.0152225 --0.0242322 0.124794 -0.000701199 -0.0400813 0.104202 0.0221684 --0.0828121 0.0830332 0.030132 -0.0159137 0.128436 0.00413586 --0.0645186 0.0597262 0.00993302 --0.0324512 0.0353306 -0.0309147 --0.0484861 0.137101 0.00939484 --0.0304745 0.0860755 0.0433189 -0.0188415 0.121733 -0.00718615 --0.0643746 0.145275 -0.0151376 -0.0208541 0.11855 -0.00976629 -0.037465 0.0434297 0.0291248 -0.0517879 0.0461689 0.0072143 --0.0837871 0.0829476 0.0282971 --0.0917215 0.129668 0.0302355 --0.0261628 0.0674202 -0.0335157 --0.0631555 0.156855 -0.014582 -0.043463 0.077603 -0.00378219 --0.0602407 0.058232 0.0121428 --0.0458636 0.102811 -0.0213024 --0.038884 0.108506 -0.019659 --0.0705258 0.142815 0.0451961 --0.0781039 0.070111 0.0193756 --0.0758474 0.109198 0.0406016 --0.0318501 0.0986369 -0.02282 --0.038215 0.0471675 -0.018189 --0.0134374 0.0516868 0.0502089 -0.0151412 0.0754034 0.0535569 --0.043493 0.105703 0.0408668 --0.0822959 0.0773319 0.0228488 -0.0452717 0.0903987 0.0151606 -0.0159567 0.120613 0.0338084 --0.0623049 0.142641 -0.00633906 -0.000467241 0.105823 0.0432483 --0.0177409 0.0671746 -0.0379913 --0.0891252 0.0889064 0.0184472 --0.0678748 0.125664 0.0510849 --0.0337468 0.127104 0.0118588 --0.0518684 0.102767 -0.0207881 -0.00221584 0.0364728 0.00081639 --0.0296253 0.0759773 0.0411397 -0.00226876 0.0682822 -0.0333186 --0.0542457 0.0574384 0.01981 --0.0659991 0.136994 -0.00799651 --0.00357593 0.127459 -0.0052112 -0.0103564 0.0538895 -0.0297771 -0.0272815 0.0718243 -0.0235929 --0.0123281 0.0344052 -0.018857 -0.0416155 0.0404142 0.0199255 --0.0106878 0.0598858 -0.0348312 --0.0305006 0.116618 0.0322439 -0.0427332 0.084569 0.0284544 --0.0712328 0.151001 -0.0437008 -0.0423623 0.0944394 0.0261744 --0.000687654 0.0583509 -0.0327859 --0.0779789 0.136876 -0.0051311 --0.0657518 0.0780369 -0.0174491 --0.0789069 0.155396 0.0141592 --0.0701046 0.156748 -0.048906 -0.0281353 0.0593598 -0.0207767 --0.066567 0.147777 -0.0287654 --0.0167976 0.0383562 0.00264497 --0.0708835 0.160996 -0.0449446 -0.0230988 0.111339 0.037076 --0.0237033 0.091176 -0.0348871 --0.0477118 0.073839 -0.0167643 --0.0540526 0.0334248 -0.00589512 --0.0535445 0.0389126 -0.0111352 -0.00251277 0.0675114 0.055914 --0.0324736 0.0532348 0.0372028 --0.0416459 0.056333 -0.0114534 --0.0460476 0.0363198 0.0451262 --0.0215027 0.163915 -0.00845889 --0.0530817 0.139518 0.0266624 --0.00971954 0.0656257 -0.0358484 --0.0175293 0.038199 0.0153321 --0.0388176 0.128112 0.00411022 --0.0579212 0.120852 -0.00959233 --0.0215953 0.03793 -0.0285032 -0.00849245 0.0473031 0.0488481 --0.045123 0.157633 -0.00869072 --0.0845016 0.0911794 -0.00456302 --0.0130394 0.0384127 0.00153612 --0.0054932 0.111405 0.0422861 --0.00614297 0.0385457 0.0227705 --0.0588822 0.108299 -0.017343 --0.0647452 0.0766241 -0.0174472 -0.0333079 0.0768384 0.0411622 --0.0345058 0.0704863 0.0415356 --0.00385823 0.0988046 -0.0266644 --0.0940576 0.125561 0.0242759 --0.0406606 0.156554 0.00601794 -0.0458479 0.0724092 0.00333418 --0.0536298 0.0345249 0.0429297 -0.0422446 0.0760949 -0.00580476 -0.0305908 0.106106 0.0356297 --0.0744956 0.13026 0.0524093 --0.060795 0.0853339 -0.0197774 --0.0659276 0.123847 -0.00897257 --0.0587952 0.0334058 0.000425547 --0.0355002 0.111108 0.0360398 -0.0106562 0.0589179 0.0524466 -0.0220342 0.108737 -0.0152173 -0.0414017 0.104253 0.00516521 --0.0487319 0.132909 0.0254731 --0.073147 0.0648981 0.0178865 --0.0655672 0.149686 0.0379738 --0.0866855 0.14466 0.00818677 --0.0690156 0.163795 -0.0519803 -0.0474899 0.0664975 0.0274045 --0.0693729 0.175081 -0.056043 --0.0811978 0.140383 -0.00182247 --0.0609117 0.111106 -0.0154828 --0.027448 0.125478 0.0053817 --0.0601827 0.0460596 0.0101722 --0.0116048 0.0377441 -0.0259987 --0.0623577 0.147557 -0.00658086 --0.0635933 0.167459 -0.0411888 --0.0420303 0.153306 -0.00761985 -0.0045298 0.102977 0.0440255 --0.0571296 0.124118 0.0402058 --0.010491 0.0487865 0.0492904 --0.00149595 0.0911539 0.0561263 --0.0644925 0.0903995 0.0447493 --0.0621097 0.156825 -0.0345957 --0.0626845 0.0455625 -0.000282658 --0.054778 0.0344845 0.0375447 --0.0704967 0.156763 -0.0469167 --0.0501084 0.0429877 0.0445637 --0.074873 0.120838 -0.00772479 -0.0354301 0.112103 0.00127449 --0.0218649 0.103029 -0.0235712 --0.09096 0.148814 0.0141536 --0.0645626 0.0459512 0.00669838 -0.0314584 0.111437 -0.00809824 --0.022876 0.0362943 -0.0189473 --0.0428901 0.0435976 -0.0193145 --0.0746823 0.0663852 0.00625465 --0.0476209 0.0547841 -0.0103184 --0.0197585 0.171251 -0.0147167 --0.0705035 0.0901829 0.0418541 -0.0494272 0.0628335 -0.00296645 -0.0266028 0.105322 -0.0155495 -0.0202061 0.126966 0.0100746 -0.013717 0.127103 0.0275992 -0.00956448 0.122301 -0.0117968 --0.0846111 0.084433 -0.00253466 --0.0889485 0.13651 0.0272017 --0.000398103 0.0385343 0.0221462 -0.0428913 0.0402636 0.016655 --0.0531156 0.156084 -0.00339606 --0.0586999 0.141645 -0.00399496 -0.0175889 0.0549386 0.0481228 -0.0242735 0.0576737 -0.0247443 --0.0435028 0.0548283 0.0392794 --0.0509876 0.0343016 0.0280109 --0.0371778 0.128019 0.00618657 --0.067159 0.152634 -0.0476967 --0.0524481 0.115128 -0.0157418 --0.00787248 0.0390234 0.0328097 --0.0368889 0.109941 -0.0191779 -0.0473251 0.0497353 0.0295737 --0.0155015 0.10721 0.0425067 --0.0607907 0.0609394 -0.0015406 -0.0214998 0.0358071 0.0181694 --0.0152794 0.114388 -0.017154 --0.0618553 0.153745 -0.0235803 --0.00541506 0.100313 0.0476265 -0.0438051 0.0987511 0.0101628 --0.0274965 0.0973724 0.0435854 -0.0448746 0.0601039 -0.00424277 -0.031559 0.0460718 0.0312637 --0.0615188 0.0448284 0.0115308 --0.0397761 0.115072 -0.015742 --0.0918654 0.131039 0.0272344 --0.0646035 0.156332 -0.00986181 -0.0383993 0.0413521 -0.00190432 --0.026722 0.0386646 -0.0162927 --0.0736148 0.0995067 0.0387799 -0.006499 0.119638 0.036869 -0.0405971 0.101404 0.0241737 --0.0944613 0.121476 0.0212834 --0.0105851 0.0337493 -0.0235512 --0.0799934 0.136838 -0.00393652 -0.0529009 0.0462649 0.0122044 --0.0539028 0.11125 -0.0176614 -0.00874316 0.130156 0.0228898 -0.0260633 0.114349 -0.00924148 -0.0113837 0.0449118 -0.0251572 --0.0461015 0.150679 0.0086365 -0.00236523 0.128663 -0.00254763 --0.0158845 0.0910066 -0.0366604 -0.0456174 0.0890068 0.0121612 --0.0634393 0.144588 -0.0113838 -0.0175304 0.120577 0.0333463 --0.0256229 0.0463679 -0.0270847 --0.0606463 0.0343588 0.0329219 --0.0622926 0.149098 -0.0115749 --0.0266239 0.0463597 -0.0270834 -0.0142234 0.0864184 -0.0301272 --0.0242795 0.0383175 -0.000652306 --0.0599506 0.0340585 0.0228145 --0.031899 0.0595768 -0.0154053 -0.0335035 0.0686838 0.0396083 --0.00350655 0.105885 0.0441283 --0.00849376 0.0576353 0.0542501 --0.0596861 0.0693591 -0.0143393 --0.0246408 0.0382637 -0.00251941 -0.0142384 0.0723592 -0.0308856 -0.0360996 0.112682 0.0101589 -0.00650478 0.0989998 0.0481043 --0.0406764 0.0344836 0.0353061 -0.0208126 0.114503 -0.0133998 --0.0664042 0.0385079 0.0306689 --0.00851871 0.0471234 0.047663 --0.0607941 0.143953 0.0367655 --0.0469959 0.06153 0.0374819 --0.0566078 0.0521283 0.00668717 --0.0117953 0.0827249 -0.0387188 --0.0651684 0.0346977 0.0334093 -0.0334291 0.0781951 0.0413414 --0.00319773 0.0384234 0.00715593 --0.0255204 0.115294 0.0339151 --0.070852 0.100833 -0.0142398 --0.0647775 0.0824087 -0.0188685 -0.0351918 0.0673501 0.0385292 --0.0201767 0.0929008 -0.0346271 --0.0292631 0.0351386 0.0510616 --0.0487306 0.0345868 0.0335095 --0.0909618 0.13376 0.0242167 --0.0399614 0.0343338 -0.0130933 -0.0409886 0.0643095 0.0292691 --0.0656099 0.0655077 0.0295065 diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index 3e7e9369..d66954d7 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -40,9 +40,9 @@ if(TARGET Boost::program_options) target_link_libraries(persistence_from_file ${TBB_LIBRARIES}) endif() add_test(NAME Persistent_cohomology_example_from_file_3_2_0 COMMAND $ - "${CMAKE_SOURCE_DIR}/data/filtered_simplicial_complex/bunny_5000_complex.fsc" "-p" "2" "-m" "0") + "${CMAKE_SOURCE_DIR}/data/filtered_simplicial_complex/Klein_bottle_complex.fsc" "-p" "2" "-m" "0") add_test(NAME Persistent_cohomology_example_from_file_3_3_100 COMMAND $ - "${CMAKE_SOURCE_DIR}/data/filtered_simplicial_complex/bunny_5000_complex.fsc" "-p" "3" "-m" "100") + "${CMAKE_SOURCE_DIR}/data/filtered_simplicial_complex/Klein_bottle_complex.fsc" "-p" "3" "-m" "100") endif() if(GMP_FOUND) diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index 73b2c6f9..81d352fc 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -29,7 +29,7 @@ if(GMP_FOUND AND NOT CGAL_VERSION VERSION_LESS 4.11.0) target_link_libraries(Simplex_tree_example_alpha_shapes_3_from_off ${TBB_LIBRARIES}) endif() add_test(NAME Simplex_tree_example_alpha_shapes_3_from_off COMMAND $ - "${CMAKE_SOURCE_DIR}/data/points/bunny_5000.off") + "${CMAKE_SOURCE_DIR}/data/points/tore3D_1307.off") endif() -- 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 From fe75d33d715d038e348b7e48512b14c7488ee4f4 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Tue, 9 Nov 2021 16:08:10 +0100 Subject: Remove sphinx warnings for torus --- src/python/doc/datasets_generators.rst | 2 +- src/python/gudhi/datasets/generators/_points.cc | 13 +++---------- src/python/gudhi/datasets/generators/points.py | 5 +---- 3 files changed, 5 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/python/doc/datasets_generators.rst b/src/python/doc/datasets_generators.rst index 6f36bce1..260c3882 100644 --- a/src/python/doc/datasets_generators.rst +++ b/src/python/doc/datasets_generators.rst @@ -42,7 +42,7 @@ Example .. autofunction:: gudhi.datasets.generators.points.sphere Points on a flat torus -^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^ You can also generate points on a torus. diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 70ce4925..6baed673 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -85,9 +85,7 @@ PYBIND11_MODULE(_points, m) { m.def("sphere", &generate_points_on_sphere, py::arg("n_samples"), py::arg("ambient_dim"), py::arg("radius") = 1., py::arg("sample") = "random", - R"pbdoc( - Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d - + R"pbdoc( Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d :param n_samples: The number of points to be generated. :type n_samples: integer :param ambient_dim: The ambient dimension d. @@ -102,19 +100,14 @@ PYBIND11_MODULE(_points, m) { 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 or as a grid - + R"pbdoc( 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 :param dim: The dimension of the torus on which points would be generated in R^2*dim. :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. - 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), where shape[0] is rounded down to the closest perfect 'dim'th power. + :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), 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 cf97777d..481f3f71 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -41,10 +41,7 @@ def torus(n_samples, dim, sample='random'): :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' : (⌊n_samples**(1./dim)⌋**dim, 2*dim), where shape[0] is rounded down to the closest perfect 'dim'th power. + :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': (⌊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 -- cgit v1.2.3 From d88e125fe3b4e1dd0c95c95c5bc715b1a2f28ce6 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 15 Nov 2021 14:53:39 +0100 Subject: Disable test of dtm warnings until next version of pykeops is released (cf. issue #543) --- src/python/test/test_dtm.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/python/test/test_dtm.py b/src/python/test/test_dtm.py index c29471cf..bdf003a3 100755 --- a/src/python/test/test_dtm.py +++ b/src/python/test/test_dtm.py @@ -13,7 +13,7 @@ import numpy import pytest import torch import math -import warnings +#import warnings # used in test_dtm_overflow_warnings def test_dtm_compare_euclidean(): @@ -89,15 +89,16 @@ def test_density(): 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"] +# TODO Uncomment this test when next version of pykeops (current is 1.5) is released (should fix the problem (cf. issue #543)) +#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) + #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 4e4a300ac9d914fa1350ca9b920ec2cc09bfd244 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 15 Nov 2021 15:52:01 +0100 Subject: Keep dtm warnings test for "hnsw" --- src/python/test/test_dtm.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/python/test/test_dtm.py b/src/python/test/test_dtm.py index bdf003a3..09876496 100755 --- a/src/python/test/test_dtm.py +++ b/src/python/test/test_dtm.py @@ -13,7 +13,7 @@ import numpy import pytest import torch import math -#import warnings # used in test_dtm_overflow_warnings +import warnings def test_dtm_compare_euclidean(): @@ -89,16 +89,13 @@ def test_density(): density = DTMDensity(weights=[0.5, 0.5], metric="neighbors", dim=1).fit_transform(distances) assert density == pytest.approx(expected) -# TODO Uncomment this test when next version of pykeops (current is 1.5) is released (should fix the problem (cf. issue #543)) -#def test_dtm_overflow_warnings(): - #pts = numpy.array([[10., 100000000000000000000000000000.], [1000., 100000000000000000000000000.]]) - #impl_warn = ["keops", "hnsw"] +def test_dtm_overflow_warnings(): + pts = numpy.array([[10., 100000000000000000000000000000.], [1000., 100000000000000000000000000.]]) - #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) + with warnings.catch_warnings(record=True) as w: + # TODO Test "keops" implementation as well when next version of pykeops (current is 1.5) is released (should fix the problem (cf. issue #543)) + dtm = DistanceToMeasure(2, q=10000, implementation="hnsw") + r = dtm.fit_transform(pts) + assert len(w) == 1 + assert issubclass(w[0].category, RuntimeWarning) + assert "Overflow" in str(w[0].message) -- cgit v1.2.3 From 6c2c1f60b40e4085519de2316198c8e1e14bf49d Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 15 Nov 2021 16:26:35 +0100 Subject: Remove irrelevant q in test_dtm_overflow_warnings --- src/python/test/test_dtm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/python/test/test_dtm.py b/src/python/test/test_dtm.py index 09876496..e46d616c 100755 --- a/src/python/test/test_dtm.py +++ b/src/python/test/test_dtm.py @@ -94,7 +94,7 @@ def test_dtm_overflow_warnings(): with warnings.catch_warnings(record=True) as w: # TODO Test "keops" implementation as well when next version of pykeops (current is 1.5) is released (should fix the problem (cf. issue #543)) - dtm = DistanceToMeasure(2, q=10000, implementation="hnsw") + dtm = DistanceToMeasure(2, implementation="hnsw") r = dtm.fit_transform(pts) assert len(w) == 1 assert issubclass(w[0].category, RuntimeWarning) -- cgit v1.2.3 From dac3b045c38ace5085049d1caac9cc4bf174229a Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 30 Nov 2021 17:33:29 +0100 Subject: Fix this boost deprecated include --- src/common/include/gudhi/reader_utils.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h index 0938f5c1..a1b104e2 100644 --- a/src/common/include/gudhi/reader_utils.h +++ b/src/common/include/gudhi/reader_utils.h @@ -14,7 +14,11 @@ #include #include -#include +#if BOOST_VERSION < 106600 +# include +#else +# include +#endif #include #include -- cgit v1.2.3 From b1a635c72d3e287c012212a491da07357b0c6136 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Fri, 3 Dec 2021 16:17:53 +0100 Subject: Indent properly the docstring Remove redundant return type --- src/python/gudhi/datasets/generators/_points.cc | 16 ++++++++++++---- src/python/gudhi/datasets/generators/points.py | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc index 6baed673..82fea25b 100644 --- a/src/python/gudhi/datasets/generators/_points.cc +++ b/src/python/gudhi/datasets/generators/_points.cc @@ -85,7 +85,9 @@ PYBIND11_MODULE(_points, m) { m.def("sphere", &generate_points_on_sphere, py::arg("n_samples"), py::arg("ambient_dim"), py::arg("radius") = 1., py::arg("sample") = "random", - R"pbdoc( Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d + R"pbdoc( + Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d + :param n_samples: The number of points to be generated. :type n_samples: integer :param ambient_dim: The ambient dimension d. @@ -94,20 +96,26 @@ PYBIND11_MODULE(_points, m) { :type radius: float :param sample: The sample type. Default and only available value is `"random"`. :type sample: string - :rtype: numpy array of float :returns: the generated points on a sphere. )pbdoc"); 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 or as a grid + R"pbdoc( + 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 :param dim: The dimension of the torus on which points would be generated in R^2*dim. :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. 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), where shape[0] is rounded down to the closest perfect 'dim'th power. :returns: 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': (⌊n_samples**(1./dim)⌋**dim, 2*dim), where shape[0] is rounded down to the closest perfect 'dim'th power. )pbdoc"); } diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py index 481f3f71..9bb2799d 100644 --- a/src/python/gudhi/datasets/generators/points.py +++ b/src/python/gudhi/datasets/generators/points.py @@ -19,15 +19,15 @@ def _generate_random_points_on_torus(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_on_torus(n_samples, dim): - + # Generate points on a dim-torus as a grid 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 = 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))): @@ -35,13 +35,19 @@ def _generate_grid_points_on_torus(n_samples, dim): return array_points[array_points_idx].reshape(-1, 2*dim) def torus(n_samples, dim, sample='random'): - """ + """ 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: If sample is 'random': (n_samples, 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: 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': (⌊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 -- cgit v1.2.3 From 971316e7a565f92954397f420a64a073155e41f5 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Mon, 13 Dec 2021 11:06:12 +0100 Subject: Fix benchmarks compilation errors in debug mode --- src/Toplex_map/benchmark/CMakeLists.txt | 4 ++++ src/common/benchmark/CMakeLists.txt | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/Toplex_map/benchmark/CMakeLists.txt b/src/Toplex_map/benchmark/CMakeLists.txt index 2d58a156..6703d9d0 100644 --- a/src/Toplex_map/benchmark/CMakeLists.txt +++ b/src/Toplex_map/benchmark/CMakeLists.txt @@ -1,3 +1,7 @@ project(Toplex_map_benchmark) add_executable(Toplex_map_benchmark benchmark_tm.cpp) + +if (TBB_FOUND) + target_link_libraries(Toplex_map_benchmark ${TBB_LIBRARIES}) +endif() diff --git a/src/common/benchmark/CMakeLists.txt b/src/common/benchmark/CMakeLists.txt index a3787d6e..26e4e6af 100644 --- a/src/common/benchmark/CMakeLists.txt +++ b/src/common/benchmark/CMakeLists.txt @@ -1,3 +1,7 @@ project(common_benchmark) add_executable(Graph_simplicial_complex_benchmark Graph_simplicial_complex_benchmark.cpp) + +if (TBB_FOUND) + target_link_libraries(Graph_simplicial_complex_benchmark ${TBB_LIBRARIES}) +endif() -- cgit v1.2.3 From a2b5e8afab53835ef442451c6763c103f02ac4f5 Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 15 Dec 2021 11:36:05 +0100 Subject: Fix failing tests in debug mode --- .../include/gudhi/Persistent_cohomology/Field_Zp.h | 2 -- src/python/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h index 8ec89e41..f442b632 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Field_Zp.h @@ -34,8 +34,6 @@ class Field_Zp { } void init(int charac) { - assert(charac > 0); // division by zero + non negative values - Prime = charac; // Check that the provided prime is less than the maximum allowed as int, calculation below, and 'plus_times_equal' function : 46337 ; i.e (max_prime-1)*max_prime <= INT_MAX diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 4a017251..1faaf50d 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -243,7 +243,7 @@ if(PYTHONINTERP_FOUND) if (TBB_FOUND AND WITH_GUDHI_USE_TBB) add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") - if(CMAKE_BUILD_TYPE MATCHES Debug) + if((CMAKE_BUILD_TYPE MATCHES Debug) AND TBB_DEBUG_LIBRARY) add_GUDHI_PYTHON_lib("${TBB_DEBUG_LIBRARY}") add_GUDHI_PYTHON_lib("${TBB_MALLOC_DEBUG_LIBRARY}") else() -- cgit v1.2.3 From c6a7f0258406542b0c2b10bb6b2878f27b13394b Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau <10407034+VincentRouvreau@users.noreply.github.com> Date: Fri, 17 Dec 2021 10:15:18 +0100 Subject: Use vs 2019 for appveyor as well as python 3.9 (#534) * Visual studio 2019 (instead of 2017) * Let vcpkg install cgal manage its dependencies (boost, mpfr and gmp) * vcpkg install tbb also * need to vcpkg integrate install * pip installations are no more in --user mode * Modify all / to \ for windows pths * Compile python module --inplace, and copy required dll inside gudhi directory (add dll path to windows PATH is not enough) * Cmake add_GUDHI_PYTHON_lib_dir was not multi-path proof (happens in windows with release_path;debug_path mechanism) * With CGAL >= 5.3.0, CGAL_HEADER_ONLY CMake variable is no more set as it is the default mode * GUDHI_PYTHON_PATH_ENV Cmake variable requires ; as path separator on windows, and : otherwise --- .appveyor.yml | 52 ++++++++++++++++++++++++++++------------------- src/python/CMakeLists.txt | 40 +++++++++++++++++++++++------------- 2 files changed, 57 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/.appveyor.yml b/.appveyor.yml index 9ff8f157..d5e35780 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,5 +1,5 @@ image: - - Visual Studio 2017 + - Visual Studio 2019 build: parallel: true @@ -10,11 +10,10 @@ configuration: environment: # update the vcpkg cache even if build fails - APPVEYOR_SAVE_CACHE_ON_ERROR: true - PYTHON: "C:\\Python37-x64" - CMAKE_GMP_FLAGS: -DGMP_INCLUDE_DIR="c:/Tools/vcpkg/installed/x64-windows/include" -DGMP_LIBRARIES="c:/Tools/vcpkg/installed/x64-windows/lib/mpir.lib" - CMAKE_MPFR_FLAGS: -DMPFR_INCLUDE_DIR="c:/Tools/vcpkg/installed/x64-windows/include" -DMPFR_LIBRARIES="c:/Tools/vcpkg/installed/x64-windows/lib/mpfr.lib" - CMAKE_VCPKG_FLAGS: -DCMAKE_TOOLCHAIN_FILE=c:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake + #APPVEYOR_SAVE_CACHE_ON_ERROR: true + PYTHON: "C:\\Python39-x64" + PYTHONPATH: "C:\\Python39-x64\\lib\\site-packages" + CMAKE_VCPKG_FLAGS: -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_TOOLCHAIN_FILE=c:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake matrix: - target: Examples @@ -30,38 +29,49 @@ environment: CMAKE_FLAGS: -DWITH_GUDHI_EXAMPLE=OFF -DWITH_GUDHI_TEST=OFF -DWITH_GUDHI_UTILITIES=OFF -DWITH_GUDHI_PYTHON=ON -cache: - - c:\Tools\vcpkg\installed - - '%LOCALAPPDATA%\pip\Cache' +#cache: +# - c:\Tools\vcpkg\installed +# - '%LOCALAPPDATA%\pip\Cache' init: - echo %target% -# tbb:x64-windows install: - git submodule update --init - - vcpkg install boost-disjoint-sets:x64-windows boost-serialization:x64-windows boost-date-time:x64-windows boost-system:x64-windows boost-filesystem:x64-windows boost-units:x64-windows boost-thread:x64-windows boost-program-options:x64-windows eigen3:x64-windows mpfr:x64-windows mpir:x64-windows cgal:x64-windows - - SET PATH=c:\Tools\vcpkg\installed\x64-windows\bin;%PATH% - - SET PATH=%PYTHON%;%PYTHON%\Scripts;%PYTHON%\Library\bin;%PATH% - - SET PYTHONPATH=%PYTHON%\\Lib\\site-packages;%PYTHONPATH% - - CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 + - vcpkg install boost-filesystem:x64-windows boost-test:x64-windows boost-program-options:x64-windows tbb:x64-windows eigen3:x64-windows cgal:x64-windows + - dir "C:\Tools\vcpkg\installed\x64-windows\bin\" + - vcpkg integrate install + - CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 + - "set PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - python --version - pip --version - - python -m pip install --user --upgrade pip - - python -m pip install --user -r ext/gudhi-deploy/build-requirements.txt + - python -m pip install --upgrade pip + - python -m pip install --upgrade setuptools + - python -m pip install -r ext\gudhi-deploy\build-requirements.txt # No PyKeOps on windows, let's workaround this one. - - for /F "tokens=*" %%A in (ext/gudhi-deploy/test-requirements.txt) do python -m pip install --user %%A + - for /F "tokens=*" %%A in (ext\gudhi-deploy\test-requirements.txt) do python -m pip install %%A + - dir "c:\python39-x64\lib\site-packages" + - dir "%LOCALAPPDATA%\pip\Cache" + - python -c "from scipy import spatial; print(spatial.cKDTree)" build_script: - mkdir build - cd build - - cmake -G "Visual Studio 15 2017 Win64" %CMAKE_FLAGS% %CMAKE_GMP_FLAGS% %CMAKE_MPFR_FLAGS% %CMAKE_VCPKG_FLAGS% .. + - cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release %CMAKE_FLAGS% %CMAKE_VCPKG_FLAGS% .. - if [%target%]==[Python] ( - cd src/python & + cd src\python & + dir . & type setup.py & - MSBuild Cython.sln /m /p:Configuration=Release /p:Platform=x64 & + copy "C:\Tools\vcpkg\installed\x64-windows\bin\mpfr-6.dll" ".\gudhi\" & + copy "C:\Tools\vcpkg\installed\x64-windows\bin\gmp.dll" ".\gudhi\" & + copy "C:\Tools\vcpkg\installed\x64-windows\bin\tbb.dll" ".\gudhi\" & + copy "C:\Tools\vcpkg\installed\x64-windows\bin\tbbmalloc.dll" ".\gudhi\" & + python setup.py build_ext --inplace & + SET PYTHONPATH=%CD%;%PYTHONPATH% & + echo %PYTHONPATH% & ctest -j 1 --output-on-failure -C Release ) else ( + dir . & MSBuild GUDHIdev.sln /m /p:Configuration=Release /p:Platform=x64 & ctest -j 1 --output-on-failure -C Release -E diff_files ) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 4a017251..0603ba71 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -14,13 +14,16 @@ function( add_GUDHI_PYTHON_lib THE_LIB ) endif(EXISTS ${THE_LIB}) endfunction( add_GUDHI_PYTHON_lib ) -function( add_GUDHI_PYTHON_lib_dir THE_LIB_DIR ) - # deals when it is not set - error on windows - if(EXISTS ${THE_LIB_DIR}) - set(GUDHI_PYTHON_LIBRARY_DIRS "${GUDHI_PYTHON_LIBRARY_DIRS}'${THE_LIB_DIR}', " PARENT_SCOPE) - else() - message("add_GUDHI_PYTHON_lib_dir - '${THE_LIB_DIR}' does not exist") - endif() +function( add_GUDHI_PYTHON_lib_dir) + # Argument may be a list (specifically on windows with release/debug paths) + foreach(THE_LIB_DIR IN LISTS ARGN) + # deals when it is not set - error on windows + if(EXISTS ${THE_LIB_DIR}) + set(GUDHI_PYTHON_LIBRARY_DIRS "${GUDHI_PYTHON_LIBRARY_DIRS}'${THE_LIB_DIR}', " PARENT_SCOPE) + else() + message("add_GUDHI_PYTHON_lib_dir - '${THE_LIB_DIR}' does not exist") + endif() + endforeach() endfunction( add_GUDHI_PYTHON_lib_dir ) # THE_TEST is the python test file name (without .py extension) containing tests functions @@ -176,6 +179,10 @@ if(PYTHONINTERP_FOUND) endif () if(CGAL_FOUND) + if(NOT CGAL_VERSION VERSION_LESS 5.3.0) + # CGAL_HEADER_ONLY has been dropped for CGAL >= 5.3. Only the header-only version is supported. + set(CGAL_HEADER_ONLY True) + endif(NOT CGAL_VERSION VERSION_LESS 5.3.0) # Add CGAL compilation args if(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL header only version ${CGAL_VERSION}") @@ -183,7 +190,7 @@ if(PYTHONINTERP_FOUND) else(CGAL_HEADER_ONLY) add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") add_GUDHI_PYTHON_lib("${CGAL_LIBRARY}") - add_GUDHI_PYTHON_lib_dir("${CGAL_LIBRARIES_DIR}") + add_GUDHI_PYTHON_lib_dir(${CGAL_LIBRARIES_DIR}) message("** Add CGAL ${CGAL_LIBRARIES_DIR}") # If CGAL is not header only, CGAL library may link with boost system, if(CMAKE_BUILD_TYPE MATCHES Debug) @@ -191,7 +198,7 @@ if(PYTHONINTERP_FOUND) else() add_GUDHI_PYTHON_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") endif() - add_GUDHI_PYTHON_lib_dir("${Boost_LIBRARY_DIRS}") + add_GUDHI_PYTHON_lib_dir(${Boost_LIBRARY_DIRS}) message("** Add Boost ${Boost_LIBRARY_DIRS}") endif(CGAL_HEADER_ONLY) # GMP and GMPXX are not required, but if present, CGAL will link with them. @@ -203,13 +210,13 @@ if(PYTHONINTERP_FOUND) get_filename_component(GMP_LIBRARIES_DIR ${GMP_LIBRARIES} PATH) message("GMP_LIBRARIES_DIR from GMP_LIBRARIES set to ${GMP_LIBRARIES_DIR}") endif(NOT GMP_LIBRARIES_DIR) - add_GUDHI_PYTHON_lib_dir("${GMP_LIBRARIES_DIR}") + add_GUDHI_PYTHON_lib_dir(${GMP_LIBRARIES_DIR}) message("** Add gmp ${GMP_LIBRARIES_DIR}") if(GMPXX_FOUND) add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") add_GUDHI_PYTHON_lib("${GMPXX_LIBRARIES}") - add_GUDHI_PYTHON_lib_dir("${GMPXX_LIBRARIES_DIR}") + add_GUDHI_PYTHON_lib_dir(${GMPXX_LIBRARIES_DIR}) message("** Add gmpxx ${GMPXX_LIBRARIES_DIR}") endif(GMPXX_FOUND) endif(GMP_FOUND) @@ -222,7 +229,7 @@ if(PYTHONINTERP_FOUND) get_filename_component(MPFR_LIBRARIES_DIR ${MPFR_LIBRARIES} PATH) message("MPFR_LIBRARIES_DIR from MPFR_LIBRARIES set to ${MPFR_LIBRARIES_DIR}") endif(NOT MPFR_LIBRARIES_DIR) - add_GUDHI_PYTHON_lib_dir("${MPFR_LIBRARIES_DIR}") + add_GUDHI_PYTHON_lib_dir(${MPFR_LIBRARIES_DIR}) message("** Add mpfr ${MPFR_LIBRARIES_DIR}") endif(MPFR_FOUND) endif(CGAL_FOUND) @@ -250,7 +257,7 @@ if(PYTHONINTERP_FOUND) add_GUDHI_PYTHON_lib("${TBB_RELEASE_LIBRARY}") add_GUDHI_PYTHON_lib("${TBB_MALLOC_RELEASE_LIBRARY}") endif() - add_GUDHI_PYTHON_lib_dir("${TBB_LIBRARY_DIRS}") + add_GUDHI_PYTHON_lib_dir(${TBB_LIBRARY_DIRS}) message("** Add tbb ${TBB_LIBRARY_DIRS}") set(GUDHI_PYTHON_INCLUDE_DIRS "${GUDHI_PYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") endif() @@ -290,7 +297,12 @@ if(PYTHONINTERP_FOUND) add_custom_target(python ALL DEPENDS gudhi.so COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") - set(GUDHI_PYTHON_PATH_ENV "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:$ENV{PYTHONPATH}") + # Path separator management for windows + if (WIN32) + set(GUDHI_PYTHON_PATH_ENV "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR};$ENV{PYTHONPATH}") + else(WIN32) + set(GUDHI_PYTHON_PATH_ENV "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:$ENV{PYTHONPATH}") + endif(WIN32) # Documentation generation is available through sphinx - requires all modules # Make it first as sphinx test is by far the longest test which is nice when testing in parallel if(SPHINX_PATH) -- cgit v1.2.3 From a6019b584f64d63bfd6613104dd4388882c545ac Mon Sep 17 00:00:00 2001 From: Hind-M Date: Wed, 29 Dec 2021 16:33:16 +0100 Subject: Fix bad gudhi_check in Cech benchmark --- src/Cech_complex/benchmark/cech_complex_benchmark.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Cech_complex/benchmark/cech_complex_benchmark.cpp b/src/Cech_complex/benchmark/cech_complex_benchmark.cpp index e489e8a4..2e4adce4 100644 --- a/src/Cech_complex/benchmark/cech_complex_benchmark.cpp +++ b/src/Cech_complex/benchmark/cech_complex_benchmark.cpp @@ -49,7 +49,7 @@ class Minimal_enclosing_ball_radius { point_cloud.push_back(p1); point_cloud.push_back(p2); - GUDHI_CHECK((p1.end() - p1.begin()) != (p2.end() - p2.begin()), "inconsistent point dimensions"); + GUDHI_CHECK((p1.end() - p1.begin()) == (p2.end() - p2.begin()), "inconsistent point dimensions"); Min_sphere min_sphere(p1.end() - p1.begin(), point_cloud.begin(), point_cloud.end()); return std::sqrt(min_sphere.squared_radius()); -- cgit v1.2.3 From 2e23ea38409b747b5f05e7400b4eba38608b3f02 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Tue, 4 Jan 2022 22:24:19 +0100 Subject: width in cm is not working for doxygen --- src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h index 653a63fd..0fd56c67 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h @@ -52,8 +52,7 @@ when \f$ \tau \neq \sigma\f$ we say that \f$ \tau\f$ is a proper-face of \f$ \si An abstract simplicial complex is a set of simplices that contains all the faces of its simplices. The 1-skeleton of a simplicial complex (or its graph) consists of its elements of dimension lower than 2. - *\image html "ds_representation.png" "Skeleton-blocker representation" width=20cm - +\image html "ds_representation.png" "Skeleton-blocker representation" To encode, a simplicial complex, one can encodes all its simplices. In case when this number gets too large, @@ -73,11 +72,7 @@ For instance, the numbers of blockers is depicted for random 3-dimensional spher in next figure. Storing the graph and blockers of such simplicial complexes is much compact in this case than storing their simplices. - - *\image html "blockers_curve.png" "Number of blockers of random triangulations of 3-spheres" width=10cm - - - +\image html "blockers_curve.png" "Number of blockers of random triangulations of 3-spheres" \section API -- cgit v1.2.3 From 01adfb0b0eb8124adc18d9bb5cd97aa83b74eeb5 Mon Sep 17 00:00:00 2001 From: Vincent Rouvreau Date: Wed, 12 Jan 2022 09:08:27 +0100 Subject: Fix #567 --- src/cmake/modules/GUDHI_third_party_libraries.cmake | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index 023061f1..21c9d47b 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -6,6 +6,7 @@ find_package(Boost 1.56.0 QUIET OPTIONAL_COMPONENTS filesystem unit_test_framewo if(NOT Boost_VERSION) message(FATAL_ERROR "NOTICE: This program requires Boost and will not be compiled.") endif(NOT Boost_VERSION) +include_directories(${Boost_INCLUDE_DIRS}) find_package(GMP) if(GMP_FOUND) -- cgit v1.2.3