summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--biblio/bibliography.bib24
-rwxr-xr-xdata/points/human.off2
-rw-r--r--src/Nerve_GIC/doc/Intro_graph_induced_complex.h96
-rw-r--r--src/Nerve_GIC/doc/coordGICvisu.pdf (renamed from src/Nerve_GIC/doc/mapperdeltacoordvisu.pdf)bin20745 -> 20745 bytes
-rw-r--r--src/Nerve_GIC/doc/coordGICvisu2.jpg (renamed from src/Nerve_GIC/doc/mapperdeltacoordvisu2.jpg)bin1259868 -> 1259868 bytes
-rw-r--r--src/Nerve_GIC/doc/funcGICvisu.jpg (renamed from src/Nerve_GIC/doc/mapperdeltafuncvisu.jpg)bin71647 -> 71647 bytes
-rw-r--r--src/Nerve_GIC/example/CMakeLists.txt24
-rw-r--r--src/Nerve_GIC/example/CoordGIC.cpp (renamed from src/Nerve_GIC/example/MapperDeltaCoord.cpp)26
-rw-r--r--src/Nerve_GIC/example/FuncGIC.cpp (renamed from src/Nerve_GIC/example/MapperDeltaFunc.cpp)26
-rw-r--r--src/Nerve_GIC/example/GIC.cpp4
-rw-r--r--src/Nerve_GIC/example/Nerve.cpp7
-rw-r--r--src/Nerve_GIC/example/VoronoiGIC.cpp (renamed from src/Nerve_GIC/example/GICvoronoi.cpp)5
-rw-r--r--src/Nerve_GIC/include/gudhi/GIC.h209
-rw-r--r--src/Nerve_GIC/test/test_GIC.cpp14
14 files changed, 243 insertions, 194 deletions
diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib
index 29fc5650..1bf5d19d 100644
--- a/biblio/bibliography.bib
+++ b/biblio/bibliography.bib
@@ -6,6 +6,30 @@
year = {2014},
}
+@article{Carriere17c,
+ author = {Carri\`ere, Mathieu and Michel, Bertrand and Oudot, Steve},
+ title = {{Statistical Analysis and Parameter Selection for Mapper}},
+ journal = {CoRR},
+ volume = {abs/1706.00204},
+ year = {2017}
+}
+
+@inproceedings{Dey13,
+ author = {Dey, Tamal and Fan, Fengtao and Wang, Yusu},
+ title = {Graph Induced Complex on Point Data},
+ booktitle = {Proceedings of the Twenty-ninth Annual Symposium on Computational Geometry},
+ year = {2013},
+ pages = {107--116},
+}
+
+@article{Carriere16,
+ title={{Structure and Stability of the 1-Dimensional Mapper}},
+ author={Carri\`ere, Mathieu and Oudot, Steve},
+ journal={CoRR},
+ volume= {abs/1511.05823},
+ year={2015}
+}
+
@inproceedings{zigzag_reflection,
author = {Jean-Daniel Boissonnat and Cl\'ement Maria and Steve Oudot},
title = {Zigzag Persistent Homology Algorithm via Reflections},
diff --git a/data/points/human.off b/data/points/human.off
index de6c925f..f9f79a3f 100755
--- a/data/points/human.off
+++ b/data/points/human.off
@@ -8,7 +8,7 @@ OFF
0.128166 -0.068572 0.432762
0.089198 0.014048 -0.447694
0.075569 0.021145 -0.417112
-0.098403 0.03188 -0.416332
+ 0.098403 0.03188 -0.416332
-0.135518 -0.031058 -0.793657
-0.155207 -0.043962 -0.867084
-0.155561 -0.039537 -0.782486
diff --git a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h
index 89b7a1b4..339c1284 100644
--- a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h
+++ b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h
@@ -34,9 +34,10 @@ namespace graph_induced_complex {
* @{
*
* Visualizations of the simplicial complexes can be done with either
- * neato (from <a target="_blank" href="http://www.graphviz.org/"> graphviz </a>),
- * <a target="_blank" href="http://www.geomview.org/"> geomview </a>, or
- * <a target="_blank" href="https://www.python.org/"> python </a> + <a target="_blank" href="https://www.mozilla.org/fr/firefox/new/"> firefox </a>.
+ * neato (from <a target="_blank" href="http://www.graphviz.org/">graphviz</a>),
+ * <a target="_blank" href="http://www.geomview.org/">geomview</a>,
+ * <a target="_blank" href="https://github.com/MLWave/kepler-mapper">KeplerMapper</a>.
+ * Input point clouds are assumed to be <a target="_blank" href="http://www.geomview.org/docs/html/OFF.html">OFF files</a>.
*
* \section covers Covers
*
@@ -75,20 +76,15 @@ namespace graph_induced_complex {
*
* \include Nerve_GIC/Nerve.txt
*
- * The program also writes a file SC.txt.
- * The first three lines in this file are requirements for visualization with Kepler-Mapper.
+ * The program also writes a file 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.
* The fourth line contains the number of vertices nv and edges ne of the Nerve.
* The next nv lines represent the vertices. Each line contains the vertex ID,
* the number of data points it contains, and their average color function value.
* Finally, the next ne lines represent the edges, characterized by the ID of their vertices.
- * Using e.g.
*
- * \code $> python KeplerMapperVisuFromTxtFile.py && firefox SC.html
- * \endcode
- *
- * one can obtain the following visualization:
+ * Using KeplerMapper, one can obtain the following visualization:
*
- * \image html "nervevisu.jpg" "Visualization with Kepler Mapper"
+ * \image html "nervevisu.jpg" "Visualization with KeplerMapper"
*
* \section gic Graph Induced Complexes (GIC)
*
@@ -98,31 +94,10 @@ namespace graph_induced_complex {
* you are also given a graph G built on top of P. Then, for any clique in G
* whose nodes all belong to different elements of C, the GIC includes a corresponding
* simplex, whose dimension is the number of nodes in the clique minus one.
- * See <a target="_blank" href="https://arxiv.org/abs/1304.0662"> this article </a>
- * for more details.
+ * See \cite Dey13 for more details.
*
* \image html "GIC.jpg" "GIC of a point cloud."
*
- * \subsection gicexample Example with cover from function
- *
- * This example builds the GIC of a point cloud sampled on a 3D human shape (human.off).
- * The cover C comes from the preimages of intervals (with length 0.075 and gain 0)
- * covering the height function (coordinate 2),
- * and the graph G comes from a Rips complex built with threshold 0.075.
- * Note that if the gain is too big, the number of cliques increases a lot,
- * which make the computation time much larger.
- *
- * \include Nerve_GIC/GIC.cpp
- *
- * When launching:
- *
- * \code $> ./GIC ../../../../data/points/human.off 0.075 2 0.075 0 --v
- * \endcode
- *
- * the program outputs SC.txt, which can be visualized with python and firefox as before:
- *
- * \image html "gicvisu.jpg" "Visualization with Kepler Mapper"
- *
* \subsection gicexamplevor Example with cover from Voronoï
*
* This example builds the GIC of a point cloud sampled on a 3D human shape (human.off).
@@ -132,11 +107,11 @@ namespace graph_induced_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/GICvoronoi.cpp
+ * \include Nerve_GIC/VoronoiGIC.cpp
*
* When launching:
*
- * \code $> ./GICvoronoi ../../../../data/points/human.off 700 --v
+ * \code $> ./VoronoiGIC ../../../../data/points/human.off 700 --v
* \endcode
*
* the program outputs SC.off. Using e.g.
@@ -148,29 +123,28 @@ namespace graph_induced_complex {
*
* \image html "gicvoronoivisu.jpg" "Visualization with Geomview"
*
- * \subsection mapperdeltadefinition Mapper Delta
+ * \subsection functionalGICdefinition Functional GIC
*
* If one restricts to the cliques in G whose nodes all belong to preimages of consecutive
* intervals (assuming the cover of the height function is minimal, i.e. no more than
* two intervals can intersect at a time), the GIC is of dimension one, i.e. a graph.
- * We call this graph the Mapper Delta, since it is related to the usual Mapper. See
- * <a target="_blank" href="https://arxiv.org/abs/1511.05823"> this article </a> for more details.
+ * We call this graph the functional GIC. See \cite Carriere16 for more details.
*
- * \subsection mapperdeltaexample Example
+ * \subsection functionalGICexample Example
*
- * Mapper Delta comes with optimal selection for the Rips threshold,
+ * Functional GIC comes with optimal selection for the Rips threshold,
* the resolution and the gain of the function cover. In this example,
- * we compute the Mapper Delta of a Klein bottle embedded in R^5,
+ * we compute the functional GIC of a Klein bottle embedded in R^5,
* where the graph G comes from a Rips complex with optimal threshold,
* and the cover C comes from the preimages of intervals covering the first coordinate,
* with optimal resolution and gain. Note that optimal threshold, resolution and gain
* can be computed as well for the Nerve.
*
- * \include Nerve_GIC/MapperDeltaCoord.cpp
+ * \include Nerve_GIC/CoordGIC.cpp
*
* When launching:
*
- * \code $> ./MapperDeltaCoord ../../../../data/points/KleinBottle5D.off 0 --v
+ * \code $> ./CoordGIC ../../../../data/points/KleinBottle5D.off 0 --v
* \endcode
*
* the program outputs SC.dot. Using e.g.
@@ -180,7 +154,7 @@ namespace graph_induced_complex {
*
* one can obtain the following visualization:
*
- * \image html "mapperdeltacoordvisu2.jpg" "Visualization with Neato"
+ * \image html "coordGICvisu2.jpg" "Visualization with Neato"
*
* where nodes are colored by the filter function values and, for each node, the first number is its ID
* and the second is the number of data points that its contain.
@@ -189,16 +163,16 @@ namespace graph_induced_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/MapperDeltaFunc.cpp
+ * \include Nerve_GIC/FuncGIC.cpp
*
* When launching:
*
- * \code $> ./MapperDeltaFunc ../../../../data/points/COIL_database/lucky_cat.off ../../../../data/points/COIL_database/lucky_cat_PCA1 --v
+ * \code $> ./FuncGIC ../../../../data/points/COIL_database/lucky_cat.off ../../../../data/points/COIL_database/lucky_cat_PCA1 --v
* \endcode
*
* the program outputs again SC.dot which gives the following visualization after using neato:
*
- * \image html "mapperdeltafuncvisu.jpg" "Visualization with Neato"
+ * \image html "funcGICvisu.jpg" "Visualization with neato"
*
* \copyright GNU General Public License v3.
* \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim
@@ -210,3 +184,31 @@ namespace graph_induced_complex {
} // namespace Gudhi
#endif // DOC_GRAPH_INDUCED_COMPLEX_INTRO_GRAPH_INDUCED_COMPLEX_H_
+
+
+/* * \subsection gicexample Example with cover from function
+ *
+ * This example builds the GIC of a point cloud sampled on a 3D human shape (human.off).
+ * The cover C comes from the preimages of intervals (with length 0.075 and gain 0)
+ * covering the height function (coordinate 2),
+ * and the graph G comes from a Rips complex built with threshold 0.075.
+ * Note that if the gain is too big, the number of cliques increases a lot,
+ * which make the computation time much larger.
+ *
+ * \include Nerve_GIC/GIC.cpp
+ *
+ * When launching:
+ *
+ * \code $> ./GIC ../../../../data/points/human.off 0.075 2 0.075 0 --v
+ * \endcode
+ *
+ * the program outputs SC.txt, which can be visualized with python and firefox as before:
+ *
+ * \image html "gicvisu.jpg" "Visualization with KeplerMapper"
+ * */
+
+
+/* * Using e.g.
+ *
+ * \code $> python KeplerMapperVisuFromTxtFile.py && firefox SC.html
+ * \endcode */
diff --git a/src/Nerve_GIC/doc/mapperdeltacoordvisu.pdf b/src/Nerve_GIC/doc/coordGICvisu.pdf
index 313aa1b5..313aa1b5 100644
--- a/src/Nerve_GIC/doc/mapperdeltacoordvisu.pdf
+++ b/src/Nerve_GIC/doc/coordGICvisu.pdf
Binary files differ
diff --git a/src/Nerve_GIC/doc/mapperdeltacoordvisu2.jpg b/src/Nerve_GIC/doc/coordGICvisu2.jpg
index 046feb2a..046feb2a 100644
--- a/src/Nerve_GIC/doc/mapperdeltacoordvisu2.jpg
+++ b/src/Nerve_GIC/doc/coordGICvisu2.jpg
Binary files differ
diff --git a/src/Nerve_GIC/doc/mapperdeltafuncvisu.jpg b/src/Nerve_GIC/doc/funcGICvisu.jpg
index f3da45ac..f3da45ac 100644
--- a/src/Nerve_GIC/doc/mapperdeltafuncvisu.jpg
+++ b/src/Nerve_GIC/doc/funcGICvisu.jpg
Binary files differ
diff --git a/src/Nerve_GIC/example/CMakeLists.txt b/src/Nerve_GIC/example/CMakeLists.txt
index ea504c11..871e46a6 100644
--- a/src/Nerve_GIC/example/CMakeLists.txt
+++ b/src/Nerve_GIC/example/CMakeLists.txt
@@ -4,24 +4,20 @@ project(Nerve_GIC_examples)
add_executable ( Nerve Nerve.cpp )
target_link_libraries(Nerve ${Boost_SYSTEM_LIBRARY})
-add_executable ( GIC GIC.cpp )
-target_link_libraries(GIC ${Boost_SYSTEM_LIBRARY})
+add_executable ( CoordGIC CoordGIC.cpp )
+target_link_libraries(CoordGIC ${Boost_SYSTEM_LIBRARY})
-add_executable ( MapperDeltaCoord MapperDeltaCoord.cpp )
-target_link_libraries(MapperDeltaCoord ${Boost_SYSTEM_LIBRARY})
+add_executable ( FuncGIC FuncGIC.cpp )
+target_link_libraries(FuncGIC ${Boost_SYSTEM_LIBRARY})
-add_executable ( MapperDeltaFunc MapperDeltaFunc.cpp )
-target_link_libraries(MapperDeltaFunc ${Boost_SYSTEM_LIBRARY})
+add_executable ( VoronoiGIC VoronoiGIC.cpp )
+target_link_libraries(VoronoiGIC ${Boost_SYSTEM_LIBRARY})
-add_executable ( GICvoronoi GICvoronoi.cpp )
-target_link_libraries(MapperDeltaFunc ${Boost_SYSTEM_LIBRARY})
-
-file(COPY KeplerMapperVisuFromTxtFile.py km.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+#[[file(COPY KeplerMapperVisuFromTxtFile.py km.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)]]
if (TBB_FOUND)
target_link_libraries(Nerve ${TBB_LIBRARIES})
- target_link_libraries(GIC ${TBB_LIBRARIES})
- target_link_libraries(MapperDeltaCoord ${TBB_LIBRARIES})
- target_link_libraries(MapperDeltaFunc ${TBB_LIBRARIES})
- target_link_libraries(GICvoronoi ${TBB_LIBRARIES})
+ target_link_libraries(CoordGIC ${TBB_LIBRARIES})
+ target_link_libraries(FuncGIC ${TBB_LIBRARIES})
+ target_link_libraries(VoronoiGIC ${TBB_LIBRARIES})
endif() \ No newline at end of file
diff --git a/src/Nerve_GIC/example/MapperDeltaCoord.cpp b/src/Nerve_GIC/example/CoordGIC.cpp
index 382649e8..89b0f9a4 100644
--- a/src/Nerve_GIC/example/MapperDeltaCoord.cpp
+++ b/src/Nerve_GIC/example/CoordGIC.cpp
@@ -38,12 +38,12 @@ int main(int argc, char **argv) {
int coord = atoi(argv[2]);
bool verb = 0; if(argc == 4) verb = 1;
- // ---------------------------------------
- // Init of a Mapper Delta from an OFF file
- // ---------------------------------------
+ // -----------------------------------------
+ // Init of a functional GIC from an OFF file
+ // -----------------------------------------
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
- GIC.set_verbose(verb); GIC.set_mask(); GIC.set_subsampling();
+ GIC.set_verbose(verb);
bool check = GIC.read_point_cloud(off_file_name);
@@ -55,25 +55,25 @@ int main(int argc, char **argv) {
GIC.set_graph_from_automatic_rips(Gudhi::Euclidean_distance());
- GIC.set_automatic_resolution_for_GICMAP(); GIC.set_gain();
+ GIC.set_automatic_resolution_for_GIC(); GIC.set_gain();
GIC.set_cover_from_function();
- GIC.find_GICMAP_simplices_with_functional_minimal_cover();
+ GIC.find_GIC_simplices_with_functional_minimal_cover();
- GIC.plot_DOT_for_neato();
+ GIC.plot_DOT();
- Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
- // ------------------------------------------
- // Display information about the Mapper Delta
- // ------------------------------------------
+ // --------------------------------------------
+ // Display information about the functional GIC
+ // --------------------------------------------
if(verb){
- std::cout << "Mapper Delta is of dimension " << stree.dimension() <<
+ std::cout << "Functional GIC is of dimension " << stree.dimension() <<
" - " << stree.num_simplices() << " simplices - " <<
stree.num_vertices() << " vertices." << std::endl;
- std::cout << "Iterator on Mapper Delta simplices" << std::endl;
+ std::cout << "Iterator on functional GIC simplices" << std::endl;
for (auto f_simplex : stree.filtration_simplex_range()) {
for (auto vertex : stree.simplex_vertex_range(f_simplex)) {
std::cout << vertex << " ";
diff --git a/src/Nerve_GIC/example/MapperDeltaFunc.cpp b/src/Nerve_GIC/example/FuncGIC.cpp
index 586b733c..56c97b7f 100644
--- a/src/Nerve_GIC/example/MapperDeltaFunc.cpp
+++ b/src/Nerve_GIC/example/FuncGIC.cpp
@@ -38,12 +38,12 @@ int main(int argc, char **argv) {
std::string func_file_name = argv[2];
bool verb = 0; if(argc == 4) verb = 1;
- // ---------------------------------------
- // Init of a Mapper Delta from an OFF file
- // ---------------------------------------
+ // -----------------------------------------
+ // Init of a functional GIC from an OFF file
+ // -----------------------------------------
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
- GIC.set_verbose(verb); GIC.set_mask(); GIC.set_subsampling();
+ GIC.set_verbose(verb);
bool check = GIC.read_point_cloud(off_file_name);
@@ -55,25 +55,25 @@ int main(int argc, char **argv) {
GIC.set_graph_from_automatic_rips(Gudhi::Euclidean_distance());
- GIC.set_automatic_resolution_for_GICMAP(); GIC.set_gain();
+ GIC.set_automatic_resolution_for_GIC(); GIC.set_gain();
GIC.set_cover_from_function();
- GIC.find_GICMAP_simplices_with_functional_minimal_cover();
+ GIC.find_GIC_simplices_with_functional_minimal_cover();
- GIC.plot_DOT_for_neato();
+ GIC.plot_DOT();
- Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
- // ------------------------------------------
- // Display information about the Mapper Delta
- // ------------------------------------------
+ // --------------------------------------------
+ // Display information about the functional GIC
+ // --------------------------------------------
if(verb){
- std::cout << "Mapper Delta is of dimension " << stree.dimension() <<
+ std::cout << "Functional GIC is of dimension " << stree.dimension() <<
" - " << stree.num_simplices() << " simplices - " <<
stree.num_vertices() << " vertices." << std::endl;
- std::cout << "Iterator on Mapper Delta simplices" << std::endl;
+ std::cout << "Iterator on functional GIC simplices" << std::endl;
for (auto f_simplex : stree.filtration_simplex_range()) {
for (auto vertex : stree.simplex_vertex_range(f_simplex)) {
std::cout << vertex << " ";
diff --git a/src/Nerve_GIC/example/GIC.cpp b/src/Nerve_GIC/example/GIC.cpp
index 6e5c5ca7..b8b5cd05 100644
--- a/src/Nerve_GIC/example/GIC.cpp
+++ b/src/Nerve_GIC/example/GIC.cpp
@@ -46,7 +46,7 @@ int main(int argc, char **argv) {
// ----------------------------------------------------------------------------
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
- GIC.set_verbose(verb); GIC.set_mask();
+ GIC.set_verbose(verb);
bool check = GIC.read_point_cloud(off_file_name);
@@ -65,7 +65,7 @@ int main(int argc, char **argv) {
GIC.plot_TXT_for_KeplerMapper();
- Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
// ----------------------------------------------------------------------------
// Display information about the graph induced complex
diff --git a/src/Nerve_GIC/example/Nerve.cpp b/src/Nerve_GIC/example/Nerve.cpp
index e47982c4..e863b48b 100644
--- a/src/Nerve_GIC/example/Nerve.cpp
+++ b/src/Nerve_GIC/example/Nerve.cpp
@@ -39,13 +39,14 @@ int main(int argc, char **argv) {
int resolution = atoi(argv[3]);
double gain = atof(argv[4]);
bool verb = 0; if(argc == 6) verb = 1;
+ //int mask = 0;
// --------------------------------
// Init of a Nerve from an OFF file
// --------------------------------
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
- GIC.set_verbose(verb); GIC.set_mask();
+ GIC.set_verbose(verb);
bool check = GIC.read_point_cloud(off_file_name);
@@ -62,9 +63,9 @@ int main(int argc, char **argv) {
GIC.find_Nerve_simplices();
- GIC.plot_TXT_for_KeplerMapper();
+ GIC.plot_TXT();
- Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
// ----------------------------------------------------------------------------
// Display information about the graph induced complex
diff --git a/src/Nerve_GIC/example/GICvoronoi.cpp b/src/Nerve_GIC/example/VoronoiGIC.cpp
index 2c4f5acf..f000c263 100644
--- a/src/Nerve_GIC/example/GICvoronoi.cpp
+++ b/src/Nerve_GIC/example/VoronoiGIC.cpp
@@ -37,13 +37,14 @@ int main(int argc, char **argv) {
std::string off_file_name(argv[1]);
int m = atoi(argv[2]);
bool verb = 0; if(argc == 4) verb = 1;
+ //int mask = 0;
// ----------------------------------------------------------------------------
// Init of a graph induced complex from an OFF file
// ----------------------------------------------------------------------------
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
- GIC.set_verbose(verb); GIC.set_mask();
+ GIC.set_verbose(verb);
bool check = GIC.read_point_cloud(off_file_name);
@@ -60,7 +61,7 @@ int main(int argc, char **argv) {
GIC.plot_OFF();
- Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
// ----------------------------------------------------------------------------
// Display information about the graph induced complex
diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h
index 384bbc8c..bacaf0b9 100644
--- a/src/Nerve_GIC/include/gudhi/GIC.h
+++ b/src/Nerve_GIC/include/gudhi/GIC.h
@@ -92,9 +92,9 @@ class Graph_induced_complex {
int resolution_int = -1;
double resolution_double = -1;
double gain = -1;
- double rate_constant; // Constant in the subsampling.
- double rate_power; // Power in the subsampling.
- int mask; // Ignore nodes containing less than mask points.
+ double rate_constant = 10; // Constant in the subsampling.
+ double rate_power = 0.001; // Power in the subsampling.
+ int mask = 0; // Ignore nodes containing less than mask points.
std::map<int, double> func;
std::map<int, double> func_color;
std::vector<int> voronoi_subsamples;
@@ -112,7 +112,7 @@ class Graph_induced_complex {
// DFS
private:
void dfs(std::map<int,std::vector<int> >& G, int p, std::vector<int>& cc, std::map<int,bool>& visit){
- cc.push_back(p);
+ cc.emplace_back(p);
visit[p] = true; int neighb = G[p].size();
for (int i = 0; i < neighb; i++)
if ( visit.find(G[p][i]) != visit.end() )
@@ -129,11 +129,10 @@ class Graph_induced_complex {
// Subsample points.
void SampleWithoutReplacement(int populationSize, int sampleSize, std::vector<int> & samples){
- int& n = sampleSize; int& N = populationSize;
int t = 0; int m = 0; double u;
- while (m < n){
+ while (m < sampleSize){
u = GetUniform();
- if ( (N - t)*u >= n - m )
+ if ( (populationSize - t)*u >= sampleSize - m )
t++;
else{samples[m] = t; t++; m++;}
}
@@ -146,8 +145,8 @@ class Graph_induced_complex {
for (auto simplex : st.complex_simplex_range()) {
if(st.dimension(simplex) == 1){
std::vector<int> vertices;
- for(auto vertex : st.simplex_vertex_range(simplex)) vertices.push_back(vertex);
- adjacency_matrix[vertices[0]].push_back(vertices[1]); adjacency_matrix[vertices[1]].push_back(vertices[0]);
+ for(auto vertex : st.simplex_vertex_range(simplex)) vertices.emplace_back(vertex);
+ adjacency_matrix[vertices[0]].emplace_back(vertices[1]); adjacency_matrix[vertices[1]].emplace_back(vertices[0]);
}
}
}
@@ -158,55 +157,67 @@ class Graph_induced_complex {
* @param[in] verb boolean (true = display info, false = do not display info).
*
*/
- void set_verbose(bool verb = 0){verbose = verb;}
+ void set_verbose(bool verb = false){verbose = verb;}
+
public:
/** \brief Sets the constants used to subsample the data set. These constants are
- * explained in "Statistical Analysis and Parameter Selection for the Mapper".
+ * explained in \cite Carriere17c.
*
* @param[in] constant double.
* @param[in] power double.
*
*/
- void set_subsampling(double constant = 10, double power = 0.001){rate_constant = constant; rate_power = power;}
+ void set_subsampling(double constant, double power){rate_constant = constant; rate_power = power;}
+
public:
- /** \brief Sets the mask, which is a threshold integer such that nodes in the complex that contain less data points
- * than this threshold are not displayed.
+ /** \brief Sets the mask, which is a threshold integer such that nodes in the complex that contain a number of data points which is less than or equal to
+ * this threshold are not displayed.
*
* @param[in] nodemask integer.
*
*/
- void set_mask(int nodemask = 0){mask = nodemask;}
+ void set_mask(int nodemask){mask = nodemask;}
public:
/** \brief Reads and stores the input point cloud.
*
- * @param[in] off_file_name name of the input .OFF file.
+ * @param[in] off_file_name name of the input .OFF or .nOFF file.
*
*/
bool read_point_cloud(std::string off_file_name){
- point_cloud_name = off_file_name;
- int numedges, numfaces, i, num; std::vector<int> edge(2);
- std::vector<int> simplex;
- std::ifstream input(off_file_name); std::string line; getline(input, line);
- if(std::strcmp((char*) line.c_str(),"nOFF")==0) input >> data_dimension; else data_dimension = 3;
- input >> n; input >> numfaces; input >> numedges; getline(input, line);
+
+ point_cloud_name = off_file_name; std::ifstream input(off_file_name); std::string line;
+
+ char comment = '#';
+ while(comment == '#'){getline(input, line); if(!line.empty() && !std::all_of(line.begin(),line.end(),isspace)) comment = line[line.find_first_not_of(' ')];}
+ if(std::strcmp((char*) line.c_str(),"nOFF")==0){
+ comment = '#'; while(comment == '#'){getline(input, line); if(!line.empty() && !std::all_of(line.begin(),line.end(),isspace)) comment = line[line.find_first_not_of(' ')];}
+ std::stringstream stream(line); stream >> data_dimension;
+ }
+ else data_dimension = 3;
+
+ comment = '#'; int numedges, numfaces, i, num;
+ while(comment == '#'){getline(input, line); if(!line.empty() && !std::all_of(line.begin(),line.end(),isspace)) comment = line[line.find_first_not_of(' ')];}
+ std::stringstream stream(line); stream >> n; stream >> numfaces; stream >> numedges;
i = 0; while(i < n){
getline(input, line);
- std::vector<double> point; std::istringstream iss(line);
- point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
- point_cloud.push_back(Point(point.begin(),point.end())); i++;
+ if(!line.empty() && line[line.find_first_not_of(' ')] != '#' && !std::all_of(line.begin(),line.end(),isspace)){
+ std::vector<double> point; std::istringstream iss(line);
+ point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>());
+ point_cloud.emplace_back(Point(point.begin(),point.begin()+data_dimension)); i++;
+ }
}
i = 0; while(i < numfaces){
- simplex.clear(); input >> num;
- for(int j = 0; j < num; j++){int k; input >> k; simplex.push_back(k);}
- for(int j = 0; j < num; j++){
- for(int k = j+1; k < num; k++){
- edge[0] = simplex[j]; edge[1] = simplex[k]; one_skeleton.push_back(edge);
- }
+ getline(input, line);
+ if(!line.empty() && line[line.find_first_not_of(' ')] != '#' && !std::all_of(line.begin(),line.end(),isspace)){
+ std::vector<int> simplex; std::istringstream iss(line);
+ simplex.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>());
+ num = simplex[0]; std::vector<int> edge(2);
+ for(int j = 1; j <= num; j++){ for(int k = j+1; k <= num; k++){ edge[0] = simplex[j]; edge[1] = simplex[k]; one_skeleton.emplace_back(edge); } }
+ i++;
}
- i++;
}
return input.is_open();
@@ -256,6 +267,7 @@ class Graph_induced_complex {
/** \brief Creates the graph G from a Rips complex.
*
* @param[in] threshold threshold value for the Rips complex.
+ * @param[in] distance distance used to compute the Rips complex.
*
*/
template<typename Distance> void set_graph_from_rips(double threshold, Distance distance){
@@ -271,7 +283,7 @@ class Graph_induced_complex {
*/
template<typename Distance> void compute_pairwise_distances(Distance ref_distance){
- double d; std::vector<double> zeros(n); for(int i = 0; i < n; i++) distances.push_back(zeros);
+ double d; std::vector<double> zeros(n); for(int i = 0; i < n; i++) distances.emplace_back(zeros);
std::string distance = point_cloud_name; distance.append("_dist");
std::ifstream input(distance.c_str(), std::ios::out | std::ios::binary);
@@ -303,9 +315,11 @@ class Graph_induced_complex {
}
public: // Automatic tuning of Rips complex.
- /** \brief Creates the graph G from a Rips complex whose threshold value is automatically tuned with subsampling.
+ /** \brief Creates the graph G from a Rips complex whose threshold value is automatically tuned with subsampling---see \cite Carriere17c.
*
- * @param[in] N number of subsampling iteration (the default reasonable value is 100, but there is no guarantee on how to choose it).
+ * @param[in] distance distance between data points.
+ * @param[in] N number of subsampling iteration (the default reasonable value is 100, but there is no guarantee on how to choose it).
+ * @param[out] delta threshold used for computing the Rips complex.
*
*/
template<typename Distance> double set_graph_from_automatic_rips(Distance distance, int N = 100){
@@ -380,27 +394,31 @@ class Graph_induced_complex {
*
*/
void set_function_from_vector(std::vector<double> function){
- for(int i = 0; i < n; i++) func.emplace(i, function[i]);
+ int index = 0; for(auto v : function){func.emplace(index, v); index++;}
}
// *******************************************************************************************************************
// Covers.
// *******************************************************************************************************************
- public: // Automatic tuning of resolution for Mapper Delta.
- /** \brief Computes the optimal length of intervals for a Mapper Delta.
+ public: // Automatic tuning of resolution for GIC.
+ /** \brief Computes the optimal length of intervals (i.e. the smallest interval length avoiding discretization artifacts---see \cite Carriere17c) for a GIC computed with a functional cover.
+ *
+ * @param[out] reso interval length used to compute the cover.
+ *
*/
- void set_automatic_resolution_for_GICMAP(){
+ double set_automatic_resolution_for_GIC(){
double reso = 0;
for (auto simplex : st.complex_simplex_range()) {
if(st.dimension(simplex) == 1){
std::vector<int> vertices;
- for(auto vertex : st.simplex_vertex_range(simplex)) vertices.push_back(vertex);
+ for(auto vertex : st.simplex_vertex_range(simplex)) vertices.emplace_back(vertex);
reso = std::max(reso, std::abs(func[vertices[0]] - func[vertices[1]]));
}
}
if(verbose) std::cout << "resolution = " << reso << std::endl;
resolution_double = reso;
+ return reso;
}
public:
@@ -423,20 +441,25 @@ class Graph_induced_complex {
*/
void set_gain(double g = 0.3){gain = g;}
- public: // Automatic tuning of resolution for Mapper Point.
- /** \brief Computes the optimal length of intervals for a standard Mapper.
+ public: // Automatic tuning of resolution for Nerve.
+ /** \brief Computes the optimal length of intervals (i.e. the smallest interval length avoiding discretization artifacts---see \cite Carriere17c) for a Nerve computed with a functional cover.
+ *
+ * @param[in] g gain.
+ * @param[out] reso interval length used to compute the cover.
+ *
*/
- void set_automatic_resolution_for_MAP(double gain){
+ double set_automatic_resolution_for_Nerve(double gain){
double reso = 0;
for (auto simplex : st.complex_simplex_range()) {
if(st.dimension(simplex) == 1){
std::vector<int> vertices;
- for(auto vertex : st.simplex_vertex_range(simplex)) vertices.push_back(vertex);
+ for(auto vertex : st.simplex_vertex_range(simplex)) vertices.emplace_back(vertex);
reso = std::max(reso, (std::abs(func[vertices[0]] - func[vertices[1]]))/gain);
}
}
if(verbose) std::cout << "resolution = " << reso << std::endl;
resolution_double = reso;
+ return reso;
}
public: // Set cover with preimages of function.
@@ -459,14 +482,14 @@ class Graph_induced_complex {
if(resolution_double == -1){ // Case we use an integer for the number of intervals.
double incr = (maxf-minf)/resolution_int; double x = minf; double alpha = (incr*gain)/(2-2*gain);
- double y = minf + incr + alpha; std::pair<double, double> interm(x,y); intervals.push_back(interm);
+ double y = minf + incr + alpha; std::pair<double, double> interm(x,y); intervals.emplace_back(interm);
for(int i = 1; i < resolution_int-1; i++){
x = minf + i*incr - alpha;
y = minf + (i+1)*incr + alpha;
- std::pair<double, double> inter(x,y); intervals.push_back(inter);
+ std::pair<double, double> inter(x,y); intervals.emplace_back(inter);
}
x = minf + (resolution_int-1)*incr - alpha; y = maxf;
- std::pair<double, double> interM(x,y); intervals.push_back(interM); res = intervals.size();
+ std::pair<double, double> interM(x,y); intervals.emplace_back(interM); res = intervals.size();
if(verbose)
for(int i = 0; i < res; i++) std::cout << "Interval " << i << " = [" << intervals[i].first << ", " << intervals[i].second << "]" << std::endl;
}
@@ -475,11 +498,11 @@ class Graph_induced_complex {
if(resolution_int == -1){ // Case we use a double for the length of the intervals.
double x = minf; double y = x + resolution_double;
while(y <= maxf && maxf - (y-gain*resolution_double) >= resolution_double){
- std::pair<double, double> inter(x,y); intervals.push_back(inter);
+ std::pair<double, double> inter(x,y); intervals.emplace_back(inter);
x = y - gain*resolution_double;
y = x + resolution_double;
}
- std::pair<double, double> interM(x,maxf); intervals.push_back(interM); res = intervals.size();
+ std::pair<double, double> interM(x,maxf); intervals.emplace_back(interM); res = intervals.size();
if(verbose)
for(int i = 0; i < res; i++) std::cout << "Interval " << i << " = [" << intervals[i].first << ", " << intervals[i].second << "]" << std::endl;
}
@@ -487,7 +510,7 @@ class Graph_induced_complex {
else{ // Case we use an integer and a double for the length of the intervals.
double x = minf; double y = x + resolution_double; int count = 0;
while(count < resolution_int && y <= maxf && maxf - (y-gain*resolution_double) >= resolution_double){
- std::pair<double, double> inter(x,y); intervals.push_back(inter); count++;
+ std::pair<double, double> inter(x,y); intervals.emplace_back(inter); count++;
x = y - gain*resolution_double;
y = x + resolution_double;
}
@@ -558,7 +581,7 @@ class Graph_induced_complex {
std::vector<int> cc; cc.clear();
dfs(prop,it->first,cc,visit); int cci = cc.size(); if(verbose) std::cout << "one CC with " << cci << " points, ";
double average_col = 0;
- for(int j = 0; j < cci; j++){cover[cc[j]].push_back(id); average_col += func_color[cc[j]]/cci;}
+ for(int j = 0; j < cci; j++){cover[cc[j]].emplace_back(id); average_col += func_color[cc[j]]/cci;}
cover_fct[id] = i; cover_color[id] = std::pair<int,double>(cci,average_col);
id++;
}
@@ -584,7 +607,7 @@ class Graph_induced_complex {
while(std::getline(input,line)){
cov_elts.clear(); std::stringstream stream(line);
while(stream >> cov){
- cov_elts.push_back(cov); cov_number.push_back(cov);
+ cov_elts.emplace_back(cov); cov_number.emplace_back(cov);
cover_fct[cov] = cov; cover_color[cov].second += func_color[vertex_id]; cover_color[cov].first++;
}
cover[vertex_id] = cov_elts; vertex_id++;
@@ -599,6 +622,7 @@ class Graph_induced_complex {
public: // Set cover from Voronoi
/** \brief Creates the cover C from the Voronoï cells of a subsampling of the point cloud.
*
+ * @param[in] distance distance between the points.
* @param[in] m number of points in the subsample.
*
*/
@@ -636,7 +660,7 @@ class Graph_induced_complex {
for(int j = 0; j < n; j++)
if(mindist[j] > dist[j]){
mindist[j] = dist[j];
- if(cover[j].size() == 0) cover[j].push_back(i);
+ if(cover[j].size() == 0) cover[j].emplace_back(i);
else cover[j][0] = i;
}
}
@@ -688,11 +712,11 @@ class Graph_induced_complex {
}
public: // Create a .dot file that can be compiled with neato to produce a .pdf file.
- /** \brief Creates a .dot file for neato (part of the graphviz package) once the simplicial complex is computed to get a visualization
+ /** \brief Creates a .dot file called SC.dot for neato (part of the graphviz package) once the simplicial complex is computed to get a visualization
* of its 1-skeleton in a .pdf file.
*/
- void plot_DOT_for_neato(){
- char mapp[11] = "SC.dot"; std::ofstream graphic(mapp); graphic << "graph Mapper {" << std::endl;
+ void plot_DOT(){
+ char mapp[11] = "SC.dot"; std::ofstream graphic(mapp); graphic << "graph GIC {" << std::endl;
double maxv, minv; maxv = std::numeric_limits<double>::min(); minv = std::numeric_limits<double>::max();
for (std::map<Cover_t,std::pair<int,double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++){
maxv = std::max(maxv, iit->second.second); minv = std::min(minv, iit->second.second);
@@ -700,7 +724,7 @@ class Graph_induced_complex {
int k = 0; std::vector<int> nodes; nodes.clear();
for (std::map<Cover_t,std::pair<int,double> >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++){
if(iit->second.first > mask){
- nodes.push_back(iit->first);
+ nodes.emplace_back(iit->first);
graphic << iit->first << "[shape=circle fontcolor=black color=black label=\"" \
<< iit->first << ":" << iit->second.first << "\" style=filled fillcolor=\"" \
<< (1-(maxv-iit->second.second)/(maxv-minv))*0.6 << ", 1, 1\"]" << std::endl;
@@ -716,11 +740,10 @@ class Graph_induced_complex {
std::cout << "SC.dot generated. It can be visualized with e.g. neato." << std::endl;
}
- public: // Create a .txt file that can be compiled with KeplerMapper to produce a .html file.
- /** \brief Creates a .txt file for KeplerMapper once the simplicial complex is computed to get a visualization
- * of its 1-skeleton in browser.
+ public: // Create a .txt file that can be compiled with KeplerMapper.
+ /** \brief Creates a .txt file called SC.txt describing the 1-skeleton, which can then be plotted with e.g. KeplerMapper.
*/
- void plot_TXT_for_KeplerMapper(){
+ void plot_TXT(){
int num_simplices = simplices.size(); int num_edges = 0;
char mapp[11] = "SC.txt"; std::ofstream graphic(mapp);
@@ -748,27 +771,29 @@ class Graph_induced_complex {
public: // Create a .off file that can be visualized (e.g. with Geomview).
- /** \brief Creates a .off file for visualization.
- * For GIC computed with Voronoi only.
+ /** \brief Creates a .off file called SC.off for 3D visualization, which contains the 2-skeleton of the GIC.
+ * This function assumes that the cover has been computed with Voronoi. If data points are in 1D or 2D,
+ * the remaining coordinates of the points embedded in 3D are set to 0.
*/
void plot_OFF(){
- assert(data_dimension <= 3);
+ assert(!cover_name.compare("Voronoi"));
char gic[11] = "SC.off"; std::ofstream graphic(gic);
graphic << "OFF" << std::endl; int m = voronoi_subsamples.size(); int numedges = 0; int numfaces = 0;
std::vector<std::vector<int> > edges, faces; int numsimplices = simplices.size();
for (int i = 0; i < numsimplices; i++) {
- if(simplices[i].size() == 2){ numedges++;
- edges.push_back(simplices[i]);
- }
- if(simplices[i].size() == 3){ numfaces++;
- faces.push_back(simplices[i]);
- }
+ if(simplices[i].size() == 2){ numedges++; edges.emplace_back(simplices[i]); }
+ if(simplices[i].size() == 3){ numfaces++; faces.emplace_back(simplices[i]); }
}
graphic << m << " " << numedges + numfaces << std::endl;
- for(int i = 0; i < m; i++) graphic << point_cloud[voronoi_subsamples[i]][0] << " " \
- << point_cloud[voronoi_subsamples[i]][1] << " " \
- << point_cloud[voronoi_subsamples[i]][2] << std::endl;
+ for(int i = 0; i < m; i++){
+ if(data_dimension <= 3){
+ for(int j = 0; j < data_dimension; j++) graphic << point_cloud[voronoi_subsamples[i]][j] << " ";
+ for(int j = data_dimension; j < 3; j++) graphic << 0 << " ";
+ graphic << std::endl;
+ }
+ else for(int j = 0; j < 3; j++) graphic << point_cloud[voronoi_subsamples[i]][j] << " ";
+ }
for(int i = 0; i < numedges; i++) graphic << 2 << " " << edges[i][0] << " " << edges[i][1] << std::endl;
for(int i = 0; i < numfaces; i++) graphic << 3 << " " << faces[i][0] << " " << faces[i][1] << " " << faces[i][2] << std::endl;
graphic.close();
@@ -783,11 +808,11 @@ class Graph_induced_complex {
public:
/** \brief Creates the simplicial complex.
*
- * @param[in] complex SimplicialComplexForGIC to be created.
+ * @param[in] complex SimplicialComplexForRips to be created.
*
*/
- template<typename SimplicialComplexForGIC>
- void create_complex(SimplicialComplexForGIC & complex) {
+ template<typename SimplicialComplexForRips>
+ void create_complex(SimplicialComplexForRips & complex) {
unsigned int dimension = 0;
for(auto const& simplex : simplices){
complex.insert_simplex_and_subfaces(simplex);
@@ -796,7 +821,7 @@ class Graph_induced_complex {
complex.set_dimension(dimension);
}
- public:
+ private:
/** \brief Finds the maximal clique formed by different elements of the cover in a set of points.
*
* @param[in] cover_elts vector of points represented by vectors of cover elements (the ones to which they belong).
@@ -807,24 +832,24 @@ class Graph_induced_complex {
std::vector<Cover_t> simplex;
for(int i = 0; i < num_nodes; i++)
for(unsigned int j = 0; j < cover_elts[i].size(); j++)
- simplex.push_back(cover_elts[i][j]);
+ simplex.emplace_back(cover_elts[i][j]);
std::sort(simplex.begin(),simplex.end()); std::vector<Cover_t>::iterator it = std::unique(simplex.begin(),simplex.end());
simplex.resize(std::distance(simplex.begin(),it));
- simplices.push_back(simplex);
+ simplices.emplace_back(simplex);
}
public:
- /** \brief Computes the simplices in the Nerve of the cover C.
+ /** \brief Computes the simplices for a Nerve.
*/
void find_Nerve_simplices(){
- for(std::map<int,std::vector<Cover_t> >::iterator it = cover.begin(); it!=cover.end(); it++) simplices.push_back(it->second);
+ for(std::map<int,std::vector<Cover_t> >::iterator it = cover.begin(); it!=cover.end(); it++) simplices.emplace_back(it->second);
std::vector<std::vector<Cover_t> >::iterator it;
std::sort(simplices.begin(),simplices.end()); it = std::unique(simplices.begin(),simplices.end());
simplices.resize(std::distance(simplices.begin(),it));
}
public:
- /** \brief Computes the simplices in the GIC of the graph G and the cover C.
+ /** \brief Computes the simplices for a GIC.
*/
void find_GIC_simplices() {
@@ -833,8 +858,8 @@ class Graph_induced_complex {
for (auto simplex : st.complex_simplex_range()) {
if(st.dimension(simplex) == 1){
std::vector<std::vector<Cover_t> > comp;
- for(auto vertex : st.simplex_vertex_range(simplex)) comp.push_back(cover[vertex]);
- if(comp[0].size() == 1 && comp[0] == comp[1]) simplex_to_remove.push_back(simplex_id);
+ for(auto vertex : st.simplex_vertex_range(simplex)) comp.emplace_back(cover[vertex]);
+ if(comp[0].size() == 1 && comp[0] == comp[1]) simplex_to_remove.emplace_back(simplex_id);
}
simplex_id++;
}
@@ -859,7 +884,7 @@ class Graph_induced_complex {
for (auto simplex : st.complex_simplex_range()) {
if(!st.has_children(simplex)){
std::vector<std::vector<Cover_t> > cover_elts;
- for (auto vertex : st.simplex_vertex_range(simplex)) cover_elts.push_back(cover[vertex]);
+ for (auto vertex : st.simplex_vertex_range(simplex)) cover_elts.emplace_back(cover[vertex]);
find_maximal_clique(cover_elts);
}
}
@@ -869,14 +894,14 @@ class Graph_induced_complex {
}
public:
- /** \brief Computes the simplices in the Mapper Delta by looking at all the edges of the graph
- * and adding the corresponding edges in the Mapper Delta if the images of the endpoints belong
- * to consecutive intervals.
+ /** \brief Speed-up special case for simplices computation for a GIC computed with a functional cover.
*
- * @exception std::invalid_argument In case the gain is greater or equal to 0.5 (causes incorrect output).
+ * @exception std::invalid_argument in case the gain is greater than or equal to 0.5 (causes incorrect output).
*
*/
- void find_GICMAP_simplices_with_functional_minimal_cover(){
+ void find_GIC_simplices_with_functional_minimal_cover(){
+
+ // Computes the simplices in the GIC by looking at all the edges of the graph and adding the corresponding edges in the GIC if the images of the endpoints belong to consecutive intervals.
if (gain >= 0.5)
throw std::invalid_argument("the output of this function is correct ONLY if the cover is minimal, i.e. the gain is less than 0.5.");
@@ -890,7 +915,7 @@ class Graph_induced_complex {
// Find cover of current point (vid).
if(cover[vid].size() == 2) v1 = std::min(cover[vid][0],cover[vid][1]); else v1 = cover[vid][0];
- std::vector<int> node(1); node[0] = v1; simplices.push_back(node);
+ std::vector<int> node(1); node[0] = v1; simplices.emplace_back(node);
// Loop on neighbors.
for(int i = 0; i < num_neighb; i++){
@@ -903,7 +928,7 @@ class Graph_induced_complex {
// If neighbor is in next interval, add edge.
if(cover_fct[v2] == cover_fct[v1] + 1){
std::vector<int> edge(2); edge[0] = v1; edge[1] = v2;
- simplices.push_back(edge);
+ simplices.emplace_back(edge);
}
}
}
diff --git a/src/Nerve_GIC/test/test_GIC.cpp b/src/Nerve_GIC/test/test_GIC.cpp
index cff49372..24fa8c8f 100644
--- a/src/Nerve_GIC/test/test_GIC.cpp
+++ b/src/Nerve_GIC/test/test_GIC.cpp
@@ -41,35 +41,35 @@ BOOST_AUTO_TEST_CASE(check_nerve) {
std::string graph_file_name("data/graph"); GIC.set_graph_from_file(graph_file_name);
std::string cover_file_name("data/cover"); GIC.set_cover_from_file(cover_file_name);
GIC.set_color_from_coordinate();
- GIC.find_Nerve_simplices(); Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ GIC.find_Nerve_simplices(); Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
BOOST_CHECK(stree.num_vertices() == 3);
BOOST_CHECK((stree.num_simplices()-stree.num_vertices()) == 0);
BOOST_CHECK(stree.dimension() == 0);
}
-BOOST_AUTO_TEST_CASE(check_GICMAP) {
+BOOST_AUTO_TEST_CASE(check_funcGIC) {
using Point = std::vector<float>;
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
std::string cloud_file_name("data/cloud"); GIC.read_point_cloud(cloud_file_name); GIC.set_color_from_coordinate();
std::string graph_file_name("data/graph"); GIC.set_graph_from_file(graph_file_name);
std::string cover_file_name("data/cover"); GIC.set_cover_from_file(cover_file_name);
- GIC.find_GICMAP_simplices_with_functional_minimal_cover(); Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ GIC.find_GIC_simplices_with_functional_minimal_cover(); Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
BOOST_CHECK(stree.num_vertices() == 3);
BOOST_CHECK((stree.num_simplices()-stree.num_vertices()) == 2);
BOOST_CHECK(stree.dimension() == 1);
}
-BOOST_AUTO_TEST_CASE(check_GICcover) {
+BOOST_AUTO_TEST_CASE(check_regGIC) {
using Point = std::vector<float>;
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
std::string cloud_file_name("data/cloud"); GIC.read_point_cloud(cloud_file_name); GIC.set_color_from_coordinate();
std::string graph_file_name("data/graph"); GIC.set_graph_from_file(graph_file_name);
std::string cover_file_name("data/cover"); GIC.set_cover_from_file(cover_file_name);
- GIC.find_GIC_simplices(); Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ GIC.find_GIC_simplices(); Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
BOOST_CHECK(stree.num_vertices() == 3);
BOOST_CHECK((stree.num_simplices()-stree.num_vertices()) == 4);
@@ -77,14 +77,14 @@ BOOST_AUTO_TEST_CASE(check_GICcover) {
}
-BOOST_AUTO_TEST_CASE(check_GICvoronoi) {
+BOOST_AUTO_TEST_CASE(check_voronoiGIC) {
using Point = std::vector<float>;
Gudhi::graph_induced_complex::Graph_induced_complex<Point> GIC;
std::string cloud_file_name("data/cloud"); GIC.read_point_cloud(cloud_file_name); GIC.set_color_from_coordinate();
std::string graph_file_name("data/graph"); GIC.set_graph_from_file(graph_file_name);
GIC.set_cover_from_Voronoi(Gudhi::Euclidean_distance(),2);
- GIC.find_GIC_simplices(); Gudhi::graph_induced_complex::Simplex_tree stree; GIC.create_complex(stree);
+ GIC.find_GIC_simplices(); Gudhi::Simplex_tree<> stree; GIC.create_complex(stree);
BOOST_CHECK(stree.num_vertices() == 2);
BOOST_CHECK((stree.num_simplices()-stree.num_vertices()) == 1);