summaryrefslogtreecommitdiff
path: root/src/Nerve_GIC
diff options
context:
space:
mode:
authormcarrier <mcarrier@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2017-05-12 15:37:55 +0000
committermcarrier <mcarrier@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2017-05-12 15:37:55 +0000
commit6adf87fe0a609443962238200e877c60d90f6a2d (patch)
tree5da27b1886fb7fe76ec8f9dd6a586ac7a5b3fd25 /src/Nerve_GIC
parent9e1a4e80bc3f2cffc965dc3f5194ea308ca9afab (diff)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@2413 636b058d-ea47-450e-bf9e-a15bfbe3eedb
Former-commit-id: a0a65ae49ca0bb6e5ed614f44cabb060fa0e7490
Diffstat (limited to 'src/Nerve_GIC')
-rw-r--r--src/Nerve_GIC/example/CMakeLists.txt6
-rw-r--r--src/Nerve_GIC/example/GIC.cpp15
-rw-r--r--src/Nerve_GIC/example/GICvoronoi.cpp59
-rw-r--r--src/Nerve_GIC/example/MapperDeltaCoord.cpp13
-rw-r--r--src/Nerve_GIC/example/MapperDeltaFunc.cpp13
-rw-r--r--src/Nerve_GIC/example/Nerve.cpp13
-rw-r--r--src/Nerve_GIC/include/gudhi/GIC.h139
-rw-r--r--src/Nerve_GIC/test/CMakeLists.txt23
8 files changed, 213 insertions, 68 deletions
diff --git a/src/Nerve_GIC/example/CMakeLists.txt b/src/Nerve_GIC/example/CMakeLists.txt
index d499613d..a4cb0f03 100644
--- a/src/Nerve_GIC/example/CMakeLists.txt
+++ b/src/Nerve_GIC/example/CMakeLists.txt
@@ -13,9 +13,15 @@ target_link_libraries(MapperDeltaCoord ${Boost_SYSTEM_LIBRARY})
add_executable ( MapperDeltaFunc MapperDeltaFunc.cpp )
target_link_libraries(MapperDeltaFunc ${Boost_SYSTEM_LIBRARY})
+add_executable ( GICvoronoi GICvoronoi.cpp )
+target_link_libraries(GICvoronoi ${Boost_SYSTEM_LIBRARY})
+
+file(COPY visu.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})
endif() \ No newline at end of file
diff --git a/src/Nerve_GIC/example/GIC.cpp b/src/Nerve_GIC/example/GIC.cpp
index 30a485d5..1ab15ecc 100644
--- a/src/Nerve_GIC/example/GIC.cpp
+++ b/src/Nerve_GIC/example/GIC.cpp
@@ -3,7 +3,7 @@
void usage(int nbArgs, char * const progName) {
std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
std::cerr << "Usage: " << progName << " filename.off threshold coordinate resolution gain\n";
- std::cerr << " i.e.: " << progName << " ../../../data/points/human.off 1.5 2 10 0.3 \n";
+ std::cerr << " i.e.: " << progName << " ../../../data/points/human.off 0.075 2 10 0.3 \n";
exit(-1); // ----- >>
}
@@ -17,11 +17,6 @@ int main(int argc, char **argv) {
double gain = atof(argv[5]);
bool verb = 0; if(argc == 7) verb = 1;
- // Type definitions
- using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\
- boost::property < vertex_filtration_t, Filtration_value >,\
- boost::property < edge_filtration_t, Filtration_value > >;
-
// ----------------------------------------------------------------------------
// Init of a graph induced complex from an OFF file
// ----------------------------------------------------------------------------
@@ -29,12 +24,16 @@ int main(int argc, char **argv) {
Gudhi::graph_induced_complex::Graph_induced_complex GIC;
GIC.set_verbose(verb);
- GIC.set_graph_from_rips(threshold, off_file_name);
- GIC.set_function_from_coordinate(coord, off_file_name);
GIC.set_color_from_coordinate(off_file_name, coord);
+ GIC.set_function_from_coordinate(coord, off_file_name);
+
+ GIC.set_graph_from_rips(threshold, off_file_name);
+
GIC.set_resolution_double(resolution); GIC.set_gain(gain);
GIC.set_cover_from_function(1);
+
GIC.find_GIC_simplices();
+
GIC.plot_with_KeplerMapper();
Simplex_tree stree; GIC.create_complex(stree);
diff --git a/src/Nerve_GIC/example/GICvoronoi.cpp b/src/Nerve_GIC/example/GICvoronoi.cpp
new file mode 100644
index 00000000..2d50ab4d
--- /dev/null
+++ b/src/Nerve_GIC/example/GICvoronoi.cpp
@@ -0,0 +1,59 @@
+#include <gudhi/GIC.h>
+
+void usage(int nbArgs, char * const progName) {
+ std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n";
+ std::cerr << "Usage: " << progName << " filename.off threshold N\n";
+ std::cerr << " i.e.: " << progName << " ../../../data/points/human.off 0.075 100 \n";
+ exit(-1); // ----- >>
+}
+
+int main(int argc, char **argv) {
+ if ((argc != 4) && (argc != 5)) usage(argc, (argv[0] - 1));
+
+ std::string off_file_name(argv[1]);
+ double threshold = atof(argv[2]);
+ int m = atoi(argv[3]);
+ bool verb = 0; if(argc == 5) verb = 1;
+
+ // ----------------------------------------------------------------------------
+ // Init of a graph induced complex from an OFF file
+ // ----------------------------------------------------------------------------
+
+ Gudhi::graph_induced_complex::Graph_induced_complex GIC;
+ GIC.set_verbose(verb);
+
+ GIC.set_color_from_coordinate(off_file_name);
+
+ GIC.set_graph_from_OFF(off_file_name);
+
+ GIC.set_cover_from_Voronoi(m, off_file_name);
+
+ GIC.find_GIC_simplices();
+
+ GIC.plot_with_KeplerMapper();
+
+ Simplex_tree stree; GIC.create_complex(stree);
+
+ std::streambuf* streambufffer = std::cout.rdbuf();
+ std::ostream output_stream(streambufffer);
+
+ // ----------------------------------------------------------------------------
+ // Display information about the graph induced complex
+ // ----------------------------------------------------------------------------
+
+ if(verb){
+ output_stream << "Graph induced complex is of dimension " << stree.dimension() <<
+ " - " << stree.num_simplices() << " simplices - " <<
+ stree.num_vertices() << " vertices." << std::endl;
+
+ output_stream << "Iterator on graph induced complex simplices" << std::endl;
+ for (auto f_simplex : stree.filtration_simplex_range()) {
+ for (auto vertex : stree.simplex_vertex_range(f_simplex)) {
+ output_stream << vertex << " ";
+ }
+ output_stream << std::endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Nerve_GIC/example/MapperDeltaCoord.cpp b/src/Nerve_GIC/example/MapperDeltaCoord.cpp
index aa12afe6..950ee58a 100644
--- a/src/Nerve_GIC/example/MapperDeltaCoord.cpp
+++ b/src/Nerve_GIC/example/MapperDeltaCoord.cpp
@@ -14,11 +14,6 @@ int main(int argc, char **argv) {
int coord = atoi(argv[2]);
bool verb = 0; if(argc == 4) verb = 1;
- // Type definitions
- using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\
- boost::property < vertex_filtration_t, Filtration_value >,\
- boost::property < edge_filtration_t, Filtration_value > >;
-
// ---------------------------------------
// Init of a Mapper Delta from an OFF file
// ---------------------------------------
@@ -26,12 +21,16 @@ int main(int argc, char **argv) {
Gudhi::graph_induced_complex::Graph_induced_complex GIC;
GIC.set_verbose(verb);
- GIC.set_graph_from_automatic_rips(off_file_name);
- GIC.set_function_from_coordinate(coord, off_file_name);
GIC.set_color_from_coordinate(off_file_name, coord);
+ GIC.set_function_from_coordinate(coord, off_file_name);
+
+ GIC.set_graph_from_automatic_rips(off_file_name);
+
GIC.set_automatic_resolution_for_GICMAP(); GIC.set_gain();
GIC.set_cover_from_function(1);
+
GIC.find_GICMAP_simplices_with_functional_minimal_cover();
+
GIC.plot_with_KeplerMapper();
Simplex_tree stree; GIC.create_complex(stree);
diff --git a/src/Nerve_GIC/example/MapperDeltaFunc.cpp b/src/Nerve_GIC/example/MapperDeltaFunc.cpp
index 20924b9c..658b0273 100644
--- a/src/Nerve_GIC/example/MapperDeltaFunc.cpp
+++ b/src/Nerve_GIC/example/MapperDeltaFunc.cpp
@@ -14,11 +14,6 @@ int main(int argc, char **argv) {
std::string func_file_name = argv[2];
bool verb = 0; if(argc == 4) verb = 1;
- // Type definitions
- using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\
- boost::property < vertex_filtration_t, Filtration_value >,\
- boost::property < edge_filtration_t, Filtration_value > >;
-
// ---------------------------------------
// Init of a Mapper Delta from an OFF file
// ---------------------------------------
@@ -26,12 +21,16 @@ int main(int argc, char **argv) {
Gudhi::graph_induced_complex::Graph_induced_complex GIC;
GIC.set_verbose(verb);
- GIC.set_graph_from_automatic_rips(off_file_name);
- GIC.set_function_from_file(func_file_name);
GIC.set_color_from_file(func_file_name);
+ GIC.set_function_from_file(func_file_name);
+
+ GIC.set_graph_from_automatic_rips(off_file_name);
+
GIC.set_automatic_resolution_for_GICMAP(); GIC.set_gain();
GIC.set_cover_from_function(1);
+
GIC.find_GICMAP_simplices_with_functional_minimal_cover();
+
GIC.plot_with_KeplerMapper();
Simplex_tree stree; GIC.create_complex(stree);
diff --git a/src/Nerve_GIC/example/Nerve.cpp b/src/Nerve_GIC/example/Nerve.cpp
index d4a68c71..a0de31ae 100644
--- a/src/Nerve_GIC/example/Nerve.cpp
+++ b/src/Nerve_GIC/example/Nerve.cpp
@@ -16,11 +16,6 @@ int main(int argc, char **argv) {
double gain = atof(argv[4]);
bool verb = 0; if(argc == 6) verb = 1;
- // Type definitions
- using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\
- boost::property < vertex_filtration_t, Filtration_value >,\
- boost::property < edge_filtration_t, Filtration_value > >;
-
// --------------------------------
// Init of a Nerve from an OFF file
// --------------------------------
@@ -28,12 +23,16 @@ int main(int argc, char **argv) {
Gudhi::graph_induced_complex::Graph_induced_complex GIC;
GIC.set_verbose(verb);
- GIC.set_graph_from_OFF(off_file_name);
+ GIC.set_color_from_coordinate(off_file_name, coord);
GIC.set_function_from_coordinate(coord, off_file_name);
- GIC.set_color_from_coordinate(off_file_name, --coord);
+
+ GIC.set_graph_from_OFF(off_file_name);
+
GIC.set_resolution_int(resolution); GIC.set_gain(gain);
GIC.set_cover_from_function(0);
+
GIC.find_Nerve_simplices();
+
GIC.plot_with_KeplerMapper();
Simplex_tree stree; GIC.create_complex(stree);
diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h
index e9b7a1f1..205aa87e 100644
--- a/src/Nerve_GIC/include/gudhi/GIC.h
+++ b/src/Nerve_GIC/include/gudhi/GIC.h
@@ -30,6 +30,8 @@
#include <gudhi/Rips_complex.h>
#include <gudhi/Points_off_io.h>
#include <gudhi/distance_functions.h>
+#include <gudhi/Kd_tree_search.h>
+#include <CGAL/Epick_d.h>
#include <boost/graph/adjacency_list.hpp>
@@ -51,11 +53,18 @@
#define ETA 0.001
#define MASK 0
+namespace gss = Gudhi::spatial_searching;
+
using Simplex_tree = Gudhi::Simplex_tree<>;
using Filtration_value = Simplex_tree::Filtration_value;
using Rips_complex = Gudhi::rips_complex::Rips_complex<Filtration_value>;
using Point = std::vector<float>;
+typedef CGAL::Epick_d<CGAL::Dimension_tag<4> > K;
+typedef typename K::Point_d Pointd;
+typedef std::vector<Pointd> Pointsd;
+typedef gss::Kd_tree_search<K, Pointsd> Points_ds;
+
std::map<int, double> func;
std::map<int, double> func_color;
@@ -88,14 +97,14 @@ namespace graph_induced_complex {
class Graph_induced_complex {
private:
- bool verbose;
- typedef int Cover_t;
+ bool verbose; // whether to display information.
+ typedef int Cover_t; // elements of cover C are indexed by integers.
std::vector<std::vector<Cover_t> > simplices;
std::map<int, std::vector<Cover_t> > cover;
- int maximal_dim;
- int data_dimension;
- std::map<Cover_t,int> cover_fct;
- std::map<Cover_t,std::pair<int,double> > cover_color;
+ int maximal_dim; // maximal dimension of output simplicial complex.
+ int data_dimension; // dimension of input data.
+ std::map<Cover_t,int> cover_fct; // integer-valued function that allows to state if two elements of the cover are consecutive or not.
+ std::map<Cover_t,std::pair<int,double> > cover_color; // size and coloring of the vertices of the output simplicial complex.
Simplex_tree<> st;
std::map<int,std::vector<int> > adjacency_matrix;
int resolution_int;
@@ -187,10 +196,10 @@ class Graph_induced_complex {
*
*/
void set_graph_from_OFF(const std::string& off_file_name){
- int numpts, numedges, numfaces, i; std::vector<int> edge(2); double x; int num; std::vector<int> simplex;
+ int n, numedges, numfaces, i; std::vector<int> edge(2); double x; int num; std::vector<int> simplex;
std::ifstream input(off_file_name); std::string line; getline(input, line);
- input >> numpts; input >> numfaces; input >> numedges;
- i = 0; while(i < numpts){input >> x; input >> x; input >> x; i++;}
+ input >> n; input >> numfaces; input >> numedges;
+ i = 0; while(i < n){input >> x; input >> x; input >> x; 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);}
@@ -204,7 +213,7 @@ class Graph_induced_complex {
}
std::vector<int> empty;
- for(int i = 0; i < numpts; i++) adjacency_matrix.insert(std::pair<int,std::vector<int> >(i,empty));
+ for(int i = 0; i < n; i++) adjacency_matrix.insert(std::pair<int,std::vector<int> >(i,empty));
for (auto simplex : st.complex_simplex_range()) {
if(st.dimension(simplex) == 1){
std::vector<int> vertices;
@@ -292,7 +301,7 @@ class Graph_induced_complex {
}
}
- #pragma omp parallel for
+ //#pragma omp parallel for
for (int i = 0; i < N; i++){
SampleWithoutReplacement(n,m,samples);
@@ -349,8 +358,8 @@ class Graph_induced_complex {
*/
void set_function_from_coordinate(const int& k, const std::string& off_file_name){
Points_off_reader<Point> off_reader(off_file_name);
- int numpts = off_reader.get_point_cloud().size();
- for(int i = 0; i < numpts; i++) func.insert(std::pair<int,double>(i,off_reader.get_point_cloud()[i][k]));
+ int n = off_reader.get_point_cloud().size();
+ for(int i = 0; i < n; i++) func.insert(std::pair<int,double>(i,off_reader.get_point_cloud()[i][k]));
}
public: // Set function from vector.
@@ -360,7 +369,8 @@ class Graph_induced_complex {
*
*/
void set_function_from_vector(const std::vector<double>& function){
- for(int i = 0; i < function.size(); i++) func.insert(std::pair<int,double>(i, function[i]));
+ int n = function.size();
+ for(int i = 0; i < n; i++) func.insert(std::pair<int,double>(i, function[i]));
}
// *******************************************************************************************************************
@@ -379,12 +389,56 @@ class Graph_induced_complex {
std::ifstream input(cover_file_name); std::string line;
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); cover_fct.insert(std::pair<Cover_t,int>(cov,cov));}
- cover.insert(std::pair<int, std::vector<Cover_t> >(vertex_id, cov_elts)); vertex_id++;
+ while(stream >> cov){
+ cov_elts.push_back(cov); cov_number.push_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++;
}
std::vector<Cover_t>::iterator it;
std::sort(cov_number.begin(),cov_number.end()); it = std::unique(cov_number.begin(),cov_number.end());
- cov_number.resize(std::distance(cov_number.begin(),it)); maximal_dim = cov_number.size();
+ cov_number.resize(std::distance(cov_number.begin(),it)); maximal_dim = cov_number.size()-1;
+ for(int i = 0; i <= maximal_dim; i++) cover_color[i].second /= cover_color[i].first;
+ }
+
+ public: // Set cover from Voronoi
+ /** \brief Creates the cover C from the Voronoï cells of a subsampling of the point cloud.
+ *
+ * @param[in] m number of points in the subsample.
+ * @param[in] off_file_name name of the input .OFF file.
+ *
+ */
+ void set_cover_from_Voronoi(const int& m, const std::string& off_file_name){
+ Points_off_reader<Point> off_reader(off_file_name);
+ int n = off_reader.get_point_cloud().size(); data_dimension = off_reader.get_point_cloud()[0].size();
+ Pointsd pointsd(m+1); std::vector<int> samples(m); SampleWithoutReplacement(n,m,samples);
+ double* coord = new double[data_dimension];
+
+ for(int i = 1; i <= m; i++){
+ for(int j = 0; j < data_dimension; j++) coord[j] = off_reader.get_point_cloud()[samples[i-1]][j];
+ pointsd[i] = Pointd(data_dimension, coord+0, coord + data_dimension); cover_fct[i-1] = i-1;
+ } std::cout << std::endl;
+
+ int curr_subsample = 0;
+ for(int i = 0; i < n; i++){
+ for(int j = 0; j < data_dimension; j++) coord[j] = off_reader.get_point_cloud()[i][j];
+ pointsd[0] = Pointd(data_dimension, coord+0, coord + data_dimension); Points_ds points_ds(pointsd);
+ auto knn_range = points_ds.query_k_nearest_neighbors(pointsd[0], 2, true);
+ Cover_t cluster = (knn_range.begin()+1)->first-1;
+ if(cluster >= 0){ // Case where i is not a subsample point.
+ cover[i].push_back(cluster); cover_color[cluster].second += func_color[i]; cover_color[cluster].first++;
+ }
+ else{ // Case where i is a subsample point.
+ cover[i].push_back(curr_subsample); cover_color[curr_subsample].second += func_color[i];
+ cover_color[curr_subsample].first++; curr_subsample++;
+ }
+ }
+
+ for(int i = 0; i < m; i++) cover_color[i].second /= cover_color[i].first;
+
+ delete [] coord;
+ maximal_dim = m-1;
+
}
public: // Automatic tuning of resolution for Mapper Delta.
@@ -448,9 +502,10 @@ class Graph_induced_complex {
void set_cover_from_function(const bool& token){
// Read function values and compute min and max
- std::map<int, double>::iterator it; double maxf, minf; minf = std::numeric_limits<float>::max(); maxf = std::numeric_limits<float>::min();
+ std::map<int, double>::iterator it;
+ double maxf, minf; minf = std::numeric_limits<float>::max(); maxf = std::numeric_limits<float>::min();
for(it = func.begin(); it != func.end(); it++){minf = std::min(minf, it->second); maxf = std::max(maxf, it->second);}
- int num_pts = func.size(); if(verbose) std::cout << "Min function value = " << minf << " and Max function value = " << maxf << std::endl;
+ int n = func.size(); if(verbose) std::cout << "Min function value = " << minf << " and Max function value = " << maxf << std::endl;
// Compute cover of im(f)
std::vector<std::pair<double,double> > intervals; int res;
@@ -477,40 +532,41 @@ class Graph_induced_complex {
y = x + resolution_double;
}
std::pair<double, double> interM(x,maxf); intervals.push_back(interM); res = intervals.size();
- for(int i = 0; i < res; i++) if(verbose) std::cout << "Interval " << i << " = [" << intervals[i].first << ", " << intervals[i].second << "]" << std::endl;
+ for(int i = 0; i < res; i++) if(verbose) std::cout << "Interval " << i << " = [" << \
+ intervals[i].first << ", " << intervals[i].second << "]" << std::endl;
}
// Sort points according to function values
- std::vector<int> points(num_pts); for(int i = 0; i < num_pts; i++) points[i] = i;
+ std::vector<int> points(n); for(int i = 0; i < n; i++) points[i] = i;
std::sort(points.begin(),points.end(),functional_comp);
- int id = 0; int pos = 0; double min_prop_int; double max_prop_int;
+ int id = 0; int pos = 0;
for(int i = 0; i < res; i++){
// Find points in the preimage
std::map<int,std::vector<int> > prop; prop.clear();
- std::pair<double, double> inter1 = intervals[i]; min_prop_int = inter1.first;
+ std::pair<double, double> inter1 = intervals[i];
int tmp = pos;
if(i != res-1){
if(i != 0){
- std::pair<double, double> inter3 = intervals[i-1]; min_prop_int = inter3.second;
- while(func[points[tmp]] < inter3.second && tmp != num_pts){
+ std::pair<double, double> inter3 = intervals[i-1];
+ while(func[points[tmp]] < inter3.second && tmp != n){
prop.insert(std::pair<int,std::vector<int> >(points[tmp],adjacency_matrix[points[tmp]]));
tmp++;
}
}
- std::pair<double, double> inter2 = intervals[i+1]; max_prop_int = inter2.first;
- while(func[points[tmp]] < inter2.first && tmp != num_pts){
+ std::pair<double, double> inter2 = intervals[i+1];
+ while(func[points[tmp]] < inter2.first && tmp != n){
prop.insert(std::pair<int,std::vector<int> >(points[tmp],adjacency_matrix[points[tmp]]));
tmp++;
}
pos = tmp;
- while(func[points[tmp]] < inter1.second && tmp != num_pts){
+ while(func[points[tmp]] < inter1.second && tmp != n){
prop.insert(std::pair<int,std::vector<int> >(points[tmp],adjacency_matrix[points[tmp]]));
tmp++;
}
@@ -520,13 +576,12 @@ class Graph_induced_complex {
else{
std::pair<double, double> inter3 = intervals[i-1];
- min_prop_int = inter3.second; max_prop_int = inter1.second;
- while(func[points[tmp]] < inter3.second && tmp != num_pts){
+ while(func[points[tmp]] < inter3.second && tmp != n){
prop.insert(std::pair<int,std::vector<int> >(points[tmp],adjacency_matrix[points[tmp]]));
tmp++;
}
- while(tmp != num_pts){
+ while(tmp != n){
prop.insert(std::pair<int,std::vector<int> >(points[tmp],adjacency_matrix[points[tmp]]));
tmp++;
}
@@ -552,7 +607,7 @@ class Graph_induced_complex {
if(verbose) std::cout << std::endl;
}
- maximal_dim = id;
+ maximal_dim = id-1;
}
@@ -583,8 +638,8 @@ class Graph_induced_complex {
*/
void set_color_from_coordinate(const std::string& off_file_name, int k = 0){
Points_off_reader<Point> off_reader(off_file_name);
- int numpts = off_reader.get_point_cloud().size();
- for(int i = 0; i < numpts; i++) func_color.insert(std::pair<int,double>(i,off_reader.get_point_cloud()[i][k]));
+ int n = off_reader.get_point_cloud().size();
+ for(int i = 0; i < n; i++) func_color[i] = off_reader.get_point_cloud()[i][k];
}
public: // Set color from vector.
@@ -594,7 +649,7 @@ class Graph_induced_complex {
*
*/
void set_color_from_vector(const std::vector<double>& color){
- for(int i = 0; i < color.size(); i++) func_color.insert(std::pair<int,double>(i, color[i]));
+ for(unsigned int i = 0; i < color.size(); i++) func_color.insert(std::pair<int,double>(i, color[i]));
}
public: // Create a .dot file that can be compiled with neato to produce a .pdf file
@@ -605,7 +660,7 @@ class Graph_induced_complex {
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);
- }
+ } //std::cout << minv << " " << maxv << std::endl;
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){
@@ -622,6 +677,9 @@ class Graph_induced_complex {
if (cover_color[simplices[i][0]].first > MASK && cover_color[simplices[i][1]].first > MASK){
graphic << " " << simplices[i][0] << " -- " << simplices[i][1] << " [weight=15];" << std::endl; ke++;}
graphic << "}"; graphic.close();
+ char command[100]; sprintf(command, "neato SC.dot -Tpdf -o SC_visu.pdf && rm SC.dot");
+ int systemRet = system(command);
+ if(systemRet == -1) std::cout << "Visualization failed. Do you have neato?" << std::endl;
}
public: // Create a .txt file that can be compiled with KeplerMapper to produce a .html file
@@ -649,6 +707,9 @@ class Graph_induced_complex {
if (cover_color[simplices[i][0]].first > MASK && cover_color[simplices[i][1]].first > MASK)
graphic << simplices[i][0] << " " << simplices[i][1] << std::endl;
graphic.close();
+ char command[100]; sprintf(command, "python visu.py && firefox SC_visu.html");
+ int systemRet = system(command);
+ if(systemRet == -1) std::cout << "Visualization failed. Do you have python and firefox?" << std::endl;
}
// *******************************************************************************************************************
@@ -663,8 +724,8 @@ class Graph_induced_complex {
*/
template<typename SimplicialComplexForGIC>
void create_complex(SimplicialComplexForGIC & complex) {
- size_t sz = simplices.size(); int dimension = 0;
- for(int i = 0; i < sz; i++){
+ size_t sz = simplices.size(); unsigned int dimension = 0;
+ for(unsigned int i = 0; i < sz; i++){
complex.insert_simplex_and_subfaces(simplices[i]);
if(dimension < simplices[i].size()-1) dimension = simplices[i].size()-1;
}
@@ -681,7 +742,7 @@ class Graph_induced_complex {
int num_nodes = cover_elts.size();
std::vector<Cover_t> simplex;
for(int i = 0; i < num_nodes; i++)
- for(int j = 0; j < cover_elts[i].size(); j++)
+ for(unsigned int j = 0; j < cover_elts[i].size(); j++)
simplex.push_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));
diff --git a/src/Nerve_GIC/test/CMakeLists.txt b/src/Nerve_GIC/test/CMakeLists.txt
new file mode 100644
index 00000000..627778fa
--- /dev/null
+++ b/src/Nerve_GIC/test/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 2.6)
+project(Graph_induced_complex_tests)
+
+if (GCOVR_PATH)
+ # for gcovr to make coverage reports - Corbera Jenkins plugin
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
+endif()
+if (GPROF_PATH)
+ # for gprof to make coverage reports - Jenkins
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg")
+endif()
+
+add_executable ( graph_induced_complex_UT test_GIC.cpp )
+target_link_libraries(graph_induced_complex_UT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(graph_induced_complex_UT ${TBB_LIBRARIES})
+endif()
+
+file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
+add_test(graph_induced_complex_UT ${CMAKE_CURRENT_BINARY_DIR}/graph_induced_complex_UT
+ # XML format for Jenkins xUnit plugin
+ --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/graph_induced_complex_UT.xml --log_level=test_suite --report_level=no)