diff options
-rw-r--r-- | src/Nerve_GIC/include/gudhi/GIC.h | 88 | ||||
-rw-r--r-- | src/cython/cython/nerve_gic.pyx | 30 |
2 files changed, 98 insertions, 20 deletions
diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index fea0b861..30f89d65 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -226,7 +226,25 @@ class Cover_complex { void set_mask(int nodemask) { mask = nodemask; } public: - /** \brief Reads and stores the input point cloud. + + + /** \brief Reads and stores the input point cloud from vector stored in memory. + * + * @param[in] cloud input vector representing the point cloud. Each row is a point and each coordinate is a vector. + * + */ + template <class InputRange> + void set_point_cloud_from_range(InputRange const & cloud) { + n = cloud.size(); data_dimension = cloud[0].size(); point_cloud_name = "matrix"; + for(int i = 0; i < n; i++){ + point_cloud.emplace_back(cloud[i].begin(), cloud[i].begin() + data_dimension); + boost::add_vertex(one_skeleton_OFF); + vertices.push_back(boost::add_vertex(one_skeleton)); + cover.emplace_back(); + } + } + + /** \brief Reads and stores the input point cloud from .(n)OFF file. * * @param[in] off_file_name name of the input .OFF or .nOFF file. * @@ -371,6 +389,28 @@ class Cover_complex { distances[index[boost::source(*ei, one_skeleton)]][index[boost::target(*ei, one_skeleton)]]); } + public: + /** \brief Reads and stores the distance matrices from vector stored in memory. + * + * @param[in] distance_matrix input vector representing the distance matrix. + * + */ + template <class InputRange> + void set_distances_from_range(InputRange const & distance_matrix) { + if(point_cloud.size() == 0){ + n = distance_matrix.size(); + point_cloud_name = "matrix"; + data_dimension = 0; + for(int i = 0; i < n; i++){ + point_cloud.emplace_back(); + boost::add_vertex(one_skeleton_OFF); + vertices.push_back(boost::add_vertex(one_skeleton)); + cover.emplace_back(); + } + } + distances = distance_matrix; + } + public: // Pairwise distances. /** \private \brief Computes all pairwise distances. */ @@ -500,9 +540,17 @@ class Cover_complex { * */ void set_function_from_coordinate(int k) { - for (int i = 0; i < n; i++) func.push_back(point_cloud[i][k]); - functional_cover = true; - cover_name = "coordinate " + std::to_string(k); + if(point_cloud[0].size() > 0){ + for (int i = 0; i < n; i++) func.push_back(point_cloud[i][k]); + functional_cover = true; + cover_name = "coordinate " + std::to_string(k); + } + else{ + std::cout << "Only pairwise distances provided---cannot access " << k << "th coordinate; returning null vector instead" << std::endl; + for (int i = 0; i < n; i++) func.push_back(0.0); + functional_cover = true; + cover_name = "null"; + } } public: // Set function from vector. @@ -953,9 +1001,17 @@ class Cover_complex { * */ void set_color_from_coordinate(int k = 0) { - for (int i = 0; i < n; i++) func_color.push_back(point_cloud[i][k]); - color_name = "coordinate "; - color_name.append(std::to_string(k)); + if(point_cloud[0].size() > 0){ + for (int i = 0; i < n; i++) func_color.push_back(point_cloud[i][k]); + color_name = "coordinate "; + color_name.append(std::to_string(k)); + } + else{ + std::cout << "Only pairwise distances provided---cannot access " << k << "th coordinate; returning null vector instead" << std::endl; + for (int i = 0; i < n; i++) func.push_back(0.0); + functional_cover = true; + cover_name = "null"; + } } public: // Set color from vector. @@ -964,7 +1020,7 @@ class Cover_complex { * @param[in] color input vector of values. * */ - void set_color_from_vector(std::vector<double> color) { + void set_color_from_range(std::vector<double> color) { for (unsigned int i = 0; i < color.size(); i++) func_color.push_back(color[i]); } @@ -1108,7 +1164,7 @@ class Cover_complex { /** \brief Computes the extended persistence diagram of the complex. * */ - void compute_PD() { + Persistence_diagram compute_PD() { Simplex_tree st; // Compute max and min @@ -1121,15 +1177,18 @@ class Cover_complex { // Build filtration for (auto const& simplex : simplices) { - std::vector<int> splx = simplex; splx.push_back(-2); + std::vector<int> splx = simplex; + splx.push_back(-2); st.insert_simplex_and_subfaces(splx, -3); } for (std::map<int, double>::iterator it = cover_std.begin(); it != cover_std.end(); it++) { int vertex = it->first; float val = it->second; int vert[] = {vertex}; int edge[] = {vertex, -2}; - st.assign_filtration(st.find(vert), -2 + (val - minf)/(maxf - minf)); - st.assign_filtration(st.find(edge), 2 - (val - minf)/(maxf - minf)); + if(st.find(vert) != st.null_simplex()){ + st.assign_filtration(st.find(vert), -2 + (val - minf)/(maxf - minf)); + st.assign_filtration(st.find(edge), 2 - (val - minf)/(maxf - minf)); + } } st.make_filtration_non_decreasing(); @@ -1159,6 +1218,7 @@ class Cover_complex { if (verbose) std::cout << " [" << birth << ", " << death << "]" << std::endl; } } + return PD; } public: @@ -1184,7 +1244,7 @@ class Cover_complex { Cboot.point_cloud.push_back(this->point_cloud[id]); Cboot.cover.emplace_back(); Cboot.func.push_back(this->func[id]); boost::add_vertex(Cboot.one_skeleton_OFF); Cboot.vertices.push_back(boost::add_vertex(Cboot.one_skeleton)); } - Cboot.set_color_from_vector(Cboot.func); + Cboot.set_color_from_range(Cboot.func); for (int j = 0; j < n; j++) { std::vector<double> dist(n); @@ -1230,7 +1290,7 @@ class Cover_complex { unsigned int N = distribution.size(); double level = 1; for (unsigned int i = 0; i < N; i++) - if (distribution[i] > d){ level = i * 1.0 / N; break; } + if (distribution[i] >= d){ level = i * 1.0 / N; break; } if (verbose) std::cout << "Confidence level of distance " << d << " is " << level << std::endl; return level; } diff --git a/src/cython/cython/nerve_gic.pyx b/src/cython/cython/nerve_gic.pyx index 30a14d3b..5f01b379 100644 --- a/src/cython/cython/nerve_gic.pyx +++ b/src/cython/cython/nerve_gic.pyx @@ -38,14 +38,14 @@ cdef extern from "Nerve_gic_interface.h" namespace "Gudhi": double compute_distance_from_confidence_level(double alpha) void compute_distribution(int N) double compute_p_value() - void compute_PD() + vector[pair[double, double]] compute_PD() void find_simplices() void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree) bool read_point_cloud(string off_file_name) double set_automatic_resolution() void set_color_from_coordinate(int k) void set_color_from_file(string color_file_name) - void set_color_from_vector(vector[double] color) + void set_color_from_range(vector[double] color) void set_cover_from_file(string cover_file_name) void set_cover_from_function() void set_cover_from_Euclidean_Voronoi(int m) @@ -67,6 +67,8 @@ cdef extern from "Nerve_gic_interface.h" namespace "Gudhi": void write_info() void plot_DOT() void plot_OFF() + void set_point_cloud_from_range(vector[vector[double]] cloud) + void set_distances_from_range(vector[vector[double]] distance_matrix) # CoverComplex python interface cdef class CoverComplex: @@ -102,6 +104,22 @@ cdef class CoverComplex: """ return self.thisptr != NULL + def set_point_cloud_from_range(self, cloud): + """ Reads and stores the input point cloud from a vector stored in memory. + + :param cloud: Input vector containing the point cloud. + :type cloud: vector[vector[double]] + """ + return self.thisptr.set_point_cloud_from_range(cloud) + + def set_distances_from_range(self, distance_matrix): + """ Reads and stores the input distance matrix from a vector stored in memory. + + :param distance_matrix: Input vector containing the distance matrix. + :type distance_matrix: vector[vector[double]] + """ + return self.thisptr.set_distances_from_range(distance_matrix) + def compute_confidence_level_from_distance(self, distance): """Computes the confidence level of a specific bottleneck distance threshold. @@ -145,7 +163,7 @@ cdef class CoverComplex: def compute_PD(self): """Computes the extended persistence diagram of the complex. """ - self.thisptr.compute_PD() + return self.thisptr.compute_PD() def create_simplex_tree(self): """ @@ -162,7 +180,7 @@ cdef class CoverComplex: self.thisptr.find_simplices() def read_point_cloud(self, off_file): - """Reads and stores the input point cloud. + """Reads and stores the input point cloud from .(n)OFF file. :param off_file: Name of the input .OFF or .nOFF file. :type off_file: string @@ -206,14 +224,14 @@ cdef class CoverComplex: else: print("file " + color_file_name + " not found.") - def set_color_from_vector(self, color): + def set_color_from_range(self, color): """Computes the function used to color the nodes of the simplicial complex from a vector stored in memory. :param color: Input vector of values. :type color: vector[double] """ - self.thisptr.set_color_from_vector(color) + self.thisptr.set_color_from_range(color) def set_cover_from_file(self, cover_file_name): """Creates the cover C from a file containing the cover elements of |