diff options
Diffstat (limited to 'src/common/include')
-rw-r--r-- | src/common/include/gudhi/Clock.h | 20 | ||||
-rw-r--r-- | src/common/include/gudhi/random_point_generators.h | 32 | ||||
-rw-r--r-- | src/common/include/gudhi/reader_utils.h | 145 |
3 files changed, 150 insertions, 47 deletions
diff --git a/src/common/include/gudhi/Clock.h b/src/common/include/gudhi/Clock.h index 77f196ca..b83de2f5 100644 --- a/src/common/include/gudhi/Clock.h +++ b/src/common/include/gudhi/Clock.h @@ -23,9 +23,9 @@ #ifndef CLOCK_H_ #define CLOCK_H_ -#include <boost/date_time/posix_time/posix_time.hpp> - +#include <iostream> #include <string> +#include <chrono> namespace Gudhi { @@ -33,20 +33,20 @@ class Clock { public: // Construct and start the timer Clock(const std::string& msg_ = std::string()) - : startTime(boost::posix_time::microsec_clock::local_time()), + : startTime(std::chrono::system_clock::now()), end_called(false), msg(msg_) { } // Restart the timer void begin() const { end_called = false; - startTime = boost::posix_time::microsec_clock::local_time(); + startTime = std::chrono::system_clock::now(); } // Stop the timer void end() const { end_called = true; - endTime = boost::posix_time::microsec_clock::local_time(); + endTime = std::chrono::system_clock::now(); } std::string message() const { @@ -62,7 +62,7 @@ class Clock { if (!clock.msg.empty()) stream << clock.msg << ": "; - stream << clock.num_seconds() << "s"; + stream << clock.num_seconds() << "s\n"; return stream; } @@ -71,15 +71,15 @@ class Clock { // - or now otherwise. In this case, the timer is not stopped. double num_seconds() const { if (!end_called) { - auto end = boost::posix_time::microsec_clock::local_time(); - return (end - startTime).total_milliseconds() / 1000.; + auto end = std::chrono::system_clock::now(); + return std::chrono::duration_cast<std::chrono::milliseconds>(end-startTime).count() / 1000.; } else { - return (endTime - startTime).total_milliseconds() / 1000.; + return std::chrono::duration_cast<std::chrono::milliseconds>(endTime-startTime).count() / 1000.; } } private: - mutable boost::posix_time::ptime startTime, endTime; + mutable std::chrono::time_point<std::chrono::system_clock> startTime, endTime; mutable bool end_called; std::string msg; }; diff --git a/src/common/include/gudhi/random_point_generators.h b/src/common/include/gudhi/random_point_generators.h index 2ec465ef..9df77760 100644 --- a/src/common/include/gudhi/random_point_generators.h +++ b/src/common/include/gudhi/random_point_generators.h @@ -282,6 +282,38 @@ std::vector<typename Kernel::Point_d> generate_points_on_sphere_d(std::size_t nu } template <typename Kernel> +std::vector<typename Kernel::Point_d> generate_points_in_ball_d(std::size_t num_points, int dim, double radius) { + typedef typename Kernel::Point_d Point; + Kernel k; + CGAL::Random rng; + CGAL::Random_points_in_ball_d<Point> generator(dim, radius); + std::vector<Point> points; + points.reserve(num_points); + for (std::size_t i = 0; i < num_points;) { + Point p = *generator++; + points.push_back(p); + ++i; + } + return points; +} + +template <typename Kernel> +std::vector<typename Kernel::Point_d> generate_points_in_cube_d(std::size_t num_points, int dim, double radius) { + typedef typename Kernel::Point_d Point; + Kernel k; + CGAL::Random rng; + CGAL::Random_points_in_cube_d<Point> generator(dim, radius); + std::vector<Point> points; + points.reserve(num_points); + for (std::size_t i = 0; i < num_points;) { + Point p = *generator++; + points.push_back(p); + ++i; + } + return points; +} + +template <typename Kernel> std::vector<typename Kernel::Point_d> generate_points_on_two_spheres_d(std::size_t num_points, int dim, double radius, double distance_between_centers, double radius_noise_percentage = 0.) { diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h index 97a87edd..90be4fc7 100644 --- a/src/common/include/gudhi/reader_utils.h +++ b/src/common/include/gudhi/reader_utils.h @@ -1,8 +1,8 @@ -/* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * - * Author(s): Clement Maria, Pawel Dlotko + * Author(s): Clement Maria, Pawel Dlotko, Clement Jamin * * Copyright (C) 2014 INRIA * @@ -24,7 +24,9 @@ #define READER_UTILS_H_ #include <gudhi/graph_simplicial_complex.h> +#include <gudhi/Debug_utils.h> +#include <boost/function_output_iterator.hpp> #include <boost/graph/adjacency_list.hpp> #include <iostream> @@ -34,6 +36,9 @@ #include <string> #include <vector> #include <utility> // for pair +#include <tuple> // for std::make_tuple + +namespace Gudhi { // Keep this file tag for Doxygen to parse the code, otherwise, functions are not documented. // It is required for global functions and variables. @@ -50,7 +55,7 @@ * X21 X22 ... X2d<br> * etc<br> */ -inline void read_points(std::string file_name, std::vector< std::vector< double > > & points) { +inline void read_points(std::string file_name, std::vector<std::vector<double>>& points) { std::ifstream in_file(file_name.c_str(), std::ios::in); if (!in_file.is_open()) { std::cerr << "Unable to open file " << file_name << std::endl; @@ -60,14 +65,13 @@ inline void read_points(std::string file_name, std::vector< std::vector< double std::string line; double x; while (getline(in_file, line)) { - std::vector< double > point; + std::vector<double> point; std::istringstream iss(line); while (iss >> x) { point.push_back(x); } // Check for empty lines - if (!point.empty()) - points.push_back(point); + if (!point.empty()) points.push_back(point); } in_file.close(); } @@ -88,17 +92,20 @@ inline void read_points(std::string file_name, std::vector< std::vector< double * Every simplex must appear exactly once. * Simplices of dimension more than 1 are ignored. */ -template< typename Graph_t, typename Filtration_value, typename Vertex_handle > +template <typename Graph_t, typename Filtration_value, typename Vertex_handle> Graph_t read_graph(std::string file_name) { std::ifstream in_(file_name.c_str(), std::ios::in); if (!in_.is_open()) { - std::cerr << "Unable to open file " << file_name << std::endl; + std::string error_str("read_graph - Unable to open file "); + error_str.append(file_name); + std::cerr << error_str << std::endl; + throw std::invalid_argument(error_str); } - typedef std::pair< Vertex_handle, Vertex_handle > Edge_t; - std::vector< Edge_t > edges; - std::vector< Filtration_value > edges_fil; - std::map< Vertex_handle, Filtration_value > vertices; + typedef std::pair<Vertex_handle, Vertex_handle> Edge_t; + std::vector<Edge_t> edges; + std::vector<Filtration_value> edges_fil; + std::map<Vertex_handle, Filtration_value> vertices; std::string line; int dim; @@ -108,8 +115,7 @@ Graph_t read_graph(std::string file_name) { std::istringstream iss(line); while (iss >> dim) { switch (dim) { - case 0: - { + case 0: { iss >> u; iss >> fil; vertices[u] = fil; @@ -118,8 +124,7 @@ Graph_t read_graph(std::string file_name) { } break; } - case 1: - { + case 1: { iss >> u; iss >> v; iss >> fil; @@ -127,16 +132,13 @@ Graph_t read_graph(std::string file_name) { edges_fil.push_back(fil); break; } - default: - { - break; - } + default: { break; } } } } in_.close(); - if ((size_t) (max_h + 1) != vertices.size()) { + if ((size_t)(max_h + 1) != vertices.size()) { std::cerr << "Error: vertices must be labeled from 0 to n-1 \n"; } @@ -164,8 +166,8 @@ Graph_t read_graph(std::string file_name) { * Every simplex must appear exactly once. * Simplices of dimension more than 1 are ignored. */ -template< typename Vertex_handle, typename Filtration_value > -bool read_simplex(std::istream & in_, std::vector< Vertex_handle > & simplex, Filtration_value & fil) { +template <typename Vertex_handle, typename Filtration_value> +bool read_simplex(std::istream& in_, std::vector<Vertex_handle>& simplex, Filtration_value& fil) { int dim = 0; if (!(in_ >> dim)) return false; Vertex_handle v; @@ -189,8 +191,8 @@ bool read_simplex(std::istream & in_, std::vector< Vertex_handle > & simplex, Fi * The key of a simplex is its position in the filtration order and also the number of its row in the file. * Dimi ki1 ki2 ... kiDimi Fili means that the ith simplex in the filtration has dimension Dimi, filtration value * fil1 and simplices with key ki1 ... kiDimi in its boundary.*/ -template< typename Simplex_key, typename Filtration_value > -bool read_hasse_simplex(std::istream & in_, std::vector< Simplex_key > & boundary, Filtration_value & fil) { +template <typename Simplex_key, typename Filtration_value> +bool read_hasse_simplex(std::istream& in_, std::vector<Simplex_key>& boundary, Filtration_value& fil) { int dim; if (!(in_ >> dim)) return false; if (dim == 0) { @@ -209,7 +211,7 @@ bool read_hasse_simplex(std::istream & in_, std::vector< Simplex_key > & boundar /** * @brief Read a lower triangular distance matrix from a csv file. We assume that the .csv store the whole * (square) matrix. - * + * * @author Pawel Dlotko * * Square matrix file format:<br> @@ -226,13 +228,13 @@ bool read_hasse_simplex(std::istream & in_, std::vector< Simplex_key > & boundar * Dj1;Dj2;...;Dj(j-1);<br> * **/ -template< typename Filtration_value > -std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from_csv_file(const std::string& filename, - const char separator = ';') { +template <typename Filtration_value> +std::vector<std::vector<Filtration_value>> read_lower_triangular_matrix_from_csv_file(const std::string& filename, + const char separator = ';') { #ifdef DEBUG_TRACES std::cout << "Using procedure read_lower_triangular_matrix_from_csv_file \n"; #endif // DEBUG_TRACES - std::vector< std::vector< Filtration_value > > result; + std::vector<std::vector<Filtration_value>> result; std::ifstream in; in.open(filename.c_str()); if (!in.is_open()) { @@ -243,7 +245,7 @@ std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from // the first line is emtpy, so we ignore it: std::getline(in, line); - std::vector< Filtration_value > values_in_this_line; + std::vector<Filtration_value> values_in_this_line; result.push_back(values_in_this_line); int number_of_line = 0; @@ -251,11 +253,10 @@ std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from // first, read the file line by line to a string: while (std::getline(in, line)) { // if line is empty, break - if (line.size() == 0) - break; + if (line.size() == 0) break; // if the last element of a string is comma: - if (line[ line.size() - 1 ] == separator) { + if (line[line.size() - 1] == separator) { // then shrink the string by one line.pop_back(); } @@ -268,7 +269,7 @@ std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from // and now read the doubles. int number_of_entry = 0; - std::vector< Filtration_value > values_in_this_line; + std::vector<Filtration_value> values_in_this_line; while (iss.good()) { double entry; iss >> entry; @@ -277,7 +278,7 @@ std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from } ++number_of_entry; } - if (!values_in_this_line.empty())result.push_back(values_in_this_line); + if (!values_in_this_line.empty()) result.push_back(values_in_this_line); ++number_of_line; } in.close(); @@ -295,4 +296,74 @@ std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from return result; } // read_lower_triangular_matrix_from_csv_file +/** +Reads a file containing persistence intervals. +Each line might contain 2, 3 or 4 values: [[field] dimension] birth death +The output iterator `out` is used this way: `*out++ = std::make_tuple(dim, birth, death);` +where `dim` is an `int`, `birth` a `double`, and `death` a `double`. +Note: the function does not check that birth <= death. +**/ +template <typename OutputIterator> +void read_persistence_intervals_and_dimension(std::string const& filename, OutputIterator out) { + std::ifstream in(filename); + if (!in.is_open()) { + std::string error_str("read_persistence_intervals_and_dimension - Unable to open file "); + error_str.append(filename); + std::cerr << error_str << std::endl; + throw std::invalid_argument(error_str); + } + + while (!in.eof()) { + std::string line; + getline(in, line); + if (line.length() != 0 && line[0] != '#') { + double numbers[4]; + int n = sscanf(line.c_str(), "%lf %lf %lf %lf", &numbers[0], &numbers[1], &numbers[2], &numbers[3]); + if (n >= 2) { + int dim = (n >= 3 ? static_cast<int>(numbers[n - 3]) : -1); + *out++ = std::make_tuple(dim, numbers[n - 2], numbers[n - 1]); + } + } + } +} + +/** +Reads a file containing persistence intervals. +Each line might contain 2, 3 or 4 values: [[field] dimension] birth death +The return value is an `std::map<dim, std::vector<std::pair<birth, death>>>` +where `dim` is an `int`, `birth` a `double`, and `death` a `double`. +Note: the function does not check that birth <= death. +**/ +inline std::map<int, std::vector<std::pair<double, double>>> read_persistence_intervals_grouped_by_dimension( + std::string const& filename) { + std::map<int, std::vector<std::pair<double, double>>> ret; + read_persistence_intervals_and_dimension( + filename, boost::make_function_output_iterator([&ret](std::tuple<int, double, double> t) { + ret[get<0>(t)].push_back(std::make_pair(get<1>(t), get<2>(t))); + })); + return ret; +} + +/** +Reads a file containing persistence intervals. +Each line might contain 2, 3 or 4 values: [[field] dimension] birth death +If `only_this_dim` = -1, dimension is ignored and all lines are returned. +If `only_this_dim` is >= 0, only the lines where dimension = `only_this_dim` +(or where dimension is not specified) are returned. +The return value is an `std::vector<std::pair<birth, death>>` +where `dim` is an `int`, `birth` a `double`, and `death` a `double`. +Note: the function does not check that birth <= death. +**/ +inline std::vector<std::pair<double, double>> read_persistence_intervals_in_dimension(std::string const& filename, + int only_this_dim = -1) { + std::vector<std::pair<double, double>> ret; + read_persistence_intervals_and_dimension( + filename, boost::make_function_output_iterator([only_this_dim, &ret](std::tuple<int, double, double> t) { + if (only_this_dim == get<0>(t) || only_this_dim == -1) ret.emplace_back(get<1>(t), get<2>(t)); + })); + return ret; +} + +} // namespace Gudhi + #endif // READER_UTILS_H_ |