reader_utils.h
Go to the documentation of this file.
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): Clement Maria, Pawel Dlotko, Clement Jamin
4  *
5  * Copyright (C) 2014 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
11 #ifndef READER_UTILS_H_
12 #define READER_UTILS_H_
13 
15 #include <gudhi/Debug_utils.h>
16 
17 #if BOOST_VERSION < 106600
18 # include <boost/function_output_iterator.hpp>
19 #else
20 # include <boost/iterator/function_output_iterator.hpp>
21 #endif
22 #include <boost/graph/adjacency_list.hpp>
23 
24 #include <iostream>
25 #include <fstream>
26 #include <map>
27 #include <limits> // for numeric_limits
28 #include <string>
29 #include <vector>
30 #include <utility> // for pair
31 #include <tuple> // for std::make_tuple
32 
33 namespace Gudhi {
34 
35 // Keep this file tag for Doxygen to parse the code, otherwise, functions are not documented.
36 // It is required for global functions and variables.
37 
50 inline void read_points(std::string file_name, std::vector<std::vector<double>>& points) {
51  std::ifstream in_file(file_name.c_str(), std::ios::in);
52  if (!in_file.is_open()) {
53  std::cerr << "Unable to open file " << file_name << std::endl;
54  return;
55  }
56 
57  std::string line;
58  double x;
59  while (getline(in_file, line)) {
60  std::vector<double> point;
61  std::istringstream iss(line);
62  while (iss >> x) {
63  point.push_back(x);
64  }
65  // Check for empty lines
66  if (!point.empty()) points.push_back(point);
67  }
68  in_file.close();
69 }
70 
87 template <typename Graph_t, typename Filtration_value, typename Vertex_handle>
88 Graph_t read_graph(std::string file_name) {
89  std::ifstream in_(file_name.c_str(), std::ios::in);
90  if (!in_.is_open()) {
91  std::string error_str("read_graph - Unable to open file ");
92  error_str.append(file_name);
93  std::cerr << error_str << std::endl;
94  throw std::invalid_argument(error_str);
95  }
96 
97  typedef std::pair<Vertex_handle, Vertex_handle> Edge_t;
98  std::vector<Edge_t> edges;
99  std::vector<Filtration_value> edges_fil;
100  std::map<Vertex_handle, Filtration_value> vertices;
101 
102  std::string line;
103  int dim;
104  Vertex_handle u, v, max_h = -1;
105  Filtration_value fil;
106  while (getline(in_, line)) {
107  std::istringstream iss(line);
108  while (iss >> dim) {
109  switch (dim) {
110  case 0: {
111  iss >> u;
112  iss >> fil;
113  vertices[u] = fil;
114  if (max_h < u) {
115  max_h = u;
116  }
117  break;
118  }
119  case 1: {
120  iss >> u;
121  iss >> v;
122  iss >> fil;
123  edges.push_back(Edge_t(u, v));
124  edges_fil.push_back(fil);
125  break;
126  }
127  default: { break; }
128  }
129  }
130  }
131  in_.close();
132 
133  if ((size_t)(max_h + 1) != vertices.size()) {
134  std::cerr << "Error: vertices must be labeled from 0 to n-1 \n";
135  }
136 
137  Graph_t skel_graph(edges.begin(), edges.end(), edges_fil.begin(), vertices.size());
138  auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph);
139 
140  typename boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
141  auto v_it = vertices.begin();
142  for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi, ++v_it) {
143  boost::put(vertex_prop, *vi, v_it->second);
144  }
145 
146  return skel_graph;
147 }
148 
161 template <typename Vertex_handle, typename Filtration_value>
162 bool read_simplex(std::istream& in_, std::vector<Vertex_handle>& simplex, Filtration_value& fil) {
163  int dim = 0;
164  if (!(in_ >> dim)) return false;
165  Vertex_handle v;
166  for (int i = 0; i < dim + 1; ++i) {
167  if (!(in_ >> v)) return false;
168  simplex.push_back(v);
169  }
170  if (!(in_ >> fil)) return false;
171  in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return
172  return true;
173 }
174 
186 template <typename Simplex_key, typename Filtration_value>
187 bool read_hasse_simplex(std::istream& in_, std::vector<Simplex_key>& boundary, Filtration_value& fil) {
188  int dim;
189  if (!(in_ >> dim)) return false;
190  if (dim == 0) {
191  in_ >> fil;
192  return true;
193  }
194  Simplex_key key;
195  for (int i = 0; i < dim + 1; ++i) {
196  in_ >> key;
197  boundary.push_back(key);
198  }
199  in_ >> fil;
200  return true;
201 }
202 
223 template <typename Filtration_value>
224 std::vector<std::vector<Filtration_value>> read_lower_triangular_matrix_from_csv_file(const std::string& filename,
225  const char separator = ';') {
226 #ifdef DEBUG_TRACES
227  std::clog << "Using procedure read_lower_triangular_matrix_from_csv_file \n";
228 #endif // DEBUG_TRACES
229  std::vector<std::vector<Filtration_value>> result;
230  std::ifstream in;
231  in.open(filename.c_str());
232  if (!in.is_open()) {
233  return result;
234  }
235 
236  std::string line;
237 
238  // the first line is emtpy, so we ignore it:
239  std::getline(in, line);
240  std::vector<Filtration_value> values_in_this_line;
241  result.push_back(values_in_this_line);
242 
243  int number_of_line = 0;
244 
245  // first, read the file line by line to a string:
246  while (std::getline(in, line)) {
247  // if line is empty, break
248  if (line.size() == 0) break;
249 
250  // if the last element of a string is comma:
251  if (line[line.size() - 1] == separator) {
252  // then shrink the string by one
253  line.pop_back();
254  }
255 
256  // replace all commas with spaces
257  std::replace(line.begin(), line.end(), separator, ' ');
258 
259  // put the new line to a stream
260  std::istringstream iss(line);
261  // and now read the doubles.
262 
263  int number_of_entry = 0;
264  std::vector<Filtration_value> values_in_this_line;
265  while (iss.good()) {
266  double entry;
267  iss >> entry;
268  if (number_of_entry <= number_of_line) {
269  values_in_this_line.push_back(entry);
270  }
271  ++number_of_entry;
272  }
273  if (!values_in_this_line.empty()) result.push_back(values_in_this_line);
274  ++number_of_line;
275  }
276  in.close();
277 
278 #ifdef DEBUG_TRACES
279  std::clog << "Here is the matrix we read : \n";
280  for (size_t i = 0; i != result.size(); ++i) {
281  for (size_t j = 0; j != result[i].size(); ++j) {
282  std::clog << result[i][j] << " ";
283  }
284  std::clog << std::endl;
285  }
286 #endif // DEBUG_TRACES
287 
288  return result;
289 } // read_lower_triangular_matrix_from_csv_file
290 
298 template <typename OutputIterator>
299 void read_persistence_intervals_and_dimension(std::string const& filename, OutputIterator out) {
300 #ifdef DEBUG_TRACES
301  std::clog << "read_persistence_intervals_and_dimension - " << filename << std::endl;
302 #endif // DEBUG_TRACES
303  std::ifstream in(filename);
304  if (!in.is_open()) {
305  std::string error_str("read_persistence_intervals_and_dimension - Unable to open file ");
306  error_str.append(filename);
307  std::cerr << error_str << std::endl;
308  throw std::invalid_argument(error_str);
309  }
310 
311  while (!in.eof()) {
312  std::string line;
313  getline(in, line);
314  if (line.length() != 0 && line[0] != '#') {
315  double numbers[4];
316  int n = sscanf(line.c_str(), "%lf %lf %lf %lf", &numbers[0], &numbers[1], &numbers[2], &numbers[3]);
317 #ifdef DEBUG_TRACES
318  std::clog << "[" << n << "] = ";
319  for (int i = 0; i < n; i++) {
320  std::clog << numbers[i] << ",";
321  }
322  std::clog << std::endl;
323 #endif // DEBUG_TRACES
324  if (n >= 2) {
325  int dim = (n >= 3 ? static_cast<int>(numbers[n - 3]) : -1);
326  *out++ = std::make_tuple(dim, numbers[n - 2], numbers[n - 1]);
327  }
328  }
329  }
330 }
331 
339 inline std::map<int, std::vector<std::pair<double, double>>> read_persistence_intervals_grouped_by_dimension(
340  std::string const& filename) {
341  std::map<int, std::vector<std::pair<double, double>>> ret;
343  filename, boost::make_function_output_iterator([&ret](std::tuple<int, double, double> t) {
344  ret[get<0>(t)].push_back(std::make_pair(get<1>(t), get<2>(t)));
345  }));
346  return ret;
347 }
348 
359 inline std::vector<std::pair<double, double>> read_persistence_intervals_in_dimension(std::string const& filename,
360  int only_this_dim = -1) {
361  std::vector<std::pair<double, double>> ret;
363  filename, boost::make_function_output_iterator([only_this_dim, &ret](std::tuple<int, double, double> t) {
364  if (only_this_dim == get<0>(t) || only_this_dim == -1) ret.emplace_back(get<1>(t), get<2>(t));
365  }));
366  return ret;
367 }
368 
369 } // namespace Gudhi
370 
371 #endif // READER_UTILS_H_
Graph simplicial complex methods.
bool read_hasse_simplex(std::istream &in_, std::vector< Simplex_key > &boundary, Filtration_value &fil)
Read a hasse simplex from a file.
Definition: reader_utils.h:187
Graph_t read_graph(std::string file_name)
Read a graph from a file.
Definition: reader_utils.h:88
std::vector< std::pair< double, double > > read_persistence_intervals_in_dimension(std::string const &filename, int only_this_dim=-1)
Definition: reader_utils.h:359
void read_persistence_intervals_and_dimension(std::string const &filename, OutputIterator out)
Definition: reader_utils.h:299
std::map< int, std::vector< std::pair< double, double > > > read_persistence_intervals_grouped_by_dimension(std::string const &filename)
Definition: reader_utils.h:339
void read_points(std::string file_name, std::vector< std::vector< double >> &points)
Read a set of points to turn it into a vector< vector<double> > by filling points.
Definition: reader_utils.h:50
bool read_simplex(std::istream &in_, std::vector< Vertex_handle > &simplex, Filtration_value &fil)
Read a face from a file.
Definition: reader_utils.h:162
std::vector< std::vector< Filtration_value > > read_lower_triangular_matrix_from_csv_file(const std::string &filename, const char separator=';')
Read a lower triangular distance matrix from a csv file. We assume that the .csv store the whole (squ...
Definition: reader_utils.h:224
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15
GUDHIdev  Version 3.5.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : MIT Generated on Sun May 1 2022 09:19:32 for GUDHIdev by Doxygen 1.9.1