From 99bff40a1028f8848cdcdc76d8f53ef3b9b9c43d Mon Sep 17 00:00:00 2001 From: mcarrier Date: Fri, 28 Jul 2017 14:33:44 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@2598 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1624f24a6f87ac092e1761c9778741102fb37a3c --- src/Nerve_GIC/include/gudhi/GIC.h | 146 ++++++++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 52 deletions(-) (limited to 'src/Nerve_GIC/include/gudhi') diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index 42225c47..f00856ed 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -77,6 +77,7 @@ class Graph_induced_complex { //Graph_induced_complex(std::map fun){func = fun;} bool verbose; // whether to display information. std::vector point_cloud; + std::vector > one_skeleton; typedef int Cover_t; // elements of cover C are indexed by integers. std::vector > simplices; std::map > cover; @@ -88,9 +89,9 @@ class Graph_induced_complex { Simplex_tree st; std::map > adjacency_matrix; std::vector > distances; - int resolution_int; - double resolution_double; - double gain; + 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. @@ -152,23 +153,62 @@ class Graph_induced_complex { } public: + /** \brief Specifies whether the program should display information or not. + * + * @param[in] verb boolean (true = display info, false = do not display info). + * + */ void set_verbose(bool verb = 0){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". + * + * @param[in] constant double. + * @param[in] power double. + * + */ void set_subsampling(double constant = 10, double power = 0.001){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. + * + * @param[in] nodemask integer. + * + */ void set_mask(int nodemask = 0){mask = nodemask;} public: + /** \brief Reads and stores the input point cloud. + * + * @param[in] off_file_name name of the input .OFF file. + * + */ bool read_point_cloud(std::string off_file_name){ - Gudhi::Points_off_reader off_reader = Points_off_reader(off_file_name); - bool check = off_reader.is_valid(); - if(check){ - point_cloud = off_reader.get_point_cloud(); - point_cloud_name = off_file_name; - n = point_cloud.size(); - data_dimension = point_cloud[0].size(); - return check; - } else return check; + point_cloud_name = off_file_name; + int numedges, numfaces, i, num; std::vector edge(2); + std::vector simplex; + std::ifstream input(off_file_name); std::string line; getline(input, line); + input >> n; input >> numfaces; input >> numedges; getline(input, line); + + i = 0; while(i < n){ + getline(input, line); + std::vector point; std::istringstream iss(line); + point.assign(std::istream_iterator(iss), std::istream_iterator()); + point_cloud.push_back(Point(point.begin(),point.end())); i++; + } data_dimension = point_cloud[0].size(); + + 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); + } + } + i++; + } + + return input.is_open(); } // ******************************************************************************************************************* @@ -197,29 +237,17 @@ class Graph_induced_complex { } public: // Set graph from OFF file. - /** \brief Creates the graph G from the triangulation given by an .OFF file. - * - * @param[in] off_file_name name of the input .OFF file. + /** \brief Creates the graph G from the triangulation given by the input .OFF file. * */ - void set_graph_from_OFF(std::string off_file_name){ - int numedges, numfaces, i; std::vector edge(2); double x; int num; std::vector simplex; - std::ifstream input(off_file_name); std::string line; getline(input, line); - 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);} - for(int j = 0; j < num; j++){ - for(int k = j+1; k < num; k++){ - edge[0] = simplex[j]; edge[1] = simplex[k]; - st.insert_simplex_and_subfaces(edge); - } - } - i++; - } + void set_graph_from_OFF(){ - fill_adjacency_matrix_from_st(); + int num_edges = one_skeleton.size(); + if(num_edges > 0){ + for(int i = 0; i < num_edges; i++) st.insert_simplex_and_subfaces(one_skeleton[i]); + fill_adjacency_matrix_from_st(); + } + else std::cout << "No triangulation read in OFF file!" << std::endl; } @@ -378,13 +406,13 @@ class Graph_induced_complex { * @param[in] reso length of intervals. * */ - void set_resolution_double(double reso){resolution_double = reso;} + void set_resolution_with_interval_length(double reso){resolution_double = reso;} /** \brief Sets a number of intervals from a value stored in memory. * * @param[in] reso number of intervals. * */ - void set_resolution_int(int reso){resolution_int = reso;} + void set_resolution_with_interval_number(int reso){resolution_int = reso;} /** \brief Sets a gain from a value stored in memory (default value 0.3). * * @param[in] g gain. @@ -410,11 +438,12 @@ class Graph_induced_complex { public: // Set cover with preimages of function. /** \brief Creates a cover C from the preimages of the function f. - * - * @param[in] token boolean specifying whether we use the length or the number of intervals for the cover of im(f). * */ - void set_cover_from_function(bool token){ + void set_cover_from_function(){ + + if(resolution_double == -1 && resolution_int == -1){ std::cout << "Number and/or length of intervals not specified" << std::endl; return; } + if(gain == -1){ std::cout << "Gain not specified" << std::endl; return; } // Read function values and compute min and max std::map::iterator it; @@ -425,7 +454,7 @@ class Graph_induced_complex { // Compute cover of im(f) std::vector > intervals; int res; - if(!token){ // Case we use an integer for the number of intervals. + 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 interm(x,y); intervals.push_back(interm); for(int i = 1; i < resolution_int-1; i++){ @@ -439,16 +468,30 @@ class Graph_induced_complex { for(int i = 0; i < res; i++) std::cout << "Interval " << i << " = [" << intervals[i].first << ", " << intervals[i].second << "]" << std::endl; } - else{ // 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 inter(x,y); intervals.push_back(inter); - x = y - gain*resolution_double; - y = x + resolution_double; + else{ + 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 inter(x,y); intervals.push_back(inter); + x = y - gain*resolution_double; + y = x + resolution_double; + } + std::pair interM(x,maxf); intervals.push_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; + } + + 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 inter(x,y); intervals.push_back(inter); count++; + x = y - gain*resolution_double; + y = x + resolution_double; + } + res = intervals.size(); + if(verbose) + for(int i = 0; i < res; i++) std::cout << "Interval " << i << " = [" << intervals[i].first << ", " << intervals[i].second << "]" << std::endl; } - std::pair interM(x,maxf); intervals.push_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; } // Sort points according to function values @@ -624,7 +667,6 @@ class Graph_induced_complex { /** \brief Computes the function used to color the nodes of the simplicial complex from the k-th coordinate. * * @param[in] k coordinate to use (start at 0). - * @param[in] off_file_name name of the input .OFF file. * */ void set_color_from_coordinate(int k = 0){ @@ -643,10 +685,10 @@ 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 once the simplicial complex is computed to get a nice visualization + /** \brief Creates a .dot file 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_pdf(){ + void plot_DOT_for_neato(){ char mapp[11] = "SC.dot"; std::ofstream graphic(mapp); graphic << "graph Mapper {" << std::endl; double maxv, minv; maxv = std::numeric_limits::min(); minv = std::numeric_limits::max(); for (std::map >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++){ @@ -672,10 +714,10 @@ class Graph_induced_complex { } 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 nice visualization + /** \brief Creates a .txt file for KeplerMapper once the simplicial complex is computed to get a visualization * of its 1-skeleton in browser. */ - void plot_txt(){ + void plot_TXT_for_KeplerMapper(){ int num_simplices = simplices.size(); int num_edges = 0; char mapp[11] = "SC.txt"; std::ofstream graphic(mapp); -- cgit v1.2.3