diff options
Diffstat (limited to 'src/Toplex_map/example')
-rw-r--r-- | src/Toplex_map/example/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/Toplex_map/example/Fake_simplex_tree.h | 188 | ||||
-rw-r--r-- | src/Toplex_map/example/Simple_toplex_map.cpp | 218 | ||||
-rw-r--r-- | src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp | 93 |
4 files changed, 504 insertions, 0 deletions
diff --git a/src/Toplex_map/example/CMakeLists.txt b/src/Toplex_map/example/CMakeLists.txt new file mode 100644 index 00000000..051d7bcd --- /dev/null +++ b/src/Toplex_map/example/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 2.6) +project(Toplex_map_examples) + +add_executable(Toplex_map_example_simple Simple_toplex_map.cpp) +add_executable(Toplex_map_example_from_cliques_of_graph Toplex_map_from_cliques_of_graph.cpp) diff --git a/src/Toplex_map/example/Fake_simplex_tree.h b/src/Toplex_map/example/Fake_simplex_tree.h new file mode 100644 index 00000000..6a7e7bdc --- /dev/null +++ b/src/Toplex_map/example/Fake_simplex_tree.h @@ -0,0 +1,188 @@ +#ifndef FAKE_SIMPLEX_TREE_H +#define FAKE_SIMPLEX_TREE_H + +#include <cmath> + +#include <gudhi/Simplex_tree.h> +#include <gudhi/Filtered_toplex_map.h> + +#include <boost/graph/adjacency_list.hpp> +#include <boost/graph/bron_kerbosch_all_cliques.hpp> + +namespace Gudhi { + +struct Visitor { + Toplex_map* tm; + + Visitor(Toplex_map* tm) + :tm(tm) + {} + + template <typename Clique, typename Graph> + void clique(const Clique& c, const Graph& g) + { + tm->insert_simplex(c); + } +}; + +/** Fake_simplex_tree is a wrapper for Filtered_toplex_map which has the interface of the Simplex_tree. + * Mostly for retro-compatibility purpose. If you use a function that output non maximal simplices, it will be non efficient. + * \ingroup toplex_map */ +class Fake_simplex_tree : public Filtered_toplex_map { + +public: + + /** Handle type to a vertex contained in the simplicial complex. + * \ingroup toplex_map */ + typedef Toplex_map::Vertex Vertex_handle; + + /** Handle type to a simplex contained in the simplicial complex. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex Simplex_handle; + + typedef void Insertion_result_type; + + /** Inserts the flag complex of a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` + * in the simplicial complex. + * \ingroup toplex_map */ + template<class OneSkeletonGraph> + void insert_graph(const OneSkeletonGraph& skel_graph); + + /** Do actually nothing. + * \ingroup toplex_map */ + void expansion(int max_dim); + + /** Returns the number of vertices stored i.e. the number of max simplices + * \ingroup toplex_map */ + std::size_t num_vertices() const; + + /** Returns the dimension of the complex. + * \ingroup toplex_map */ + std::size_t dimension() const; + + /** Returns the dimension of a given simplex in the complex. + * \ingroup toplex_map */ + std::size_t dimension(Simplex_ptr& sptr) const; + + /** Returns the number of simplices stored i.e. the number of maximal simplices. + * \ingroup toplex_map */ + std::size_t num_simplices() const; + + /** Returns a range over the vertices of a simplex. + * \ingroup toplex_map */ + Toplex_map::Simplex simplex_vertex_range(const Simplex& s) const; + + /** Returns a set of all maximal (critical if there is filtration values) simplices. + * \ingroup toplex_map */ + std::vector<Toplex_map::Simplex> max_simplices() const; + + /** Returns all the simplices, of max dimension d if a parameter d is given. + * \ingroup toplex_map */ + std::vector<Toplex_map::Simplex> filtration_simplex_range(int d=std::numeric_limits<int>::max()) const; + + /** Returns all the simplices of max dimension d + * \ingroup toplex_map */ + std::vector<Toplex_map::Simplex> skeleton_simplex_range(int d) const; + + Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); + + +protected: + + /** \internal Does all the facets of the given simplex belong to the complex ? + * \ingroup toplex_map */ + template <typename Input_vertex_range> + bool all_facets_inside(const Input_vertex_range &vertex_range) const; + +}; + +template<class OneSkeletonGraph> +void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ + toplex_maps.emplace(nan(""), new Toplex_map()); + using vertex_iterator = typename boost::graph_traits<OneSkeletonGraph>::vertex_iterator; + vertex_iterator vi, vi_end; + for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) { + Simplex s; s.insert(*vi); + insert_simplex_and_subfaces(s); + } + bron_kerbosch_all_cliques(skel_graph, Visitor(this->toplex_maps.at(nan("")))); +} + +void Fake_simplex_tree::expansion(int max_dim){} + +template <typename Input_vertex_range> +bool Fake_simplex_tree::all_facets_inside(const Input_vertex_range &vertex_range) const{ + Simplex sigma(vertex_range); + for(const Simplex& s : facets(sigma)) + if(!membership(s)) return false; + return true; +} + +std::size_t Fake_simplex_tree::dimension() const { + std::size_t max = 0; + for(const Simplex& s : max_simplices()) + max = std::max(max, s.size()); + return max-1; +} + +std::size_t Fake_simplex_tree::dimension(Simplex_ptr& sptr) const{ + return sptr->size(); +} + +std::size_t Fake_simplex_tree::num_simplices() const { + return max_simplices().size(); +} + +std::size_t Fake_simplex_tree::num_vertices() const { + std::unordered_set<Toplex_map::Vertex> vertices; + for(const Toplex_map::Simplex& s : max_simplices()) + for (Toplex_map::Vertex v : s) + vertices.emplace(v); + return vertices.size(); +} + +Toplex_map::Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { + return s; +} + +std::vector<Toplex_map::Simplex> Fake_simplex_tree::max_simplices() const{ + std::vector<Toplex_map::Simplex> max_s; + for(auto kv : toplex_maps) + for(const Toplex_map::Simplex_ptr& sptr : kv.second->maximal_cofaces(Simplex())) + max_s.emplace_back(*sptr); + return max_s; +} + +std::vector<Toplex_map::Simplex> Fake_simplex_tree::filtration_simplex_range(int d) const{ + std::vector<Toplex_map::Simplex> m = max_simplices(); + std::vector<Toplex_map::Simplex> range; + Toplex_map::Simplex_ptr_set seen; + while(m.begin()!=m.end()){ + Toplex_map::Simplex s(m.back()); + m.pop_back(); + if(seen.find(get_key(s))==seen.end()){ + if((int) s.size()-1 <=d) + range.emplace_back(s); + seen.emplace(get_key(s)); + if(s.size()>0) + for(Simplex& sigma : facets(s)) + m.emplace_back(sigma); + } + } + return range; +} + +std::vector<Toplex_map::Simplex> Fake_simplex_tree::skeleton_simplex_range(int d) const{ + return filtration_simplex_range(d); +} + +Toplex_map::Vertex Fake_simplex_tree::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y){ + for(auto kv : toplex_maps) + kv.second->contraction(x,y); + return y; +} + +} //namespace Gudhi + +#endif /* FAKE_SIMPLEX_TREE_H */ + diff --git a/src/Toplex_map/example/Simple_toplex_map.cpp b/src/Toplex_map/example/Simple_toplex_map.cpp new file mode 100644 index 00000000..d383e84b --- /dev/null +++ b/src/Toplex_map/example/Simple_toplex_map.cpp @@ -0,0 +1,218 @@ +/* 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): Vincent Rouvreau + * + * Copyright (C) 2017 + * + * 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/>. + */ + +#include <gudhi/graph_simplicial_complex.h> +#include "Fake_simplex_tree.h" + +#include <iostream> +#include <utility> // for pair +#include <vector> + +using Toplex_map = Gudhi::Fake_simplex_tree; +using typeVectorVertex = std::vector< Toplex_map::Vertex_handle >; +using typePairSimplexBool = std::pair< Toplex_map::Simplex_handle, bool >; + +int main(int argc, char * const argv[]) { + + // TEST OF INSERTION + std::cout << "********************************************************************" << std::endl; + std::cout << "EXAMPLE OF SIMPLE INSERTION" << std::endl; + // Construct the Toplex_map + Toplex_map t_map; + + /* Simplex to be inserted: */ + /* 1 */ + /* o */ + /* /X\ */ + /* o---o---o */ + /* 2 0 3 */ + + // ++ FIRST + std::cout << " * INSERT 0" << std::endl; + typeVectorVertex firstSimplexVector = { 0 }; + typePairSimplexBool returnValue = t_map.insert_simplex_and_subfaces(firstSimplexVector, 0.1); + + if (returnValue.second == true) { + std::cout << " + 0 INSERTED" << std::endl; + } else { + std::cout << " - 0 NOT INSERTED" << std::endl; + } + + // ++ SECOND + std::cout << " * INSERT 1" << std::endl; + typeVectorVertex secondSimplexVector = { 1 }; + returnValue = t_map.insert_simplex_and_subfaces(secondSimplexVector, 0.1); + + if (returnValue.second == true) { + std::cout << " + 1 INSERTED" << std::endl; + } else { + std::cout << " - 1 NOT INSERTED" << std::endl; + } + + // ++ THIRD + std::cout << " * INSERT (0,1)" << std::endl; + typeVectorVertex thirdSimplexVector = { 0, 1 }; + returnValue = + t_map.insert_simplex_and_subfaces(thirdSimplexVector, 0.2); + + if (returnValue.second == true) { + std::cout << " + (0,1) INSERTED" << std::endl; + } else { + std::cout << " - (0,1) NOT INSERTED" << std::endl; + } + + // ++ FOURTH + std::cout << " * INSERT 2" << std::endl; + typeVectorVertex fourthSimplexVector = { 2 }; + returnValue = + t_map.insert_simplex_and_subfaces(fourthSimplexVector, 0.1); + + if (returnValue.second == true) { + std::cout << " + 2 INSERTED" << std::endl; + } else { + std::cout << " - 2 NOT INSERTED" << std::endl; + } + + // ++ FIFTH + std::cout << " * INSERT (2,0)" << std::endl; + typeVectorVertex fifthSimplexVector = { 2, 0 }; + returnValue = + t_map.insert_simplex_and_subfaces(fifthSimplexVector, 0.2); + + if (returnValue.second == true) { + std::cout << " + (2,0) INSERTED" << std::endl; + } else { + std::cout << " - (2,0) NOT INSERTED" << std::endl; + } + + // ++ SIXTH + std::cout << " * INSERT (2,1)" << std::endl; + typeVectorVertex sixthSimplexVector = { 2, 1 }; + returnValue = + t_map.insert_simplex_and_subfaces(sixthSimplexVector, 0.2); + + if (returnValue.second == true) { + std::cout << " + (2,1) INSERTED" << std::endl; + } else { + std::cout << " - (2,1) NOT INSERTED" << std::endl; + } + + // ++ SEVENTH + std::cout << " * INSERT (2,1,0)" << std::endl; + typeVectorVertex seventhSimplexVector = { 2, 1, 0 }; + returnValue = + t_map.insert_simplex_and_subfaces(seventhSimplexVector, 0.3); + + if (returnValue.second == true) { + std::cout << " + (2,1,0) INSERTED" << std::endl; + } else { + std::cout << " - (2,1,0) NOT INSERTED" << std::endl; + } + + // ++ EIGHTH + std::cout << " * INSERT 3" << std::endl; + typeVectorVertex eighthSimplexVector = { 3 }; + returnValue = + t_map.insert_simplex_and_subfaces(eighthSimplexVector, 0.1); + + if (returnValue.second == true) { + std::cout << " + 3 INSERTED" << std::endl; + } else { + std::cout << " - 3 NOT INSERTED" << std::endl; + } + + // ++ NINETH + std::cout << " * INSERT (3,0)" << std::endl; + typeVectorVertex ninethSimplexVector = { 3, 0 }; + returnValue = + t_map.insert_simplex_and_subfaces(ninethSimplexVector, 0.2); + + if (returnValue.second == true) { + std::cout << " + (3,0) INSERTED" << std::endl; + } else { + std::cout << " - (3,0) NOT INSERTED" << std::endl; + } + + // ++ TENTH + std::cout << " * INSERT 0 (already inserted)" << std::endl; + typeVectorVertex tenthSimplexVector = { 0 }; + // With a different filtration value + returnValue = t_map.insert_simplex_and_subfaces(tenthSimplexVector, 0.4); + + if (returnValue.second == true) { + std::cout << " + 0 INSERTED" << std::endl; + } else { + std::cout << " - 0 NOT INSERTED" << std::endl; + } + + // ++ ELEVENTH + std::cout << " * INSERT (2,1,0) (already inserted)" << std::endl; + typeVectorVertex eleventhSimplexVector = { 2, 1, 0 }; + returnValue = + t_map.insert_simplex_and_subfaces(eleventhSimplexVector, 0.4); + + if (returnValue.second == true) { + std::cout << " + (2,1,0) INSERTED" << std::endl; + } else { + std::cout << " - (2,1,0) NOT INSERTED" << std::endl; + } + + // ++ GENERAL VARIABLE SET + + std::cout << "********************************************************************\n"; + // Display the Simplex_tree - Can not be done in the middle of 2 inserts + std::cout << "* The complex contains " << t_map.num_vertices() << " vertices and " << t_map.num_simplices() + << " simplices - dimension is " << t_map.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : t_map.filtration_simplex_range()) { + if (f_simplex.size() > 0) { + std::cout << " " << "[" << t_map.filtration(f_simplex) << "] "; + for (auto vertex : t_map.simplex_vertex_range(f_simplex)) + std::cout << "(" << vertex << ")"; + std::cout << std::endl; + } + } + // [0.1] 0 + // [0.1] 1 + // [0.1] 2 + // [0.1] 3 + // [0.2] 1 0 + // [0.2] 2 0 + // [0.2] 2 1 + // [0.2] 3 0 + // [0.3] 2 1 0 + + std::cout << std::endl << std::endl; + + std::cout << "Iterator on skeleton[1]:" << std::endl; + for (auto f_simplex : t_map.skeleton_simplex_range(1)) { + if (f_simplex.size() > 0) { + std::cout << " " << "[" << t_map.filtration(f_simplex) << "] "; + for (auto vertex : t_map.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; + } + std::cout << std::endl; + } + } + + return 0; +} diff --git a/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp b/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp new file mode 100644 index 00000000..c43f1b69 --- /dev/null +++ b/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp @@ -0,0 +1,93 @@ +/* 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): Vincent Rouvreau + * + * Copyright (C) 2017 INRIA + * + * 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/>. + */ + +#include <gudhi/reader_utils.h> +#include "Fake_simplex_tree.h" + +#include <iostream> +#include <ctime> +#include <string> +#include <utility> // for std::pair + +using Toplex_map = Gudhi::Fake_simplex_tree; +using Vertex_handle = Toplex_map::Vertex_handle; +using Filtration_value = Toplex_map::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; + +int main(int argc, char * const argv[]) { + if (argc != 3) { + std::cerr << "Usage: " << argv[0] + << " path_to_file_graph max_dim \n"; + return 0; + } + std::string filegraph = argv[1]; + int max_dim = atoi(argv[2]); + + clock_t start, end; + // Construct the Toplex Map + Toplex_map t_map; + + start = clock(); + auto g = Gudhi::read_graph<Graph_t, Filtration_value, Vertex_handle>(filegraph); + // insert the graph in the toplex map as 1-skeleton + t_map.insert_graph(g); + end = clock(); + std::cout << "Insert the 1-skeleton in the toplex map in " + << static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n"; + + start = clock(); + // expand the 1-skeleton until dimension max_dim + t_map.expansion(max_dim); + end = clock(); + std::cout << "max_dim = " << max_dim << "\n"; + std::cout << "Expand the toplex map in " + << static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n"; + + std::cout << "Information of the toplex map: " << std::endl; + std::cout << " Number of vertices = " << t_map.num_vertices() << " "; + std::cout << " Number of simplices = " << t_map.num_simplices() << std::endl; + std::cout << std::endl << std::endl; + + std::cout << "Iterator on Simplices in the filtration:" << std::endl; + for (auto f_simplex : t_map.filtration_simplex_range()) { + std::cout << " " << "[" << t_map.filtration(f_simplex) << "] "; + for (auto vertex : t_map.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; + } + std::cout << std::endl; + } + + std::cout << std::endl << std::endl; + + std::cout << "Iterator on skeleton:" << std::endl; + for (auto f_simplex : t_map.skeleton_simplex_range(max_dim)) { + std::cout << " " << "[" << t_map.filtration(f_simplex) << "] "; + for (auto vertex : t_map.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; + } + std::cout << std::endl; + } + return 0; +} |