reader_utils.h
Go to the documentation of this file.
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): Clement Maria, Pawel Dlotko, Clement Jamin
6  *
7  * Copyright (C) 2014 Inria
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef READER_UTILS_H_
24 #define READER_UTILS_H_
25 
26 #include <gudhi/graph_simplicial_complex.h>
27 #include <gudhi/Debug_utils.h>
28 
29 #include <boost/function_output_iterator.hpp>
30 #include <boost/graph/adjacency_list.hpp>
31 
32 #include <iostream>
33 #include <fstream>
34 #include <map>
35 #include <limits> // for numeric_limits
36 #include <string>
37 #include <vector>
38 #include <utility> // for pair
39 #include <tuple> // for std::make_tuple
40 
41 namespace Gudhi {
42 
43 // Keep this file tag for Doxygen to parse the code, otherwise, functions are not documented.
44 // It is required for global functions and variables.
45 
58 inline void read_points(std::string file_name, std::vector<std::vector<double>>& points) {
59  std::ifstream in_file(file_name.c_str(), std::ios::in);
60  if (!in_file.is_open()) {
61  std::cerr << "Unable to open file " << file_name << std::endl;
62  return;
63  }
64 
65  std::string line;
66  double x;
67  while (getline(in_file, line)) {
68  std::vector<double> point;
69  std::istringstream iss(line);
70  while (iss >> x) {
71  point.push_back(x);
72  }
73  // Check for empty lines
74  if (!point.empty()) points.push_back(point);
75  }
76  in_file.close();
77 }
78 
95 template <typename Graph_t, typename Filtration_value, typename Vertex_handle>
96 Graph_t read_graph(std::string file_name) {
97  std::ifstream in_(file_name.c_str(), std::ios::in);
98  if (!in_.is_open()) {
99  std::string error_str("read_graph - Unable to open file ");
100  error_str.append(file_name);
101  std::cerr << error_str << std::endl;
102  throw std::invalid_argument(error_str);
103  }
104 
105  typedef std::pair<Vertex_handle, Vertex_handle> Edge_t;
106  std::vector<Edge_t> edges;
107  std::vector<Filtration_value> edges_fil;
108  std::map<Vertex_handle, Filtration_value> vertices;
109 
110  std::string line;
111  int dim;
112  Vertex_handle u, v, max_h = -1;
113  Filtration_value fil;
114  while (getline(in_, line)) {
115  std::istringstream iss(line);
116  while (iss >> dim) {
117  switch (dim) {
118  case 0: {
119  iss >> u;
120  iss >> fil;
121  vertices[u] = fil;
122  if (max_h < u) {
123  max_h = u;
124  }
125  break;
126  }
127  case 1: {
128  iss >> u;
129  iss >> v;
130  iss >> fil;
131  edges.push_back(Edge_t(u, v));
132  edges_fil.push_back(fil);
133  break;
134  }
135  default: { break; }
136  }
137  }
138  }
139  in_.close();
140 
141  if ((size_t)(max_h + 1) != vertices.size()) {
142  std::cerr << "Error: vertices must be labeled from 0 to n-1 \n";
143  }
144 
145  Graph_t skel_graph(edges.begin(), edges.end(), edges_fil.begin(), vertices.size());
146  auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph);
147 
148  typename boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
149  auto v_it = vertices.begin();
150  for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi, ++v_it) {
151  boost::put(vertex_prop, *vi, v_it->second);
152  }
153 
154  return skel_graph;
155 }
156 
169 template <typename Vertex_handle, typename Filtration_value>
170 bool read_simplex(std::istream& in_, std::vector<Vertex_handle>& simplex, Filtration_value& fil) {
171  int dim = 0;
172  if (!(in_ >> dim)) return false;
173  Vertex_handle v;
174  for (int i = 0; i < dim + 1; ++i) {
175  in_ >> v;
176  simplex.push_back(v);
177  }
178  in_ >> fil;
179  in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return
180  return true;
181 }
182 
194 template <typename Simplex_key, typename Filtration_value>
195 bool read_hasse_simplex(std::istream& in_, std::vector<Simplex_key>& boundary, Filtration_value& fil) {
196  int dim;
197  if (!(in_ >> dim)) return false;
198  if (dim == 0) {
199  in_ >> fil;
200  return true;
201  }
202  Simplex_key key;
203  for (int i = 0; i < dim + 1; ++i) {
204  in_ >> key;
205  boundary.push_back(key);
206  }
207  in_ >> fil;
208  return true;
209 }
210 
231 template <typename Filtration_value>
232 std::vector<std::vector<Filtration_value>> read_lower_triangular_matrix_from_csv_file(const std::string& filename,
233  const char separator = ';') {
234 #ifdef DEBUG_TRACES
235  std::cout << "Using procedure read_lower_triangular_matrix_from_csv_file \n";
236 #endif // DEBUG_TRACES
237  std::vector<std::vector<Filtration_value>> result;
238  std::ifstream in;
239  in.open(filename.c_str());
240  if (!in.is_open()) {
241  return result;
242  }
243 
244  std::string line;
245 
246  // the first line is emtpy, so we ignore it:
247  std::getline(in, line);
248  std::vector<Filtration_value> values_in_this_line;
249  result.push_back(values_in_this_line);
250 
251  int number_of_line = 0;
252 
253  // first, read the file line by line to a string:
254  while (std::getline(in, line)) {
255  // if line is empty, break
256  if (line.size() == 0) break;
257 
258  // if the last element of a string is comma:
259  if (line[line.size() - 1] == separator) {
260  // then shrink the string by one
261  line.pop_back();
262  }
263 
264  // replace all commas with spaces
265  std::replace(line.begin(), line.end(), separator, ' ');
266 
267  // put the new line to a stream
268  std::istringstream iss(line);
269  // and now read the doubles.
270 
271  int number_of_entry = 0;
272  std::vector<Filtration_value> values_in_this_line;
273  while (iss.good()) {
274  double entry;
275  iss >> entry;
276  if (number_of_entry <= number_of_line) {
277  values_in_this_line.push_back(entry);
278  }
279  ++number_of_entry;
280  }
281  if (!values_in_this_line.empty()) result.push_back(values_in_this_line);
282  ++number_of_line;
283  }
284  in.close();
285 
286 #ifdef DEBUG_TRACES
287  std::cerr << "Here is the matrix we read : \n";
288  for (size_t i = 0; i != result.size(); ++i) {
289  for (size_t j = 0; j != result[i].size(); ++j) {
290  std::cerr << result[i][j] << " ";
291  }
292  std::cerr << std::endl;
293  }
294 #endif // DEBUG_TRACES
295 
296  return result;
297 } // read_lower_triangular_matrix_from_csv_file
298 
306 template <typename OutputIterator>
307 void read_persistence_intervals_and_dimension(std::string const& filename, OutputIterator out) {
308  std::ifstream in(filename);
309  if (!in.is_open()) {
310  std::string error_str("read_persistence_intervals_and_dimension - Unable to open file ");
311  error_str.append(filename);
312  std::cerr << error_str << std::endl;
313  throw std::invalid_argument(error_str);
314  }
315 
316  while (!in.eof()) {
317  std::string line;
318  getline(in, line);
319  if (line.length() != 0 && line[0] != '#') {
320  double numbers[4];
321  int n = sscanf(line.c_str(), "%lf %lf %lf %lf", &numbers[0], &numbers[1], &numbers[2], &numbers[3]);
322  if (n >= 2) {
323  int dim = (n >= 3 ? static_cast<int>(numbers[n - 3]) : -1);
324  *out++ = std::make_tuple(dim, numbers[n - 2], numbers[n - 1]);
325  }
326  }
327  }
328 }
329 
337 inline std::map<int, std::vector<std::pair<double, double>>> read_persistence_intervals_grouped_by_dimension(
338  std::string const& filename) {
339  std::map<int, std::vector<std::pair<double, double>>> ret;
341  filename, boost::make_function_output_iterator([&ret](std::tuple<int, double, double> t) {
342  ret[get<0>(t)].push_back(std::make_pair(get<1>(t), get<2>(t)));
343  }));
344  return ret;
345 }
346 
357 inline std::vector<std::pair<double, double>> read_persistence_intervals_in_dimension(std::string const& filename,
358  int only_this_dim = -1) {
359  std::vector<std::pair<double, double>> ret;
361  filename, boost::make_function_output_iterator([only_this_dim, &ret](std::tuple<int, double, double> t) {
362  if (only_this_dim == get<0>(t) || only_this_dim == -1) ret.emplace_back(get<1>(t), get<2>(t));
363  }));
364  return ret;
365 }
366 
367 } // namespace Gudhi
368 
369 #endif // READER_UTILS_H_
Graph_t read_graph(std::string file_name)
Read a graph from a file.
Definition: reader_utils.h:96
std::map< int, std::vector< std::pair< double, double > > > read_persistence_intervals_grouped_by_dimension(std::string const &filename)
Definition: reader_utils.h:337
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:232
Definition: SimplicialComplexForAlpha.h:26
void read_persistence_intervals_and_dimension(std::string const &filename, OutputIterator out)
Definition: reader_utils.h:307
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:58
std::vector< std::pair< double, double > > read_persistence_intervals_in_dimension(std::string const &filename, int only_this_dim=-1)
Definition: reader_utils.h:357
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:32
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:195
bool read_simplex(std::istream &in_, std::vector< Vertex_handle > &simplex, Filtration_value &fil)
Read a face from a file.
Definition: reader_utils.h:170
GUDHI  Version 2.2.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Thu Jun 14 2018 15:00:54 for GUDHI by Doxygen 1.8.13