summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-01-12 16:07:10 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2016-01-12 16:07:10 +0000
commit11b195d4e26d48cdc56883957cbad16e298e43ca (patch)
tree0cbe94cf64b53ed9a84050689db0811795fdba51 /src
parentf9b5b9b3306f3f00f5bfa2724cbfa087d5161fcb (diff)
Fix alpha complex remarks and bugs
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/alphashapes@957 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fa837fd1a4373c2322db16353d98767907f34c79
Diffstat (limited to 'src')
-rw-r--r--src/Alpha_complex/test/CMakeLists.txt2
-rw-r--r--src/GudhUI/alpha_complex_persistence.cpp78
-rw-r--r--src/GudhUI/utils/Bar_code_persistence.h3
-rw-r--r--src/GudhUI/utils/Persistence_compute.h15
-rw-r--r--src/Persistent_cohomology/example/CMakeLists.txt100
-rw-r--r--src/Persistent_cohomology/example/alpha_complex_persistence.cpp92
-rw-r--r--src/Persistent_cohomology/example/rips_persistence.cpp3
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree.h81
-rw-r--r--src/Simplex_tree/test/simplex_tree_unit_test.cpp56
-rw-r--r--src/common/include/gudhi/distance_functions.h4
-rw-r--r--src/common/include/gudhi/reader_utils.h4
11 files changed, 191 insertions, 247 deletions
diff --git a/src/Alpha_complex/test/CMakeLists.txt b/src/Alpha_complex/test/CMakeLists.txt
index d7c13da0..fa24e1b1 100644
--- a/src/Alpha_complex/test/CMakeLists.txt
+++ b/src/Alpha_complex/test/CMakeLists.txt
@@ -18,8 +18,6 @@ if(CGAL_FOUND)
add_executable ( AlphaComplexUT Alpha_complex_unit_test.cpp )
target_link_libraries(AlphaComplexUT ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
- add_executable ( cerr cerr.cpp )
-
# Do not forget to copy test files in current binary dir
file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
diff --git a/src/GudhUI/alpha_complex_persistence.cpp b/src/GudhUI/alpha_complex_persistence.cpp
deleted file mode 100644
index 4f85459a..00000000
--- a/src/GudhUI/alpha_complex_persistence.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <iostream>
-#include <string>
-
-
-#include <QtGui/QApplication>
-
-// to construct a Delaunay_triangulation from a OFF file
-#include <gudhi/Delaunay_triangulation_off_io.h>
-#include <gudhi/Alpha_complex.h>
-#include <gudhi/Persistent_cohomology.h>
-
-#include "utils/Bar_code_persistence.h"
-
-void usage(char * const progName) {
- std::cerr << "Usage: " << progName << " filename.off " << // alpha_square_max_value[double] " <<
- "coeff_field_characteristic[integer > 0] min_persistence[double >= -1.0]" << std::endl;
- std::cerr << " i.e.: " << progName << " ../../data/points/alphacomplexdoc.off 60.0 2 0.02" << std::endl;
- exit(-1); // ----- >>
-}
-
-int main(int argc, char **argv) {
- if (argc != 4) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
- usage(argv[0]);
- }
-
- QApplication qtapp(argc, argv);
-
- std::string off_file_name(argv[1]);
- // double alpha_square_max_value = atof(argv[2]);
- double alpha_square_max_value = 1e20;
- int coeff_field_characteristic = atoi(argv[2]); // argv[3]
- double min_persistence = atof(argv[3]); // argv[4]
-
- // ----------------------------------------------------------------------------
- // Init of an alpha complex from an OFF file
- // ----------------------------------------------------------------------------
- typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
- Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_name, alpha_square_max_value);
-
- // ----------------------------------------------------------------------------
- // Display information about the alpha complex
- // ----------------------------------------------------------------------------
- std::cout << "Alpha complex is of dimension " << alpha_complex_from_file.dimension() <<
- " - " << alpha_complex_from_file.num_simplices() << " simplices - " <<
- alpha_complex_from_file.num_vertices() << " vertices." << std::endl;
-
- // Sort the simplices in the order of the filtration
- alpha_complex_from_file.initialize_filtration();
-
- std::cout << "Simplex_tree dim: " << alpha_complex_from_file.dimension() << std::endl;
- // Compute the persistence diagram of the complex
- Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::alphacomplex::Alpha_complex<Kernel>,
- Gudhi::persistent_cohomology::Field_Zp > pcoh(alpha_complex_from_file);
-
- std::cout << "coeff_field_characteristic " << coeff_field_characteristic <<
- " - min_persistence " << min_persistence << std::endl;
-
- // initializes the coefficient field for homology
- pcoh.init_coefficients(coeff_field_characteristic);
-
- pcoh.compute_persistent_cohomology(min_persistence);
-
- pcoh.output_diagram();
-
- std::vector<std::pair<double, double>> persistence_vector;
- pcoh.get_persistence(persistence_vector);
-
- Bar_code_persistence bc_persistence;
-
- for (auto persistence : persistence_vector) {
- bc_persistence.insert(persistence.first, persistence.second);
- }
-
- bc_persistence.show();
-
- return qtapp.exec();
-}
diff --git a/src/GudhUI/utils/Bar_code_persistence.h b/src/GudhUI/utils/Bar_code_persistence.h
index a1a46ea8..a4cd8156 100644
--- a/src/GudhUI/utils/Bar_code_persistence.h
+++ b/src/GudhUI/utils/Bar_code_persistence.h
@@ -39,7 +39,7 @@ class Bar_code_persistence {
max_death = death;
}
- void show() {
+ void show(const std::string& window_title) {
// Create a view, put a scene in it
QGraphicsView * view = new QGraphicsView();
QGraphicsScene * scene = new QGraphicsScene();
@@ -78,6 +78,7 @@ class Bar_code_persistence {
QGraphicsTextItem* dimText = scene->addText(scale_value, QFont("Helvetica", 8));
dimText->setPos(scale - (3.0 * scale_value.size()), height + 9.0 * (modulo % 2));
}
+ view->setWindowTitle(window_title.c_str());
// Show the view
view->show();
}
diff --git a/src/GudhUI/utils/Persistence_compute.h b/src/GudhUI/utils/Persistence_compute.h
index 0b9961d3..1f04cc6b 100644
--- a/src/GudhUI/utils/Persistence_compute.h
+++ b/src/GudhUI/utils/Persistence_compute.h
@@ -46,10 +46,6 @@ struct Persistence_params {
* Show persistence into output stream
*/
template<typename SkBlComplex> class Persistence_compute {
- private:
- SkBlComplex& complex_;
- std::ostream& stream_;
-
public:
typedef typename SkBlComplex::Vertex_handle Vertex_handle;
typedef typename SkBlComplex::Edge_handle Edge_handle;
@@ -61,9 +57,7 @@ template<typename SkBlComplex> class Persistence_compute {
* double threshold
* int p for coefficient Z_p
*/
- Persistence_compute(SkBlComplex& complex, std::ostream& stream, const Persistence_params& params) :
- // double threshold = 0.5,unsigned dim_max = 8):
- complex_(complex), stream_(stream) {
+ Persistence_compute(SkBlComplex& complex, std::ostream& stream, const Persistence_params& params) {
// for now everything is copied, todo boost adapt iterators to points of SkBlComplex instead of copying to an
// initial vector
typedef std::vector<double> Point_t;
@@ -87,10 +81,11 @@ template<typename SkBlComplex> class Persistence_compute {
pcoh.init_coefficients(params.p);
// put params.min_pers
pcoh.compute_persistent_cohomology(params.min_pers);
- stream_ << "persistence: \n";
- stream_ << "p dimension birth death: \n";
+ stream << "persistence: \n";
+ stream << "p dimension birth death: \n";
- pcoh.output_diagram(stream_);
+ pcoh.output_diagram(stream);
+
}
};
diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt
index eb4ee3e3..9e96adc0 100644
--- a/src/Persistent_cohomology/example/CMakeLists.txt
+++ b/src/Persistent_cohomology/example/CMakeLists.txt
@@ -22,63 +22,61 @@ add_executable(persistence_from_file persistence_from_file.cpp)
target_link_libraries(persistence_from_file ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
add_test(persistence_from_file_3_2_0 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 2 -m 0)
add_test(persistence_from_file_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/persistence_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
-
-if(GMPXX_FOUND AND GMP_FOUND)
- message("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}")
- message("GMP_LIBRARIES = ${GMP_LIBRARIES}")
-
- add_executable(rips_multifield_persistence rips_multifield_persistence.cpp )
- target_link_libraries(rips_multifield_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
- add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100)
-
- add_executable ( performance_rips_persistence performance_rips_persistence.cpp )
- target_link_libraries(performance_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
-
- if(CGAL_FOUND)
- add_executable(alpha_shapes_persistence alpha_shapes_persistence.cpp)
- target_link_libraries(alpha_shapes_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
- add_test(alpha_shapes_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 2 0.5)
- #add_test(alpha_shapes_persistence_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
-
-
-
- if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
- message(STATUS "CGAL version: ${CGAL_VERSION}.")
-
- include( ${CGAL_USE_FILE} )
- # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten.
- # cf. http://doc.cgal.org/latest/Manual/installation.html#title40
- # A workaround is to add "-std=c++11" again.
- # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
- # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html
- # but it implies to use cmake version 3.1 at least.
- if(NOT MSVC)
- include(CheckCXXCompilerFlag)
- CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
- if(COMPILER_SUPPORTS_CXX11)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+if(GMPXX_FOUND AND GMP_FOUND)
+ message("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}")
+ message("GMP_LIBRARIES = ${GMP_LIBRARIES}")
+
+ add_executable(rips_multifield_persistence rips_multifield_persistence.cpp )
+ target_link_libraries(rips_multifield_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+ add_test(rips_multifield_persistence_2_71 ${CMAKE_CURRENT_BINARY_DIR}/rips_multifield_persistence ${CMAKE_SOURCE_DIR}/data/points/Kl.txt -r 0.25 -d 3 -p 2 -q 71 -m 100)
+
+ add_executable ( performance_rips_persistence performance_rips_persistence.cpp )
+ target_link_libraries(performance_rips_persistence ${Boost_SYSTEM_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES})
+
+ if(CGAL_FOUND)
+ add_executable(alpha_shapes_persistence alpha_shapes_persistence.cpp)
+ target_link_libraries(alpha_shapes_persistence ${Boost_SYSTEM_LIBRARY} ${GMPXX_LIBRARIES} ${GMP_LIBRARIES} ${CGAL_LIBRARY})
+ add_test(alpha_shapes_persistence_2_0_5 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 2 0.5)
+ #add_test(alpha_shapes_persistence_3_3_100 ${CMAKE_CURRENT_BINARY_DIR}/alpha_shapes_persistence ${CMAKE_SOURCE_DIR}/data/points/bunny_5000.st -p 3 -m 100)
+
+ if (NOT CGAL_VERSION VERSION_LESS 4.7.0)
+ message(STATUS "CGAL version: ${CGAL_VERSION}.")
+
+ include( ${CGAL_USE_FILE} )
+ # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten.
+ # cf. http://doc.cgal.org/latest/Manual/installation.html#title40
+ # A workaround is to add "-std=c++11" again.
+ # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
+ # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html
+ # but it implies to use cmake version 3.1 at least.
+ if(NOT MSVC)
+ include(CheckCXXCompilerFlag)
+ CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
+ if(COMPILER_SUPPORTS_CXX11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
endif()
- endif()
- # - End of workaround
+ # - End of workaround
- find_package(Eigen3 3.1.0)
- if (EIGEN3_FOUND)
- message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
- include( ${EIGEN3_USE_FILE} )
+ find_package(Eigen3 3.1.0)
+ if (EIGEN3_FOUND)
+ message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.")
+ include( ${EIGEN3_USE_FILE} )
- add_executable (alphacomplexpersistence alpha_complex_persistence.cpp)
- target_link_libraries(alphacomplexpersistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY})
+ add_executable (alpha_complex_persistence alpha_complex_persistence.cpp)
+ target_link_libraries(alpha_complex_persistence ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
+ else()
+ message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.")
+ endif()
else()
- message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.")
- endif()
+ message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.")
+ endif ()
else()
- message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.")
- endif ()
-
-
-
- endif()
+ # message(WARNING "CGAL not found.")
+ endif()
+else()
+ # message(WARNING "GMP not found.")
endif()
diff --git a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
index fbadf673..0dabdeac 100644
--- a/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
+++ b/src/Persistent_cohomology/example/alpha_complex_persistence.cpp
@@ -1,34 +1,35 @@
#include <iostream>
#include <string>
+#include <boost/program_options.hpp>
+
// to construct a Delaunay_triangulation from a OFF file
#include <gudhi/Delaunay_triangulation_off_io.h>
#include <gudhi/Alpha_complex.h>
#include <gudhi/Persistent_cohomology.h>
-void usage(char * const progName) {
- std::cerr << "Usage: " << progName << " filename.off alpha_square_max_value[double] " <<
- "coeff_field_characteristic[integer > 0] min_persistence[double >= -1.0]" << std::endl;
- std::cerr << " i.e.: " << progName << " ../../data/points/alphacomplexdoc.off 60.0 2 0.02" << std::endl;
- exit(-1); // ----- >>
-}
+void program_options(int argc, char * argv[]
+ , std::string & off_file_points
+ , std::string & output_file_diag
+ , Filtration_value & alpha_square_max_value
+ , int & coeff_field_characteristic
+ , Filtration_value & min_persistence);
int main(int argc, char **argv) {
- if (argc != 5) {
- std::cerr << "Error: Number of arguments (" << argc << ") is not correct" << std::endl;
- usage(argv[0]);
- }
+ std::string off_file_points;
+ std::string output_file_diag;
+ Filtration_value alpha_square_max_value;
+ int coeff_field_characteristic;
+ Filtration_value min_persistence;
+
+ program_options(argc, argv, off_file_points, output_file_diag, alpha_square_max_value, coeff_field_characteristic, min_persistence);
- std::string off_file_name(argv[1]);
- double alpha_square_max_value = atof(argv[2]);
- int coeff_field_characteristic = atoi(argv[3]);
- double min_persistence = atof(argv[4]);
// ----------------------------------------------------------------------------
// Init of an alpha complex from an OFF file
// ----------------------------------------------------------------------------
typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kernel;
- Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_name, alpha_square_max_value);
+ Gudhi::alphacomplex::Alpha_complex<Kernel> alpha_complex_from_file(off_file_points, alpha_square_max_value);
// ----------------------------------------------------------------------------
// Display information about the alpha complex
@@ -49,7 +50,66 @@ int main(int argc, char **argv) {
pcoh.compute_persistent_cohomology(min_persistence);
- pcoh.output_diagram();
+ // Output the diagram in filediag
+ if (output_file_diag.empty()) {
+ pcoh.output_diagram();
+ } else {
+ std::cout << "Result in file: " << output_file_diag << std::endl;
+ std::ofstream out(output_file_diag);
+ pcoh.output_diagram(out);
+ out.close();
+ }
return 0;
}
+
+void program_options(int argc, char * argv[]
+ , std::string & off_file_points
+ , std::string & output_file_diag
+ , Filtration_value & alpha_square_max_value
+ , int & coeff_field_characteristic
+ , Filtration_value & min_persistence) {
+ namespace po = boost::program_options;
+ po::options_description hidden("Hidden options");
+ hidden.add_options()
+ ("input-file", po::value<std::string>(&off_file_points),
+ "Name of file containing a point set. Format is one point per line: X1 ... Xd ");
+
+ po::options_description visible("Allowed options", 100);
+ visible.add_options()
+ ("help,h", "produce help message")
+ ("output-file,o", po::value<std::string>(&output_file_diag)->default_value(std::string()),
+ "Name of file in which the persistence diagram is written. Default print in std::cout")
+ ("max-alpha-square-value,r", po::value<Filtration_value>(&alpha_square_max_value)->default_value(std::numeric_limits<Filtration_value>::infinity()),
+ "Maximal alpha square value for the Alpha complex construction.")
+ ("field-charac,p", po::value<int>(&coeff_field_characteristic)->default_value(11),
+ "Characteristic p of the coefficient field Z/pZ for computing homology.")
+ ("min-persistence,m", po::value<Filtration_value>(&min_persistence),
+ "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals");
+
+ po::positional_options_description pos;
+ pos.add("input-file", 1);
+
+ po::options_description all;
+ all.add(visible).add(hidden);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).
+ options(all).positional(pos).run(), vm);
+ po::notify(vm);
+
+ if (vm.count("help") || !vm.count("input-file")) {
+ std::cout << std::endl;
+ std::cout << "Compute the persistent homology with coefficient field Z/pZ \n";
+ std::cout << "of an Alpha complex defined on a set of input points.\n \n";
+ std::cout << "The output diagram contains one bar per line, written with the convention: \n";
+ std::cout << " p dim b d \n";
+ std::cout << "where dim is the dimension of the homological feature,\n";
+ std::cout << "b and d are respectively the birth and death of the feature and \n";
+ std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl;
+
+ std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl;
+ std::cout << visible << std::endl;
+ std::abort();
+ }
+}
diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp
index 9b1ef42f..fa0449a8 100644
--- a/src/Persistent_cohomology/example/rips_persistence.cpp
+++ b/src/Persistent_cohomology/example/rips_persistence.cpp
@@ -30,6 +30,7 @@
#include <string>
#include <vector>
+#include <limits> // infinity
using namespace Gudhi;
using namespace Gudhi::persistent_cohomology;
@@ -114,7 +115,7 @@ void program_options(int argc, char * argv[]
("help,h", "produce help message")
("output-file,o", po::value<std::string>(&filediag)->default_value(std::string()),
"Name of file in which the persistence diagram is written. Default print in std::cout")
- ("max-edge-length,r", po::value<Filtration_value>(&threshold)->default_value(0),
+ ("max-edge-length,r", po::value<Filtration_value>(&threshold)->default_value(std::numeric_limits<Filtration_value>::infinity()),
"Maximal length of an edge for the Rips complex construction.")
("cpx-dimension,d", po::value<int>(&dim_max)->default_value(1),
"Maximal dimension of the Rips complex we want to compute.")
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h
index 4b04e75a..d4f9aeae 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h
@@ -1160,43 +1160,28 @@ std::cout << "prune_above_filtration - filtration=" << filtration << std::endl;
threshold_ = filtration;
// Initialize filtration_vect_ if required
if (filtration_vect_.empty()) {
-std::cout << "prune_above_filtration - initialize_filtration" << std::endl;
initialize_filtration();
}
-
-std::cout << "prune_above_filtration - after initialize_filtration ";
-for(auto sh : filtration_vect_) {
-for (auto vertex : simplex_vertex_range(sh)) {
-std::cout << (int) vertex << ", ";
-}
-std::cout << " - filtration=" << sh->second.filtration() << " - " << &(sh->second) << std::endl;
-}
-
+ std::vector<std::vector<Vertex_handle>> simplex_list_to_removed;
// Loop in reverse mode until threshold is reached
- auto f_simplex = filtration_vect_.rbegin();
- for (; (f_simplex != filtration_vect_.rend()) && ((*f_simplex)->second.filtration() > threshold_); f_simplex++) {
-
-std::cout << "prune_above_filtration - remove ";
-for (auto vertex : simplex_vertex_range(*f_simplex)) {
-std::cout << (int) vertex << ", ";
-}
-std::cout << " - " << &((*f_simplex)->second) << std::endl;
-
- remove_maximal_simplex(*f_simplex);
+ // Do not erase while looping, because removing is shifting data in a flat_map
+ for (auto f_simplex = filtration_vect_.rbegin();
+ (f_simplex != filtration_vect_.rend()) && ((*f_simplex)->second.filtration() > threshold_);
+ f_simplex++) {
+ std::vector<Vertex_handle> simplex_to_remove;
+ for (auto vertex : simplex_vertex_range(*f_simplex))
+ simplex_to_remove.insert(simplex_to_remove.begin(), vertex);
+ simplex_list_to_removed.push_back(simplex_to_remove);
}
-std::cout << "prune_above_filtration - remove STOPPED ON ";
-for (auto vertex : simplex_vertex_range(*f_simplex)) {
-std::cout << (int) vertex << ", ";
-}
-std::cout << " - filtration=" << (*f_simplex)->second.filtration() << " - " << &(*f_simplex->second) << std::endl;
- if (f_simplex != filtration_vect_.rbegin()) {
- // Do not forget to update filtration_vect_ - resize is enough
- std::size_t new_size = filtration_vect_.size() - (f_simplex - filtration_vect_.rbegin());
-std::cout << "prune_above_filtration - resize" << new_size << std::endl;
- filtration_vect_.resize(new_size);
+ for (auto simplex_to_remove : simplex_list_to_removed) {
+ Simplex_handle sh = find_simplex(simplex_to_remove);
+ if (sh != null_simplex())
+ remove_maximal_simplex(sh);
}
-
+ // Re-initialize filtration_vect_ if dta were removed, because removing is shifting data in a flat_map
+ if (simplex_list_to_removed.size() > 0)
+ initialize_filtration();
}
}
}
@@ -1205,6 +1190,7 @@ std::cout << "prune_above_filtration - resize" << new_size << std::endl;
* @param[in] sh Simplex handle on the maximal simplex to remove.
* \pre Please check the simplex has no coface before removing it.
* \warning In debug mode, the exception std::invalid_argument is thrown if sh has children.
+ * \warning Be aware that removing is shifting data in a flat_map (initialize_filtration to be done).
*/
void remove_maximal_simplex(Simplex_handle sh) {
// Guarantee the simplex has no children
@@ -1213,49 +1199,18 @@ std::cout << "prune_above_filtration - resize" << new_size << std::endl;
// Simplex is a leaf, it means the child is the Siblings owning the leaf
Siblings* child = sh->second.children();
+
if ((child->size() > 1) || (child == root())) {
// Not alone, just remove it from members
// Special case when child is the root of the simplex tree, just remove it from members
-std::cout << "remove_maximal_simplex - members removal" << std::endl;
child->erase(sh->first);
} else {
// Sibling is emptied : must be deleted, and its parent must point on his own Sibling
-std::cout << "remove_maximal_simplex - members is empty" << std::endl;
child->oncles()->members().at(child->parent()).assign_children(child->oncles());
delete child;
}
}
-/***************************************************************************************************************/
- public:
- /** \brief Prints the simplex_tree hierarchically.
- * Since it prints the vertices recursively, one can watch its tree shape.
- */
- void print_tree() {
- for (auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) {
- std::cout << sh->first << " ";
- if (has_children(sh)) {
- std::cout << "(";
- rec_print(sh->second.children());
- std::cout << ")";
- }
- std::cout << std::endl;
- }
- }
-
- /** \brief Recursively prints the simplex_tree, using depth first search. */
- private:
- void rec_print(Siblings * sib) {
- for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) {
- std::cout << " " << sh->first << " ";
- if (has_children(sh)) {
- std::cout << "(";
- rec_print(sh->second.children());
- std::cout << ")";
- }
- }
- }
-/*****************************************************************************************************************/
private:
Vertex_handle null_vertex_;
/** \brief Upper bound on the filtration values of the simplices.*/
diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
index f6bd5411..0d73d347 100644
--- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp
+++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
@@ -351,7 +351,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) {
// Display the Simplex_tree - Can not be done in the middle of 2 inserts
std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
for (auto f_simplex : st.filtration_simplex_range()) {
std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
for (auto vertex : st.simplex_vertex_range(f_simplex)) {
@@ -549,7 +549,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) {
// Display the Simplex_tree - Can not be done in the middle of 2 inserts
std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
for (auto f_simplex : st.filtration_simplex_range()) {
std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
for (auto vertex : st.simplex_vertex_range(f_simplex)) {
@@ -805,7 +805,7 @@ struct MyOptions : Simplex_tree_options_full_featured {
};
typedef Simplex_tree<MyOptions> miniST;
-/*BOOST_AUTO_TEST_CASE(remove_maximal_simplex) {
+BOOST_AUTO_TEST_CASE(remove_maximal_simplex) {
std::cout << "********************************************************************" << std::endl;
std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl;
@@ -887,7 +887,7 @@ typedef Simplex_tree<MyOptions> miniST;
st.remove_maximal_simplex(st.find({7}));
BOOST_CHECK(st == st_wo_seven);
-}*/
+}
BOOST_AUTO_TEST_CASE(prune_above_filtration) {
std::cout << "********************************************************************" << std::endl;
@@ -939,10 +939,10 @@ BOOST_AUTO_TEST_CASE(prune_above_filtration) {
st.prune_above_filtration(5.0);
BOOST_CHECK(st == st_complete);
- // Display the Simplex_tree - Can not be done in the middle of 2 inserts
+ // Display the Simplex_tree
std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
- std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
for (auto f_simplex : st.filtration_simplex_range()) {
std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
for (auto vertex : st.simplex_vertex_range(f_simplex)) {
@@ -955,35 +955,45 @@ BOOST_AUTO_TEST_CASE(prune_above_filtration) {
// Set the st_pruned filtration for operator==
st_pruned.set_filtration(2.5);
st.prune_above_filtration(2.5);
- /*BOOST_CHECK(st == st_pruned);
+ BOOST_CHECK(st == st_pruned);
+
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices" << std::endl;
+ std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
st_pruned.set_filtration(2.0);
st.prune_above_filtration(2.0);
BOOST_CHECK(st == st_pruned);
-*/
-/* std::cout << "The complex contains " << st.num_simplices() << " simplices --------------------------" << std::endl;
- std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
- st.print_tree();
- std::cout << "The pruned complex contains " << st_pruned.num_simplices() << " simplices --------------------------" << std::endl;
- std::cout << " - dimension " << st_pruned.dimension() << " - filtration " << st_pruned.filtration() << std::endl;
- st_pruned.print_tree();
-
typeST st_empty;
// FIXME
st_empty.set_dimension(3);
st.prune_above_filtration(0.0);
- */
- /*BOOST_CHECK(st == st_empty);
+
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ std::cout << " - dimension " << st.dimension() << " - filtration " << st.filtration() << std::endl;
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(st == st_empty);
// Test case to the limit
st.prune_above_filtration(-1.0);
st_empty.set_filtration(-1.0);
BOOST_CHECK(st == st_empty);
-*/
}
-
-/*BOOST_AUTO_TEST_CASE(sanitizer) {
- int a[2] = {1, 0};
- int b=a[2];
-}*/
diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h
index e5c79ded..cd518581 100644
--- a/src/common/include/gudhi/distance_functions.h
+++ b/src/common/include/gudhi/distance_functions.h
@@ -23,6 +23,8 @@
#ifndef DISTANCE_FUNCTIONS_H_
#define DISTANCE_FUNCTIONS_H_
+#include <cmath> // for std::sqrt
+
/* Compute the Euclidean distance between two Points given
* by a range of coordinates. The points are assumed to have
* the same dimension. */
@@ -35,7 +37,7 @@ double euclidean_distance(Point &p1, Point &p2) {
double tmp = *it1 - *it2;
dist += tmp*tmp;
}
- return sqrt(dist);
+ return std::sqrt(dist);
}
#endif // DISTANCE_FUNCTIONS_H_
diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h
index e05714c7..da2c2c36 100644
--- a/src/common/include/gudhi/reader_utils.h
+++ b/src/common/include/gudhi/reader_utils.h
@@ -58,7 +58,9 @@ inline void read_points(std::string file_name, std::vector< std::vector< double
while (iss >> x) {
point.push_back(x);
}
- points.push_back(point);
+ // Check for empty lines
+ if (!point.empty())
+ points.push_back(point);
}
in_file.close();
}