diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/doc/main_page.h | 182 | ||||
-rw-r--r-- | src/common/include/gudhi/Clock.h | 151 | ||||
-rw-r--r-- | src/common/include/gudhi/Off_reader.h | 289 | ||||
-rw-r--r-- | src/common/include/gudhi/Point.h | 286 | ||||
-rw-r--r-- | src/common/include/gudhi/Simple_object_pool.h | 81 | ||||
-rw-r--r-- | src/common/include/gudhi/Test.h | 156 | ||||
-rw-r--r-- | src/common/include/gudhi/Utils.h | 74 | ||||
-rw-r--r-- | src/common/include/gudhi/distance_functions.h | 64 | ||||
-rw-r--r-- | src/common/include/gudhi/graph_simplicial_complex.h | 125 | ||||
-rw-r--r-- | src/common/include/gudhi/reader_utils.h | 193 |
10 files changed, 875 insertions, 726 deletions
diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index 315aa0ac..689e7a4d 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -1,72 +1,118 @@ -/** -\mainpage - -\image html "Gudhi_banner.jpg" "" width=20cm - -The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic C++ library for -topological analysis of high-dimensional data whose goal is to provide robust, efficient, flexible and easy to use -implementations of -state-of-the-art algorithms and data structures for computational topology. -This library is part of the <a href="https://project.inria.fr/gudhi/">Gudhi project</a>. - -The current release of the library allows to use several data-structures for simplicial complexes : -simplex tree, Hasse diagram or skeleton-blocker. Several operations can then be done on top of these -representations such as persistent homology computation or simplification. -All data-structures are generic and several of their aspects (such as stored elements, policies) -can be parameterized via template classes. -We refer to -\cite gudhilibrary_ICMS14 -for a detailed description of the design of the library. - -\section installation Gudhi installation - -As Gudhi is a header only library, there is no need to install the library. - -Examples of Gudhi headers inclusion can be found in \ref demos. - - -\section compiling Compiling - -The library uses c++11 and requires <a href="http://www.boost.org/">Boost</a> with version 1.48.0 or more recent. -It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2013. - - -\subsection gmp GMP: -The multi-field persistent homology algorithm requires GMP which is a free library for arbitrary-precision -arithmetic, operating on signed integers, rational numbers, and floating point numbers. - -The following examples require the <a href="http://gmplib.org/">GNU Multiple Precision Arithmetic Library</a> (GMP) -and will not be built if GMP is not installed: - - Persistent_cohomology/rips_multifield_persistence - - Simplex_tree/simplex_tree_from_alpha_shapes_3 - -Having GMP version 4.2 or higher installed is recommended. - -\subsection cgal CGAL: -CGAL is a C++ library which provides easy access to efficient and reliable geometric algorithms. - -The following example requires the <a href="http://www.cgal.org/">Computational Geometry Algorithms Library</a> (CGAL) -and will not be built if CGAL is not installed: - - Simplex_tree/simplex_tree_from_alpha_shapes_3 - -Having CGAL version 4.4 or higher installed is recommended. The procedure to install this library according to -your operating system is detailed here http://doc.cgal.org/latest/Manual/installation.html - -\subsection demos Demos and examples - -To build the demos and libraries, run the following commands in a terminal: - -\verbatim -cd /path-to-gudhi/ -mkdir build -cd build/ -cmake .. -make -\endverbatim +/*! \mainpage + * \image html "Gudhi_banner.jpg" "" width=20cm + * + * \section Introduction Introduction + * The Gudhi library (Geometric Understanding in Higher Dimensions) is a generic open source C++ library for + * Computational Topology and Topological Data Analysis + * (<a class="el" target="_blank" href="https://en.wikipedia.org/wiki/Topological_data_analysis">TDA</a>). + * The GUDHI library is developed as part of the + * <a class="el" target="_blank" href="https://project.inria.fr/gudhi/">GUDHI project</a> supported by the European + * Research Council. The GUDHI library intends to help the development of new algorithmic solutions in TDA and their + * transfer to applications. It provides robust, efficient, flexible and easy to use implementations of + * state-of-the-art algorithms and data structures. + * + * The current release of the GUDHI library includes: + * + * \li Data structures to represent, construct and manipulate simplicial complexes. + * \li Algorithms to compute persistent homology and multi-field persistent homology. + * \li Simplication of simplicial complexes by edge contraction. + * + * All data-structures are generic and several of their aspects can be parameterized via template classes. + * We refer to \cite gudhilibrary_ICMS14 for a detailed description of the design of the library. + * + * The library is available <a class="el" target="_blank" href="https://gforge.inria.fr/frs/?group_id=3865">here</a> + * and the documentation is available at this <a class="el" href="http://gudhi.gforge.inria.fr/doc/latest/"> + * webpage</a>. + * + * The library comes with data sets, \ref demos and \ref testsuites. + * + * Gudhi is also accessible though the + * <a class="el" target="_blank" href="https://cran.r-project.org/web/packages/TDA/index.html">R package TDA</a> + * (Statistical Tools for Topological Data Analysis). + * + * The development of the GUDHI library is steered by an Editorial Board composed of: + * + * \li <a class="el" target="_blank" href="http://www-sop.inria.fr/members/Jean-Daniel.Boissonnat/"> + * Jean-Daniel Boissonnat</a> | INRIA Sophia Antipolis - Méditerranée + * \li <a class="el" target="_blank" href="http://geometrica.saclay.inria.fr/team/Marc.Glisse/">Marc Glisse</a> | INRIA Saclay - Ile de France + * \li Clément Jamin | INRIA Sophia Antipolis - Méditerranée + * \li Vincent Rouvreau | INRIA Saclay - Ile de France + * +*/ -\details +/*! \page installation Gudhi installation + * As Gudhi is a header only library, there is no need to install the library. + * + * Examples of Gudhi headers inclusion can be found in \ref demos. + * + * \section compiling Compiling + * The library uses c++11 and requires <a target="_blank" href="http://www.boost.org/">Boost</a> with version 1.48.0 or + * more recent. It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2013. + * + * \subsection gmp GMP: + * The multi-field persistent homology algorithm requires GMP which is a free library for arbitrary-precision + * arithmetic, operating on signed integers, rational numbers, and floating point numbers. + * + * The following example requires the <a target="_blank" href="http://gmplib.org/">GNU Multiple Precision Arithmetic + * Library</a> (GMP) and will not be built if GMP is not installed: + * \li Persistent_cohomology/rips_multifield_persistence + * Having GMP version 4.2 or higher installed is recommended. + * + * \subsection cgal CGAL: + * CGAL is a C++ library which provides easy access to efficient and reliable geometric algorithms. + * + * The following examples require the <a target="_blank" href="http://www.cgal.org/">Computational Geometry Algorithms + * Library</a> (CGAL) and will not be built if CGAL is not installed: + * \li GudhUI + * \li Persistent_cohomology/alpha_shapes_persistence + * \li Simplex_tree/simplex_tree_from_alpha_shapes_3 + * + * Having CGAL version 4.4 or higher installed is recommended. The procedure to install this library according to + * your operating system is detailed here http://doc.cgal.org/latest/Manual/installation.html + * + * \subsection demos Demos and examples + * To build the demos and libraries, run the following commands in a terminal: + * \verbatim + * cd /path-to-gudhi/ + * mkdir build + * cd build/ + * cmake .. + * make + * \endverbatim + * + * \subsection testsuites Test suites + * To test your build, run the following command in a terminal: + * \verbatim + * make test + * \endverbatim + * + * \section Contributions Bug reports and contributions + * Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to: + * \verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim + * + * Gudhi is open to external contributions. If you want to join our development team, please contact us. + * +*/ -\copyright GNU General Public License v3. -\verbatim Contact: gudhi-users@lists.gforge.inria.fr \endverbatim +/*! \page Upcoming Upcoming + * + * The library is under active development. New packages to be released next include: + * \li Alpha complex. + * \li Bottleneck distance. + * \li Zig zag persistence. + * \li Witness complex. + * \li Tangential complex. + * \li Clustering. +*/ +/*! \page Citation Acknowledging the GUDHI library + * We kindly ask users to cite the GUDHI library as appropriately as possible in their papers, and to mention the use + * of the GUDHI library on the web pages of their projects using GUDHI and provide us with links to these web pages. + * Feel free to contact us in case you have any question or remark on this topic. + * + * We provide \ref GudhiBibtex entries for the modules of the User and Reference Manual, as well as for publications + * directly related to the GUDHI library. + * \section GudhiBibtex GUDHI bibtex + * \verbinclude biblio/how_to_cite_gudhi.bib */ + diff --git a/src/common/include/gudhi/Clock.h b/src/common/include/gudhi/Clock.h index 08096c05..04c6ffb9 100644 --- a/src/common/include/gudhi/Clock.h +++ b/src/common/include/gudhi/Clock.h @@ -1,82 +1,79 @@ - /* 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): David Salinas - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef GUDHI_CLOCK_H_ -#define GUDHI_CLOCK_H_ - +/* 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): David Salinas + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CLOCK_H_ +#define CLOCK_H_ #include <boost/date_time/posix_time/posix_time.hpp> -class Clock{ - -public: - Clock():end_called(false){ - startTime = boost::posix_time::microsec_clock::local_time( ); - } - - Clock(const std::string& msg_){ - end_called = false; - begin(); - msg = msg_; - } - - - void begin() const{ - end_called = false; - startTime = boost::posix_time::microsec_clock::local_time( ); - } - - void end() const{ - end_called = true; - endTime = boost::posix_time::microsec_clock::local_time( ); - } - - void print() const{ - std::cout << *this << std::endl; - } - - friend std::ostream& operator<< (std::ostream& stream,const Clock& clock){ - if(!clock.end_called) - clock.end(); - - if(!clock.end_called) stream << "end not called"; - else{ - stream << clock.msg <<":"<<clock.num_seconds() <<"s"; - } - return stream; - - } - - double num_seconds() const{ - if(!end_called) return -1; - return (endTime-startTime).total_milliseconds()/1000.; - } - -private: - mutable boost::posix_time::ptime startTime, endTime; - mutable bool end_called; - std::string msg; - +#include <string> + +class Clock { + public: + Clock() : end_called(false) { + startTime = boost::posix_time::microsec_clock::local_time(); + } + + Clock(const std::string& msg_) { + end_called = false; + begin(); + msg = msg_; + } + + void begin() const { + end_called = false; + startTime = boost::posix_time::microsec_clock::local_time(); + } + + void end() const { + end_called = true; + endTime = boost::posix_time::microsec_clock::local_time(); + } + + void print() const { + std::cout << *this << std::endl; + } + + friend std::ostream& operator<<(std::ostream& stream, const Clock& clock) { + if (!clock.end_called) + clock.end(); + + if (!clock.end_called) { + stream << "end not called"; + } else { + stream << clock.msg << ":" << clock.num_seconds() << "s"; + } + return stream; + } + + double num_seconds() const { + if (!end_called) return -1; + return (endTime - startTime).total_milliseconds() / 1000.; + } + + private: + mutable boost::posix_time::ptime startTime, endTime; + mutable bool end_called; + std::string msg; }; - -#endif /* GUDHI_CLOCK_H_ */ +#endif // CLOCK_H_ diff --git a/src/common/include/gudhi/Off_reader.h b/src/common/include/gudhi/Off_reader.h index e29218d8..81b9e634 100644 --- a/src/common/include/gudhi/Off_reader.h +++ b/src/common/include/gudhi/Off_reader.h @@ -1,13 +1,10 @@ -/* - * Off_reader.h - * Created on: Nov 28, 2014 - * This file is part of the Gudhi Library. The Gudhi library +/* 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): David Salinas * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,14 +22,15 @@ */ -#ifndef GUDHI_OFF_READER_H_ -#define GUDHI_OFF_READER_H_ +#ifndef OFF_READER_H_ +#define OFF_READER_H_ #include <sstream> #include <iostream> #include <iterator> - +#include <string> +#include <vector> namespace Gudhi { @@ -48,151 +46,144 @@ namespace Gudhi { * * The number of edges num_edges is optional and can be left to zero. */ -class Off_reader{ -public: - Off_reader(std::ifstream& stream):stream_(stream){ - } -// Off_reader(const std::string& name):stream_(name){ -// if(!stream_.is_open()) -// std::cerr <<"could not open file \n"; -// } - - ~Off_reader(){ - stream_.close(); - } - - /** - * read an off file and calls the following methods : - * void init(int dim,int num_vertices,int num_faces,int num_edges); //num_edges may not be set - * void point(const std::vector<double>& point); - * void maximal_face(const std::list<int>& face); - * void done(); - * of the visitor when reading a point or a maximal face. - */ - template<typename OffVisitor> - bool read(OffVisitor& off_visitor){ - bool success_read_off_preambule = read_off_preambule(off_visitor); - if(!success_read_off_preambule) { - std::cerr <<"could not read off preambule\n"; - return false; - } - - bool success_read_off_points = read_off_points(off_visitor); - if(!success_read_off_points) { - std::cerr <<"could not read off points\n"; - return false; - } - - bool success_read_off_faces = read_off_faces(off_visitor); - if(!success_read_off_faces) { - std::cerr <<"could not read off faces\n"; - return false; - } - - off_visitor.done(); - return success_read_off_preambule && success_read_off_points && success_read_off_faces; - } - -private: - std::ifstream& stream_; - - struct Off_info{ - int dim; - int num_vertices; - int num_edges; - int num_faces; - }; - - Off_info off_info_; - - template<typename OffVisitor> - bool read_off_preambule(OffVisitor& off_visitor){ - std::string line; - if(!goto_next_uncomment_line(line)) return false; - - bool is_off_file = (line.find("OFF") != std::string::npos); - bool is_noff_file = (line.find("nOFF") != std::string::npos); - - if(!is_off_file && !is_noff_file) { - std::cerr << line<<std::endl; - std::cerr << "missing off header\n"; - return false; - } - - if(!goto_next_uncomment_line(line)) return false; - std::istringstream iss(line); - if(is_off_file){ - off_info_.dim = 3; - if(!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)){ - std::cerr << "incorrect number of vertices/faces/edges\n"; - return false; - } - } - else - if(!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)){ - std::cerr << "incorrect number of vertices/faces/edges\n"; - return false; - } - off_visitor.init(off_info_.dim,off_info_.num_vertices,off_info_.num_faces,off_info_.num_edges); - - return true; - } - - bool goto_next_uncomment_line(std::string& uncomment_line){ - uncomment_line.clear(); - do - std::getline(stream_, uncomment_line); - while(uncomment_line[0] == '%');// || uncomment_line.empty()); - return (uncomment_line.size()>0 && uncomment_line[0] != '%'); - } - - - template<typename OffVisitor> - bool read_off_points(OffVisitor& visitor){ - int num_vertices_to_read = off_info_.num_vertices; - while(num_vertices_to_read--){ - std::string line; - if(!goto_next_uncomment_line(line)) return false; - std::vector<double> point; - std::istringstream iss(line); - point.assign(std::istream_iterator<double>(iss),std::istream_iterator<double>()); -// if(point.size() != off_info_.dim) return false; - visitor.point(point); - } - return true; - } - - template<typename OffVisitor> - bool read_off_faces(OffVisitor& visitor){ - std::string line; - while(goto_next_uncomment_line(line)){ - std::istringstream iss(line); - int num_face_vertices; - iss >> num_face_vertices; - std::vector<int> face; - face.assign(std::istream_iterator<int>(iss),std::istream_iterator<int>()); - if(!face.size() == off_info_.num_vertices) return false; - visitor.maximal_face(face); - } - return true; - } +class Off_reader { + public: + Off_reader(std::ifstream& stream) : stream_(stream) { } + // Off_reader(const std::string& name):stream_(name){ + // if(!stream_.is_open()) + // std::cerr <<"could not open file \n"; + // } + + ~Off_reader() { + stream_.close(); + } + + /** + * read an off file and calls the following methods : + * void init(int dim,int num_vertices,int num_faces,int num_edges); //num_edges may not be set + * void point(const std::vector<double>& point); + * void maximal_face(const std::list<int>& face); + * void done(); + * of the visitor when reading a point or a maximal face. + */ + template<typename OffVisitor> + bool read(OffVisitor& off_visitor) { + bool success_read_off_preambule = read_off_preambule(off_visitor); + if (!success_read_off_preambule) { + std::cerr << "could not read off preambule\n"; + return false; + } + + bool success_read_off_points = read_off_points(off_visitor); + if (!success_read_off_points) { + std::cerr << "could not read off points\n"; + return false; + } + + bool success_read_off_faces = read_off_faces(off_visitor); + if (!success_read_off_faces) { + std::cerr << "could not read off faces\n"; + return false; + } + + off_visitor.done(); + return success_read_off_preambule && success_read_off_points && success_read_off_faces; + } + + private: + std::ifstream& stream_; + + struct Off_info { + int dim; + int num_vertices; + int num_edges; + int num_faces; + }; + + Off_info off_info_; + + template<typename OffVisitor> + bool read_off_preambule(OffVisitor& off_visitor) { + std::string line; + if (!goto_next_uncomment_line(line)) return false; + + bool is_off_file = (line.find("OFF") != std::string::npos); + bool is_noff_file = (line.find("nOFF") != std::string::npos); + + if (!is_off_file && !is_noff_file) { + std::cerr << line << std::endl; + std::cerr << "missing off header\n"; + return false; + } + + if (!goto_next_uncomment_line(line)) return false; + std::istringstream iss(line); + if (is_off_file) { + off_info_.dim = 3; + if (!(iss >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) { + std::cerr << "incorrect number of vertices/faces/edges\n"; + return false; + } + } else { + if (!(iss >> off_info_.dim >> off_info_.num_vertices >> off_info_.num_faces >> off_info_.num_edges)) { + std::cerr << "incorrect number of vertices/faces/edges\n"; + return false; + } + } + off_visitor.init(off_info_.dim, off_info_.num_vertices, off_info_.num_faces, off_info_.num_edges); + + return true; + } + + bool goto_next_uncomment_line(std::string& uncomment_line) { + uncomment_line.clear(); + do + std::getline(stream_, uncomment_line); while (uncomment_line[0] == '%'); // || uncomment_line.empty()); + return (uncomment_line.size() > 0 && uncomment_line[0] != '%'); + } + + template<typename OffVisitor> + bool read_off_points(OffVisitor& visitor) { + int num_vertices_to_read = off_info_.num_vertices; + while (num_vertices_to_read--) { + std::string line; + if (!goto_next_uncomment_line(line)) return false; + std::vector<double> point; + std::istringstream iss(line); + point.assign(std::istream_iterator<double>(iss), std::istream_iterator<double>()); + // if(point.size() != off_info_.dim) return false; + visitor.point(point); + } + return true; + } + + template<typename OffVisitor> + bool read_off_faces(OffVisitor& visitor) { + std::string line; + while (goto_next_uncomment_line(line)) { + std::istringstream iss(line); + int num_face_vertices; + iss >> num_face_vertices; + std::vector<int> face; + face.assign(std::istream_iterator<int>(iss), std::istream_iterator<int>()); + if (face.size() != off_info_.dim) return false; + visitor.maximal_face(face); + } + return true; + } }; - template<typename OFFVisitor> -void read_off(const std::string& name_file_off,OFFVisitor& vis){ - std::ifstream stream(name_file_off); - if(!stream.is_open()) - std::cerr <<"could not open file \n"; - else{ - Off_reader off_reader(stream); - off_reader.read(vis); - } +void read_off(const std::string& name_file_off, OFFVisitor& vis) { + std::ifstream stream(name_file_off); + if (!stream.is_open()) { + std::cerr << "could not open file \n"; + } else { + Off_reader off_reader(stream); + off_reader.read(vis); + } } - - } // namespace Gudhi - -#endif /* GUDHI_OFF_READER_H_ */ +#endif // OFF_READER_H_ diff --git a/src/common/include/gudhi/Point.h b/src/common/include/gudhi/Point.h index 4023445b..0479e71e 100644 --- a/src/common/include/gudhi/Point.h +++ b/src/common/include/gudhi/Point.h @@ -1,13 +1,10 @@ -/* - * Basic_geometry.h - * Created on: Feb 10, 2015 - * This file is part of the Gudhi Library. The Gudhi library +/* 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): David Salinas * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,9 +21,8 @@ * */ - -#ifndef BASIC_GEOMETRY_H_ -#define BASIC_GEOMETRY_H_ +#ifndef POINT_H_ +#define POINT_H_ #include <cmath> #include <vector> @@ -34,143 +30,141 @@ #include <cstddef> #include <initializer_list> -class Point_d{ -public: - Point_d(size_t dim=3):coords_(dim,0){} - Point_d(const Point_d& other):coords_(other.coords_){} - Point_d(const std::initializer_list<double>& list):coords_(list) { - } - template<typename CoordsIt> - Point_d(CoordsIt begin,CoordsIt end):coords_(begin,end){} - - size_t dimension() const{ - return coords_.size(); - } - - double x() const{ - return coords_[0]; - } - - double y() const{ - return coords_[1]; - } - - double z() const{ - return coords_[2]; - } - - double& x(){ - return coords_[0]; - } - - double& y(){ - return coords_[1]; - } - - double& z(){ - return coords_[2]; - } - - std::vector<double>::const_iterator begin() const{ - return coords_.begin(); - } - - std::vector<double>::const_iterator end() const{ - return coords_.end(); - } - - double& operator[](unsigned i){ - return coords_[i]; - } - const double& operator[](unsigned i) const{ - return coords_[i]; - } - - double squared_norm() const{ - double res = 0; - for(auto x : coords_) - res+= x*x; - return res; - } - - friend double squared_dist(const Point_d& p1,const Point_d& p2){ - assert(p1.dimension()==p2.dimension()); - double res = 0; - for(unsigned i = 0; i < p1.coords_.size(); ++i) - res+= (p1[i]-p2[i])*(p1[i]-p2[i]); - return res; - } - - /** - * dot product - */ - double operator*(const Point_d& other) const{ - assert(dimension()==other.dimension()); - double res = 0; - for(unsigned i = 0; i < coords_.size(); ++i) - res+= coords_[i]*other[i]; - return res; - } - - /** - * only if points have dimension 3 - */ - Point_d cross_product(const Point_d& other){ - assert(dimension()==3 && other.dimension()==3); - Point_d res(3); - res[0] = (*this)[1] * other[2] - (*this)[2] * other[1]; - res[1] = (*this)[2] * other[0] - (*this)[0] * other[2]; - res[2] = (*this)[0] * other[1] - (*this)[1] * other[0]; - return res; - } - - Point_d operator+(const Point_d& other) const{ - assert(dimension()==other.dimension()); - Point_d res(dimension()); - for(unsigned i = 0; i < coords_.size(); ++i) - res[i] = (*this)[i] + other[i]; - return res; - } - - Point_d operator*(double lambda) const{ - Point_d res(dimension()); - for(unsigned i = 0; i < coords_.size(); ++i) - res[i] = (*this)[i] * lambda; - return res; - } - - Point_d operator/(double lambda) const{ - Point_d res(dimension()); - for(unsigned i = 0; i < coords_.size(); ++i) - res[i] = (*this)[i] / lambda; - return res; - } - - Point_d operator-(const Point_d& other) const{ - assert(dimension()==other.dimension()); - Point_d res(dimension()); - for(unsigned i = 0; i < coords_.size(); ++i) - res[i] = (*this)[i] - other[i]; - return res; - } - - friend Point_d unit_normal(const Point_d& p1,const Point_d& p2,const Point_d& p3){ - assert(p1.dimension()==3); - assert(p2.dimension()==3); - assert(p3.dimension()==3); - Point_d p1p2 = p2 - p1; - Point_d p1p3 = p3 - p1; - Point_d res(p1p2.cross_product(p1p3)); - return res / std::sqrt(res.squared_norm()); - } - - -private: - std::vector<double> coords_; +class Point_d { + public: + Point_d(size_t dim = 3) : coords_(dim, 0) { } + + Point_d(const Point_d& other) : coords_(other.coords_) { } + + Point_d(const std::initializer_list<double>& list) : coords_(list) { } + + template<typename CoordsIt> + Point_d(CoordsIt begin, CoordsIt end) : coords_(begin, end) { } + + size_t dimension() const { + return coords_.size(); + } + + double x() const { + return coords_[0]; + } + + double y() const { + return coords_[1]; + } + + double z() const { + return coords_[2]; + } + + double& x() { + return coords_[0]; + } + + double& y() { + return coords_[1]; + } + + double& z() { + return coords_[2]; + } + + std::vector<double>::const_iterator begin() const { + return coords_.begin(); + } + + std::vector<double>::const_iterator end() const { + return coords_.end(); + } + + double& operator[](unsigned i) { + return coords_[i]; + } + + const double& operator[](unsigned i) const { + return coords_[i]; + } + + double squared_norm() const { + double res = 0; + for (auto x : coords_) + res += x * x; + return res; + } + + friend double squared_dist(const Point_d& p1, const Point_d& p2) { + assert(p1.dimension() == p2.dimension()); + double res = 0; + for (unsigned i = 0; i < p1.coords_.size(); ++i) + res += (p1[i] - p2[i])*(p1[i] - p2[i]); + return res; + } + + /** + * dot product + */ + double operator*(const Point_d& other) const { + assert(dimension() == other.dimension()); + double res = 0; + for (unsigned i = 0; i < coords_.size(); ++i) + res += coords_[i] * other[i]; + return res; + } + + /** + * only if points have dimension 3 + */ + Point_d cross_product(const Point_d& other) { + assert(dimension() == 3 && other.dimension() == 3); + Point_d res(3); + res[0] = (*this)[1] * other[2] - (*this)[2] * other[1]; + res[1] = (*this)[2] * other[0] - (*this)[0] * other[2]; + res[2] = (*this)[0] * other[1] - (*this)[1] * other[0]; + return res; + } + + Point_d operator+(const Point_d& other) const { + assert(dimension() == other.dimension()); + Point_d res(dimension()); + for (unsigned i = 0; i < coords_.size(); ++i) + res[i] = (*this)[i] + other[i]; + return res; + } + + Point_d operator*(double lambda) const { + Point_d res(dimension()); + for (unsigned i = 0; i < coords_.size(); ++i) + res[i] = (*this)[i] * lambda; + return res; + } + + Point_d operator/(double lambda) const { + Point_d res(dimension()); + for (unsigned i = 0; i < coords_.size(); ++i) + res[i] = (*this)[i] / lambda; + return res; + } + + Point_d operator-(const Point_d& other) const { + assert(dimension() == other.dimension()); + Point_d res(dimension()); + for (unsigned i = 0; i < coords_.size(); ++i) + res[i] = (*this)[i] - other[i]; + return res; + } + + friend Point_d unit_normal(const Point_d& p1, const Point_d& p2, const Point_d& p3) { + assert(p1.dimension() == 3); + assert(p2.dimension() == 3); + assert(p3.dimension() == 3); + Point_d p1p2 = p2 - p1; + Point_d p1p3 = p3 - p1; + Point_d res(p1p2.cross_product(p1p3)); + return res / std::sqrt(res.squared_norm()); + } + + private: + std::vector<double> coords_; }; - - - - -#endif /* BASIC_GEOMETRY_H_ */ +#endif // POINT_H_ diff --git a/src/common/include/gudhi/Simple_object_pool.h b/src/common/include/gudhi/Simple_object_pool.h new file mode 100644 index 00000000..fb9c8e23 --- /dev/null +++ b/src/common/include/gudhi/Simple_object_pool.h @@ -0,0 +1,81 @@ +/* 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): Marc Glisse + * + * Copyright (C) 2015 INRIA Saclay - Ile de France + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SIMPLE_OBJECT_POOL_H_ +#define SIMPLE_OBJECT_POOL_H_ + +#include <boost/pool/pool.hpp> +#include <utility> + +namespace Gudhi { + +/** \private + * This is a simpler version of boost::object_pool, that requires + * that users explicitly destroy all objects. This lets the + * performance scale much better, see + * https://svn.boost.org/trac/boost/ticket/3789 . + */ +template <class T> +class Simple_object_pool : protected boost::pool<boost::default_user_allocator_malloc_free> { + protected: + typedef boost::pool<boost::default_user_allocator_malloc_free> Base; + typedef T* pointer; + + Base& base() { + return *this; + } + + Base const& base()const { + return *this; + } + + public: + typedef T element_type; + typedef boost::default_user_allocator_malloc_free user_allocator; + typedef typename Base::size_type size_type; + typedef typename Base::difference_type difference_type; + + template<class...U> + Simple_object_pool(U&&...u) : Base(sizeof (T), std::forward<U>(u)...) { } + + template<class...U> + pointer construct(U&&...u) { + void* p = base().malloc BOOST_PREVENT_MACRO_SUBSTITUTION(); + assert(p); + try { + new(p) T(std::forward<U>(u)...); + } catch (...) { + base().free BOOST_PREVENT_MACRO_SUBSTITUTION(p); + throw; + } + return static_cast<pointer> (p); + } + + void destroy(pointer p) { + p->~T(); + base().free BOOST_PREVENT_MACRO_SUBSTITUTION(p); + } +}; + +} // namespace Gudhi + +#endif // SIMPLE_OBJECT_POOL_H_ diff --git a/src/common/include/gudhi/Test.h b/src/common/include/gudhi/Test.h index 18b7ca82..6024c822 100644 --- a/src/common/include/gudhi/Test.h +++ b/src/common/include/gudhi/Test.h @@ -1,5 +1,28 @@ -#ifndef __TEST_H -#define __TEST_H +/* 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): David Salinas + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef TEST_H_ +#define TEST_H_ #include <list> #include <string> @@ -8,78 +31,75 @@ #include <iostream> -#define TEST(a) std::cout << "TEST: " << (a)<<std::endl -#define TESTMSG(a,b) std::cout << "TEST: " << a<<b<<std::endl -#define TESTVALUE(a) std::cout << "TEST: " << #a << ": " << a<<std::endl - +#define TEST(a) std::cout << "TEST: " << (a) << std::endl +#define TESTMSG(a, b) std::cout << "TEST: " << a << b << std::endl +#define TESTVALUE(a) std::cout << "TEST: " << #a << ": " << a << std::endl /** * Class to perform test */ -class Test -{ -private : - std::string name; - bool (*test)(); - - std::string separation() const{ - return "+++++++++++++++++++++++++++++++++++++++++++++++++\n"; - } - - std::string print_between_plus(std::string& s) const{ - std::stringstream res; - res << "+++++++++++++++++"<<s<<"+++++++++++++++++\n"; - return res.str(); - } - - -public: - Test(std::string name_,bool (*test_)()){ - name=name_; - test =test_; - } - - bool run(){ - std::cout << print_between_plus(name); - return test(); - } - std::string getName(){ - return name; - } +class Test { + private: + std::string name; + bool (*test)(); + + std::string separation() const { + return "+++++++++++++++++++++++++++++++++++++++++++++++++\n"; + } + + std::string print_between_plus(std::string& s) const { + std::stringstream res; + res << "+++++++++++++++++" << s << "+++++++++++++++++\n"; + return res.str(); + } + + public: + Test(std::string name_, bool (*test_)()) { + name = name_; + test = test_; + } + + bool run() { + std::cout << print_between_plus(name); + return test(); + } + + std::string getName() { + return name; + } }; - -class Tests -{ -private: - std::list<Test> tests; - -public: - void add(std::string name_,bool (*test_)()){ - Test test(name_,test_); - tests.push_back(test); - } - bool run(){ - bool tests_succesful(true); - std::vector<bool> res; - for (Test test : tests){ - res.push_back(test.run()); - } - std::cout << "\n\n results of tests : "<<std::endl; - int i=0; - for (Test t : tests){ - std::cout << "Test "<<i<< " \""<<t.getName()<<"\" --> "; - if (res[i++]) std::cout << "OK"<<std::endl; - else { - std::cout << "Fail"<<std::endl; - tests_succesful = false; - break; - } - } - return tests_succesful; - - } +class Tests { + private: + std::list<Test> tests; + + public: + void add(std::string name_, bool (*test_)()) { + Test test(name_, test_); + tests.push_back(test); + } + + bool run() { + bool tests_succesful(true); + std::vector<bool> res; + for (Test test : tests) { + res.push_back(test.run()); + } + std::cout << "\n\n results of tests : " << std::endl; + int i = 0; + for (Test t : tests) { + std::cout << "Test " << i << " \"" << t.getName() << "\" --> "; + if (res[i++]) { + std::cout << "OK" << std::endl; + } else { + std::cout << "Fail" << std::endl; + tests_succesful = false; + break; + } + } + return tests_succesful; + } }; -#endif +#endif // TEST_H_ diff --git a/src/common/include/gudhi/Utils.h b/src/common/include/gudhi/Utils.h index 7678685c..43916f11 100644 --- a/src/common/include/gudhi/Utils.h +++ b/src/common/include/gudhi/Utils.h @@ -1,48 +1,46 @@ - /* 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): David Salinas - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -#ifndef GUDHI_UTILS_H_ -#define GUDHI_UTILS_H_ +/* 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): David Salinas + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef UTILS_H_ +#define UTILS_H_ -#define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)"<<std::endl +#define PRINT(a) std::cerr << #a << ": " << (a) << " (DISP)" << std::endl -//#define DBG_VERBOSE +// #define DBG_VERBOSE #ifdef DBG_VERBOSE -#define DBG(a) std::cerr << "DBG: " << (a)<<std::endl -#define DBGMSG(a,b) std::cerr << "DBG: " << a<<b<<std::endl -#define DBGVALUE(a) std::cerr << "DBG: " << #a << ": " << a<<std::endl -#define DBGCONT(a) std::cerr << "DBG: container "<< #a<<" -> "; for(auto x:a) std::cerr<< x << ","; std::cerr<<std::endl +#define DBG(a) std::cerr << "DBG: " << (a) << std::endl +#define DBGMSG(a, b) std::cerr << "DBG: " << a << b << std::endl +#define DBGVALUE(a) std::cerr << "DBG: " << #a << ": " << a << std::endl +#define DBGCONT(a) std::cerr << "DBG: container " << #a << " -> "; for (auto x : a) std::cerr << x << ","; std::cerr << +std::endl #else -//#define DBG(a) a -//#define DBGMSG(a,b) b -//#define DBGVALUE(a) a -//#define DBGCONT(a) a +// #define DBG(a) a +// #define DBGMSG(a,b) b +// #define DBGVALUE(a) a +// #define DBGCONT(a) a #define DBG(a) -#define DBGMSG(a,b) +#define DBGMSG(a, b) #define DBGVALUE(a) #define DBGCONT(a) #endif - - - -#endif /* UTILS_H_ */ +#endif // UTILS_H_ diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index 7a2ab035..e5c79ded 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -1,37 +1,41 @@ - /* 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): Clément Maria - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +/* 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): Clément Maria + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DISTANCE_FUNCTIONS_H_ +#define DISTANCE_FUNCTIONS_H_ /* Compute the Euclidean distance between two Points given * by a range of coordinates. The points are assumed to have * the same dimension. */ template< typename Point > -double euclidean_distance( Point &p1, Point &p2) -{ +double euclidean_distance(Point &p1, Point &p2) { double dist = 0.; - auto it1 = p1.begin(); auto it2 = p2.begin(); - for(; it1 != p1.end(); ++it1, ++it2) - { - double tmp = *it1 - *it2; - dist += tmp*tmp; - } - return sqrt(dist); + auto it1 = p1.begin(); + auto it2 = p2.begin(); + for (; it1 != p1.end(); ++it1, ++it2) { + double tmp = *it1 - *it2; + dist += tmp*tmp; + } + return sqrt(dist); } + +#endif // DISTANCE_FUNCTIONS_H_ diff --git a/src/common/include/gudhi/graph_simplicial_complex.h b/src/common/include/gudhi/graph_simplicial_complex.h index 1ad9dabd..042ef516 100644 --- a/src/common/include/gudhi/graph_simplicial_complex.h +++ b/src/common/include/gudhi/graph_simplicial_complex.h @@ -1,96 +1,99 @@ - /* 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): Clément Maria - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +/* 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): Clément Maria + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ -#ifndef GUDHI_GRAPH_SIMPLICIAL_COMPLEX_FILTRATION_TAG_H -#define GUDHI_GRAPH_SIMPLICIAL_COMPLEX_FILTRATION_TAG_H +#ifndef GRAPH_SIMPLICIAL_COMPLEX_H_ +#define GRAPH_SIMPLICIAL_COMPLEX_H_ #include <boost/graph/adjacency_list.hpp> +#include <utility> // for pair<> +#include <vector> +#include <map> + /* Edge tag for Boost PropertyGraph. */ struct edge_filtration_t { typedef boost::edge_property_tag kind; }; + /* Vertex tag for Boost PropertyGraph. */ struct vertex_filtration_t { typedef boost::vertex_property_tag kind; }; -typedef int Vertex_handle; -typedef double Filtration_value; +typedef int Vertex_handle; +typedef double Filtration_value; typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS - , boost::property < vertex_filtration_t, Filtration_value > - , boost::property < edge_filtration_t, Filtration_value > - > Graph_t; +, boost::property < vertex_filtration_t, Filtration_value > +, boost::property < edge_filtration_t, Filtration_value > +> Graph_t; typedef std::pair< Vertex_handle, Vertex_handle > Edge_t; /** \brief Output the proximity graph of the points. - * - * If points contains n elements, the proximity graph is the graph - * with n vertices, and an edge [u,v] iff the distance function between - * points u and v is smaller than threshold. - * - * The type PointCloud furnishes .begin() and .end() methods, that return - * iterators with value_type Point. - */ + * + * If points contains n elements, the proximity graph is the graph + * with n vertices, and an edge [u,v] iff the distance function between + * points u and v is smaller than threshold. + * + * The type PointCloud furnishes .begin() and .end() methods, that return + * iterators with value_type Point. + */ template< typename PointCloud - , typename Point > -Graph_t compute_proximity_graph( PointCloud &points - , Filtration_value threshold - , Filtration_value distance(Point p1, Point p2) ) -{ - std::vector< Edge_t > edges; - std::vector< Filtration_value > edges_fil; +, typename Point > +Graph_t compute_proximity_graph(PointCloud &points + , Filtration_value threshold + , Filtration_value distance(Point p1, Point p2)) { + std::vector< Edge_t > edges; + std::vector< Filtration_value > edges_fil; std::map< Vertex_handle, Filtration_value > vertices; Vertex_handle idx_u, idx_v; Filtration_value fil; idx_u = 0; - for(auto it_u = points.begin(); it_u != points.end(); ++it_u) - { - idx_v = idx_u+1; - for(auto it_v = it_u+1; it_v != points.end(); ++it_v, ++idx_v) - { - fil = distance(*it_u,*it_v); - if(fil <= threshold) { - edges.emplace_back(idx_u,idx_v); + for (auto it_u = points.begin(); it_u != points.end(); ++it_u) { + idx_v = idx_u + 1; + for (auto it_v = it_u + 1; it_v != points.end(); ++it_v, ++idx_v) { + fil = distance(*it_u, *it_v); + if (fil <= threshold) { + edges.emplace_back(idx_u, idx_v); edges_fil.push_back(fil); } } ++idx_u; } - Graph_t skel_graph( edges.begin() - , edges.end() - , edges_fil.begin() - , idx_u); //number of points labeled from 0 to idx_u-1 + Graph_t skel_graph(edges.begin() + , edges.end() + , edges_fil.begin() + , idx_u); // number of points labeled from 0 to idx_u-1 - auto vertex_prop = boost::get(vertex_filtration_t(),skel_graph); + auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph); boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end; - for ( std::tie(vi, vi_end) = boost::vertices(skel_graph); - vi != vi_end; ++vi ) - { boost::put(vertex_prop, *vi, 0.); } - + for (std::tie(vi, vi_end) = boost::vertices(skel_graph); + vi != vi_end; ++vi) { + boost::put(vertex_prop, *vi, 0.); + } + return skel_graph; } -#endif // GUDHI_GRAPH_SIMPLICIAL_COMPLEX_FILTRATION_TAG_H +#endif // GRAPH_SIMPLICIAL_COMPLEX_H_ diff --git a/src/common/include/gudhi/reader_utils.h b/src/common/include/gudhi/reader_utils.h index ab12c268..e05714c7 100644 --- a/src/common/include/gudhi/reader_utils.h +++ b/src/common/include/gudhi/reader_utils.h @@ -1,32 +1,38 @@ - /* 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): Clément Maria - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef GUDHI_READER_UTILS_H -#define GUDHI_READER_UTILS_H +/* 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): Clément Maria + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef READER_UTILS_H_ +#define READER_UTILS_H_ + +#include <gudhi/graph_simplicial_complex.h> + +#include <boost/graph/adjacency_list.hpp> #include <iostream> #include <fstream> -#include <boost/graph/adjacency_list.hpp> -#include "gudhi/graph_simplicial_complex.h" +#include <map> +#include <limits> // for numeric_limits<> +#include <string> +#include <vector> /** * \brief Read a set of points to turn it @@ -37,22 +43,21 @@ * X21 X22 ... X2d * etc */ -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()) { +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; - return;} + return; + } std::string line; double x; - while( getline ( in_file , line ) ) - { + while (getline(in_file, line)) { std::vector< double > point; - std::istringstream iss( line ); - while(iss >> x) { point.push_back(x); } + std::istringstream iss(line); + while (iss >> x) { + point.push_back(x); + } points.push_back(point); } in_file.close(); @@ -70,53 +75,64 @@ read_points ( std::string file_name * Every simplex must appear exactly once. * Simplices of dimension more than 1 are ignored. */ -inline 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::vector< Edge_t > edges; - std::vector< Filtration_value > edges_fil; +inline 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::vector< Edge_t > edges; + std::vector< Filtration_value > edges_fil; std::map< Vertex_handle, Filtration_value > vertices; - - std::string line; - int dim; - Vertex_handle u,v,max_h = -1; + + std::string line; + int dim; + Vertex_handle u, v, max_h = -1; Filtration_value fil; - while( getline ( in_ , line ) ) - { - std::istringstream iss( line ); - while(iss >> dim) { - switch ( dim ) { - case 0 : { - iss >> u; iss >> fil; + while (getline(in_, line)) { + std::istringstream iss(line); + while (iss >> dim) { + switch (dim) { + case 0: + { + iss >> u; + iss >> fil; vertices[u] = fil; - if(max_h < u) { max_h = u; } + if (max_h < u) { + max_h = u; + } break; } - case 1 : { - iss >> u; iss >> v; iss >> fil; - edges.push_back(Edge_t(u,v)); + case 1: + { + iss >> u; + iss >> v; + iss >> fil; + edges.push_back(Edge_t(u, v)); edges_fil.push_back(fil); break; } - default: {break;} - } + default: + { + break; + } + } } } in_.close(); - if((size_t)(max_h+1) != vertices.size()) - { std::cerr << "Error: vertices must be labeled from 0 to n-1 \n"; } + if ((size_t) (max_h + 1) != vertices.size()) { + std::cerr << "Error: vertices must be labeled from 0 to n-1 \n"; + } - Graph_t skel_graph(edges.begin(),edges.end(),edges_fil.begin(),vertices.size()); - auto vertex_prop = boost::get(vertex_filtration_t(),skel_graph); + Graph_t skel_graph(edges.begin(), edges.end(), edges_fil.begin(), vertices.size()); + auto vertex_prop = boost::get(vertex_filtration_t(), skel_graph); boost::graph_traits<Graph_t>::vertex_iterator vi, vi_end; auto v_it = vertices.begin(); - for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi,++v_it) - { boost::put(vertex_prop, *vi, v_it->second); } + for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi, ++v_it) { + boost::put(vertex_prop, *vi, v_it->second); + } return skel_graph; } @@ -133,17 +149,15 @@ 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 ) -{ - int dim=0; - if(!(in_ >> dim)) return false; +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; - for(int i=0; i<dim+1; ++i) - { in_ >> v; simplex.push_back(v); } + for (int i = 0; i < dim + 1; ++i) { + in_ >> v; + simplex.push_back(v); + } in_ >> fil; in_.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); // ignore until the carriage return return true; @@ -162,20 +176,21 @@ bool read_simplex ( std::istream & in_ * 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) {in_ >> fil; return true;} + if (!(in_ >> dim)) return false; + if (dim == 0) { + in_ >> fil; + return true; + } Simplex_key key; - for(int i=0; i<dim+1; ++i) - { in_ >> key; boundary.push_back(key); } + for (int i = 0; i < dim + 1; ++i) { + in_ >> key; + boundary.push_back(key); + } in_ >> fil; return true; } -#endif // GUDHI_READER_UTILS_H +#endif // READER_UTILS_H_ |