Loading...
Searching...
No Matches
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# include <boost/iterator/function_output_iterator.hpp>
18#include <boost/graph/adjacency_list.hpp>
19
20#include <iostream>
21#include <fstream>
22#include <map>
23#include <limits> // for numeric_limits
24#include <string>
25#include <vector>
26#include <utility> // for pair
27#include <tuple> // for std::make_tuple
28
29namespace Gudhi {
30
31// Keep this file tag for Doxygen to parse the code, otherwise, functions are not documented.
32// It is required for global functions and variables.
33
46inline void read_points(std::string file_name, std::vector<std::vector<double>>& points) {
47 std::ifstream in_file(file_name.c_str(), std::ios::in);
48 if (!in_file.is_open()) {
49 std::cerr << "Unable to open file " << file_name << std::endl;
50 return;
51 }
52
53 std::string line;
54 double x;
55 while (getline(in_file, line)) {
56 std::vector<double> point;
57 std::istringstream iss(line);
58 while (iss >> x) {
59 point.push_back(x);
60 }
61 // Check for empty lines
62 if (!point.empty()) points.push_back(point);
63 }
64 in_file.close();
65}
66
83template <typename Graph_t, typename Filtration_value, typename Vertex_handle>
84Graph_t read_graph(std::string file_name) {
85 std::ifstream in_(file_name.c_str(), std::ios::in);
86 if (!in_.is_open()) {
87 std::string error_str("read_graph - Unable to open file ");
88 error_str.append(file_name);
89 std::cerr << error_str << std::endl;
90 throw std::invalid_argument(error_str);
91 }
92
93 typedef std::pair<Vertex_handle, Vertex_handle> Edge_t;
94 std::vector<Edge_t> edges;
95 std::vector<Filtration_value> edges_fil;
96 std::map<Vertex_handle, Filtration_value> vertices;
97
98 std::string line;
99 int dim;
100 Vertex_handle u, v, max_h = -1;
102 while (getline(in_, line)) {
103 std::istringstream iss(line);
104 while (iss >> dim) {
105 switch (dim) {
106 case 0: {
107 iss >> u;
108 iss >> fil;
109 vertices[u] = fil;
110 if (max_h < u) {
111 max_h = u;
112 }
113 break;
114 }
115 case 1: {
116 iss >> u;
117 iss >> v;
118 iss >> fil;
119 edges.push_back(Edge_t(u, v));
120 edges_fil.push_back(fil);
121 break;
122 }
123 default: { break; }
124 }
125 }
126 }
127 in_.close();
128
129 if ((size_t)(max_h + 1) != vertices.size()) {
130 std::cerr << "Error: vertices must be labeled from 0 to n-1 \n";
131 }
132
133 Graph_t skel_graph(edges.begin(), edges.end(), edges_fil.begin(), vertices.size());
134 auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph);
135
136 typename boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end;
137 auto v_it = vertices.begin();
138 for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi, ++v_it) {
139 boost::put(vertex_prop, *vi, v_it->second);
140 }
141
142 return skel_graph;
143}
144
157template <typename Vertex_handle, typename Filtration_value>
158bool read_simplex(std::istream& in_, std::vector<Vertex_handle>& simplex, Filtration_value& fil) {
159 int dim = 0;
160 if (!(in_ >> dim)) return false;
162 for (int i = 0; i < dim + 1; ++i) {
163 if (!(in_ >> v)) return false;
164 simplex.push_back(v);
165 }
166 if (!(in_ >> fil)) return false;
167 in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return
168 return true;
169}
170
182template <typename Simplex_key, typename Filtration_value>
183bool read_hasse_simplex(std::istream& in_, std::vector<Simplex_key>& boundary, Filtration_value& fil) {
184 int dim;
185 if (!(in_ >> dim)) return false;
186 if (dim == 0) {
187 in_ >> fil;
188 return true;
189 }
190 Simplex_key key;
191 for (int i = 0; i < dim + 1; ++i) {
192 in_ >> key;
193 boundary.push_back(key);
194 }
195 in_ >> fil;
196 return true;
197}
198
219template <typename Filtration_value>
220std::vector<std::vector<Filtration_value>> read_lower_triangular_matrix_from_csv_file(const std::string& filename,
221 const char separator = ';') {
222#ifdef DEBUG_TRACES
223 std::clog << "Using procedure read_lower_triangular_matrix_from_csv_file \n";
224#endif // DEBUG_TRACES
225 std::vector<std::vector<Filtration_value>> result;
226 std::ifstream in;
227 in.open(filename.c_str());
228 if (!in.is_open()) {
229 return result;
230 }
231
232 std::string line;
233
234 // the first line is empty, so we ignore it:
235 std::getline(in, line);
236 std::vector<Filtration_value> values_in_this_line;
237 result.push_back(values_in_this_line);
238
239 int number_of_line = 0;
240
241 // first, read the file line by line to a string:
242 while (std::getline(in, line)) {
243 // if line is empty, break
244 if (line.size() == 0) break;
245
246 // if the last element of a string is comma:
247 if (line[line.size() - 1] == separator) {
248 // then shrink the string by one
249 line.pop_back();
250 }
251
252 // replace all commas with spaces
253 std::replace(line.begin(), line.end(), separator, ' ');
254
255 // put the new line to a stream
256 std::istringstream iss(line);
257 // and now read the doubles.
258
259 int number_of_entry = 0;
260 std::vector<Filtration_value> values_in_this_line;
261 while (iss.good()) {
262 double entry;
263 iss >> entry;
264 if (number_of_entry <= number_of_line) {
265 values_in_this_line.push_back(entry);
266 }
267 ++number_of_entry;
268 }
269 if (!values_in_this_line.empty()) result.push_back(values_in_this_line);
270 ++number_of_line;
271 }
272 in.close();
273
274#ifdef DEBUG_TRACES
275 std::clog << "Here is the matrix we read : \n";
276 for (size_t i = 0; i != result.size(); ++i) {
277 for (size_t j = 0; j != result[i].size(); ++j) {
278 std::clog << result[i][j] << " ";
279 }
280 std::clog << std::endl;
281 }
282#endif // DEBUG_TRACES
283
284 return result;
285} // read_lower_triangular_matrix_from_csv_file
286
294template <typename OutputIterator>
295void read_persistence_intervals_and_dimension(std::string const& filename, OutputIterator out) {
296#ifdef DEBUG_TRACES
297 std::clog << "read_persistence_intervals_and_dimension - " << filename << std::endl;
298#endif // DEBUG_TRACES
299 std::ifstream in(filename);
300 if (!in.is_open()) {
301 std::string error_str("read_persistence_intervals_and_dimension - Unable to open file ");
302 error_str.append(filename);
303 std::cerr << error_str << std::endl;
304 throw std::invalid_argument(error_str);
305 }
306
307 while (!in.eof()) {
308 std::string line;
309 getline(in, line);
310 if (line.length() != 0 && line[0] != '#') {
311 double numbers[4];
312 int n = sscanf(line.c_str(), "%lf %lf %lf %lf", &numbers[0], &numbers[1], &numbers[2], &numbers[3]);
313#ifdef DEBUG_TRACES
314 std::clog << "[" << n << "] = ";
315 for (int i = 0; i < n; i++) {
316 std::clog << numbers[i] << ",";
317 }
318 std::clog << std::endl;
319#endif // DEBUG_TRACES
320 if (n >= 2) {
321 int dim = (n >= 3 ? static_cast<int>(numbers[n - 3]) : -1);
322 *out++ = std::make_tuple(dim, numbers[n - 2], numbers[n - 1]);
323 }
324 }
325 }
326}
327
335inline std::map<int, std::vector<std::pair<double, double>>> read_persistence_intervals_grouped_by_dimension(
336 std::string const& filename) {
337 std::map<int, std::vector<std::pair<double, double>>> ret;
339 filename, boost::make_function_output_iterator([&ret](std::tuple<int, double, double> t) {
340 ret[get<0>(t)].push_back(std::make_pair(get<1>(t), get<2>(t)));
341 }));
342 return ret;
343}
344
355inline std::vector<std::pair<double, double>> read_persistence_intervals_in_dimension(std::string const& filename,
356 int only_this_dim = -1) {
357 std::vector<std::pair<double, double>> ret;
359 filename, boost::make_function_output_iterator([only_this_dim, &ret](std::tuple<int, double, double> t) {
360 if (only_this_dim == get<0>(t) || only_this_dim == -1) ret.emplace_back(get<1>(t), get<2>(t));
361 }));
362 return ret;
363}
364
365} // namespace Gudhi
366
367#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:183
Graph_t read_graph(std::string file_name)
Read a graph from a file.
Definition: reader_utils.h:84
std::vector< std::pair< double, double > > read_persistence_intervals_in_dimension(std::string const &filename, int only_this_dim=-1)
Definition: reader_utils.h:355
void read_persistence_intervals_and_dimension(std::string const &filename, OutputIterator out)
Definition: reader_utils.h:295
bool read_simplex(std::istream &in_, std::vector< Vertex_handle > &simplex, Filtration_value &fil)
Read a face from a file.
Definition: reader_utils.h:158
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:220
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:46
std::map< int, std::vector< std::pair< double, double > > > read_persistence_intervals_grouped_by_dimension(std::string const &filename)
Definition: reader_utils.h:335
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