From d8e1da2f6465e3d6baa0c6e921a3cc0b9ce3f2c7 Mon Sep 17 00:00:00 2001 From: fgodi Date: Fri, 13 Oct 2017 09:33:33 +0000 Subject: module toplex_map added git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2784 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 61f8f8a2d3920dbc30b86dd808a0e316383af137 --- src/Toplex_map/doc/Intro_Toplex_map.h | 57 ++++ src/Toplex_map/doc/map.png | Bin 0 -> 278692 bytes src/Toplex_map/example/CMakeLists.txt | 4 + src/Toplex_map/example/chrono.cpp | 137 +++++++++ src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 207 ++++++++++++++ src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 45 +++ src/Toplex_map/include/gudhi/Lazy_toplex_map.h | 218 +++++++++++++++ src/Toplex_map/include/gudhi/Toplex_map.h | 307 +++++++++++++++++++++ src/Toplex_map/test/CMakeLists.txt | 14 + src/Toplex_map/test/test.cpp | 71 +++++ 10 files changed, 1060 insertions(+) create mode 100644 src/Toplex_map/doc/Intro_Toplex_map.h create mode 100644 src/Toplex_map/doc/map.png create mode 100644 src/Toplex_map/example/CMakeLists.txt create mode 100644 src/Toplex_map/example/chrono.cpp create mode 100644 src/Toplex_map/include/gudhi/Fake_simplex_tree.h create mode 100644 src/Toplex_map/include/gudhi/Filtered_toplex_map.h create mode 100644 src/Toplex_map/include/gudhi/Lazy_toplex_map.h create mode 100644 src/Toplex_map/include/gudhi/Toplex_map.h create mode 100644 src/Toplex_map/test/CMakeLists.txt create mode 100644 src/Toplex_map/test/test.cpp (limited to 'src') diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h new file mode 100644 index 00000000..da9562ec --- /dev/null +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -0,0 +1,57 @@ +/* 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: François Godi + * + * 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 . + */ + +#ifndef DOC_TOPLEX_MAP_H_ +#define DOC_TOPLEX_MAP_H_ + +// needs namespace for Doxygen to link on classes +namespace Gudhi { + +/** \defgroup toplex_map Toplex Map + * + * \author François Godi + * @{ + * + * \section toplexmapdefinition Definition + * + * Let's consider a simplicial complex, denote by $d$ its dimension + * and by $k$ its number of maximal simplices. + * Furthermore, denote by $\gamma_0$ the maximal number of toplices, i.e. maximal simplices, + * that contain a same vertex. + * + * The goal of the Toplex Map is both to represent the complex in optimal + * O(kd) space and to provide fast standard operations such as : insertion, removal + * and membership of a simplex, contraction of an edge, collapses. The time needed + * for these operation is linear or quadratic in $\gamma_0$ and $d$. + * + * Toplex map is composed firstly of a raw storage of toplices and secondly of a + * map which associate any vertex to a set of pointers toward all toplices + * containing this vertex. + * + * \image html map.png + * + */ +/** @} */ // end defgroup toplex_map + +} // namespace Gudhi + +#endif // DOC_TOPLEX_MAP_H_ diff --git a/src/Toplex_map/doc/map.png b/src/Toplex_map/doc/map.png new file mode 100644 index 00000000..d1987043 Binary files /dev/null and b/src/Toplex_map/doc/map.png differ diff --git a/src/Toplex_map/example/CMakeLists.txt b/src/Toplex_map/example/CMakeLists.txt new file mode 100644 index 00000000..2341fe06 --- /dev/null +++ b/src/Toplex_map/example/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 2.6) +project(Toplex_map_examples) + +add_executable(chrono chrono.cpp) diff --git a/src/Toplex_map/example/chrono.cpp b/src/Toplex_map/example/chrono.cpp new file mode 100644 index 00000000..d93d1e1f --- /dev/null +++ b/src/Toplex_map/example/chrono.cpp @@ -0,0 +1,137 @@ +#include +#include +#include + +#include +#include + +using namespace Gudhi; + +typedef Simplex typeVectorVertex; +typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +class ST_wrapper { + +public: + void insert_simplex(const Simplex& tau); + bool membership(const Simplex& tau); + Vertex contraction(const Vertex x, const Vertex y); + std::size_t num_simplices(); + +private: + Simplex_tree<> simplexTree; + void erase_max(const Simplex& sigma); +}; + +void ST_wrapper::insert_simplex(const Simplex& tau){ + simplexTree.insert_simplex_and_subfaces(tau); +} + +bool ST_wrapper::membership(const Simplex& tau) { + return simplexTree.find(tau) != simplexTree.null_simplex(); +} + +void ST_wrapper::erase_max(const Simplex& sigma){ + if(membership(sigma)) + simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); +} + +Vertex ST_wrapper::contraction(const Vertex x, const Vertex y){ + Simplex sx; sx.insert(x); + auto hx = simplexTree.find(sx); + if(hx != simplexTree.null_simplex()) + for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ + auto sr = simplexTree.simplex_vertex_range(h); + Simplex sigma(sr.begin(),sr.end()); + erase_max(sigma); + sigma.erase(x); + sigma.insert(y); + insert_simplex(sigma); + } + return y; +} + +std::size_t ST_wrapper::num_simplices(){ + return simplexTree.num_simplices(); +} + + + +int n = 300; + +int nb_insert_simplex1 = 3000; +int nb_membership1 = 4000; +int nb_contraction = 300; +int nb_insert_simplex2 = 3000; +int nb_membership2 = 400000; + +Simplex random_simplex(int n, int d){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1, n); + Simplex s; + while(s.size()!=d) + s.insert(dis(gen)); + return s; +} + +std::vector r_vector_simplices(int n, int max_d, int m){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1, max_d); + std::vector v; + for(int i=0; i +void chrono(int n, int d){ + complex_type K; + std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); + std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); + std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); + std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); + std::chrono::time_point start, end; + + for(const Simplex& s : simplices_insert_simplex1) + K.insert_simplex(s); + + for(const Simplex& s : simplices_membership1) + K.membership(s); + + start = std::chrono::system_clock::now(); + for(int i = 0; i<=nb_contraction; i++) + K.contraction(n-2*i,n-2*i-1); + end = std::chrono::system_clock::now(); + auto c3 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_insert_simplex2) + K.insert_simplex(s); + end = std::chrono::system_clock::now(); + auto c1 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_membership2) + K.membership(s); + end = std::chrono::system_clock::now(); + auto c2 = std::chrono::duration_cast(end-start).count(); + + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_simplices() << std::endl; +} + +int main(){ + for(int d=5;d<=40;d+=5){ + std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; + std::cout << "T Map \t \t"; + chrono(n,d); + std::cout << "Lazy \t \t"; + chrono(n,d); + if(d<=15){ + std::cout << "ST \t \t"; + chrono(n,d); + } + std::cout << std::endl; + } +} diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h new file mode 100644 index 00000000..5c7e7b12 --- /dev/null +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -0,0 +1,207 @@ +#ifndef FAKE_SIMPLEX_TREE_H +#define FAKE_SIMPLEX_TREE_H + +#include +#include + +namespace Gudhi { + +class Fake_simplex_tree : public Filtered_toplex_map { + +public: + + typedef Vertex Vertex_handle; + + typedef Simplex_ptr Simplex_handle; + + /** \brief Inserts a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` in the simplicial + * complex. */ + template + void insert_graph(const OneSkeletonGraph& skel_graph); + + /** \brief Expands the simplicial complex containing only its one skeleton until a given maximal dimension as + * explained in \ref ripsdefinition. */ + void expansion(int max_dim); + + /** \brief Returns the number of vertices in the simplicial complex. */ + std::size_t num_vertices(); + + Simplex_ptr_set candidates() const; + + std::size_t dimension() const; + + std::size_t num_simplices() const; + + std::size_t num_vertices() const; + + Simplex simplex_vertex_range(Simplex_ptr &sptr) const; + + std::vector max_simplices() const; + + std::unordered_set filtration_simplex_range() const; + + std::unordered_set skeleton_simplex_range(int d=std::numeric_limits::max()) const; + + std::size_t dimension(Simplex_ptr& sptr) const; + + void assign_filtration(Simplex_ptr& f_simplex, Filtration_value alpha_complex_filtration); + + void make_filtration_non_decreasing(); + +protected: + + /** \internal Does all the facets of the given simplex belong to the complex ? + * \ingroup toplex_map */ + template + bool all_facets_inside(const Input_vertex_range &vertex_range) const; + +}; + +template +void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ + typename boost::graph_traits::edge_iterator e_it, + e_it_end; + for (std::tie(e_it, e_it_end) = boost::edges(skel_graph); e_it != e_it_end; ++e_it) { + auto u = source(*e_it, skel_graph); + auto v = target(*e_it, skel_graph); + if(u +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(!filtrations.count(get_key(s))) return false; + return true; +} + +Simplex_ptr_set Fake_simplex_tree::candidates() const{ + Simplex_ptr_set c; + std::unordered_map, Toplex_map::Sptr_hash, Toplex_map::Sptr_equal> facets_to_max; + for(const auto& kv : filtrations){ + Simplex sigma (*(kv.first)); + for(Vertex v : sigma){ + sigma.erase(v); + auto sptr = get_key(sigma); + if(!facets_to_max.count(sptr)) facets_to_max.emplace(sptr, std::vector()); + facets_to_max.at(sptr).emplace_back(v); + sigma.insert(v); + } + } + for(const auto& kv : facets_to_max){ + std::unordered_set facets(kv.second.begin(), kv.second.end()); + for(Vertex v : kv.second){ + facets.erase(v); + for(Vertex w : facets){ + Simplex sigma(*(kv.first)); + sigma.insert(v); + sigma.insert(w); + if(all_facets_inside(sigma)) + c.emplace(get_key(sigma)); + } + facets.emplace(v); + } + } + return c; +} + +std::size_t Fake_simplex_tree::dimension() const { + std::size_t max = 0; + for(auto kv : filtrations) + max = std::max(max, kv.first->size()); + return max; +} + +std::size_t Fake_simplex_tree::num_simplices() const { + return filtration_simplex_range().size(); +} + +std::size_t Fake_simplex_tree::num_vertices() const { + std::unordered_set vertices; + for(auto kv : filtrations) + for (Vertex v : *(kv.first)) + vertices.emplace(v); + return vertices.size(); +} + +Simplex Fake_simplex_tree::simplex_vertex_range(Simplex_ptr& sptr) const { + return *sptr; +} + +std::unordered_set Fake_simplex_tree::filtration_simplex_range() const{ + std::vector m = max_simplices(); + std::unordered_set seen; + while(m.begin()!=m.end()){ + Simplex_ptr& sptr = m.back(); + m.pop_back(); + if(seen.find(sptr)!=seen.end()){ + seen.emplace(sptr); + for(Simplex& sigma : facets(*sptr)) + m.emplace_back(get_key(sigma)); + } + } + return seen; +} + +std::unordered_set Fake_simplex_tree::skeleton_simplex_range(int d) const{ + std::unordered_set simplices; + for(auto sptr: filtration_simplex_range()) + if(sptr->size()<=d) + simplices.emplace(sptr); + return simplices; +} + +std::vector Fake_simplex_tree::max_simplices() const{ + std::vector s; + for(auto kv : filtrations) + s.emplace_back(kv.first); + return s; +} + +std::size_t Fake_simplex_tree::dimension(Simplex_ptr& sptr) const{ + return sptr->size(); +} + + +void Fake_simplex_tree::assign_filtration(Simplex_ptr& f_simplex, Filtration_value alpha_complex_filtration){ + filtrations.emplace(f_simplex,alpha_complex_filtration); +} + +void Fake_simplex_tree::make_filtration_non_decreasing(){ + for(auto yt = filtrations.begin(); yt != filtrations.end(); ++yt) + for (auto it = toplex_maps.begin(); it != toplex_maps.end(); ++it){ + if(it->first == yt -> second) + break; + if(it->second.membership(*(yt->first))) + for(const Simplex_ptr& sptr : it->second.maximal_cofaces(*(yt->first))){ + it->second.erase_maximal(sptr); + toplex_maps.at(yt->second).insert_simplex(*sptr); + filtrations.emplace(sptr,yt->second); + } + } + +} + + + +} //namespace Gudhi + +#endif /* FAKE_SIMPLEX_TREE_H */ + diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h new file mode 100644 index 00000000..4b626f11 --- /dev/null +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -0,0 +1,45 @@ +#ifndef FILTERED_TOPLEX_MAP_H +#define FILTERED_TOPLEX_MAP_H + +#include +#include + +#define filtration_upper_bound std::numeric_limits::max() + +namespace Gudhi { + +typedef double Filtration_value; + +class Filtered_toplex_map { + +public: + template + void insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = filtration_upper_bound); + + template + Filtration_value filtration(const Input_vertex_range &vertex_range) const; + +protected: + std::unordered_map toplex_maps; + std::unordered_map filtrations; + +}; + +template +void Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ + if(!toplex_maps.count(f)) toplex_maps.emplace(f,Toplex_map()); + toplex_maps.at(f).insert_simplex(vertex_range); + filtrations.emplace(get_key(vertex_range),f); +} + +template +Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ + for(auto kv : toplex_maps) + if(kv.second.membership(vertex_range)) + return kv.first; + return filtration_upper_bound; +} + +} //namespace Gudhi + +#endif /* FILTERED_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h new file mode 100644 index 00000000..3ffe8214 --- /dev/null +++ b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h @@ -0,0 +1,218 @@ +#ifndef LAZY_TOPLEX_MAP_H +#define LAZY_TOPLEX_MAP_H + +#include +#include + +namespace Gudhi { + +class Lazy_Toplex_map { + +public: + template + void insert_max_simplex(const Input_vertex_range &vertex_range); + template + bool insert_simplex(const Input_vertex_range &vertex_range); + template + void remove_simplex(const Input_vertex_range &vertex_range); + + template + bool membership(const Input_vertex_range &vertex_range); + template + bool all_facets_inside(const Input_vertex_range &vertex_range); + + Vertex contraction(const Vertex x, const Vertex y); + + std::size_t num_simplices() const; + +private: + template + void erase_max(const Input_vertex_range &vertex_range); + template + Vertex best_index(const Input_vertex_range &vertex_range); + void clean(const Vertex v); + + std::unordered_map t0; + bool empty_toplex; // Is the empty simplex a toplex ? + + typedef boost::heap::fibonacci_heap> PriorityQueue; + PriorityQueue cleaning_priority; + std::unordered_map cp_handles; + + std::unordered_map gamma0_lbounds; + std::size_t get_gamma0_lbound(const Vertex v) const; + + std::size_t size_lbound = 0; + std::size_t size = 0; + + const double alpha = 2; //time + const double betta = 3; //memory +}; + +template +void Lazy_Toplex_map::insert_max_simplex(const Input_vertex_range &vertex_range){ + for(const Vertex& v : vertex_range) + if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); + else gamma0_lbounds[v]++; + size_lbound++; + insert_simplex(vertex_range); +} + +template +bool Lazy_Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + empty_toplex = (sigma.size()==0); //vérifier la gestion de empty face + Simplex_ptr sptr = std::make_shared(sigma); + bool inserted = false; + for(const Vertex& v : sigma){ + if(!t0.count(v)){ + t0.emplace(v, Simplex_ptr_set()); + auto v_handle = cleaning_priority.push(std::make_pair(0, v)); + cp_handles.emplace(v, v_handle); + } + inserted = t0.at(v).emplace(sptr).second; + cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v),v)); + } + if(inserted) + size++; + if(size > size_lbound * betta) + clean(cleaning_priority.top().second); + return inserted; +} + +template +void Lazy_Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ + if(vertex_range.begin()==vertex_range.end()){ + t0.clear(); + gamma0_lbounds.clear(); + cleaning_priority.clear(); + size_lbound = 0; + size = 0; + empty_toplex = false; + } + else { + const Vertex& v = best_index(vertex_range); + //Copy constructor needed because the set is modified + if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) + if(included(vertex_range, *sptr)){ + erase_max(*sptr); + for(const Simplex& f : facets(vertex_range)) + insert_max_simplex(f); + } + } +} + +template +bool Lazy_Toplex_map::membership(const Input_vertex_range &vertex_range){ + if(t0.size()==0 && !empty_toplex) return false; //empty complex + if(vertex_range.begin()==vertex_range.end()) return true; //empty query simplex + Vertex v = best_index(vertex_range); + if(!t0.count(v)) return false; + for(const Simplex_ptr& sptr : t0.at(v)) + if(included(vertex_range, *sptr)) return true; + return false; +} + +template +bool Lazy_Toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + Vertex v = best_index(sigma); + if(!t0.count(v)) return false; + Simplex f = sigma; f.erase(v); + if(!membership(f)) return false; + std::unordered_set facets_inside; + for(const Simplex_ptr& sptr : t0.at(v)) + for(const Vertex& w : sigma){ + f = sigma; f.erase(w); + if(included(f, *sptr)) facets_inside.insert(w); + } + return facets_inside.size() == sigma.size() - 1; +} + +/* Returns the remaining vertex */ +Vertex Lazy_Toplex_map::contraction(const Vertex x, const Vertex y){ + if(!t0.count(x)) return y; + if(!t0.count(y)) return x; + Vertex k, d; + if(t0.at(x).size() > t0.at(y).size()) + k=x, d=y; + else + k=y, d=x; + //Copy constructor needed because the set is modified + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ + Simplex sigma(*sptr); + erase_max(sigma); + sigma.erase(d); + sigma.insert(k); + insert_simplex(sigma); + } + t0.erase(d); + return k; +} + +/* No facets insert_simplexed */ +template +inline void Lazy_Toplex_map::erase_max(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + empty_toplex = false; + Simplex_ptr sptr = std::make_shared(sigma); + bool erased; + for(const Vertex& v : sigma){ + erased = t0.at(v).erase(sptr) > 0; + if(t0.at(v).size()==0) + t0.erase(v); + } + if (erased) + size--; +} + +template +Vertex Lazy_Toplex_map::best_index(const Input_vertex_range &vertex_range){ + Simplex tau(vertex_range.begin(),vertex_range.end()); + std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; + for(const Vertex& v : tau) + if(!t0.count(v)) return v; + else if(t0.at(v).size() < min) + min = t0.at(v).size(), arg_min = v; + if(min > alpha * get_gamma0_lbound(arg_min)) + clean(arg_min); + return arg_min; +} + +std::size_t Lazy_Toplex_map::get_gamma0_lbound(const Vertex v) const{ + return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; +} + + +void Lazy_Toplex_map::clean(const Vertex v){ + Toplex_map toplices; + std::unordered_map> dsorted_simplices; + int max_dim = 0; + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ + if(sptr->size() > max_dim){ + for(int d = max_dim+1; d<=sptr->size(); d++) + dsorted_simplices.emplace(d, std::vector()); + max_dim = sptr->size(); + } + dsorted_simplices[sptr->size()].emplace_back(*sptr); + erase_max(*sptr); + } + for(int d = max_dim; d>=1; d--) + for(const Simplex &s : dsorted_simplices.at(d)) + if(!toplices.membership(s)) + toplices.insert_independent_simplex(s); + Simplex sv; sv.insert(v); + auto clean_cofaces = toplices.maximal_cofaces(sv); + size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); + gamma0_lbounds[v] = clean_cofaces.size(); + for(const Simplex_ptr& sptr : clean_cofaces) + insert_simplex(*sptr); +} + +std::size_t Lazy_Toplex_map::num_simplices() const{ + return size; +} + +} //namespace Gudhi + +#endif /* LAZY_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h new file mode 100644 index 00000000..0b6cad37 --- /dev/null +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -0,0 +1,307 @@ +#ifndef TOPLEX_MAP_H +#define TOPLEX_MAP_H + +#include +#include +#include +#include + +#define vertex_upper_bound std::numeric_limits::max() + +namespace Gudhi { + +/** Vertex is the type of vertices. + * \ingroup toplex_map */ +typedef std::size_t Vertex; + +/** Simplex is the type of simplices. + * \ingroup toplex_map */ +typedef std::unordered_set Simplex; + +/** A Toplex_map represents the simplicial complex. + * A "toplex" is a maximal simplex. + * \ingroup toplex_map */ +class Toplex_map { + +public: + /** The type of the pointers to maximal simplices. + * \ingroup toplex_map */ + typedef std::shared_ptr Simplex_ptr; + + struct Sptr_hash{ std::size_t operator()(const Simplex_ptr& s) const; }; + struct Sptr_equal{ std::size_t operator()(const Simplex_ptr& a, const Simplex_ptr& b) const; }; + /** The type of the sets of Simplex_ptr. + * \ingroup toplex_map */ + typedef std::unordered_set Simplex_ptr_set; + + /** \brief Adds the given simplex to the complex. + * Nothing happens if the simplex has a coface in the complex. + * \ingroup toplex_map */ + template + void insert_simplex(const Input_vertex_range &vertex_range); + + /** \brief Removes the given simplex and its cofaces from the complex. + * Its faces are kept inside. + * \ingroup toplex_map */ + template + void remove_simplex(const Input_vertex_range &vertex_range); + + /** Does a simplex belong to the complex ? + * \ingroup toplex_map */ + template + bool membership(const Input_vertex_range &vertex_range) const; + + /** Does a simplex is a toplex ? + * \ingroup toplex_map */ + template + bool maximality(const Input_vertex_range &vertex_range) const; + + /** Gives a set of pointers to the maximal cofaces of a simplex. + * Gives the toplices if given the empty simplex. + * Gives not more than max_number maximal cofaces if max_number is strictly positive. + * \ingroup toplex_map */ + template + Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; + + /** Contracts one edge in the complex. + * The edge has to verify the link condition if you want to preserve topology. + * Returns the remaining vertex. + * \ingroup toplex_map */ + Vertex contraction(const Vertex x, const Vertex y); + + /** Adds the given simplex to the complex. + * The simplex must not have neither maximal face nor coface in the complex. + * \ingroup toplex_map */ + template + void insert_independent_simplex(const Input_vertex_range &vertex_range); + + + /** \internal Removes a toplex without adding facets after. + * \ingroup toplex_map */ + void erase_maximal(const Simplex_ptr& sptr); + + /** Removes a vertex from any simplex containing it. + * \ingroup toplex_map */ + void remove_vertex(const Vertex x); + + /** \brief Number of maximal simplices. + * /!\ Not efficient ! + * \ingroup toplex_map */ + std::size_t num_simplices() const; + +protected: + /** \internal Gives an index in order to look for a simplex quickly. + * \ingroup toplex_map */ + template + Vertex best_index(const Input_vertex_range &vertex_range) const; + + /** \internal The map from vertices to toplices + * \ingroup toplex_map */ + std::unordered_map t0; + +}; + +typedef Toplex_map::Simplex_ptr Simplex_ptr; +typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + +// Pointers are also used as key in the hash sets. +template +Simplex_ptr get_key(const Input_vertex_range &vertex_range); + +// Is the first simplex a face of the second ? +template +bool included(const Input_vertex_range1 &vertex_range1, const Input_vertex_range2 &vertex_range2); + +// All the facets of the given simplex. +template +std::vector facets(const Input_vertex_range &vertex_range); + +template +void Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ + if(membership(vertex_range)) return; + bool replace_facets = true; + for(const Simplex& facet : facets(vertex_range)) + if(!maximality(facet)) + { + replace_facets=false; + break; + } + if(replace_facets) + for(const Simplex& facet : facets(vertex_range)) + erase_maximal(get_key(facet)); + else + for(const Vertex& v : vertex_range) + if(t0.count(v)) for(const Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v))) + //Copy constructor needed because the set is modified + if(included(*fptr,vertex_range)) erase_maximal(fptr); + // We erase all the maximal faces of the simplex + insert_independent_simplex(vertex_range); +} + +template +void Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ + if(vertex_range.begin()==vertex_range.end()) + t0.clear(); + // Removal of the empty simplex means cleaning everything + else { + const Vertex& v = best_index(vertex_range); + if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) + //Copy constructor needed because the set is modified + if(included(vertex_range, *sptr)){ + erase_maximal(sptr); + for(const Simplex& f : facets(vertex_range)) + if(!membership(f)) insert_independent_simplex(f); + // We add the facets which are new maximal simplices + } + } +} + +template +bool Toplex_map::membership(const Input_vertex_range &vertex_range) const{ + if(t0.size()==0) return false; + const Vertex& v = best_index(vertex_range); + if(!t0.count(v)) return false; + if(maximality(vertex_range)) return true; + for(const Simplex_ptr& sptr : t0.at(v)) + if(included(vertex_range, *sptr)) + return true; + return false; +} + +template +bool Toplex_map::maximality(const Input_vertex_range &vertex_range) const{ + const Vertex& v = best_index(vertex_range); + if(!t0.count(v)) return false; + return t0.at(v).count(get_key(vertex_range)); +} + +template +Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number) const{ + Simplex_ptr_set cofaces; + if(maximality(vertex_range)) + cofaces.emplace(get_key(vertex_range)); + else if(vertex_range.begin()==vertex_range.end()) + for(const auto& kv : t0) + for(const Simplex_ptr& sptr : kv.second){ + //kv.second is a Simplex_ptr_set + cofaces.emplace(sptr); + if(cofaces.size()==max_number) + return cofaces; + } + else { + const Vertex& v = best_index(vertex_range); + if(t0.count(v)) for(const Simplex_ptr& sptr : t0.at(v)) + if(included(vertex_range, *sptr)){ + cofaces.emplace(sptr); + if(cofaces.size()==max_number) + return cofaces; + } + } + return cofaces; +} + +Vertex Toplex_map::contraction(const Vertex x, const Vertex y){ + if(!t0.count(x)) return y; + if(!t0.count(y)) return x; + int k, d; + if(t0.at(x).size() > t0.at(y).size()) + k=x, d=y; + else + k=y, d=x; + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ + //Copy constructor needed because the set is modified + Simplex sigma(*sptr); + erase_maximal(sptr); + sigma.erase(d); + sigma.insert(k); + insert_simplex(sigma); + } + return k; +} + +template +void Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ + for(const Vertex& v : vertex_range){ + if(!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); + t0.at(v).emplace(get_key(vertex_range)); + } +} + +void Toplex_map::remove_vertex(const Vertex x){ + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(x))){ + Simplex sigma(*sptr); + erase_maximal(sptr); + sigma.erase(x); + insert_simplex(sigma); + } +} + +std::size_t Toplex_map::num_simplices() const{ + return maximal_cofaces(Simplex()).size(); +} + +inline void Toplex_map::erase_maximal(const Simplex_ptr& sptr){ + Simplex sigma(*sptr); + if (sptr->size()==0) + sigma.insert(vertex_upper_bound); + for(const Vertex& v : sigma){ + t0.at(v).erase(sptr); + if(t0.at(v).size()==0) t0.erase(v); + } +} + +template +Vertex Toplex_map::best_index(const Input_vertex_range &vertex_range) const{ + std::size_t min = std::numeric_limits::max(); + Vertex arg_min = vertex_upper_bound; + for(const Vertex& v : vertex_range) + if(!t0.count(v)) return v; + else if(t0.at(v).size() < min) + min = t0.at(v).size(), arg_min = v; + return arg_min; +} + +std::size_t Toplex_map::Sptr_equal::operator()(const Simplex_ptr& s1, const Simplex_ptr& s2) const { + if (s1->size() != s2->size()) return false; + return included(*s1,*s2); + // inclusion tests equality for same size simplices +} + +std::size_t Toplex_map::Sptr_hash::operator()(const Simplex_ptr& s) const { + std::hash h_f; + //double hash works better than int hash + size_t h = 0; + for(const Vertex& v : *s) + h += h_f(static_cast(v)); + return h; +} + +template +Simplex_ptr get_key(const Input_vertex_range &vertex_range){ + Simplex s(vertex_range.begin(), vertex_range.end()); + return std::make_shared(s); +} + +template +bool included(const Input_vertex_range1 &vertex_range1, const Input_vertex_range2 &vertex_range2){ + Simplex s2(vertex_range2.begin(), vertex_range2.end()); + for(const Vertex& v : vertex_range1) + if(!s2.count(v)) return false; + return true; +} + +template +std::vector facets(const Input_vertex_range &vertex_range){ + std::vector facets; + Simplex f(vertex_range.begin(), vertex_range.end()); + for(const Vertex& v : vertex_range){ + f.erase(v); + facets.emplace_back(f); + f.insert(v); + } + return facets; +} + +} //namespace Gudhi + +#endif /* TOPLEX_MAP_H */ diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt new file mode 100644 index 00000000..223ebccb --- /dev/null +++ b/src/Toplex_map/test/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.6) +project(Toplex_map_tests) + +add_executable ( ToplexMapUT test.cpp ) +target_link_libraries(ToplexMapUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + + +# Unitary tests +add_test(NAME SalUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/ToplexMapUT + ${CMAKE_SOURCE_DIR}/src/Toplex_map/test/test.txt + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/ToplexMapUT.xml --log_level=test_suite --report_level=no) + diff --git a/src/Toplex_map/test/test.cpp b/src/Toplex_map/test/test.cpp new file mode 100644 index 00000000..3f4d96c2 --- /dev/null +++ b/src/Toplex_map/test/test.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "toplex map" +#include + +using namespace Gudhi; + +std::vector sigma1 = {1, 2, 3, 4}; +std::vector sigma2 = {5, 2, 3, 6}; +std::vector sigma3 = {5}; +std::vector sigma4 = {5, 2, 3}; +std::vector sigma5 = {5, 2, 7}; +std::vector sigma6 = {4, 5, 3}; +std::vector sigma7 = {4, 5, 9}; +std::vector sigma8 = {1, 2, 3, 6}; + + +BOOST_AUTO_TEST_CASE(toplexmap) { + Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma6); + K.insert_simplex(sigma7); + BOOST_CHECK(K.membership(sigma4)); + BOOST_CHECK(!K.maximality(sigma5)); + BOOST_CHECK(!K.membership(sigma5)); + K.contraction(4,5); + BOOST_CHECK(!K.membership(sigma6)); +} + +BOOST_AUTO_TEST_CASE(ltoplexmap) { + Lazy_Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma6); + K.insert_simplex(sigma7); + BOOST_CHECK(K.membership(sigma4)); + BOOST_CHECK(!K.membership(sigma5)); + K.contraction(4,5); + BOOST_CHECK(!K.membership(sigma6)); +} + +BOOST_AUTO_TEST_CASE(ftoplexmap) { + Filtered_toplex_map K; + K.insert_simplex_and_subfaces(sigma1, 2.); + K.insert_simplex_and_subfaces(sigma2, 2.); + K.insert_simplex_and_subfaces(sigma6, 1.); + K.insert_simplex_and_subfaces(sigma7, 1.); + BOOST_CHECK(K.filtration(sigma4)==2.); + BOOST_CHECK(K.filtration(sigma3)==1.); +} + +/* +BOOST_AUTO_TEST_CASE(toplexmap_candidates) { + Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.remove_simplex(sigma1); + K.remove_simplex(sigma2); + auto c = K.candidates(); + BOOST_CHECK(c.count(get_key(sigma1))); + BOOST_CHECK(c.count(get_key(sigma2))); + BOOST_CHECK(c.size()==2); +} +*/ -- cgit v1.2.3 From 64b6499858101c47374a9a6b24dd8ec001147982 Mon Sep 17 00:00:00 2001 From: fgodi Date: Fri, 13 Oct 2017 09:43:14 +0000 Subject: strong witness compatibility git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2785 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: eee09c30f4a5503f800761a7dbe4d08401b5bc1f --- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 5c7e7b12..60f8981a 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -14,6 +14,8 @@ public: typedef Simplex_ptr Simplex_handle; + typedef void Insertion_result_type; + /** \brief Inserts a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` in the simplicial * complex. */ template -- cgit v1.2.3 From 8fd07bda067d82fd0d345c3bde0dce7de18a6722 Mon Sep 17 00:00:00 2001 From: fgodi Date: Fri, 13 Oct 2017 10:08:55 +0000 Subject: cmakelists git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2786 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 83c6616972403884967c825f20155cecf124c39e --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 13 +++++++++++-- .../example/example_strong_witness_complex_off.cpp | 4 +++- 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index fbb359e1..f872b5df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ add_gudhi_module(Skeleton_blocker) add_gudhi_module(Spatial_searching) add_gudhi_module(Subsampling) add_gudhi_module(Tangential_complex) +add_gudhi_module(Toplex_map) add_gudhi_module(Witness_complex) message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 795005b1..e1ae774a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ add_gudhi_module(Skeleton_blocker) add_gudhi_module(Spatial_searching) add_gudhi_module(Subsampling) add_gudhi_module(Tangential_complex) +add_gudhi_module(Toplex_map) add_gudhi_module(Witness_complex) message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 60f8981a..10ef39d7 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -26,7 +26,7 @@ public: void expansion(int max_dim); /** \brief Returns the number of vertices in the simplicial complex. */ - std::size_t num_vertices(); + std::size_t num_vertices() const; Simplex_ptr_set candidates() const; @@ -34,7 +34,7 @@ public: std::size_t num_simplices() const; - std::size_t num_vertices() const; + void set_dimension(int d); Simplex simplex_vertex_range(Simplex_ptr &sptr) const; @@ -59,6 +59,10 @@ protected: }; +void Fake_simplex_tree::set_dimension(int d){ + +} + template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ typename boost::graph_traits::edge_iterator e_it, @@ -149,6 +153,11 @@ Simplex Fake_simplex_tree::simplex_vertex_range(Simplex_ptr& sptr) const { std::unordered_set Fake_simplex_tree::filtration_simplex_range() const{ std::vector m = max_simplices(); + std::cout << m.size()<< std::endl; + std::cout << m.size()<< std::endl; + + std::cout << m.size()<< std::endl; + std::unordered_set seen; while(m.begin()!=m.end()){ Simplex_ptr& sptr = m.back(); diff --git a/src/Witness_complex/example/example_strong_witness_complex_off.cpp b/src/Witness_complex/example/example_strong_witness_complex_off.cpp index 0ee9ee90..4a232481 100644 --- a/src/Witness_complex/example/example_strong_witness_complex_off.cpp +++ b/src/Witness_complex/example/example_strong_witness_complex_off.cpp @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -49,7 +50,8 @@ int main(int argc, char * const argv[]) { int nbL = atoi(argv[2]), lim_dim = atoi(argv[4]); double alpha2 = atof(argv[3]); clock_t start, end; - Gudhi::Simplex_tree<> simplex_tree; + //Gudhi::Simplex_tree<> simplex_tree; + Gudhi::Fake_simplex_tree simplex_tree; // Read the point file Point_vector point_vector, landmarks; -- cgit v1.2.3 From 23e265d8c48d921a51eb0265afa6d8af27b27559 Mon Sep 17 00:00:00 2001 From: fgodi Date: Wed, 25 Oct 2017 11:19:00 +0000 Subject: include limits in toplex_map git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2804 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a42cc7c557c193c57e3696eb0b877f6196841aaf --- src/Rips_complex/example/CMakeLists.txt | 2 + .../example/example_rips_complex_from_fvecs.cpp | 67 ++++++++++ src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 142 +++++++++------------ src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 8 +- src/Toplex_map/include/gudhi/Toplex_map.h | 30 ++--- src/Witness_complex/example/CMakeLists.txt | 2 + .../example/example_strong_witness_complex_off.cpp | 4 +- 7 files changed, 153 insertions(+), 102 deletions(-) create mode 100644 src/Rips_complex/example/example_rips_complex_from_fvecs.cpp (limited to 'src') diff --git a/src/Rips_complex/example/CMakeLists.txt b/src/Rips_complex/example/CMakeLists.txt index 2940f164..b854b1c9 100644 --- a/src/Rips_complex/example/CMakeLists.txt +++ b/src/Rips_complex/example/CMakeLists.txt @@ -4,6 +4,8 @@ project(Rips_complex_examples) # Point cloud add_executable ( Rips_complex_example_from_off example_rips_complex_from_off_file.cpp ) +add_executable ( Rips_complex_example_from_fvecs example_rips_complex_from_fvecs.cpp ) + add_executable ( Rips_complex_example_one_skeleton_from_points example_one_skeleton_rips_from_points.cpp ) # Distance matrix diff --git a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp new file mode 100644 index 00000000..c05d038a --- /dev/null +++ b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp @@ -0,0 +1,67 @@ +#include +// to construct Rips_complex from a fvecs file of points +#include +#include +#include +#include + +#include + +#include +#include +#include + +void usage(int nbArgs, char * const progName) { + std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n"; + std::cerr << "Usage: " << progName << " filename.fvecs threshold dim_max [ouput_file.txt]\n"; + std::cerr << " i.e.: " << progName << " ../../data/points/alphacomplexdoc.fvecs 60.0\n"; + exit(-1); // ----- >> +} + +int main(int argc, char **argv) { + if ((argc != 4) && (argc != 5)) usage(argc, (argv[0] - 1)); + + std::string file_name(argv[1]); + double threshold = atof(argv[2]); + int dim_max = atoi(argv[3]); + + // Type definitions + using K = CGAL::Epick_d; + using Point = typename K::Point_d; + //using Simplex_tree = Gudhi::Simplex_tree<>; + using Simplex_tree = Gudhi::Fake_simplex_tree; + using Filtration_value = Simplex_tree::Filtration_value; + using Rips_complex = Gudhi::rips_complex::Rips_complex; + using Point_vector = std::vector; + + // ---------------------------------------------------------------------------- + // Init of a Rips complex from an fvecs file + // ---------------------------------------------------------------------------- + Point_vector point_vector; + Gudhi::load_points_from_fvecs_file(file_name, std::back_insert_iterator< Point_vector >(point_vector)); + + Rips_complex rips_complex_from_file(point_vector, threshold, Gudhi::Euclidean_distance()); + + std::streambuf* streambufffer; + std::ofstream ouput_file_stream; + + if (argc == 5) { + ouput_file_stream.open(std::string(argv[4])); + streambufffer = ouput_file_stream.rdbuf(); + } else { + streambufffer = std::cout.rdbuf(); + } + + Simplex_tree stree; + rips_complex_from_file.create_complex(stree, dim_max); + std::ostream output_stream(streambufffer); + + // ---------------------------------------------------------------------------- + // Display information about the Rips complex + // ---------------------------------------------------------------------------- + output_stream << "Rips complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices." << std::endl; + + ouput_file_stream.close(); + return 0; +} diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 10ef39d7..b318acb4 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -1,9 +1,12 @@ #ifndef FAKE_SIMPLEX_TREE_H #define FAKE_SIMPLEX_TREE_H +#include #include + #include + namespace Gudhi { class Fake_simplex_tree : public Filtered_toplex_map { @@ -12,7 +15,7 @@ public: typedef Vertex Vertex_handle; - typedef Simplex_ptr Simplex_handle; + typedef Simplex Simplex_handle; typedef void Insertion_result_type; @@ -36,20 +39,16 @@ public: void set_dimension(int d); - Simplex simplex_vertex_range(Simplex_ptr &sptr) const; + Simplex simplex_vertex_range(const Simplex& s) const; - std::vector max_simplices() const; + std::vector max_simplices() const; - std::unordered_set filtration_simplex_range() const; + std::vector filtration_simplex_range() const; - std::unordered_set skeleton_simplex_range(int d=std::numeric_limits::max()) const; + std::vector skeleton_simplex_range(int d=std::numeric_limits::max()) const; std::size_t dimension(Simplex_ptr& sptr) const; - void assign_filtration(Simplex_ptr& f_simplex, Filtration_value alpha_complex_filtration); - - void make_filtration_non_decreasing(); - protected: /** \internal Does all the facets of the given simplex belong to the complex ? @@ -65,28 +64,34 @@ void Fake_simplex_tree::set_dimension(int d){ template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - typename boost::graph_traits::edge_iterator e_it, - e_it_end; + if (boost::num_vertices(skel_graph) == 0) return; + typename boost::graph_traits::vertex_iterator v_it, v_it_end; + for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end; ++v_it){ + Simplex s; + s.insert(*v_it); + insert_simplex_and_subfaces(s, boost::get(vertex_filtration_t(), skel_graph, *v_it)); + } + + typename boost::graph_traits::edge_iterator e_it, e_it_end; for (std::tie(e_it, e_it_end) = boost::edges(skel_graph); e_it != e_it_end; ++e_it) { - auto u = source(*e_it, skel_graph); - auto v = target(*e_it, skel_graph); - if(u, Toplex_map::Sptr_hash, Toplex_map::Sptr_equal> facets_to_max; + std::unordered_map, Sptr_hash, Sptr_equal> facets_to_max; for(const auto& kv : filtrations){ Simplex sigma (*(kv.first)); - for(Vertex v : sigma){ - sigma.erase(v); - auto sptr = get_key(sigma); - if(!facets_to_max.count(sptr)) facets_to_max.emplace(sptr, std::vector()); - facets_to_max.at(sptr).emplace_back(v); - sigma.insert(v); - } + if(sigma.size()>1) + for(Vertex v : *(kv.first)){ + sigma.erase(v); + auto sptr = get_key(sigma); + if(!facets_to_max.count(sptr)) + facets_to_max.emplace(sptr, std::vector()); + facets_to_max.at(sptr).emplace_back(v); + sigma.insert(v); + } } for(const auto& kv : facets_to_max){ std::unordered_set facets(kv.second.begin(), kv.second.end()); @@ -132,11 +139,12 @@ std::size_t Fake_simplex_tree::dimension() const { std::size_t max = 0; for(auto kv : filtrations) max = std::max(max, kv.first->size()); - return max; + return max-1; } std::size_t Fake_simplex_tree::num_simplices() const { - return filtration_simplex_range().size(); + //return filtration_simplex_range().size(); + return max_simplices().size(); } std::size_t Fake_simplex_tree::num_vertices() const { @@ -147,42 +155,40 @@ std::size_t Fake_simplex_tree::num_vertices() const { return vertices.size(); } -Simplex Fake_simplex_tree::simplex_vertex_range(Simplex_ptr& sptr) const { - return *sptr; +Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { + return s; } -std::unordered_set Fake_simplex_tree::filtration_simplex_range() const{ - std::vector m = max_simplices(); - std::cout << m.size()<< std::endl; - std::cout << m.size()<< std::endl; - - std::cout << m.size()<< std::endl; - - std::unordered_set seen; +std::vector Fake_simplex_tree::filtration_simplex_range() const{ + std::vector m = max_simplices(); + std::vector seen1; + Simplex_ptr_set seen2; while(m.begin()!=m.end()){ - Simplex_ptr& sptr = m.back(); + Simplex s(m.back()); m.pop_back(); - if(seen.find(sptr)!=seen.end()){ - seen.emplace(sptr); - for(Simplex& sigma : facets(*sptr)) - m.emplace_back(get_key(sigma)); + if(seen2.find(get_key(s))==seen2.end()){ + seen1.emplace_back(s); + seen2.emplace(get_key(s)); + if(s.size()>0) + for(Simplex& sigma : facets(s)) + m.emplace_back(sigma); } } - return seen; + return seen1; } -std::unordered_set Fake_simplex_tree::skeleton_simplex_range(int d) const{ - std::unordered_set simplices; - for(auto sptr: filtration_simplex_range()) - if(sptr->size()<=d) - simplices.emplace(sptr); +std::vector Fake_simplex_tree::skeleton_simplex_range(int d) const{ + std::vector simplices; + for(auto s: filtration_simplex_range()) + if(s.size()<=d) + simplices.emplace_back(s); return simplices; } -std::vector Fake_simplex_tree::max_simplices() const{ - std::vector s; +std::vector Fake_simplex_tree::max_simplices() const{ + std::vector s; for(auto kv : filtrations) - s.emplace_back(kv.first); + s.emplace_back(*(kv.first)); return s; } @@ -190,28 +196,6 @@ std::size_t Fake_simplex_tree::dimension(Simplex_ptr& sptr) const{ return sptr->size(); } - -void Fake_simplex_tree::assign_filtration(Simplex_ptr& f_simplex, Filtration_value alpha_complex_filtration){ - filtrations.emplace(f_simplex,alpha_complex_filtration); -} - -void Fake_simplex_tree::make_filtration_non_decreasing(){ - for(auto yt = filtrations.begin(); yt != filtrations.end(); ++yt) - for (auto it = toplex_maps.begin(); it != toplex_maps.end(); ++it){ - if(it->first == yt -> second) - break; - if(it->second.membership(*(yt->first))) - for(const Simplex_ptr& sptr : it->second.maximal_cofaces(*(yt->first))){ - it->second.erase_maximal(sptr); - toplex_maps.at(yt->second).insert_simplex(*sptr); - filtrations.emplace(sptr,yt->second); - } - } - -} - - - } //namespace Gudhi #endif /* FAKE_SIMPLEX_TREE_H */ diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index 4b626f11..6d89c062 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -8,11 +8,11 @@ namespace Gudhi { -typedef double Filtration_value; - class Filtered_toplex_map { public: + typedef double Filtration_value; + template void insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = filtration_upper_bound); @@ -21,7 +21,7 @@ public: protected: std::unordered_map toplex_maps; - std::unordered_map filtrations; + std::unordered_map filtrations; }; @@ -33,7 +33,7 @@ void Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range & } template -Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ +Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ for(auto kv : toplex_maps) if(kv.second.membership(vertex_range)) return kv.first; diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 0b6cad37..9de3a6be 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -5,6 +5,7 @@ #include #include #include +#include #define vertex_upper_bound std::numeric_limits::max() @@ -18,22 +19,22 @@ typedef std::size_t Vertex; * \ingroup toplex_map */ typedef std::unordered_set Simplex; +/** The type of the pointers to maximal simplices. + * \ingroup toplex_map */ +typedef std::shared_ptr Simplex_ptr; + +struct Sptr_hash{ std::size_t operator()(const Simplex_ptr& s) const; }; +struct Sptr_equal{ std::size_t operator()(const Simplex_ptr& a, const Simplex_ptr& b) const; }; +/** The type of the sets of Simplex_ptr. + * \ingroup toplex_map */ +typedef std::unordered_set Simplex_ptr_set; + /** A Toplex_map represents the simplicial complex. * A "toplex" is a maximal simplex. * \ingroup toplex_map */ class Toplex_map { public: - /** The type of the pointers to maximal simplices. - * \ingroup toplex_map */ - typedef std::shared_ptr Simplex_ptr; - - struct Sptr_hash{ std::size_t operator()(const Simplex_ptr& s) const; }; - struct Sptr_equal{ std::size_t operator()(const Simplex_ptr& a, const Simplex_ptr& b) const; }; - /** The type of the sets of Simplex_ptr. - * \ingroup toplex_map */ - typedef std::unordered_set Simplex_ptr_set; - /** \brief Adds the given simplex to the complex. * Nothing happens if the simplex has a coface in the complex. * \ingroup toplex_map */ @@ -75,7 +76,6 @@ public: template void insert_independent_simplex(const Input_vertex_range &vertex_range); - /** \internal Removes a toplex without adding facets after. * \ingroup toplex_map */ void erase_maximal(const Simplex_ptr& sptr); @@ -98,12 +98,8 @@ protected: /** \internal The map from vertices to toplices * \ingroup toplex_map */ std::unordered_map t0; - }; -typedef Toplex_map::Simplex_ptr Simplex_ptr; -typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; - // Pointers are also used as key in the hash sets. template Simplex_ptr get_key(const Input_vertex_range &vertex_range); @@ -261,13 +257,13 @@ Vertex Toplex_map::best_index(const Input_vertex_range &vertex_range) const{ return arg_min; } -std::size_t Toplex_map::Sptr_equal::operator()(const Simplex_ptr& s1, const Simplex_ptr& s2) const { +std::size_t Sptr_equal::operator()(const Simplex_ptr& s1, const Simplex_ptr& s2) const { if (s1->size() != s2->size()) return false; return included(*s1,*s2); // inclusion tests equality for same size simplices } -std::size_t Toplex_map::Sptr_hash::operator()(const Simplex_ptr& s) const { +std::size_t Sptr_hash::operator()(const Simplex_ptr& s) const { std::hash h_f; //double hash works better than int hash size_t h = 0; diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index cbc53902..0f709409 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -14,6 +14,7 @@ install(TARGETS Witness_complex_example_nearest_landmark_table DESTINATION bin) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) add_executable( Witness_complex_example_off example_witness_complex_off.cpp ) add_executable( Witness_complex_example_strong_off example_strong_witness_complex_off.cpp ) +add_executable( Witness_complex_example_strong_fvecs example_strong_witness_complex_fvecs.cpp ) add_executable ( Witness_complex_example_sphere example_witness_complex_sphere.cpp ) add_executable ( Witness_complex_example_witness_persistence example_witness_complex_persistence.cpp ) @@ -44,6 +45,7 @@ if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) install(TARGETS Witness_complex_example_off DESTINATION bin) install(TARGETS Witness_complex_example_strong_off DESTINATION bin) + install(TARGETS Witness_complex_example_strong_fvecs DESTINATION bin) install(TARGETS Witness_complex_example_sphere DESTINATION bin) install(TARGETS Witness_complex_example_witness_persistence DESTINATION bin) install(TARGETS Witness_complex_example_strong_witness_persistence DESTINATION bin) diff --git a/src/Witness_complex/example/example_strong_witness_complex_off.cpp b/src/Witness_complex/example/example_strong_witness_complex_off.cpp index 4a232481..6292e248 100644 --- a/src/Witness_complex/example/example_strong_witness_complex_off.cpp +++ b/src/Witness_complex/example/example_strong_witness_complex_off.cpp @@ -50,8 +50,8 @@ int main(int argc, char * const argv[]) { int nbL = atoi(argv[2]), lim_dim = atoi(argv[4]); double alpha2 = atof(argv[3]); clock_t start, end; - //Gudhi::Simplex_tree<> simplex_tree; - Gudhi::Fake_simplex_tree simplex_tree; + Gudhi::Simplex_tree<> simplex_tree; + //Gudhi::Fake_simplex_tree simplex_tree; // Read the point file Point_vector point_vector, landmarks; -- cgit v1.2.3 From 03566e8a3a7f52f180bfa643b801f302c033f3fa Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 26 Oct 2017 15:20:03 +0000 Subject: boost clique algorithm for ribs git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2808 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 99ab7e5ce4cf1de7c710333ca1328c552499a446 --- .../example/example_rips_complex_from_fvecs.cpp | 71 ++++++-------- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 108 ++++++--------------- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 15 ++- 3 files changed, 74 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp index c05d038a..5e7667bd 100644 --- a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp @@ -10,58 +10,49 @@ #include #include #include +#include void usage(int nbArgs, char * const progName) { - std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n"; - std::cerr << "Usage: " << progName << " filename.fvecs threshold dim_max [ouput_file.txt]\n"; - std::cerr << " i.e.: " << progName << " ../../data/points/alphacomplexdoc.fvecs 60.0\n"; - exit(-1); // ----- >> + std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n"; + std::cerr << "Usage: " << progName << " filename.fvecs threshold dim_max [ouput_file.txt]\n"; + std::cerr << " i.e.: " << progName << " ../../data/points/alphacomplexdoc.fvecs 60.0\n"; + exit(-1); // ----- >> } int main(int argc, char **argv) { - if ((argc != 4) && (argc != 5)) usage(argc, (argv[0] - 1)); + if (argc != 4) usage(argc, (argv[0] - 1)); - std::string file_name(argv[1]); - double threshold = atof(argv[2]); - int dim_max = atoi(argv[3]); + std::string file_name(argv[1]); + double threshold = atof(argv[2]); + int dim_max = atoi(argv[3]); - // Type definitions - using K = CGAL::Epick_d; - using Point = typename K::Point_d; - //using Simplex_tree = Gudhi::Simplex_tree<>; - using Simplex_tree = Gudhi::Fake_simplex_tree; - using Filtration_value = Simplex_tree::Filtration_value; - using Rips_complex = Gudhi::rips_complex::Rips_complex; - using Point_vector = std::vector; + // Type definitions + using K = CGAL::Epick_d; + using Point = typename K::Point_d; + //using Simplex_tree = Gudhi::Simplex_tree<>; + using Simplex_tree = Gudhi::Fake_simplex_tree; + using Filtration_value = Simplex_tree::Filtration_value; + using Rips_complex = Gudhi::rips_complex::Rips_complex; + using Point_vector = std::vector; - // ---------------------------------------------------------------------------- - // Init of a Rips complex from an fvecs file - // ---------------------------------------------------------------------------- - Point_vector point_vector; - Gudhi::load_points_from_fvecs_file(file_name, std::back_insert_iterator< Point_vector >(point_vector)); + // ---------------------------------------------------------------------------- + // Init of a Rips complex from an fvecs file + // ---------------------------------------------------------------------------- + Point_vector point_vector; + Gudhi::load_points_from_fvecs_file(file_name, std::back_insert_iterator< Point_vector >(point_vector)); - Rips_complex rips_complex_from_file(point_vector, threshold, Gudhi::Euclidean_distance()); + Rips_complex rips_complex_from_file(point_vector, threshold, Gudhi::Euclidean_distance()); - std::streambuf* streambufffer; - std::ofstream ouput_file_stream; - if (argc == 5) { - ouput_file_stream.open(std::string(argv[4])); - streambufffer = ouput_file_stream.rdbuf(); - } else { - streambufffer = std::cout.rdbuf(); - } + Simplex_tree stree; - Simplex_tree stree; - rips_complex_from_file.create_complex(stree, dim_max); - std::ostream output_stream(streambufffer); + clock_t start, end; + start = clock(); + rips_complex_from_file.create_complex(stree, dim_max); + end = clock(); - // ---------------------------------------------------------------------------- - // Display information about the Rips complex - // ---------------------------------------------------------------------------- - output_stream << "Rips complex is of dimension " << stree.dimension() << - " - " << stree.num_simplices() << " simplices." << std::endl; + std::cout << "Strong witness complex took "<< static_cast(end - start) / CLOCKS_PER_SEC << " s." << std::endl; + std::cout << "Rips complex is of dimension " << stree.dimension() << " - " << stree.num_simplices() << " simplices." << std::endl; - ouput_file_stream.close(); - return 0; + return 0; } diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index b318acb4..6a0782ea 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -5,10 +5,26 @@ #include #include +#include +#define filtration_upper_bound std::numeric_limits::max() namespace Gudhi { +struct Visitor { + Toplex_map* tm; + + Visitor(Toplex_map* tm) + :tm(tm) + {} + + template + void clique(const Clique& c, const Graph& g) + { + tm->insert_simplex(c); + } +}; + class Fake_simplex_tree : public Filtered_toplex_map { public: @@ -31,14 +47,12 @@ public: /** \brief Returns the number of vertices in the simplicial complex. */ std::size_t num_vertices() const; - Simplex_ptr_set candidates() const; + Simplex_ptr_set candidates(int min_dim=-1) const; std::size_t dimension() const; std::size_t num_simplices() const; - void set_dimension(int d); - Simplex simplex_vertex_range(const Simplex& s) const; std::vector max_simplices() const; @@ -58,87 +72,26 @@ protected: }; -void Fake_simplex_tree::set_dimension(int d){ - -} - template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - if (boost::num_vertices(skel_graph) == 0) return; - typename boost::graph_traits::vertex_iterator v_it, v_it_end; - for (std::tie(v_it, v_it_end) = boost::vertices(skel_graph); v_it != v_it_end; ++v_it){ - Simplex s; - s.insert(*v_it); - insert_simplex_and_subfaces(s, boost::get(vertex_filtration_t(), skel_graph, *v_it)); - } - - typename boost::graph_traits::edge_iterator e_it, e_it_end; - for (std::tie(e_it, e_it_end) = boost::edges(skel_graph); e_it != e_it_end; ++e_it) { - Vertex u = source(*e_it, skel_graph); - Vertex v = target(*e_it, skel_graph); - if (u < v) { - Simplex s; - s.insert(u); - s.insert(v); - insert_simplex_and_subfaces(s, boost::get(edge_filtration_t(), skel_graph, *e_it)); - } - } + toplex_maps.emplace(filtration_upper_bound,Toplex_map()); + bron_kerbosch_all_cliques(skel_graph, Visitor(&(this->toplex_maps.at(filtration_upper_bound)))); } -void Fake_simplex_tree::expansion(int max_dim){ - for(int d=2; d <= max_dim; d++){ - Simplex_ptr_set cs = candidates(); //dimension ? - if(cs.empty()) std::cout << d << std::endl; - if(cs.empty()) return; - for(const Simplex_ptr& sptr: cs) - insert_simplex_and_subfaces(*sptr); //filtration ? - } -} +void Fake_simplex_tree::expansion(int max_dim){} template 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(!filtrations.count(get_key(s))) return false; + if(!membership(s)) return false; return true; } -Simplex_ptr_set Fake_simplex_tree::candidates() const{ - Simplex_ptr_set c; - std::unordered_map, Sptr_hash, Sptr_equal> facets_to_max; - for(const auto& kv : filtrations){ - Simplex sigma (*(kv.first)); - if(sigma.size()>1) - for(Vertex v : *(kv.first)){ - sigma.erase(v); - auto sptr = get_key(sigma); - if(!facets_to_max.count(sptr)) - facets_to_max.emplace(sptr, std::vector()); - facets_to_max.at(sptr).emplace_back(v); - sigma.insert(v); - } - } - for(const auto& kv : facets_to_max){ - std::unordered_set facets(kv.second.begin(), kv.second.end()); - for(Vertex v : kv.second){ - facets.erase(v); - for(Vertex w : facets){ - Simplex sigma(*(kv.first)); - sigma.insert(v); - sigma.insert(w); - if(all_facets_inside(sigma)) - c.emplace(get_key(sigma)); - } - facets.emplace(v); - } - } - return c; -} - std::size_t Fake_simplex_tree::dimension() const { std::size_t max = 0; - for(auto kv : filtrations) - max = std::max(max, kv.first->size()); + for(const Simplex& s : max_simplices()) + max = std::max(max, s.size()); return max-1; } @@ -149,8 +102,8 @@ std::size_t Fake_simplex_tree::num_simplices() const { std::size_t Fake_simplex_tree::num_vertices() const { std::unordered_set vertices; - for(auto kv : filtrations) - for (Vertex v : *(kv.first)) + for(const Simplex& s : max_simplices()) + for (Vertex v : s) vertices.emplace(v); return vertices.size(); } @@ -179,17 +132,18 @@ std::vector Fake_simplex_tree::filtration_simplex_range() const{ std::vector Fake_simplex_tree::skeleton_simplex_range(int d) const{ std::vector simplices; - for(auto s: filtration_simplex_range()) + for(const Simplex& s : max_simplices()) if(s.size()<=d) simplices.emplace_back(s); return simplices; } std::vector Fake_simplex_tree::max_simplices() const{ - std::vector s; - for(auto kv : filtrations) - s.emplace_back(*(kv.first)); - return s; + std::vector max_s; + for(auto kv : toplex_maps) + for(const Simplex_ptr& sptr : kv.second.maximal_cofaces(Simplex())) + max_s.emplace_back(*sptr); + return max_s; } std::size_t Fake_simplex_tree::dimension(Simplex_ptr& sptr) const{ diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index 6d89c062..5bf50fc5 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -19,19 +19,20 @@ public: template Filtration_value filtration(const Input_vertex_range &vertex_range) const; + template + bool membership(const Input_vertex_range &vertex_range) const; + protected: std::unordered_map toplex_maps; - std::unordered_map filtrations; - }; template void Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ if(!toplex_maps.count(f)) toplex_maps.emplace(f,Toplex_map()); toplex_maps.at(f).insert_simplex(vertex_range); - filtrations.emplace(get_key(vertex_range),f); } + template Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ for(auto kv : toplex_maps) @@ -40,6 +41,14 @@ Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Inpu return filtration_upper_bound; } +template +bool Filtered_toplex_map::membership(const Input_vertex_range &vertex_range) const{ + for(auto kv : toplex_maps) + if(kv.second.membership(vertex_range)) + return true; + return false; +} + } //namespace Gudhi #endif /* FILTERED_TOPLEX_MAP_H */ -- cgit v1.2.3 From e5a2be33e10b0653258252451330c021fa0bc204 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 26 Oct 2017 15:57:09 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2809 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 67f6ba752b6284763cdc706d5dec3e100386c602 --- src/Tangential_complex/example/example_basic.cpp | 7 +++++-- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Tangential_complex/example/example_basic.cpp b/src/Tangential_complex/example/example_basic.cpp index 4f2b859e..39165397 100644 --- a/src/Tangential_complex/example/example_basic.cpp +++ b/src/Tangential_complex/example/example_basic.cpp @@ -1,5 +1,7 @@ #include #include +#include + #include #include @@ -20,7 +22,7 @@ CGAL::Parallel_tag> TC; int main(void) { const int INTRINSIC_DIM = 2; const int AMBIENT_DIM = 3; - const int NUM_POINTS = 1000; + const int NUM_POINTS = 100; Kernel k; @@ -36,7 +38,8 @@ int main(void) { tc.compute_tangential_complex(); // Export the TC into a Simplex_tree - Gudhi::Simplex_tree<> stree; + //Gudhi::Simplex_tree<> stree; + Gudhi::Fake_simplex_tree stree; tc.create_complex(stree); // Display stats about inconsistencies diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index 5bf50fc5..3a0064dc 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -14,7 +14,7 @@ public: typedef double Filtration_value; template - void insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = filtration_upper_bound); + std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = filtration_upper_bound); template Filtration_value filtration(const Input_vertex_range &vertex_range) const; @@ -27,9 +27,12 @@ protected: }; template -void Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ +std::pair Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ + Simplex s(vertex_range.begin(),vertex_range.end()); + if(membership(s)) return make_pair(s,false); if(!toplex_maps.count(f)) toplex_maps.emplace(f,Toplex_map()); toplex_maps.at(f).insert_simplex(vertex_range); + return make_pair(s,true); } -- cgit v1.2.3 From 0a0c72f24969de374396378bd0fb82af6f0bdbc5 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 16 Nov 2017 14:25:10 +0000 Subject: file added git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2891 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4a89b348bd830123e99ed3f29b1b62526fbc5bbe --- .../example_strong_witness_complex_fvecs.cpp | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp (limited to 'src') diff --git a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp new file mode 100644 index 00000000..a8e16fb0 --- /dev/null +++ b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp @@ -0,0 +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): Siargey Kachanovich + * + * Copyright (C) 2016 INRIA (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 . + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +using K = CGAL::Epick_d; +using Point_d = typename K::Point_d; +using Witness_complex = Gudhi::witness_complex::Euclidean_strong_witness_complex; +using Point_vector = std::vector; + +int main(int argc, char * const argv[]) { + if (argc != 5) { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file number_of_landmarks max_squared_alpha limit_dimension\n"; + return 0; + } + + std::string file_name = argv[1]; + int nbL = atoi(argv[2]), lim_dim = atoi(argv[4]); + double alpha2 = atof(argv[3]); + clock_t start, end; + //Gudhi::Simplex_tree<> simplex_tree; + Gudhi::Fake_simplex_tree simplex_tree; + + // Read the point file + Point_vector point_vector, landmarks; + Gudhi::load_points_from_fvecs_file(file_name, std::back_insert_iterator< Point_vector >(point_vector)); + + + std::cout << "Successfully read " << point_vector.size() << " points.\n"; + std::cout << "Ambient dimension is " << point_vector[0].dimension() << ".\n"; + + // Choose landmarks + Gudhi::subsampling::pick_n_random_points(point_vector, nbL, std::back_inserter(landmarks)); + + // Compute witness complex + start = clock(); + Witness_complex witness_complex(landmarks, + point_vector); + + witness_complex.create_complex(simplex_tree, alpha2, lim_dim); + end = clock(); + std::cout << "Strong witness complex took " + << static_cast(end - start) / CLOCKS_PER_SEC << " s. \n"; + std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << std::endl; + std::cout << "Max dimension is : " << simplex_tree.dimension() << std::endl; + +} -- cgit v1.2.3 From 8d3be7f7008eb06b001797510c965a2b2a4009a9 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 16 Nov 2017 15:12:14 +0000 Subject: set dimension deprecated, no ? git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2892 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 84029be094a63f148cdadbd412aab630be9cd8db --- src/Witness_complex/include/gudhi/Strong_witness_complex.h | 1 - src/Witness_complex/include/gudhi/Witness_complex.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Strong_witness_complex.h b/src/Witness_complex/include/gudhi/Strong_witness_complex.h index 6f4bcf60..c18335d3 100644 --- a/src/Witness_complex/include/gudhi/Strong_witness_complex.h +++ b/src/Witness_complex/include/gudhi/Strong_witness_complex.h @@ -127,7 +127,6 @@ class Strong_witness_complex { if ((Landmark_id)simplex.size() - 1 > complex_dim) complex_dim = simplex.size() - 1; } - complex.set_dimension(complex_dim); return true; } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index bcfe8484..53c38520 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -130,7 +130,6 @@ class Witness_complex { } k++; } - complex.set_dimension(k-1); return true; } -- cgit v1.2.3 From bf84494b3e7f3d2a36661b66defb131e515cdc5b Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 21 Nov 2017 18:38:25 +0000 Subject: ... git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2926 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d872eef9342046002b81f55cc12760e799df0c1d --- src/Toplex_map/benchmarks/CMakeLists.txt | 4 + src/Toplex_map/benchmarks/chrono.cpp | 137 +++++++++++++++++++++ src/Toplex_map/doc/Intro_Toplex_map.h | 8 +- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 69 +++++------ src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 11 +- 5 files changed, 182 insertions(+), 47 deletions(-) create mode 100644 src/Toplex_map/benchmarks/CMakeLists.txt create mode 100644 src/Toplex_map/benchmarks/chrono.cpp (limited to 'src') diff --git a/src/Toplex_map/benchmarks/CMakeLists.txt b/src/Toplex_map/benchmarks/CMakeLists.txt new file mode 100644 index 00000000..2341fe06 --- /dev/null +++ b/src/Toplex_map/benchmarks/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 2.6) +project(Toplex_map_examples) + +add_executable(chrono chrono.cpp) diff --git a/src/Toplex_map/benchmarks/chrono.cpp b/src/Toplex_map/benchmarks/chrono.cpp new file mode 100644 index 00000000..d93d1e1f --- /dev/null +++ b/src/Toplex_map/benchmarks/chrono.cpp @@ -0,0 +1,137 @@ +#include +#include +#include + +#include +#include + +using namespace Gudhi; + +typedef Simplex typeVectorVertex; +typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +class ST_wrapper { + +public: + void insert_simplex(const Simplex& tau); + bool membership(const Simplex& tau); + Vertex contraction(const Vertex x, const Vertex y); + std::size_t num_simplices(); + +private: + Simplex_tree<> simplexTree; + void erase_max(const Simplex& sigma); +}; + +void ST_wrapper::insert_simplex(const Simplex& tau){ + simplexTree.insert_simplex_and_subfaces(tau); +} + +bool ST_wrapper::membership(const Simplex& tau) { + return simplexTree.find(tau) != simplexTree.null_simplex(); +} + +void ST_wrapper::erase_max(const Simplex& sigma){ + if(membership(sigma)) + simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); +} + +Vertex ST_wrapper::contraction(const Vertex x, const Vertex y){ + Simplex sx; sx.insert(x); + auto hx = simplexTree.find(sx); + if(hx != simplexTree.null_simplex()) + for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ + auto sr = simplexTree.simplex_vertex_range(h); + Simplex sigma(sr.begin(),sr.end()); + erase_max(sigma); + sigma.erase(x); + sigma.insert(y); + insert_simplex(sigma); + } + return y; +} + +std::size_t ST_wrapper::num_simplices(){ + return simplexTree.num_simplices(); +} + + + +int n = 300; + +int nb_insert_simplex1 = 3000; +int nb_membership1 = 4000; +int nb_contraction = 300; +int nb_insert_simplex2 = 3000; +int nb_membership2 = 400000; + +Simplex random_simplex(int n, int d){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1, n); + Simplex s; + while(s.size()!=d) + s.insert(dis(gen)); + return s; +} + +std::vector r_vector_simplices(int n, int max_d, int m){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1, max_d); + std::vector v; + for(int i=0; i +void chrono(int n, int d){ + complex_type K; + std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); + std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); + std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); + std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); + std::chrono::time_point start, end; + + for(const Simplex& s : simplices_insert_simplex1) + K.insert_simplex(s); + + for(const Simplex& s : simplices_membership1) + K.membership(s); + + start = std::chrono::system_clock::now(); + for(int i = 0; i<=nb_contraction; i++) + K.contraction(n-2*i,n-2*i-1); + end = std::chrono::system_clock::now(); + auto c3 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_insert_simplex2) + K.insert_simplex(s); + end = std::chrono::system_clock::now(); + auto c1 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_membership2) + K.membership(s); + end = std::chrono::system_clock::now(); + auto c2 = std::chrono::duration_cast(end-start).count(); + + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_simplices() << std::endl; +} + +int main(){ + for(int d=5;d<=40;d+=5){ + std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; + std::cout << "T Map \t \t"; + chrono(n,d); + std::cout << "Lazy \t \t"; + chrono(n,d); + if(d<=15){ + std::cout << "ST \t \t"; + chrono(n,d); + } + std::cout << std::endl; + } +} diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h index da9562ec..6f4c1a1b 100644 --- a/src/Toplex_map/doc/Intro_Toplex_map.h +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -33,15 +33,15 @@ namespace Gudhi { * * \section toplexmapdefinition Definition * - * Let's consider a simplicial complex, denote by $d$ its dimension - * and by $k$ its number of maximal simplices. - * Furthermore, denote by $\gamma_0$ the maximal number of toplices, i.e. maximal simplices, + * Let's consider a simplicial complex, denote by \f$d\f$ its dimension + * and by \f$k\f$ its number of maximal simplices. + * Furthermore, denote by \f$\gamma_0\f$ the maximal number of toplices, i.e. maximal simplices, * that contain a same vertex. * * The goal of the Toplex Map is both to represent the complex in optimal * O(kd) space and to provide fast standard operations such as : insertion, removal * and membership of a simplex, contraction of an edge, collapses. The time needed - * for these operation is linear or quadratic in $\gamma_0$ and $d$. + * for these operation is linear or quadratic in \f$\gamma_0\f$ and \f$d\f$. * * Toplex map is composed firstly of a raw storage of toplices and secondly of a * map which associate any vertex to a set of pointers toward all toplices diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 6a0782ea..3de962af 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -1,14 +1,14 @@ #ifndef FAKE_SIMPLEX_TREE_H #define FAKE_SIMPLEX_TREE_H +#include + #include #include #include #include -#define filtration_upper_bound std::numeric_limits::max() - namespace Gudhi { struct Visitor { @@ -35,33 +35,31 @@ public: typedef void Insertion_result_type; - /** \brief Inserts a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` in the simplicial + /** \brief Inserts the flag complex of a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` in the simplicial * complex. */ template void insert_graph(const OneSkeletonGraph& skel_graph); - /** \brief Expands the simplicial complex containing only its one skeleton until a given maximal dimension as - * explained in \ref ripsdefinition. */ + /** \brief Do nothing */ void expansion(int max_dim); - /** \brief Returns the number of vertices in the simplicial complex. */ + /** \brief Returns the number of vertices stored i.e. the number of max simplices */ std::size_t num_vertices() const; - Simplex_ptr_set candidates(int min_dim=-1) const; - std::size_t dimension() const; + std::size_t dimension(Simplex_ptr& sptr) const; + std::size_t num_simplices() const; Simplex simplex_vertex_range(const Simplex& s) const; std::vector max_simplices() const; - std::vector filtration_simplex_range() const; + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - std::vector skeleton_simplex_range(int d=std::numeric_limits::max()) const; + std::vector skeleton_simplex_range(int d) const; - std::size_t dimension(Simplex_ptr& sptr) const; protected: @@ -74,8 +72,8 @@ protected: template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(filtration_upper_bound,Toplex_map()); - bron_kerbosch_all_cliques(skel_graph, Visitor(&(this->toplex_maps.at(filtration_upper_bound)))); + toplex_maps.emplace(nan(""),Toplex_map()); + bron_kerbosch_all_cliques(skel_graph, Visitor(&(this->toplex_maps.at(nan(""))))); } void Fake_simplex_tree::expansion(int max_dim){} @@ -95,6 +93,10 @@ std::size_t Fake_simplex_tree::dimension() const { 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 filtration_simplex_range().size(); return max_simplices().size(); @@ -112,42 +114,35 @@ Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { return s; } -std::vector Fake_simplex_tree::filtration_simplex_range() const{ +std::vector Fake_simplex_tree::max_simplices() const{ + std::vector max_s; + for(auto kv : toplex_maps) + for(const Simplex_ptr& sptr : kv.second.maximal_cofaces(Simplex())) + max_s.emplace_back(*sptr); + return max_s; +} + +std::vector Fake_simplex_tree::filtration_simplex_range(int d) const{ std::vector m = max_simplices(); - std::vector seen1; - Simplex_ptr_set seen2; + std::vector range; + Simplex_ptr_set seen; while(m.begin()!=m.end()){ Simplex s(m.back()); m.pop_back(); - if(seen2.find(get_key(s))==seen2.end()){ - seen1.emplace_back(s); - seen2.emplace(get_key(s)); + if(seen.find(get_key(s))==seen.end()){ + if(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 seen1; + return range; } std::vector Fake_simplex_tree::skeleton_simplex_range(int d) const{ - std::vector simplices; - for(const Simplex& s : max_simplices()) - if(s.size()<=d) - simplices.emplace_back(s); - return simplices; -} - -std::vector Fake_simplex_tree::max_simplices() const{ - std::vector max_s; - for(auto kv : toplex_maps) - for(const Simplex_ptr& sptr : kv.second.maximal_cofaces(Simplex())) - max_s.emplace_back(*sptr); - return max_s; -} - -std::size_t Fake_simplex_tree::dimension(Simplex_ptr& sptr) const{ - return sptr->size(); + return filtration_simplex_range(d); } } //namespace Gudhi diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index 3a0064dc..a0c24304 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -2,10 +2,9 @@ #define FILTERED_TOPLEX_MAP_H #include +#include #include -#define filtration_upper_bound std::numeric_limits::max() - namespace Gudhi { class Filtered_toplex_map { @@ -14,7 +13,7 @@ public: typedef double Filtration_value; template - std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = filtration_upper_bound); + std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = nan("")); template Filtration_value filtration(const Input_vertex_range &vertex_range) const; @@ -23,7 +22,7 @@ public: bool membership(const Input_vertex_range &vertex_range) const; protected: - std::unordered_map toplex_maps; + std::map toplex_maps; }; template @@ -40,8 +39,8 @@ template Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ for(auto kv : toplex_maps) if(kv.second.membership(vertex_range)) - return kv.first; - return filtration_upper_bound; + return kv.first; //min only because a map is ordered + return nan(""); } template -- cgit v1.2.3 From a4677295cf1dd3a8e02dd135348b321eae044104 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 21 Nov 2017 18:38:45 +0000 Subject: ... git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2927 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1b3f9508c2697619d27776a9824defaa02a1420f --- src/Toplex_map/example/CMakeLists.txt | 4 - src/Toplex_map/example/chrono.cpp | 137 ---------------------------------- 2 files changed, 141 deletions(-) delete mode 100644 src/Toplex_map/example/CMakeLists.txt delete mode 100644 src/Toplex_map/example/chrono.cpp (limited to 'src') diff --git a/src/Toplex_map/example/CMakeLists.txt b/src/Toplex_map/example/CMakeLists.txt deleted file mode 100644 index 2341fe06..00000000 --- a/src/Toplex_map/example/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -cmake_minimum_required(VERSION 2.6) -project(Toplex_map_examples) - -add_executable(chrono chrono.cpp) diff --git a/src/Toplex_map/example/chrono.cpp b/src/Toplex_map/example/chrono.cpp deleted file mode 100644 index d93d1e1f..00000000 --- a/src/Toplex_map/example/chrono.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include - -#include -#include - -using namespace Gudhi; - -typedef Simplex typeVectorVertex; -typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - -class ST_wrapper { - -public: - void insert_simplex(const Simplex& tau); - bool membership(const Simplex& tau); - Vertex contraction(const Vertex x, const Vertex y); - std::size_t num_simplices(); - -private: - Simplex_tree<> simplexTree; - void erase_max(const Simplex& sigma); -}; - -void ST_wrapper::insert_simplex(const Simplex& tau){ - simplexTree.insert_simplex_and_subfaces(tau); -} - -bool ST_wrapper::membership(const Simplex& tau) { - return simplexTree.find(tau) != simplexTree.null_simplex(); -} - -void ST_wrapper::erase_max(const Simplex& sigma){ - if(membership(sigma)) - simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); -} - -Vertex ST_wrapper::contraction(const Vertex x, const Vertex y){ - Simplex sx; sx.insert(x); - auto hx = simplexTree.find(sx); - if(hx != simplexTree.null_simplex()) - for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ - auto sr = simplexTree.simplex_vertex_range(h); - Simplex sigma(sr.begin(),sr.end()); - erase_max(sigma); - sigma.erase(x); - sigma.insert(y); - insert_simplex(sigma); - } - return y; -} - -std::size_t ST_wrapper::num_simplices(){ - return simplexTree.num_simplices(); -} - - - -int n = 300; - -int nb_insert_simplex1 = 3000; -int nb_membership1 = 4000; -int nb_contraction = 300; -int nb_insert_simplex2 = 3000; -int nb_membership2 = 400000; - -Simplex random_simplex(int n, int d){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(1, n); - Simplex s; - while(s.size()!=d) - s.insert(dis(gen)); - return s; -} - -std::vector r_vector_simplices(int n, int max_d, int m){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(1, max_d); - std::vector v; - for(int i=0; i -void chrono(int n, int d){ - complex_type K; - std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); - std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); - std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); - std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); - std::chrono::time_point start, end; - - for(const Simplex& s : simplices_insert_simplex1) - K.insert_simplex(s); - - for(const Simplex& s : simplices_membership1) - K.membership(s); - - start = std::chrono::system_clock::now(); - for(int i = 0; i<=nb_contraction; i++) - K.contraction(n-2*i,n-2*i-1); - end = std::chrono::system_clock::now(); - auto c3 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_insert_simplex2) - K.insert_simplex(s); - end = std::chrono::system_clock::now(); - auto c1 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_membership2) - K.membership(s); - end = std::chrono::system_clock::now(); - auto c2 = std::chrono::duration_cast(end-start).count(); - - std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_simplices() << std::endl; -} - -int main(){ - for(int d=5;d<=40;d+=5){ - std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; - std::cout << "T Map \t \t"; - chrono(n,d); - std::cout << "Lazy \t \t"; - chrono(n,d); - if(d<=15){ - std::cout << "ST \t \t"; - chrono(n,d); - } - std::cout << std::endl; - } -} -- cgit v1.2.3 From 6f4c7c0177b6ccf88b61056ea9d2ae2b066e056a Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 23 Nov 2017 17:18:13 +0000 Subject: 3 files - 3 docs git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2945 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ce6663f33da653f2ac520b4d0f3684b4776aec94 --- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 53 ++++- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 28 +++ src/Toplex_map/include/gudhi/Lazy_toplex_map.h | 218 --------------------- src/Toplex_map/include/gudhi/Toplex_map.h | 42 ++-- 4 files changed, 98 insertions(+), 243 deletions(-) delete mode 100644 src/Toplex_map/include/gudhi/Lazy_toplex_map.h (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 3de962af..8876b56d 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -25,39 +25,78 @@ struct Visitor { } }; +/** 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: + /** Vertex is the type of vertices. + * \ingroup toplex_map */ + typedef Toplex_map::Vertex Vertex; + + /** Simplex is the type of simplices. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex Simplex; + + /** The type of the pointers to maximal simplices. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex_ptr Simplex_ptr; + + /** The type of the sets of Simplex_ptr. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + /** Handle type to a vertex contained in the simplicial complex. + * \ingroup toplex_map */ typedef Vertex Vertex_handle; + /** Handle type to a simplex contained in the simplicial complex. + * \ingroup toplex_map */ typedef Simplex Simplex_handle; typedef void Insertion_result_type; - /** \brief Inserts the flag complex of a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` in the simplicial - * complex. */ + /** Inserts the flag complex of a given range `Gudhi::rips_complex::Rips_complex::OneSkeletonGraph` + * in the simplicial complex. + * \ingroup toplex_map */ template void insert_graph(const OneSkeletonGraph& skel_graph); - /** \brief Do nothing */ + /** Do actually nothing. + * \ingroup toplex_map */ void expansion(int max_dim); - /** \brief Returns the number of vertices stored i.e. the number of max simplices */ + /** 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 */ 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 max_simplices() const; + /** Returns all the simplices, of max dimension d if a parameter d is given. + * \ingroup toplex_map */ std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + /** Returns all the simplices of max dimension d + * \ingroup toplex_map */ std::vector skeleton_simplex_range(int d) const; @@ -73,6 +112,12 @@ protected: template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ toplex_maps.emplace(nan(""),Toplex_map()); + using vertex_iterator = typename boost::graph_traits::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(""))))); } diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index a0c24304..28814d15 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -7,17 +7,45 @@ namespace Gudhi { +/** A Filtered_toplex_map represents the simplicial complex with a filtration. + * A "toplex" is a critical simplex. + * \ingroup toplex_map */ class Filtered_toplex_map { public: + /** Vertex is the type of vertices. + * \ingroup toplex_map */ + typedef Toplex_map::Vertex Vertex; + + /** Simplex is the type of simplices. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex Simplex; + + /** The type of the pointers to maximal simplices. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex_ptr Simplex_ptr; + + /** The type of the sets of Simplex_ptr. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + + /** The type of the filtration values. + * \ingroup toplex_map */ typedef double Filtration_value; + /** Add a simplex and its subfaces with the given filtration value + * in the Filtered_toplex_map. + * \ingroup toplex_map */ template std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = nan("")); + /** Gives the filtration of the input simplex. + * \ingroup toplex_map */ template Filtration_value filtration(const Input_vertex_range &vertex_range) const; + /** Is the input simplex member of the complex ? + * \ingroup toplex_map */ template bool membership(const Input_vertex_range &vertex_range) const; diff --git a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h deleted file mode 100644 index 3ffe8214..00000000 --- a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef LAZY_TOPLEX_MAP_H -#define LAZY_TOPLEX_MAP_H - -#include -#include - -namespace Gudhi { - -class Lazy_Toplex_map { - -public: - template - void insert_max_simplex(const Input_vertex_range &vertex_range); - template - bool insert_simplex(const Input_vertex_range &vertex_range); - template - void remove_simplex(const Input_vertex_range &vertex_range); - - template - bool membership(const Input_vertex_range &vertex_range); - template - bool all_facets_inside(const Input_vertex_range &vertex_range); - - Vertex contraction(const Vertex x, const Vertex y); - - std::size_t num_simplices() const; - -private: - template - void erase_max(const Input_vertex_range &vertex_range); - template - Vertex best_index(const Input_vertex_range &vertex_range); - void clean(const Vertex v); - - std::unordered_map t0; - bool empty_toplex; // Is the empty simplex a toplex ? - - typedef boost::heap::fibonacci_heap> PriorityQueue; - PriorityQueue cleaning_priority; - std::unordered_map cp_handles; - - std::unordered_map gamma0_lbounds; - std::size_t get_gamma0_lbound(const Vertex v) const; - - std::size_t size_lbound = 0; - std::size_t size = 0; - - const double alpha = 2; //time - const double betta = 3; //memory -}; - -template -void Lazy_Toplex_map::insert_max_simplex(const Input_vertex_range &vertex_range){ - for(const Vertex& v : vertex_range) - if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); - else gamma0_lbounds[v]++; - size_lbound++; - insert_simplex(vertex_range); -} - -template -bool Lazy_Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - empty_toplex = (sigma.size()==0); //vérifier la gestion de empty face - Simplex_ptr sptr = std::make_shared(sigma); - bool inserted = false; - for(const Vertex& v : sigma){ - if(!t0.count(v)){ - t0.emplace(v, Simplex_ptr_set()); - auto v_handle = cleaning_priority.push(std::make_pair(0, v)); - cp_handles.emplace(v, v_handle); - } - inserted = t0.at(v).emplace(sptr).second; - cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v),v)); - } - if(inserted) - size++; - if(size > size_lbound * betta) - clean(cleaning_priority.top().second); - return inserted; -} - -template -void Lazy_Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ - if(vertex_range.begin()==vertex_range.end()){ - t0.clear(); - gamma0_lbounds.clear(); - cleaning_priority.clear(); - size_lbound = 0; - size = 0; - empty_toplex = false; - } - else { - const Vertex& v = best_index(vertex_range); - //Copy constructor needed because the set is modified - if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) - if(included(vertex_range, *sptr)){ - erase_max(*sptr); - for(const Simplex& f : facets(vertex_range)) - insert_max_simplex(f); - } - } -} - -template -bool Lazy_Toplex_map::membership(const Input_vertex_range &vertex_range){ - if(t0.size()==0 && !empty_toplex) return false; //empty complex - if(vertex_range.begin()==vertex_range.end()) return true; //empty query simplex - Vertex v = best_index(vertex_range); - if(!t0.count(v)) return false; - for(const Simplex_ptr& sptr : t0.at(v)) - if(included(vertex_range, *sptr)) return true; - return false; -} - -template -bool Lazy_Toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - Vertex v = best_index(sigma); - if(!t0.count(v)) return false; - Simplex f = sigma; f.erase(v); - if(!membership(f)) return false; - std::unordered_set facets_inside; - for(const Simplex_ptr& sptr : t0.at(v)) - for(const Vertex& w : sigma){ - f = sigma; f.erase(w); - if(included(f, *sptr)) facets_inside.insert(w); - } - return facets_inside.size() == sigma.size() - 1; -} - -/* Returns the remaining vertex */ -Vertex Lazy_Toplex_map::contraction(const Vertex x, const Vertex y){ - if(!t0.count(x)) return y; - if(!t0.count(y)) return x; - Vertex k, d; - if(t0.at(x).size() > t0.at(y).size()) - k=x, d=y; - else - k=y, d=x; - //Copy constructor needed because the set is modified - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ - Simplex sigma(*sptr); - erase_max(sigma); - sigma.erase(d); - sigma.insert(k); - insert_simplex(sigma); - } - t0.erase(d); - return k; -} - -/* No facets insert_simplexed */ -template -inline void Lazy_Toplex_map::erase_max(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - empty_toplex = false; - Simplex_ptr sptr = std::make_shared(sigma); - bool erased; - for(const Vertex& v : sigma){ - erased = t0.at(v).erase(sptr) > 0; - if(t0.at(v).size()==0) - t0.erase(v); - } - if (erased) - size--; -} - -template -Vertex Lazy_Toplex_map::best_index(const Input_vertex_range &vertex_range){ - Simplex tau(vertex_range.begin(),vertex_range.end()); - std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; - for(const Vertex& v : tau) - if(!t0.count(v)) return v; - else if(t0.at(v).size() < min) - min = t0.at(v).size(), arg_min = v; - if(min > alpha * get_gamma0_lbound(arg_min)) - clean(arg_min); - return arg_min; -} - -std::size_t Lazy_Toplex_map::get_gamma0_lbound(const Vertex v) const{ - return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; -} - - -void Lazy_Toplex_map::clean(const Vertex v){ - Toplex_map toplices; - std::unordered_map> dsorted_simplices; - int max_dim = 0; - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ - if(sptr->size() > max_dim){ - for(int d = max_dim+1; d<=sptr->size(); d++) - dsorted_simplices.emplace(d, std::vector()); - max_dim = sptr->size(); - } - dsorted_simplices[sptr->size()].emplace_back(*sptr); - erase_max(*sptr); - } - for(int d = max_dim; d>=1; d--) - for(const Simplex &s : dsorted_simplices.at(d)) - if(!toplices.membership(s)) - toplices.insert_independent_simplex(s); - Simplex sv; sv.insert(v); - auto clean_cofaces = toplices.maximal_cofaces(sv); - size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); - gamma0_lbounds[v] = clean_cofaces.size(); - for(const Simplex_ptr& sptr : clean_cofaces) - insert_simplex(*sptr); -} - -std::size_t Lazy_Toplex_map::num_simplices() const{ - return size; -} - -} //namespace Gudhi - -#endif /* LAZY_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 9de3a6be..b433f3de 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -11,30 +11,31 @@ namespace Gudhi { -/** Vertex is the type of vertices. - * \ingroup toplex_map */ -typedef std::size_t Vertex; - -/** Simplex is the type of simplices. - * \ingroup toplex_map */ -typedef std::unordered_set Simplex; - -/** The type of the pointers to maximal simplices. - * \ingroup toplex_map */ -typedef std::shared_ptr Simplex_ptr; - -struct Sptr_hash{ std::size_t operator()(const Simplex_ptr& s) const; }; -struct Sptr_equal{ std::size_t operator()(const Simplex_ptr& a, const Simplex_ptr& b) const; }; -/** The type of the sets of Simplex_ptr. - * \ingroup toplex_map */ -typedef std::unordered_set Simplex_ptr_set; - /** A Toplex_map represents the simplicial complex. * A "toplex" is a maximal simplex. * \ingroup toplex_map */ class Toplex_map { public: + + /** Vertex is the type of vertices. + * \ingroup toplex_map */ + typedef std::size_t Vertex; + + /** Simplex is the type of simplices. + * \ingroup toplex_map */ + typedef std::unordered_set Simplex; + + /** The type of the pointers to maximal simplices. + * \ingroup toplex_map */ + typedef std::shared_ptr Simplex_ptr; + + struct Sptr_hash{ std::size_t operator()(const Simplex_ptr& s) const; }; + struct Sptr_equal{ std::size_t operator()(const Simplex_ptr& a, const Simplex_ptr& b) const; }; + /** The type of the sets of Simplex_ptr. + * \ingroup toplex_map */ + typedef std::unordered_set Simplex_ptr_set; + /** \brief Adds the given simplex to the complex. * Nothing happens if the simplex has a coface in the complex. * \ingroup toplex_map */ @@ -58,7 +59,7 @@ public: bool maximality(const Input_vertex_range &vertex_range) const; /** Gives a set of pointers to the maximal cofaces of a simplex. - * Gives the toplices if given the empty simplex. + * Gives all the toplices if given the empty simplex. * Gives not more than max_number maximal cofaces if max_number is strictly positive. * \ingroup toplex_map */ template @@ -85,8 +86,7 @@ public: void remove_vertex(const Vertex x); /** \brief Number of maximal simplices. - * /!\ Not efficient ! - * \ingroup toplex_map */ + * \ingroup toplex_map */ std::size_t num_simplices() const; protected: -- cgit v1.2.3 From a983b3bec81a6909c75f6760281cb09ab296123e Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 23 Nov 2017 17:20:14 +0000 Subject: test name git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2946 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d663b0f8578cb9a3ebced7d170bae5c924a02d78 --- src/Toplex_map/test/CMakeLists.txt | 2 +- src/Toplex_map/test/test.cpp | 71 ---------------------------- src/Toplex_map/test/toplex_map_unit_test.cpp | 71 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 72 deletions(-) delete mode 100644 src/Toplex_map/test/test.cpp create mode 100644 src/Toplex_map/test/toplex_map_unit_test.cpp (limited to 'src') diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt index 223ebccb..25fcabac 100644 --- a/src/Toplex_map/test/CMakeLists.txt +++ b/src/Toplex_map/test/CMakeLists.txt @@ -6,7 +6,7 @@ target_link_libraries(ToplexMapUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAM # Unitary tests -add_test(NAME SalUT +add_test(NAME ToplexMapUT COMMAND ${CMAKE_CURRENT_BINARY_DIR}/ToplexMapUT ${CMAKE_SOURCE_DIR}/src/Toplex_map/test/test.txt # XML format for Jenkins xUnit plugin diff --git a/src/Toplex_map/test/test.cpp b/src/Toplex_map/test/test.cpp deleted file mode 100644 index 3f4d96c2..00000000 --- a/src/Toplex_map/test/test.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include - -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE "toplex map" -#include - -using namespace Gudhi; - -std::vector sigma1 = {1, 2, 3, 4}; -std::vector sigma2 = {5, 2, 3, 6}; -std::vector sigma3 = {5}; -std::vector sigma4 = {5, 2, 3}; -std::vector sigma5 = {5, 2, 7}; -std::vector sigma6 = {4, 5, 3}; -std::vector sigma7 = {4, 5, 9}; -std::vector sigma8 = {1, 2, 3, 6}; - - -BOOST_AUTO_TEST_CASE(toplexmap) { - Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma6); - K.insert_simplex(sigma7); - BOOST_CHECK(K.membership(sigma4)); - BOOST_CHECK(!K.maximality(sigma5)); - BOOST_CHECK(!K.membership(sigma5)); - K.contraction(4,5); - BOOST_CHECK(!K.membership(sigma6)); -} - -BOOST_AUTO_TEST_CASE(ltoplexmap) { - Lazy_Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma6); - K.insert_simplex(sigma7); - BOOST_CHECK(K.membership(sigma4)); - BOOST_CHECK(!K.membership(sigma5)); - K.contraction(4,5); - BOOST_CHECK(!K.membership(sigma6)); -} - -BOOST_AUTO_TEST_CASE(ftoplexmap) { - Filtered_toplex_map K; - K.insert_simplex_and_subfaces(sigma1, 2.); - K.insert_simplex_and_subfaces(sigma2, 2.); - K.insert_simplex_and_subfaces(sigma6, 1.); - K.insert_simplex_and_subfaces(sigma7, 1.); - BOOST_CHECK(K.filtration(sigma4)==2.); - BOOST_CHECK(K.filtration(sigma3)==1.); -} - -/* -BOOST_AUTO_TEST_CASE(toplexmap_candidates) { - Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.remove_simplex(sigma1); - K.remove_simplex(sigma2); - auto c = K.candidates(); - BOOST_CHECK(c.count(get_key(sigma1))); - BOOST_CHECK(c.count(get_key(sigma2))); - BOOST_CHECK(c.size()==2); -} -*/ diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp new file mode 100644 index 00000000..3f4d96c2 --- /dev/null +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "toplex map" +#include + +using namespace Gudhi; + +std::vector sigma1 = {1, 2, 3, 4}; +std::vector sigma2 = {5, 2, 3, 6}; +std::vector sigma3 = {5}; +std::vector sigma4 = {5, 2, 3}; +std::vector sigma5 = {5, 2, 7}; +std::vector sigma6 = {4, 5, 3}; +std::vector sigma7 = {4, 5, 9}; +std::vector sigma8 = {1, 2, 3, 6}; + + +BOOST_AUTO_TEST_CASE(toplexmap) { + Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma6); + K.insert_simplex(sigma7); + BOOST_CHECK(K.membership(sigma4)); + BOOST_CHECK(!K.maximality(sigma5)); + BOOST_CHECK(!K.membership(sigma5)); + K.contraction(4,5); + BOOST_CHECK(!K.membership(sigma6)); +} + +BOOST_AUTO_TEST_CASE(ltoplexmap) { + Lazy_Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma6); + K.insert_simplex(sigma7); + BOOST_CHECK(K.membership(sigma4)); + BOOST_CHECK(!K.membership(sigma5)); + K.contraction(4,5); + BOOST_CHECK(!K.membership(sigma6)); +} + +BOOST_AUTO_TEST_CASE(ftoplexmap) { + Filtered_toplex_map K; + K.insert_simplex_and_subfaces(sigma1, 2.); + K.insert_simplex_and_subfaces(sigma2, 2.); + K.insert_simplex_and_subfaces(sigma6, 1.); + K.insert_simplex_and_subfaces(sigma7, 1.); + BOOST_CHECK(K.filtration(sigma4)==2.); + BOOST_CHECK(K.filtration(sigma3)==1.); +} + +/* +BOOST_AUTO_TEST_CASE(toplexmap_candidates) { + Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.remove_simplex(sigma1); + K.remove_simplex(sigma2); + auto c = K.candidates(); + BOOST_CHECK(c.count(get_key(sigma1))); + BOOST_CHECK(c.count(get_key(sigma2))); + BOOST_CHECK(c.size()==2); +} +*/ -- cgit v1.2.3 From 5430f6a24b6909f1d63cd2028e88ef2d69fb8a0d Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 23 Nov 2017 17:27:56 +0000 Subject: examples added git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@2947 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1f1710698fae160c3ad9f55f402e11f200877f88 --- src/Toplex_map/example/Simple_toplex_map.cpp | 214 +++++++++++++++++++++ .../example/Toplex_map_from_cliques_of_graph.cpp | 94 +++++++++ src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 2 +- 3 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 src/Toplex_map/example/Simple_toplex_map.cpp create mode 100644 src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp (limited to 'src') 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..b165af8a --- /dev/null +++ b/src/Toplex_map/example/Simple_toplex_map.cpp @@ -0,0 +1,214 @@ +/* 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 . + */ + +#include +#include + +#include +#include // for pair +#include + +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()) { + 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:" << std::endl; + for (auto f_simplex : t_map.skeleton_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; + } + + 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..aad31554 --- /dev/null +++ b/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp @@ -0,0 +1,94 @@ +/* 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 . + */ + +#include +#include + +#include +#include +#include +#include // 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(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(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(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()) { + 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/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 8876b56d..104f1742 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -175,7 +175,7 @@ std::vector Fake_simplex_tree::filtration_simplex_range(int d) const{ Simplex s(m.back()); m.pop_back(); if(seen.find(get_key(s))==seen.end()){ - if(s.size()-1<=d) + if((int) s.size()-1 <=d) range.emplace_back(s); seen.emplace(get_key(s)); if(s.size()>0) -- cgit v1.2.3 From 20034acbc1a6aa83a0a9fd2ee660bcda4dec6ebf Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 7 Dec 2017 15:46:43 +0000 Subject: small modifications git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3053 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7eeee9f036954c20f1f64369fc74dd64c98000bc --- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 38 ++++---- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 4 +- src/Toplex_map/include/gudhi/Toplex_map.h | 100 ++++++++++----------- 3 files changed, 71 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index 104f1742..ea5ac618 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -49,11 +49,11 @@ public: /** Handle type to a vertex contained in the simplicial complex. * \ingroup toplex_map */ - typedef Vertex Vertex_handle; + typedef Toplex_map::Vertex Vertex_handle; /** Handle type to a simplex contained in the simplicial complex. * \ingroup toplex_map */ - typedef Simplex Simplex_handle; + typedef Toplex_map::Simplex Simplex_handle; typedef void Insertion_result_type; @@ -85,19 +85,19 @@ public: /** Returns a range over the vertices of a simplex. * \ingroup toplex_map */ - Simplex simplex_vertex_range(const Simplex& s) const; + 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 max_simplices() const; + std::vector max_simplices() const; /** Returns all the simplices, of max dimension d if a parameter d is given. * \ingroup toplex_map */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; /** Returns all the simplices of max dimension d * \ingroup toplex_map */ - std::vector skeleton_simplex_range(int d) const; + std::vector skeleton_simplex_range(int d) const; protected: @@ -148,31 +148,31 @@ std::size_t Fake_simplex_tree::num_simplices() const { } std::size_t Fake_simplex_tree::num_vertices() const { - std::unordered_set vertices; - for(const Simplex& s : max_simplices()) - for (Vertex v : s) + std::unordered_set vertices; + for(const Toplex_map::Simplex& s : max_simplices()) + for (Toplex_map::Vertex v : s) vertices.emplace(v); return vertices.size(); } -Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { +Toplex_map::Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { return s; } -std::vector Fake_simplex_tree::max_simplices() const{ - std::vector max_s; +std::vector Fake_simplex_tree::max_simplices() const{ + std::vector max_s; for(auto kv : toplex_maps) - for(const Simplex_ptr& sptr : kv.second.maximal_cofaces(Simplex())) + for(const Toplex_map::Simplex_ptr& sptr : kv.second.maximal_cofaces(Simplex())) max_s.emplace_back(*sptr); return max_s; } -std::vector Fake_simplex_tree::filtration_simplex_range(int d) const{ - std::vector m = max_simplices(); - std::vector range; - Simplex_ptr_set seen; +std::vector Fake_simplex_tree::filtration_simplex_range(int d) const{ + std::vector m = max_simplices(); + std::vector range; + Toplex_map::Simplex_ptr_set seen; while(m.begin()!=m.end()){ - Simplex s(m.back()); + Toplex_map::Simplex s(m.back()); m.pop_back(); if(seen.find(get_key(s))==seen.end()){ if((int) s.size()-1 <=d) @@ -186,7 +186,7 @@ std::vector Fake_simplex_tree::filtration_simplex_range(int d) const{ return range; } -std::vector Fake_simplex_tree::skeleton_simplex_range(int d) const{ +std::vector Fake_simplex_tree::skeleton_simplex_range(int d) const{ return filtration_simplex_range(d); } diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index 28814d15..379c65dd 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -1,4 +1,4 @@ -#ifndef FILTERED_TOPLEX_MAP_H + #ifndef FILTERED_TOPLEX_MAP_H #define FILTERED_TOPLEX_MAP_H #include @@ -54,7 +54,7 @@ protected: }; template -std::pair Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ +std::pair Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ Simplex s(vertex_range.begin(),vertex_range.end()); if(membership(s)) return make_pair(s,false); if(!toplex_maps.count(f)) toplex_maps.emplace(f,Toplex_map()); diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index b433f3de..00127baf 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -7,7 +7,7 @@ #include #include -#define vertex_upper_bound std::numeric_limits::max() +#define vertex_upper_bound std::numeric_limits::max() namespace Gudhi { @@ -24,17 +24,17 @@ public: /** Simplex is the type of simplices. * \ingroup toplex_map */ - typedef std::unordered_set Simplex; + typedef std::unordered_set Simplex; /** The type of the pointers to maximal simplices. * \ingroup toplex_map */ - typedef std::shared_ptr Simplex_ptr; + typedef std::shared_ptr Simplex_ptr; - struct Sptr_hash{ std::size_t operator()(const Simplex_ptr& s) const; }; - struct Sptr_equal{ std::size_t operator()(const Simplex_ptr& a, const Simplex_ptr& b) const; }; - /** The type of the sets of Simplex_ptr. + struct Sptr_hash{ std::size_t operator()(const Toplex_map::Simplex_ptr& s) const; }; + struct Sptr_equal{ std::size_t operator()(const Toplex_map::Simplex_ptr& a, const Toplex_map::Simplex_ptr& b) const; }; + /** The type of the sets of Toplex_map::Simplex_ptr. * \ingroup toplex_map */ - typedef std::unordered_set Simplex_ptr_set; + typedef std::unordered_set Simplex_ptr_set; /** \brief Adds the given simplex to the complex. * Nothing happens if the simplex has a coface in the complex. @@ -63,13 +63,13 @@ public: * Gives not more than max_number maximal cofaces if max_number is strictly positive. * \ingroup toplex_map */ template - Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; + Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; /** Contracts one edge in the complex. * The edge has to verify the link condition if you want to preserve topology. * Returns the remaining vertex. * \ingroup toplex_map */ - Vertex contraction(const Vertex x, const Vertex y); + Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); /** Adds the given simplex to the complex. * The simplex must not have neither maximal face nor coface in the complex. @@ -79,11 +79,11 @@ public: /** \internal Removes a toplex without adding facets after. * \ingroup toplex_map */ - void erase_maximal(const Simplex_ptr& sptr); + void erase_maximal(const Toplex_map::Simplex_ptr& sptr); /** Removes a vertex from any simplex containing it. * \ingroup toplex_map */ - void remove_vertex(const Vertex x); + void remove_vertex(const Toplex_map::Vertex x); /** \brief Number of maximal simplices. * \ingroup toplex_map */ @@ -93,16 +93,16 @@ protected: /** \internal Gives an index in order to look for a simplex quickly. * \ingroup toplex_map */ template - Vertex best_index(const Input_vertex_range &vertex_range) const; + Toplex_map::Vertex best_index(const Input_vertex_range &vertex_range) const; /** \internal The map from vertices to toplices * \ingroup toplex_map */ - std::unordered_map t0; + std::unordered_map t0; }; // Pointers are also used as key in the hash sets. template -Simplex_ptr get_key(const Input_vertex_range &vertex_range); +Toplex_map::Simplex_ptr get_key(const Input_vertex_range &vertex_range); // Is the first simplex a face of the second ? template @@ -110,24 +110,24 @@ bool included(const Input_vertex_range1 &vertex_range1, const Input_vertex_range // All the facets of the given simplex. template -std::vector facets(const Input_vertex_range &vertex_range); +std::vector facets(const Input_vertex_range &vertex_range); template void Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ if(membership(vertex_range)) return; bool replace_facets = true; - for(const Simplex& facet : facets(vertex_range)) + for(const Toplex_map::Simplex& facet : facets(vertex_range)) if(!maximality(facet)) { replace_facets=false; break; } if(replace_facets) - for(const Simplex& facet : facets(vertex_range)) + for(const Toplex_map::Simplex& facet : facets(vertex_range)) erase_maximal(get_key(facet)); else - for(const Vertex& v : vertex_range) - if(t0.count(v)) for(const Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v))) + for(const Toplex_map::Vertex& v : vertex_range) + if(t0.count(v)) for(const Toplex_map::Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v))) //Copy constructor needed because the set is modified if(included(*fptr,vertex_range)) erase_maximal(fptr); // We erase all the maximal faces of the simplex @@ -140,12 +140,12 @@ void Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ t0.clear(); // Removal of the empty simplex means cleaning everything else { - const Vertex& v = best_index(vertex_range); - if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) + const Toplex_map::Vertex& v = best_index(vertex_range); + if(t0.count(v)) for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) //Copy constructor needed because the set is modified if(included(vertex_range, *sptr)){ erase_maximal(sptr); - for(const Simplex& f : facets(vertex_range)) + for(const Toplex_map::Simplex& f : facets(vertex_range)) if(!membership(f)) insert_independent_simplex(f); // We add the facets which are new maximal simplices } @@ -155,10 +155,10 @@ void Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ template bool Toplex_map::membership(const Input_vertex_range &vertex_range) const{ if(t0.size()==0) return false; - const Vertex& v = best_index(vertex_range); + const Toplex_map::Vertex& v = best_index(vertex_range); if(!t0.count(v)) return false; if(maximality(vertex_range)) return true; - for(const Simplex_ptr& sptr : t0.at(v)) + for(const Toplex_map::Simplex_ptr& sptr : t0.at(v)) if(included(vertex_range, *sptr)) return true; return false; @@ -166,27 +166,27 @@ bool Toplex_map::membership(const Input_vertex_range &vertex_range) const{ template bool Toplex_map::maximality(const Input_vertex_range &vertex_range) const{ - const Vertex& v = best_index(vertex_range); + const Toplex_map::Vertex& v = best_index(vertex_range); if(!t0.count(v)) return false; return t0.at(v).count(get_key(vertex_range)); } template -Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number) const{ +Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number) const{ Simplex_ptr_set cofaces; if(maximality(vertex_range)) cofaces.emplace(get_key(vertex_range)); else if(vertex_range.begin()==vertex_range.end()) for(const auto& kv : t0) - for(const Simplex_ptr& sptr : kv.second){ + for(const Toplex_map::Simplex_ptr& sptr : kv.second){ //kv.second is a Simplex_ptr_set cofaces.emplace(sptr); if(cofaces.size()==max_number) return cofaces; } else { - const Vertex& v = best_index(vertex_range); - if(t0.count(v)) for(const Simplex_ptr& sptr : t0.at(v)) + const Toplex_map::Vertex& v = best_index(vertex_range); + if(t0.count(v)) for(const Toplex_map::Simplex_ptr& sptr : t0.at(v)) if(included(vertex_range, *sptr)){ cofaces.emplace(sptr); if(cofaces.size()==max_number) @@ -196,7 +196,7 @@ Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range &vertex_ran return cofaces; } -Vertex Toplex_map::contraction(const Vertex x, const Vertex y){ +Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y){ if(!t0.count(x)) return y; if(!t0.count(y)) return x; int k, d; @@ -204,7 +204,7 @@ Vertex Toplex_map::contraction(const Vertex x, const Vertex y){ k=x, d=y; else k=y, d=x; - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ + for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ //Copy constructor needed because the set is modified Simplex sigma(*sptr); erase_maximal(sptr); @@ -217,14 +217,14 @@ Vertex Toplex_map::contraction(const Vertex x, const Vertex y){ template void Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ - for(const Vertex& v : vertex_range){ + for(const Toplex_map::Vertex& v : vertex_range){ if(!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); t0.at(v).emplace(get_key(vertex_range)); } } -void Toplex_map::remove_vertex(const Vertex x){ - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(x))){ +void Toplex_map::remove_vertex(const Toplex_map::Vertex x){ + for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(x))){ Simplex sigma(*sptr); erase_maximal(sptr); sigma.erase(x); @@ -236,61 +236,61 @@ std::size_t Toplex_map::num_simplices() const{ return maximal_cofaces(Simplex()).size(); } -inline void Toplex_map::erase_maximal(const Simplex_ptr& sptr){ +inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr){ Simplex sigma(*sptr); if (sptr->size()==0) sigma.insert(vertex_upper_bound); - for(const Vertex& v : sigma){ + for(const Toplex_map::Vertex& v : sigma){ t0.at(v).erase(sptr); if(t0.at(v).size()==0) t0.erase(v); } } template -Vertex Toplex_map::best_index(const Input_vertex_range &vertex_range) const{ +Toplex_map::Vertex Toplex_map::best_index(const Input_vertex_range &vertex_range) const{ std::size_t min = std::numeric_limits::max(); Vertex arg_min = vertex_upper_bound; - for(const Vertex& v : vertex_range) + for(const Toplex_map::Vertex& v : vertex_range) if(!t0.count(v)) return v; else if(t0.at(v).size() < min) min = t0.at(v).size(), arg_min = v; return arg_min; } -std::size_t Sptr_equal::operator()(const Simplex_ptr& s1, const Simplex_ptr& s2) const { +std::size_t Toplex_map::Sptr_equal::operator()(const Toplex_map::Simplex_ptr& s1, const Toplex_map::Simplex_ptr& s2) const { if (s1->size() != s2->size()) return false; return included(*s1,*s2); // inclusion tests equality for same size simplices } -std::size_t Sptr_hash::operator()(const Simplex_ptr& s) const { +std::size_t Toplex_map::Sptr_hash::operator()(const Toplex_map::Simplex_ptr& s) const { std::hash h_f; //double hash works better than int hash size_t h = 0; - for(const Vertex& v : *s) + for(const Toplex_map::Vertex& v : *s) h += h_f(static_cast(v)); return h; } template -Simplex_ptr get_key(const Input_vertex_range &vertex_range){ - Simplex s(vertex_range.begin(), vertex_range.end()); - return std::make_shared(s); +Toplex_map::Simplex_ptr get_key(const Input_vertex_range &vertex_range){ + Toplex_map::Simplex s(vertex_range.begin(), vertex_range.end()); + return std::make_shared(s); } template bool included(const Input_vertex_range1 &vertex_range1, const Input_vertex_range2 &vertex_range2){ - Simplex s2(vertex_range2.begin(), vertex_range2.end()); - for(const Vertex& v : vertex_range1) + Toplex_map::Simplex s2(vertex_range2.begin(), vertex_range2.end()); + for(const Toplex_map::Vertex& v : vertex_range1) if(!s2.count(v)) return false; return true; } template -std::vector facets(const Input_vertex_range &vertex_range){ - std::vector facets; - Simplex f(vertex_range.begin(), vertex_range.end()); - for(const Vertex& v : vertex_range){ +std::vector facets(const Input_vertex_range &vertex_range){ + std::vector facets; + Toplex_map::Simplex f(vertex_range.begin(), vertex_range.end()); + for(const Toplex_map::Vertex& v : vertex_range){ f.erase(v); facets.emplace_back(f); f.insert(v); -- cgit v1.2.3 From 6485e6957ef3c9310f618db6caaf2858cc56db66 Mon Sep 17 00:00:00 2001 From: fgodi Date: Mon, 8 Jan 2018 10:57:04 +0000 Subject: test name git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3115 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4d65b9218d81a3f7e32dd873ba8eb0d5e6524095 --- src/Toplex_map/doc/Intro_Toplex_map.h | 5 +++++ src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 12 ---------- src/Toplex_map/test/CMakeLists.txt | 2 +- src/Toplex_map/test/toplex_map_unit_test.cpp | 28 ++---------------------- 4 files changed, 8 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h index 6f4c1a1b..e3f18b32 100644 --- a/src/Toplex_map/doc/Intro_Toplex_map.h +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -49,6 +49,11 @@ namespace Gudhi { * * \image html map.png * + * The performances are a lot better than in simplex tree as soon you use maximal simplices and not simplices, + * here the construction of a strong witness complex of a point set with growing parameter : + * + * \image html graph.png + * */ /** @} */ // end defgroup toplex_map diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index ea5ac618..abd815f9 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -31,18 +31,6 @@ struct Visitor { class Fake_simplex_tree : public Filtered_toplex_map { public: - /** Vertex is the type of vertices. - * \ingroup toplex_map */ - typedef Toplex_map::Vertex Vertex; - - /** Simplex is the type of simplices. - * \ingroup toplex_map */ - typedef Toplex_map::Simplex Simplex; - - /** The type of the pointers to maximal simplices. - * \ingroup toplex_map */ - typedef Toplex_map::Simplex_ptr Simplex_ptr; - /** The type of the sets of Simplex_ptr. * \ingroup toplex_map */ typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt index 25fcabac..5ed55e97 100644 --- a/src/Toplex_map/test/CMakeLists.txt +++ b/src/Toplex_map/test/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.6) project(Toplex_map_tests) -add_executable ( ToplexMapUT test.cpp ) +add_executable ( ToplexMapUT toplex_map_unit_test.cpp ) target_link_libraries(ToplexMapUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index 3f4d96c2..b7a9251c 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -9,6 +8,8 @@ using namespace Gudhi; +typedef Toplex_map::Vertex Vertex; + std::vector sigma1 = {1, 2, 3, 4}; std::vector sigma2 = {5, 2, 3, 6}; std::vector sigma3 = {5}; @@ -33,18 +34,6 @@ BOOST_AUTO_TEST_CASE(toplexmap) { BOOST_CHECK(!K.membership(sigma6)); } -BOOST_AUTO_TEST_CASE(ltoplexmap) { - Lazy_Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma6); - K.insert_simplex(sigma7); - BOOST_CHECK(K.membership(sigma4)); - BOOST_CHECK(!K.membership(sigma5)); - K.contraction(4,5); - BOOST_CHECK(!K.membership(sigma6)); -} BOOST_AUTO_TEST_CASE(ftoplexmap) { Filtered_toplex_map K; @@ -56,16 +45,3 @@ BOOST_AUTO_TEST_CASE(ftoplexmap) { BOOST_CHECK(K.filtration(sigma3)==1.); } -/* -BOOST_AUTO_TEST_CASE(toplexmap_candidates) { - Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.remove_simplex(sigma1); - K.remove_simplex(sigma2); - auto c = K.candidates(); - BOOST_CHECK(c.count(get_key(sigma1))); - BOOST_CHECK(c.count(get_key(sigma2))); - BOOST_CHECK(c.size()==2); -} -*/ -- cgit v1.2.3 From 7f3ea79d26c78c8b2107a6a85feba933bd5512ac Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 27 Mar 2018 18:46:18 +0000 Subject: sb_wrapper working git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3308 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c7400a11583b8b67483974664e410f4c77232fb1 --- .../example/example_rips_complex_from_fvecs.cpp | 8 +++++--- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 17 +++++++++++------ src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 10 +++++----- src/Toplex_map/include/gudhi/Toplex_map.h | 7 ++++--- src/Toplex_map/test/toplex_map_unit_test.cpp | 2 ++ .../example/example_strong_witness_complex_fvecs.cpp | 8 +++++--- src/common/doc/main_page.h | 17 +++++++++++++++++ 7 files changed, 49 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp index 5e7667bd..1b683326 100644 --- a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp @@ -1,10 +1,11 @@ #include -// to construct Rips_complex from a fvecs file of points #include #include +#include #include #include + #include #include @@ -30,7 +31,8 @@ int main(int argc, char **argv) { using K = CGAL::Epick_d; using Point = typename K::Point_d; //using Simplex_tree = Gudhi::Simplex_tree<>; - using Simplex_tree = Gudhi::Fake_simplex_tree; + //using Simplex_tree = Gudhi::Fake_simplex_tree; + using Simplex_tree = Gudhi::Sb_wrapper; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; using Point_vector = std::vector; @@ -52,7 +54,7 @@ int main(int argc, char **argv) { end = clock(); std::cout << "Strong witness complex took "<< static_cast(end - start) / CLOCKS_PER_SEC << " s." << std::endl; - std::cout << "Rips complex is of dimension " << stree.dimension() << " - " << stree.num_simplices() << " simplices." << std::endl; + //std::cout << "Rips complex is of dimension " << stree.dimension() << " - " << stree.num_simplices() << " simplices." << std::endl; return 0; } diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h index abd815f9..55955e7b 100644 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h @@ -31,9 +31,6 @@ struct Visitor { class Fake_simplex_tree : public Filtered_toplex_map { public: - /** The type of the sets of Simplex_ptr. - * \ingroup toplex_map */ - typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; /** Handle type to a vertex contained in the simplicial complex. * \ingroup toplex_map */ @@ -87,6 +84,8 @@ public: * \ingroup toplex_map */ std::vector skeleton_simplex_range(int d) const; + Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); + protected: @@ -99,14 +98,14 @@ protected: template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(nan(""),Toplex_map()); + toplex_maps.emplace(nan(""), new Toplex_map()); using vertex_iterator = typename boost::graph_traits::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(""))))); + bron_kerbosch_all_cliques(skel_graph, Visitor(this->toplex_maps.at(nan("")))); } void Fake_simplex_tree::expansion(int max_dim){} @@ -150,7 +149,7 @@ Toplex_map::Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) co std::vector Fake_simplex_tree::max_simplices() const{ std::vector max_s; for(auto kv : toplex_maps) - for(const Toplex_map::Simplex_ptr& sptr : kv.second.maximal_cofaces(Simplex())) + for(const Toplex_map::Simplex_ptr& sptr : kv.second->maximal_cofaces(Simplex())) max_s.emplace_back(*sptr); return max_s; } @@ -178,6 +177,12 @@ std::vector Fake_simplex_tree::skeleton_simplex_range(int d 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,true); + return y; +} + } //namespace Gudhi #endif /* FAKE_SIMPLEX_TREE_H */ diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index 379c65dd..a3653acd 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -50,15 +50,15 @@ public: bool membership(const Input_vertex_range &vertex_range) const; protected: - std::map toplex_maps; + std::map toplex_maps; }; template std::pair Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ Simplex s(vertex_range.begin(),vertex_range.end()); if(membership(s)) return make_pair(s,false); - if(!toplex_maps.count(f)) toplex_maps.emplace(f,Toplex_map()); - toplex_maps.at(f).insert_simplex(vertex_range); + if(!toplex_maps.count(f)) toplex_maps.emplace(f,new Toplex_map()); + toplex_maps.at(f)->insert_simplex(vertex_range); return make_pair(s,true); } @@ -66,7 +66,7 @@ std::pair Filtered_toplex_map::insert_simplex_and_sub template Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ for(auto kv : toplex_maps) - if(kv.second.membership(vertex_range)) + if(kv.second->membership(vertex_range)) return kv.first; //min only because a map is ordered return nan(""); } @@ -74,7 +74,7 @@ Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Inpu template bool Filtered_toplex_map::membership(const Input_vertex_range &vertex_range) const{ for(auto kv : toplex_maps) - if(kv.second.membership(vertex_range)) + if(kv.second->membership(vertex_range)) return true; return false; } diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 00127baf..ccea34d5 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -69,7 +69,7 @@ public: * The edge has to verify the link condition if you want to preserve topology. * Returns the remaining vertex. * \ingroup toplex_map */ - Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); + Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y, bool force=false); /** Adds the given simplex to the complex. * The simplex must not have neither maximal face nor coface in the complex. @@ -196,17 +196,18 @@ Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range return cofaces; } -Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y){ +Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y, bool force){ if(!t0.count(x)) return y; if(!t0.count(y)) return x; int k, d; - if(t0.at(x).size() > t0.at(y).size()) + if(force || (t0.at(x).size() > t0.at(y).size())) k=x, d=y; else k=y, d=x; for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ //Copy constructor needed because the set is modified Simplex sigma(*sptr); + Simplex s; s.insert(2); erase_maximal(sptr); sigma.erase(d); sigma.insert(k); diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index b7a9251c..b714cd2a 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -1,6 +1,8 @@ #include #include #include +#include + #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "toplex map" diff --git a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp index a8e16fb0..9f5b32c4 100644 --- a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp +++ b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -51,7 +52,8 @@ int main(int argc, char * const argv[]) { double alpha2 = atof(argv[3]); clock_t start, end; //Gudhi::Simplex_tree<> simplex_tree; - Gudhi::Fake_simplex_tree simplex_tree; + //Gudhi::Fake_simplex_tree simplex_tree; + Gudhi::Sb_wrapper simplex_tree; // Read the point file Point_vector point_vector, landmarks; @@ -73,7 +75,7 @@ int main(int argc, char * const argv[]) { end = clock(); std::cout << "Strong witness complex took " << static_cast(end - start) / CLOCKS_PER_SEC << " s. \n"; - std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << std::endl; - std::cout << "Max dimension is : " << simplex_tree.dimension() << std::endl; +// std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << std::endl; + // std::cout << "Max dimension is : " << simplex_tree.dimension() << std::endl; } diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index d6569f0c..71655824 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -133,6 +133,23 @@ + \subsection ToplexMapDataStructure Toplex Map + \image html "map.png" "Toplex map representation" + + + + + + \subsection WitnessComplexDataStructure Witness complex \image html "Witness_complex_representation.png" "Witness complex representation"
+ Author: François Godi
+ Introduced in: GUDHI 2.1.0
+ Copyright: GPL v3
+
+ The Toplex map data structure is composed firstly of a raw storage of toplices (the maximal simplices) + and secondly of a map which associate any vertex to a set of pointers toward all toplices + containing this vertex. + User manual: \ref toplex_map - Reference manual: Gudhi::Toplex_map +
-- cgit v1.2.3 From 7ffe37e7d0aa9d9977e29f6bb05637dc0f18dc74 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 29 Mar 2018 09:36:23 +0000 Subject: wrappers repertory git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3312 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b93766b7d2d49c7b55ddfec57ae400951fc71f82 --- src/Toplex_map/include/gudhi/Fake_simplex_tree.h | 189 --------------------- .../include/gudhi/wrappers/Fake_simplex_tree.h | 189 +++++++++++++++++++++ src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h | 109 ++++++++++++ 3 files changed, 298 insertions(+), 189 deletions(-) delete mode 100644 src/Toplex_map/include/gudhi/Fake_simplex_tree.h create mode 100644 src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h create mode 100644 src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/Fake_simplex_tree.h deleted file mode 100644 index 55955e7b..00000000 --- a/src/Toplex_map/include/gudhi/Fake_simplex_tree.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef FAKE_SIMPLEX_TREE_H -#define FAKE_SIMPLEX_TREE_H - -#include - -#include -#include - -#include -#include - -namespace Gudhi { - -struct Visitor { - Toplex_map* tm; - - Visitor(Toplex_map* tm) - :tm(tm) - {} - - template - 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 - 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 max_simplices() const; - - /** Returns all the simplices, of max dimension d if a parameter d is given. - * \ingroup toplex_map */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - - /** Returns all the simplices of max dimension d - * \ingroup toplex_map */ - std::vector 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 - bool all_facets_inside(const Input_vertex_range &vertex_range) const; - -}; - -template -void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(nan(""), new Toplex_map()); - using vertex_iterator = typename boost::graph_traits::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 -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 filtration_simplex_range().size(); - return max_simplices().size(); -} - -std::size_t Fake_simplex_tree::num_vertices() const { - std::unordered_set 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 Fake_simplex_tree::max_simplices() const{ - std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ - std::vector m = max_simplices(); - std::vector 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 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,true); - return y; -} - -} //namespace Gudhi - -#endif /* FAKE_SIMPLEX_TREE_H */ - diff --git a/src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h new file mode 100644 index 00000000..55955e7b --- /dev/null +++ b/src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h @@ -0,0 +1,189 @@ +#ifndef FAKE_SIMPLEX_TREE_H +#define FAKE_SIMPLEX_TREE_H + +#include + +#include +#include + +#include +#include + +namespace Gudhi { + +struct Visitor { + Toplex_map* tm; + + Visitor(Toplex_map* tm) + :tm(tm) + {} + + template + 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 + 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 max_simplices() const; + + /** Returns all the simplices, of max dimension d if a parameter d is given. + * \ingroup toplex_map */ + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + + /** Returns all the simplices of max dimension d + * \ingroup toplex_map */ + std::vector 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 + bool all_facets_inside(const Input_vertex_range &vertex_range) const; + +}; + +template +void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ + toplex_maps.emplace(nan(""), new Toplex_map()); + using vertex_iterator = typename boost::graph_traits::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 +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 filtration_simplex_range().size(); + return max_simplices().size(); +} + +std::size_t Fake_simplex_tree::num_vertices() const { + std::unordered_set 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 Fake_simplex_tree::max_simplices() const{ + std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ + std::vector m = max_simplices(); + std::vector 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 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,true); + return y; +} + +} //namespace Gudhi + +#endif /* FAKE_SIMPLEX_TREE_H */ + diff --git a/src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h b/src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h new file mode 100644 index 00000000..0bdf7b9c --- /dev/null +++ b/src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h @@ -0,0 +1,109 @@ +#include + +#ifndef SKELETON_BLOCKER_WRAPPER_H_ +#define SKELETON_BLOCKER_WRAPPER_H_ + +namespace Gudhi { + +class Sb_wrapper{ + +public: + + typedef Gudhi::skeleton_blocker::Skeleton_blocker_simple_traits Traits; + typedef Gudhi::skeleton_blocker::Skeleton_blocker_complex Complex; + + typedef Complex::Vertex_handle Vertex_handle; + + typedef Complex::Simplex Simplex; + + typedef Toplex_map::Vertex Vertex; + + typedef Toplex_map::Simplex_ptr Simplex_ptr; + + typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + + typedef double Filtration_value; + + template + std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double); + + template + bool membership(const Input_vertex_range &vertex_range) const; + + 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. */ + template + void insert_graph(const OneSkeletonGraph& skel_graph); + + /** Do actually nothing. */ + void expansion(int max_dim); + + /** Returns the number of vertices stored i.e. the number of max simplices */ + std::size_t num_vertices() const; + + /** Returns the dimension of the complex. */ + std::size_t dimension() const; + + /** Returns the dimension of a given simplex in the complex. */ + std::size_t dimension(Simplex_ptr& sptr) const; + + /** Returns the number of simplices stored i.e. the number of maximal simplices. */ + std::size_t num_simplices() const; + + /** Returns a range over the vertices of a simplex. */ + Toplex_map::Simplex simplex_vertex_range(const Simplex& s) const; + + /** Returns a set of all maximal (critical if there is filtration values) simplices. */ + std::vector max_simplices() const; + + /** Returns all the simplices, of max dimension d if a parameter d is given. */ + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + + /** Returns all the simplices of max dimension d */ + std::vector skeleton_simplex_range(int d) const; + +private: + + Complex sb; + +}; + + +template +void Sb_wrapper::insert_graph(const OneSkeletonGraph& skel_graph){ + using vertex_iterator = typename boost::graph_traits::vertex_iterator; + vertex_iterator vi, vi_end; + // for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) + // insert_vertex(*vi); + //edges +} + +void Sb_wrapper::expansion(int max_dim){} + +template +std::pair Sb_wrapper::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double){ + Complex::Simplex s; + for (auto v : vertex_range) + s.add_vertex(Vertex_handle(v)); + if(sb.contains(s)) + return std::make_pair(false,false); + sb.add_simplex(s); + return std::make_pair(true,true); +} + +std::size_t Sb_wrapper::num_vertices() const{ + std::size_t num_vertices = 0; + for(auto v : sb.vertex_range()) + ++num_vertices; + return num_vertices; +} + + + +} + +#endif -- cgit v1.2.3 From 1c2d52705af9ae38cba9401bff66d9e8095d0c9e Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 29 Mar 2018 09:41:34 +0000 Subject: names git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3313 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a2d37ef72c86e5050408496fe1620a69c6c55242 --- src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h | 189 +++++++++++++++++++++ src/Toplex_map/include/gudhi/sb_to_st_wrapper.h | 109 ++++++++++++ .../include/gudhi/wrappers/Fake_simplex_tree.h | 189 --------------------- src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h | 109 ------------ 4 files changed, 298 insertions(+), 298 deletions(-) create mode 100644 src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h create mode 100644 src/Toplex_map/include/gudhi/sb_to_st_wrapper.h delete mode 100644 src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h delete mode 100644 src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h b/src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h new file mode 100644 index 00000000..55955e7b --- /dev/null +++ b/src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h @@ -0,0 +1,189 @@ +#ifndef FAKE_SIMPLEX_TREE_H +#define FAKE_SIMPLEX_TREE_H + +#include + +#include +#include + +#include +#include + +namespace Gudhi { + +struct Visitor { + Toplex_map* tm; + + Visitor(Toplex_map* tm) + :tm(tm) + {} + + template + 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 + 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 max_simplices() const; + + /** Returns all the simplices, of max dimension d if a parameter d is given. + * \ingroup toplex_map */ + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + + /** Returns all the simplices of max dimension d + * \ingroup toplex_map */ + std::vector 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 + bool all_facets_inside(const Input_vertex_range &vertex_range) const; + +}; + +template +void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ + toplex_maps.emplace(nan(""), new Toplex_map()); + using vertex_iterator = typename boost::graph_traits::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 +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 filtration_simplex_range().size(); + return max_simplices().size(); +} + +std::size_t Fake_simplex_tree::num_vertices() const { + std::unordered_set 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 Fake_simplex_tree::max_simplices() const{ + std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ + std::vector m = max_simplices(); + std::vector 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 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,true); + return y; +} + +} //namespace Gudhi + +#endif /* FAKE_SIMPLEX_TREE_H */ + diff --git a/src/Toplex_map/include/gudhi/sb_to_st_wrapper.h b/src/Toplex_map/include/gudhi/sb_to_st_wrapper.h new file mode 100644 index 00000000..0bdf7b9c --- /dev/null +++ b/src/Toplex_map/include/gudhi/sb_to_st_wrapper.h @@ -0,0 +1,109 @@ +#include + +#ifndef SKELETON_BLOCKER_WRAPPER_H_ +#define SKELETON_BLOCKER_WRAPPER_H_ + +namespace Gudhi { + +class Sb_wrapper{ + +public: + + typedef Gudhi::skeleton_blocker::Skeleton_blocker_simple_traits Traits; + typedef Gudhi::skeleton_blocker::Skeleton_blocker_complex Complex; + + typedef Complex::Vertex_handle Vertex_handle; + + typedef Complex::Simplex Simplex; + + typedef Toplex_map::Vertex Vertex; + + typedef Toplex_map::Simplex_ptr Simplex_ptr; + + typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + + typedef double Filtration_value; + + template + std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double); + + template + bool membership(const Input_vertex_range &vertex_range) const; + + 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. */ + template + void insert_graph(const OneSkeletonGraph& skel_graph); + + /** Do actually nothing. */ + void expansion(int max_dim); + + /** Returns the number of vertices stored i.e. the number of max simplices */ + std::size_t num_vertices() const; + + /** Returns the dimension of the complex. */ + std::size_t dimension() const; + + /** Returns the dimension of a given simplex in the complex. */ + std::size_t dimension(Simplex_ptr& sptr) const; + + /** Returns the number of simplices stored i.e. the number of maximal simplices. */ + std::size_t num_simplices() const; + + /** Returns a range over the vertices of a simplex. */ + Toplex_map::Simplex simplex_vertex_range(const Simplex& s) const; + + /** Returns a set of all maximal (critical if there is filtration values) simplices. */ + std::vector max_simplices() const; + + /** Returns all the simplices, of max dimension d if a parameter d is given. */ + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + + /** Returns all the simplices of max dimension d */ + std::vector skeleton_simplex_range(int d) const; + +private: + + Complex sb; + +}; + + +template +void Sb_wrapper::insert_graph(const OneSkeletonGraph& skel_graph){ + using vertex_iterator = typename boost::graph_traits::vertex_iterator; + vertex_iterator vi, vi_end; + // for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) + // insert_vertex(*vi); + //edges +} + +void Sb_wrapper::expansion(int max_dim){} + +template +std::pair Sb_wrapper::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double){ + Complex::Simplex s; + for (auto v : vertex_range) + s.add_vertex(Vertex_handle(v)); + if(sb.contains(s)) + return std::make_pair(false,false); + sb.add_simplex(s); + return std::make_pair(true,true); +} + +std::size_t Sb_wrapper::num_vertices() const{ + std::size_t num_vertices = 0; + for(auto v : sb.vertex_range()) + ++num_vertices; + return num_vertices; +} + + + +} + +#endif diff --git a/src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h b/src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h deleted file mode 100644 index 55955e7b..00000000 --- a/src/Toplex_map/include/gudhi/wrappers/Fake_simplex_tree.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef FAKE_SIMPLEX_TREE_H -#define FAKE_SIMPLEX_TREE_H - -#include - -#include -#include - -#include -#include - -namespace Gudhi { - -struct Visitor { - Toplex_map* tm; - - Visitor(Toplex_map* tm) - :tm(tm) - {} - - template - 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 - 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 max_simplices() const; - - /** Returns all the simplices, of max dimension d if a parameter d is given. - * \ingroup toplex_map */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - - /** Returns all the simplices of max dimension d - * \ingroup toplex_map */ - std::vector 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 - bool all_facets_inside(const Input_vertex_range &vertex_range) const; - -}; - -template -void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(nan(""), new Toplex_map()); - using vertex_iterator = typename boost::graph_traits::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 -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 filtration_simplex_range().size(); - return max_simplices().size(); -} - -std::size_t Fake_simplex_tree::num_vertices() const { - std::unordered_set 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 Fake_simplex_tree::max_simplices() const{ - std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ - std::vector m = max_simplices(); - std::vector 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 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,true); - return y; -} - -} //namespace Gudhi - -#endif /* FAKE_SIMPLEX_TREE_H */ - diff --git a/src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h b/src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h deleted file mode 100644 index 0bdf7b9c..00000000 --- a/src/Toplex_map/include/gudhi/wrappers/Sb_wrapper.h +++ /dev/null @@ -1,109 +0,0 @@ -#include - -#ifndef SKELETON_BLOCKER_WRAPPER_H_ -#define SKELETON_BLOCKER_WRAPPER_H_ - -namespace Gudhi { - -class Sb_wrapper{ - -public: - - typedef Gudhi::skeleton_blocker::Skeleton_blocker_simple_traits Traits; - typedef Gudhi::skeleton_blocker::Skeleton_blocker_complex Complex; - - typedef Complex::Vertex_handle Vertex_handle; - - typedef Complex::Simplex Simplex; - - typedef Toplex_map::Vertex Vertex; - - typedef Toplex_map::Simplex_ptr Simplex_ptr; - - typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; - - typedef double Filtration_value; - - template - std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double); - - template - bool membership(const Input_vertex_range &vertex_range) const; - - 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. */ - template - void insert_graph(const OneSkeletonGraph& skel_graph); - - /** Do actually nothing. */ - void expansion(int max_dim); - - /** Returns the number of vertices stored i.e. the number of max simplices */ - std::size_t num_vertices() const; - - /** Returns the dimension of the complex. */ - std::size_t dimension() const; - - /** Returns the dimension of a given simplex in the complex. */ - std::size_t dimension(Simplex_ptr& sptr) const; - - /** Returns the number of simplices stored i.e. the number of maximal simplices. */ - std::size_t num_simplices() const; - - /** Returns a range over the vertices of a simplex. */ - Toplex_map::Simplex simplex_vertex_range(const Simplex& s) const; - - /** Returns a set of all maximal (critical if there is filtration values) simplices. */ - std::vector max_simplices() const; - - /** Returns all the simplices, of max dimension d if a parameter d is given. */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - - /** Returns all the simplices of max dimension d */ - std::vector skeleton_simplex_range(int d) const; - -private: - - Complex sb; - -}; - - -template -void Sb_wrapper::insert_graph(const OneSkeletonGraph& skel_graph){ - using vertex_iterator = typename boost::graph_traits::vertex_iterator; - vertex_iterator vi, vi_end; - // for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) - // insert_vertex(*vi); - //edges -} - -void Sb_wrapper::expansion(int max_dim){} - -template -std::pair Sb_wrapper::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double){ - Complex::Simplex s; - for (auto v : vertex_range) - s.add_vertex(Vertex_handle(v)); - if(sb.contains(s)) - return std::make_pair(false,false); - sb.add_simplex(s); - return std::make_pair(true,true); -} - -std::size_t Sb_wrapper::num_vertices() const{ - std::size_t num_vertices = 0; - for(auto v : sb.vertex_range()) - ++num_vertices; - return num_vertices; -} - - - -} - -#endif -- cgit v1.2.3 From 552ce6a0b42af77e210d252d8e8c5b25138a518b Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 29 Mar 2018 09:56:16 +0000 Subject: msg git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3314 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2591252fddbe57daee885ad29e5df242b33f5f52 --- src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h | 189 ----------------------- src/Toplex_map/include/gudhi/sb_to_st_wrapper.h | 109 ------------- 2 files changed, 298 deletions(-) delete mode 100644 src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h delete mode 100644 src/Toplex_map/include/gudhi/sb_to_st_wrapper.h (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h b/src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h deleted file mode 100644 index 55955e7b..00000000 --- a/src/Toplex_map/include/gudhi/ftm_to_st_wrapper.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef FAKE_SIMPLEX_TREE_H -#define FAKE_SIMPLEX_TREE_H - -#include - -#include -#include - -#include -#include - -namespace Gudhi { - -struct Visitor { - Toplex_map* tm; - - Visitor(Toplex_map* tm) - :tm(tm) - {} - - template - 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 - 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 max_simplices() const; - - /** Returns all the simplices, of max dimension d if a parameter d is given. - * \ingroup toplex_map */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - - /** Returns all the simplices of max dimension d - * \ingroup toplex_map */ - std::vector 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 - bool all_facets_inside(const Input_vertex_range &vertex_range) const; - -}; - -template -void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(nan(""), new Toplex_map()); - using vertex_iterator = typename boost::graph_traits::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 -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 filtration_simplex_range().size(); - return max_simplices().size(); -} - -std::size_t Fake_simplex_tree::num_vertices() const { - std::unordered_set 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 Fake_simplex_tree::max_simplices() const{ - std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ - std::vector m = max_simplices(); - std::vector 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 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,true); - return y; -} - -} //namespace Gudhi - -#endif /* FAKE_SIMPLEX_TREE_H */ - diff --git a/src/Toplex_map/include/gudhi/sb_to_st_wrapper.h b/src/Toplex_map/include/gudhi/sb_to_st_wrapper.h deleted file mode 100644 index 0bdf7b9c..00000000 --- a/src/Toplex_map/include/gudhi/sb_to_st_wrapper.h +++ /dev/null @@ -1,109 +0,0 @@ -#include - -#ifndef SKELETON_BLOCKER_WRAPPER_H_ -#define SKELETON_BLOCKER_WRAPPER_H_ - -namespace Gudhi { - -class Sb_wrapper{ - -public: - - typedef Gudhi::skeleton_blocker::Skeleton_blocker_simple_traits Traits; - typedef Gudhi::skeleton_blocker::Skeleton_blocker_complex Complex; - - typedef Complex::Vertex_handle Vertex_handle; - - typedef Complex::Simplex Simplex; - - typedef Toplex_map::Vertex Vertex; - - typedef Toplex_map::Simplex_ptr Simplex_ptr; - - typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; - - typedef double Filtration_value; - - template - std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double); - - template - bool membership(const Input_vertex_range &vertex_range) const; - - 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. */ - template - void insert_graph(const OneSkeletonGraph& skel_graph); - - /** Do actually nothing. */ - void expansion(int max_dim); - - /** Returns the number of vertices stored i.e. the number of max simplices */ - std::size_t num_vertices() const; - - /** Returns the dimension of the complex. */ - std::size_t dimension() const; - - /** Returns the dimension of a given simplex in the complex. */ - std::size_t dimension(Simplex_ptr& sptr) const; - - /** Returns the number of simplices stored i.e. the number of maximal simplices. */ - std::size_t num_simplices() const; - - /** Returns a range over the vertices of a simplex. */ - Toplex_map::Simplex simplex_vertex_range(const Simplex& s) const; - - /** Returns a set of all maximal (critical if there is filtration values) simplices. */ - std::vector max_simplices() const; - - /** Returns all the simplices, of max dimension d if a parameter d is given. */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - - /** Returns all the simplices of max dimension d */ - std::vector skeleton_simplex_range(int d) const; - -private: - - Complex sb; - -}; - - -template -void Sb_wrapper::insert_graph(const OneSkeletonGraph& skel_graph){ - using vertex_iterator = typename boost::graph_traits::vertex_iterator; - vertex_iterator vi, vi_end; - // for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) - // insert_vertex(*vi); - //edges -} - -void Sb_wrapper::expansion(int max_dim){} - -template -std::pair Sb_wrapper::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, double){ - Complex::Simplex s; - for (auto v : vertex_range) - s.add_vertex(Vertex_handle(v)); - if(sb.contains(s)) - return std::make_pair(false,false); - sb.add_simplex(s); - return std::make_pair(true,true); -} - -std::size_t Sb_wrapper::num_vertices() const{ - std::size_t num_vertices = 0; - for(auto v : sb.vertex_range()) - ++num_vertices; - return num_vertices; -} - - - -} - -#endif -- cgit v1.2.3 From acd156a740dce76d3ea5ea569e56f7a30c81a046 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 29 Mar 2018 09:58:24 +0000 Subject: fvec simplex_tree git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3315 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: eb72df78970030b4835b020af679b5de5b2c2356 --- src/Rips_complex/example/example_rips_complex_from_fvecs.cpp | 4 ++-- src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp index 1b683326..e11dc3ea 100644 --- a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp @@ -30,9 +30,9 @@ int main(int argc, char **argv) { // Type definitions using K = CGAL::Epick_d; using Point = typename K::Point_d; - //using Simplex_tree = Gudhi::Simplex_tree<>; + using Simplex_tree = Gudhi::Simplex_tree<>; //using Simplex_tree = Gudhi::Fake_simplex_tree; - using Simplex_tree = Gudhi::Sb_wrapper; + //using Simplex_tree = Gudhi::Sb_wrapper; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; using Point_vector = std::vector; diff --git a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp index 9f5b32c4..5c431ec1 100644 --- a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp +++ b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp @@ -51,9 +51,9 @@ int main(int argc, char * const argv[]) { int nbL = atoi(argv[2]), lim_dim = atoi(argv[4]); double alpha2 = atof(argv[3]); clock_t start, end; - //Gudhi::Simplex_tree<> simplex_tree; + Gudhi::Simplex_tree<> simplex_tree; //Gudhi::Fake_simplex_tree simplex_tree; - Gudhi::Sb_wrapper simplex_tree; + //Gudhi::Sb_wrapper simplex_tree; // Read the point file Point_vector point_vector, landmarks; -- cgit v1.2.3 From 367ffaf3633eca5335b12d71b085a61b2818f7be Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 29 Mar 2018 10:07:50 +0000 Subject: compile git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3316 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f156ee6e355e93a362784a27b143c755e66e1045 --- src/Rips_complex/example/example_rips_complex_from_fvecs.cpp | 4 ++-- src/Tangential_complex/example/example_basic.cpp | 6 +++--- src/Toplex_map/test/toplex_map_unit_test.cpp | 2 -- .../example/example_strong_witness_complex_fvecs.cpp | 4 ++-- src/Witness_complex/example/example_strong_witness_complex_off.cpp | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp index e11dc3ea..40aab5dc 100644 --- a/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_fvecs.cpp @@ -1,7 +1,7 @@ #include #include -#include -#include +//#include +//#include #include #include diff --git a/src/Tangential_complex/example/example_basic.cpp b/src/Tangential_complex/example/example_basic.cpp index 39165397..ab35edf0 100644 --- a/src/Tangential_complex/example/example_basic.cpp +++ b/src/Tangential_complex/example/example_basic.cpp @@ -1,6 +1,6 @@ #include #include -#include +//#include #include @@ -38,8 +38,8 @@ int main(void) { tc.compute_tangential_complex(); // Export the TC into a Simplex_tree - //Gudhi::Simplex_tree<> stree; - Gudhi::Fake_simplex_tree stree; + Gudhi::Simplex_tree<> stree; + //Gudhi::Fake_simplex_tree stree; tc.create_complex(stree); // Display stats about inconsistencies diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index b714cd2a..95ee7a02 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #define BOOST_TEST_DYN_LINK diff --git a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp index 5c431ec1..3e0efa15 100644 --- a/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp +++ b/src/Witness_complex/example/example_strong_witness_complex_fvecs.cpp @@ -21,8 +21,8 @@ */ #include -#include -#include +//#include +//#include #include #include #include diff --git a/src/Witness_complex/example/example_strong_witness_complex_off.cpp b/src/Witness_complex/example/example_strong_witness_complex_off.cpp index 6292e248..f195953b 100644 --- a/src/Witness_complex/example/example_strong_witness_complex_off.cpp +++ b/src/Witness_complex/example/example_strong_witness_complex_off.cpp @@ -21,7 +21,7 @@ */ #include -#include +//#include #include #include #include -- cgit v1.2.3 From 75580c5ea4da0a2bc1a75424a9d36e25eabac8d8 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 29 Mar 2018 18:16:46 +0000 Subject: fvecs reader git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3321 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a57c3e9b3258a25ff1d59f0b8ce135ebb19188cf --- src/common/include/gudhi/Points_fvecs_reader.h | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/common/include/gudhi/Points_fvecs_reader.h (limited to 'src') diff --git a/src/common/include/gudhi/Points_fvecs_reader.h b/src/common/include/gudhi/Points_fvecs_reader.h new file mode 100644 index 00000000..eb03bb72 --- /dev/null +++ b/src/common/include/gudhi/Points_fvecs_reader.h @@ -0,0 +1,68 @@ +/* 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) 2015 INRIA Saclay (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 . + */ +#ifndef POINTS_FVECS_READER_H_ +#define POINTS_FVECS_READER_H_ + +namespace Gudhi { + +template +bool load_points_from_fvecs_file(const std::string &filename, OutputIteratorPoints points, int only_the_first_n_points = -1) +{ + typedef typename Kernel::Point_d Point; + + std::ifstream in(filename, std::ios::binary); + if (!in.is_open()) { + std::cerr << "Could not open '" << filename << "'" << std::endl; + return false; + } + + Kernel k; + unsigned long pt_dim = 0; + + in.read(reinterpret_cast(&pt_dim), 4); + std::vector current_pt; + current_pt.reserve(pt_dim); + for (int c = 0; !in.fail() && c != only_the_first_n_points; ++c) { + + for (int j = 0; j < pt_dim; ++j) + { + float coord = 0.f; + in.read(reinterpret_cast(&coord), 4); + current_pt.push_back(coord); + } + + *points++ = Point(current_pt.begin(), current_pt.end()); + current_pt.clear(); + in.read(reinterpret_cast(&pt_dim), 4); + } + +#ifdef DEBUG_TRACES + std::cerr << "'" << filename << "' loaded." << std::endl; +#endif + + return true; +} + + +} // namespace Gudhi + +#endif // POINTS_FVECS_READER_H_ -- cgit v1.2.3 From 5207236bc6cfacf1789b3eac99360a272a008678 Mon Sep 17 00:00:00 2001 From: fgodi Date: Mon, 23 Apr 2018 16:17:49 +0000 Subject: Lazy ré-ajouté MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3390 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f4b2cbaf62e0c43d29f8d52b7df45e62b52f067f --- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 236 +++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 src/Toplex_map/include/gudhi/Lazy_Toplex_map.h (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h new file mode 100644 index 00000000..481d33a1 --- /dev/null +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -0,0 +1,236 @@ +#ifndef LAZY_TOPLEX_MAP_H +#define LAZY_TOPLEX_MAP_H + +#include +#include + +namespace Gudhi { + +class Lazy_Toplex_map { + +public: + + /** Vertex is the type of vertices. + * \ingroup toplex_map */ + typedef Toplex_map::Vertex Vertex; + + /** Simplex is the type of simplices. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex Simplex; + + /** The type of the pointers to maximal simplices. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex_ptr Simplex_ptr; + + /** The type of the sets of Simplex_ptr. + * \ingroup toplex_map */ + typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + + template + void insert_max_simplex(const Input_vertex_range &vertex_range); + template + bool insert_simplex(const Input_vertex_range &vertex_range); + template + void remove_simplex(const Input_vertex_range &vertex_range); + + template + bool membership(const Input_vertex_range &vertex_range); + template + bool all_facets_inside(const Input_vertex_range &vertex_range); + + Vertex contraction(const Vertex x, const Vertex y); + + std::size_t num_simplices() const; + + std::unordered_map gamma0_lbounds; + +private: + template + void erase_max(const Input_vertex_range &vertex_range); + template + Vertex best_index(const Input_vertex_range &vertex_range); + void clean(const Vertex v); + + std::unordered_map t0; + bool empty_toplex; // Is the empty simplex a toplex ? + + typedef boost::heap::fibonacci_heap> PriorityQueue; + PriorityQueue cleaning_priority; + std::unordered_map cp_handles; + + std::size_t get_gamma0_lbound(const Vertex v) const; + + std::size_t size_lbound = 0; + std::size_t size = 0; + + const double alpha = 2; //time + const double betta = 4; //memory +}; + +template +void Lazy_Toplex_map::insert_max_simplex(const Input_vertex_range &vertex_range){ + for(const Vertex& v : vertex_range) + if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); + else gamma0_lbounds[v]++; + size_lbound++; + insert_simplex(vertex_range); +} + +template +bool Lazy_Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + empty_toplex = (sigma.size()==0); //vérifier la gestion de empty face + Simplex_ptr sptr = std::make_shared(sigma); + bool inserted = false; + for(const Vertex& v : sigma){ + if(!t0.count(v)){ + t0.emplace(v, Simplex_ptr_set()); + auto v_handle = cleaning_priority.push(std::make_pair(0, v)); + cp_handles.emplace(v, v_handle); + } + inserted = t0.at(v).emplace(sptr).second; + cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v),v)); + } + if(inserted) + size++; + if(size > (size_lbound+1) * betta) + clean(cleaning_priority.top().second); + return inserted; +} + +template +void Lazy_Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ + if(vertex_range.begin()==vertex_range.end()){ + t0.clear(); + gamma0_lbounds.clear(); + cleaning_priority.clear(); + size_lbound = 0; + size = 0; + empty_toplex = false; + } + else { + const Vertex& v = best_index(vertex_range); + //Copy constructor needed because the set is modified + if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) + if(included(vertex_range, *sptr)){ + erase_max(*sptr); + for(const Simplex& f : facets(vertex_range)) + insert_max_simplex(f); + } + } +} + +template +bool Lazy_Toplex_map::membership(const Input_vertex_range &vertex_range){ + if(t0.size()==0 && !empty_toplex) return false; //empty complex + if(vertex_range.begin()==vertex_range.end()) return true; //empty query simplex + Vertex v = best_index(vertex_range); + if(!t0.count(v)) return false; + for(const Simplex_ptr& sptr : t0.at(v)) + if(included(vertex_range, *sptr)) return true; + return false; +} + +template +bool Lazy_Toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + Vertex v = best_index(sigma); + if(!t0.count(v)) return false; + Simplex f = sigma; f.erase(v); + if(!membership(f)) return false; + std::unordered_set facets_inside; + for(const Simplex_ptr& sptr : t0.at(v)) + for(const Vertex& w : sigma){ + f = sigma; f.erase(w); + if(included(f, *sptr)) facets_inside.insert(w); + } + return facets_inside.size() == sigma.size() - 1; +} + +/* Returns the remaining vertex */ +Toplex_map::Vertex Lazy_Toplex_map::contraction(const Vertex x, const Vertex y){ + if(!t0.count(x)) return y; + if(!t0.count(y)) return x; + Vertex k, d; + if(t0.at(x).size() > t0.at(y).size()) + k=x, d=y; + else + k=y, d=x; + //Copy constructor needed because the set is modified + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ + Simplex sigma(*sptr); + erase_max(sigma); + sigma.erase(d); + sigma.insert(k); + insert_simplex(sigma); + } + t0.erase(d); + return k; +} + +/* No facets insert_simplexed */ +template +inline void Lazy_Toplex_map::erase_max(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + empty_toplex = false; + Simplex_ptr sptr = std::make_shared(sigma); + bool erased; + for(const Vertex& v : sigma){ + erased = t0.at(v).erase(sptr) > 0; + if(t0.at(v).size()==0) + t0.erase(v); + } + if (erased) + size--; +} + +template +Toplex_map::Vertex Lazy_Toplex_map::best_index(const Input_vertex_range &vertex_range){ + Simplex tau(vertex_range.begin(),vertex_range.end()); + std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; + for(const Vertex& v : tau) + if(!t0.count(v)) return v; + else if(t0.at(v).size() < min) + min = t0.at(v).size(), arg_min = v; + if(min > alpha * get_gamma0_lbound(arg_min)) + clean(arg_min); + return arg_min; +} + +std::size_t Lazy_Toplex_map::get_gamma0_lbound(const Vertex v) const{ + return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; +} + + +void Lazy_Toplex_map::clean(const Vertex v){ + Toplex_map toplices; + std::unordered_map> dsorted_simplices; + int max_dim = 0; + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ + if(sptr->size() > max_dim){ + for(int d = max_dim+1; d<=sptr->size(); d++) + dsorted_simplices.emplace(d, std::vector()); + max_dim = sptr->size(); + } + dsorted_simplices[sptr->size()].emplace_back(*sptr); + erase_max(*sptr); + } + for(int d = max_dim; d>=1; d--) + for(const Simplex &s : dsorted_simplices.at(d)) + if(!toplices.membership(s)) + toplices.insert_independent_simplex(s); + Simplex sv; sv.insert(v); + auto clean_cofaces = toplices.maximal_cofaces(sv); + size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); + gamma0_lbounds[v] = clean_cofaces.size(); + for(const Simplex_ptr& sptr : clean_cofaces) + insert_simplex(*sptr); +} + +std::size_t Lazy_Toplex_map::num_simplices() const{ + return size; +} + +} //namespace Gudhi + +#endif /* LAZY_TOPLEX_MAP_H */ -- cgit v1.2.3 From 2aa8114f1b8e55ef3433461c72f102868ce55866 Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 3 May 2018 13:02:44 +0000 Subject: compile on linux git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3410 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 01b43f553d2095f852bb40d15abe57aa91c8f3ff --- src/Toplex_map/benchmark/CMakeLists.txt | 4 + src/Toplex_map/benchmark/chrono.cpp | 137 +++++++++++++++++++++ src/Toplex_map/benchmarks/CMakeLists.txt | 4 - src/Toplex_map/benchmarks/chrono.cpp | 137 --------------------- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 4 +- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 1 + 6 files changed, 144 insertions(+), 143 deletions(-) create mode 100644 src/Toplex_map/benchmark/CMakeLists.txt create mode 100644 src/Toplex_map/benchmark/chrono.cpp delete mode 100644 src/Toplex_map/benchmarks/CMakeLists.txt delete mode 100644 src/Toplex_map/benchmarks/chrono.cpp (limited to 'src') diff --git a/src/Toplex_map/benchmark/CMakeLists.txt b/src/Toplex_map/benchmark/CMakeLists.txt new file mode 100644 index 00000000..2341fe06 --- /dev/null +++ b/src/Toplex_map/benchmark/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 2.6) +project(Toplex_map_examples) + +add_executable(chrono chrono.cpp) diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp new file mode 100644 index 00000000..10449b48 --- /dev/null +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -0,0 +1,137 @@ +#include +#include +#include + +#include +#include + +using namespace Gudhi; + +typedef Simplex typeVectorVertex; +typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +class ST_wrapper { + +public: + void insert_simplex(const Simplex& tau); + bool membership(const Simplex& tau); + Vertex contraction(const Vertex x, const Vertex y); + std::size_t num_simplices(); + +private: + Simplex_tree<> simplexTree; + void erase_max(const Simplex& sigma); +}; + +void ST_wrapper::insert_simplex(const Simplex& tau){ + simplexTree.insert_simplex_and_subfaces(tau); +} + +bool ST_wrapper::membership(const Simplex& tau) { + return simplexTree.find(tau) != simplexTree.null_simplex(); +} + +void ST_wrapper::erase_max(const Simplex& sigma){ + if(membership(sigma)) + simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); +} + +Vertex ST_wrapper::contraction(const Vertex x, const Vertex y){ + Simplex sx; sx.insert(x); + auto hx = simplexTree.find(sx); + if(hx != simplexTree.null_simplex()) + for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ + auto sr = simplexTree.simplex_vertex_range(h); + Simplex sigma(sr.begin(),sr.end()); + erase_max(sigma); + sigma.erase(x); + sigma.insert(y); + insert_simplex(sigma); + } + return y; +} + +std::size_t ST_wrapper::num_simplices(){ + return simplexTree.num_simplices(); +} + + + +int n = 300; + +int nb_insert_simplex1 = 3000; +int nb_membership1 = 4000; +int nb_contraction = 300; +int nb_insert_simplex2 = 3000; +int nb_membership2 = 400000; + +Simplex random_simplex(int n, int d){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1, n); + Simplex s; + while(s.size()!=d) + s.insert(dis(gen)); + return s; +} + +std::vector r_vector_simplices(int n, int max_d, int m){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1, max_d); + std::vector v; + for(int i=0; i +void chrono(int n, int d){ + complex_type K; + std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); + std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); + std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); + std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); + std::chrono::time_point start, end; + + for(const Simplex& s : simplices_insert_simplex1) + K.insert_simplex(s); + + for(const Simplex& s : simplices_membership1) + K.membership(s); + + start = std::chrono::system_clock::now(); + for(int i = 0; i<=nb_contraction; i++) + K.contraction(n-2*i,n-2*i-1); + end = std::chrono::system_clock::now(); + auto c3 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_insert_simplex2) + K.insert_simplex(s); + end = std::chrono::system_clock::now(); + auto c1 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_membership2) + K.membership(s); + end = std::chrono::system_clock::now(); + auto c2 = std::chrono::duration_cast(end-start).count(); + + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_simplices() << std::endl; +} + +int main(){ + for(int d=5;d<=40;d+=5){ + std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; + std::cout << "T Map \t \t"; + chrono(n,d); + std::cout << "Lazy \t \t"; + chrono(n,d); + if(d<=15){ + std::cout << "ST \t \t"; + chrono(n,d); + } + std::cout << std::endl; + } +} diff --git a/src/Toplex_map/benchmarks/CMakeLists.txt b/src/Toplex_map/benchmarks/CMakeLists.txt deleted file mode 100644 index 2341fe06..00000000 --- a/src/Toplex_map/benchmarks/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -cmake_minimum_required(VERSION 2.6) -project(Toplex_map_examples) - -add_executable(chrono chrono.cpp) diff --git a/src/Toplex_map/benchmarks/chrono.cpp b/src/Toplex_map/benchmarks/chrono.cpp deleted file mode 100644 index d93d1e1f..00000000 --- a/src/Toplex_map/benchmarks/chrono.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include - -#include -#include - -using namespace Gudhi; - -typedef Simplex typeVectorVertex; -typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - -class ST_wrapper { - -public: - void insert_simplex(const Simplex& tau); - bool membership(const Simplex& tau); - Vertex contraction(const Vertex x, const Vertex y); - std::size_t num_simplices(); - -private: - Simplex_tree<> simplexTree; - void erase_max(const Simplex& sigma); -}; - -void ST_wrapper::insert_simplex(const Simplex& tau){ - simplexTree.insert_simplex_and_subfaces(tau); -} - -bool ST_wrapper::membership(const Simplex& tau) { - return simplexTree.find(tau) != simplexTree.null_simplex(); -} - -void ST_wrapper::erase_max(const Simplex& sigma){ - if(membership(sigma)) - simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); -} - -Vertex ST_wrapper::contraction(const Vertex x, const Vertex y){ - Simplex sx; sx.insert(x); - auto hx = simplexTree.find(sx); - if(hx != simplexTree.null_simplex()) - for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ - auto sr = simplexTree.simplex_vertex_range(h); - Simplex sigma(sr.begin(),sr.end()); - erase_max(sigma); - sigma.erase(x); - sigma.insert(y); - insert_simplex(sigma); - } - return y; -} - -std::size_t ST_wrapper::num_simplices(){ - return simplexTree.num_simplices(); -} - - - -int n = 300; - -int nb_insert_simplex1 = 3000; -int nb_membership1 = 4000; -int nb_contraction = 300; -int nb_insert_simplex2 = 3000; -int nb_membership2 = 400000; - -Simplex random_simplex(int n, int d){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(1, n); - Simplex s; - while(s.size()!=d) - s.insert(dis(gen)); - return s; -} - -std::vector r_vector_simplices(int n, int max_d, int m){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(1, max_d); - std::vector v; - for(int i=0; i -void chrono(int n, int d){ - complex_type K; - std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); - std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); - std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); - std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); - std::chrono::time_point start, end; - - for(const Simplex& s : simplices_insert_simplex1) - K.insert_simplex(s); - - for(const Simplex& s : simplices_membership1) - K.membership(s); - - start = std::chrono::system_clock::now(); - for(int i = 0; i<=nb_contraction; i++) - K.contraction(n-2*i,n-2*i-1); - end = std::chrono::system_clock::now(); - auto c3 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_insert_simplex2) - K.insert_simplex(s); - end = std::chrono::system_clock::now(); - auto c1 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_membership2) - K.membership(s); - end = std::chrono::system_clock::now(); - auto c2 = std::chrono::duration_cast(end-start).count(); - - std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_simplices() << std::endl; -} - -int main(){ - for(int d=5;d<=40;d+=5){ - std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; - std::cout << "T Map \t \t"; - chrono(n,d); - std::cout << "Lazy \t \t"; - chrono(n,d); - if(d<=15){ - std::cout << "ST \t \t"; - chrono(n,d); - } - std::cout << std::endl; - } -} diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index a3653acd..ed65e36f 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -37,7 +37,7 @@ public: * in the Filtered_toplex_map. * \ingroup toplex_map */ template - std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = nan("")); + std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = std::numeric_limits::quiet_NaN()); /** Gives the filtration of the input simplex. * \ingroup toplex_map */ @@ -68,7 +68,7 @@ Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Inpu for(auto kv : toplex_maps) if(kv.second->membership(vertex_range)) return kv.first; //min only because a map is ordered - return nan(""); + return std::numeric_limits::quiet_NaN() ; } template diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 481d33a1..50785b5a 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -3,6 +3,7 @@ #include #include +#include namespace Gudhi { -- cgit v1.2.3 From b088d634d6d5496548d7feb93cbd1bce1ac94d6a Mon Sep 17 00:00:00 2001 From: fgodi Date: Thu, 3 May 2018 13:22:25 +0000 Subject: strange git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3411 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 68a8c63789279eab7c0bb08df74d3ed52d2a73dd --- src/Toplex_map/benchmark/chrono.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp index 10449b48..bbe28da0 100644 --- a/src/Toplex_map/benchmark/chrono.cpp +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -7,8 +7,8 @@ using namespace Gudhi; -typedef Simplex typeVectorVertex; -typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; +typedef Toplex_map::Vertex Vertex; +typedef Toplex_map::Simplex Simplex; class ST_wrapper { -- cgit v1.2.3 From 4ce8d6e4f0eb5d738dba039e0e66a3c7777a9d49 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 15 May 2018 11:56:06 +0000 Subject: toplex_map_chrono git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3438 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 196ab30aa05e434634f2c5c3149c13eb3b82bdca --- src/Toplex_map/benchmark/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/CMakeLists.txt b/src/Toplex_map/benchmark/CMakeLists.txt index 2341fe06..e4cfab6f 100644 --- a/src/Toplex_map/benchmark/CMakeLists.txt +++ b/src/Toplex_map/benchmark/CMakeLists.txt @@ -1,4 +1,4 @@ cmake_minimum_required(VERSION 2.6) project(Toplex_map_examples) -add_executable(chrono chrono.cpp) +add_executable(toplex_map_chrono chrono.cpp) -- cgit v1.2.3 From ebdfe5e949b684e88b725a755c3c80c6e9083ef6 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 15 May 2018 12:17:21 +0000 Subject: compile with gcc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3439 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9faf621edc02f2758cec654326a18ebfda07f546 --- src/Toplex_map/benchmark/chrono.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp index bbe28da0..e65dcba2 100644 --- a/src/Toplex_map/benchmark/chrono.cpp +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -68,7 +68,7 @@ int nb_membership2 = 400000; Simplex random_simplex(int n, int d){ std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(1, n); + std::uniform_int_distribution dis(1, n); Simplex s; while(s.size()!=d) s.insert(dis(gen)); @@ -78,7 +78,7 @@ Simplex random_simplex(int n, int d){ std::vector r_vector_simplices(int n, int max_d, int m){ std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(1, max_d); + std::uniform_int_distribution dis(1, max_d); std::vector v; for(int i=0; i Date: Tue, 15 May 2018 12:23:56 +0000 Subject: fake simplex tree in example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3440 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6703d83ee05c895fb08f2d8a46db758654f9eb8c --- src/Toplex_map/example/Simple_toplex_map.cpp | 2 +- src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/example/Simple_toplex_map.cpp b/src/Toplex_map/example/Simple_toplex_map.cpp index b165af8a..4fa735a6 100644 --- a/src/Toplex_map/example/Simple_toplex_map.cpp +++ b/src/Toplex_map/example/Simple_toplex_map.cpp @@ -21,7 +21,7 @@ */ #include -#include +#include "gudhi/Fake_simplex_tree.h" #include #include // for pair 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 index aad31554..3df0cbd9 100644 --- a/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp +++ b/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp @@ -21,7 +21,7 @@ */ #include -#include +#include "gudhi/Fake_simplex_tree.h" #include #include -- cgit v1.2.3 From 6a450d80816647cbd5a26fbe62b7573c5f7b7ec7 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 15 May 2018 12:24:18 +0000 Subject: fake simplex tree in example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3441 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7240acaf10216c579d0c395559e21287bbf96837 --- src/Toplex_map/example/Fake_simplex_tree.h | 194 +++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/Toplex_map/example/Fake_simplex_tree.h (limited to 'src') 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..8187e24e --- /dev/null +++ b/src/Toplex_map/example/Fake_simplex_tree.h @@ -0,0 +1,194 @@ +#ifndef FAKE_SIMPLEX_TREE_H +#define FAKE_SIMPLEX_TREE_H + +#include + +#include +#include + +#include +#include + +namespace Gudhi { + +struct Visitor { + Lazy_Toplex_map* tm; + + Visitor(Lazy_Toplex_map* tm) + :tm(tm) + {} + + template + 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 + 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 max_simplices() const; + + /** Returns all the simplices, of max dimension d if a parameter d is given. + * \ingroup toplex_map */ + std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; + + /** Returns all the simplices of max dimension d + * \ingroup toplex_map */ + std::vector 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 + bool all_facets_inside(const Input_vertex_range &vertex_range) const; + +}; + +template +void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ + toplex_maps.emplace(nan(""), new Lazy_Toplex_map()); + using vertex_iterator = typename boost::graph_traits::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 +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 filtration_simplex_range().size(); + return max_simplices().size(); +} +*/ +std::size_t Fake_simplex_tree::num_vertices() const { + /* + std::unordered_set vertices; + for(const Toplex_map::Simplex& s : max_simplices()) + for (Toplex_map::Vertex v : s) + vertices.emplace(v); + return vertices.size(); + */ + return 0; +} + +Toplex_map::Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { + return s; +} + +/* +std::vector Fake_simplex_tree::max_simplices() const{ + std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ + std::vector m = max_simplices(); + std::vector 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 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 */ + -- cgit v1.2.3 From e94d787c89a7c9a71c86118bc3e048241e9c5ca1 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 15 May 2018 14:16:45 +0000 Subject: Add examples with Fake_simplex_tree git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3442 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ccdd8f43c0e86a98efd3f9d7e9c7b8728ebd27a7 --- src/Toplex_map/benchmark/CMakeLists.txt | 2 +- src/Toplex_map/example/CMakeLists.txt | 5 +++++ src/Toplex_map/example/Fake_simplex_tree.h | 19 ++++++---------- src/Toplex_map/example/Simple_toplex_map.cpp | 26 +++++++++++++--------- .../example/Toplex_map_from_cliques_of_graph.cpp | 5 ++--- 5 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 src/Toplex_map/example/CMakeLists.txt (limited to 'src') diff --git a/src/Toplex_map/benchmark/CMakeLists.txt b/src/Toplex_map/benchmark/CMakeLists.txt index e4cfab6f..2c67892c 100644 --- a/src/Toplex_map/benchmark/CMakeLists.txt +++ b/src/Toplex_map/benchmark/CMakeLists.txt @@ -1,4 +1,4 @@ cmake_minimum_required(VERSION 2.6) -project(Toplex_map_examples) +project(Toplex_map_benchmark) add_executable(toplex_map_chrono chrono.cpp) 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 index 8187e24e..c3d87e47 100644 --- a/src/Toplex_map/example/Fake_simplex_tree.h +++ b/src/Toplex_map/example/Fake_simplex_tree.h @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -117,39 +118,34 @@ bool Fake_simplex_tree::all_facets_inside(const Input_vertex_range &vertex_range 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 filtration_simplex_range().size(); return max_simplices().size(); } -*/ + std::size_t Fake_simplex_tree::num_vertices() const { - /* std::unordered_set vertices; for(const Toplex_map::Simplex& s : max_simplices()) for (Toplex_map::Vertex v : s) vertices.emplace(v); return vertices.size(); - */ - return 0; } Toplex_map::Simplex Fake_simplex_tree::simplex_vertex_range(const Simplex& s) const { return s; } -/* std::vector Fake_simplex_tree::max_simplices() const{ std::vector max_s; for(auto kv : toplex_maps) @@ -157,8 +153,7 @@ std::vector Fake_simplex_tree::max_simplices() const{ max_s.emplace_back(*sptr); return max_s; } -*/ -/* + std::vector Fake_simplex_tree::filtration_simplex_range(int d) const{ std::vector m = max_simplices(); std::vector range; @@ -180,7 +175,7 @@ std::vector Fake_simplex_tree::filtration_simplex_range(int std::vector 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) diff --git a/src/Toplex_map/example/Simple_toplex_map.cpp b/src/Toplex_map/example/Simple_toplex_map.cpp index 4fa735a6..d383e84b 100644 --- a/src/Toplex_map/example/Simple_toplex_map.cpp +++ b/src/Toplex_map/example/Simple_toplex_map.cpp @@ -21,7 +21,7 @@ */ #include -#include "gudhi/Fake_simplex_tree.h" +#include "Fake_simplex_tree.h" #include #include // for pair @@ -184,10 +184,12 @@ int main(int argc, char * const argv[]) { << " 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()) { - std::cout << " " << "[" << t_map.filtration(f_simplex) << "] "; - for (auto vertex : t_map.simplex_vertex_range(f_simplex)) - std::cout << "(" << vertex << ")"; - std::cout << std::endl; + 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 @@ -201,13 +203,15 @@ int main(int argc, char * const argv[]) { std::cout << std::endl << std::endl; - std::cout << "Iterator on skeleton:" << std::endl; - for (auto f_simplex : t_map.skeleton_simplex_range()) { - std::cout << " " << "[" << t_map.filtration(f_simplex) << "] "; - for (auto vertex : t_map.simplex_vertex_range(f_simplex)) { - std::cout << vertex << " "; + 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; } - 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 index 3df0cbd9..c43f1b69 100644 --- a/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp +++ b/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp @@ -21,7 +21,7 @@ */ #include -#include "gudhi/Fake_simplex_tree.h" +#include "Fake_simplex_tree.h" #include #include @@ -82,7 +82,7 @@ int main(int argc, char * const argv[]) { std::cout << std::endl << std::endl; std::cout << "Iterator on skeleton:" << std::endl; - for (auto f_simplex : t_map.skeleton_simplex_range()) { + 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 << " "; @@ -91,4 +91,3 @@ int main(int argc, char * const argv[]) { } return 0; } -} -- cgit v1.2.3 From 04da883af94d96ea54faf09a1fb87e3b8e0bf847 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 15 May 2018 14:21:13 +0000 Subject: fake simplex tree for toplex map git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3443 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7bdafb844ee99d834cfd47b37ae32cb52863b4b1 --- src/Toplex_map/example/Fake_simplex_tree.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/example/Fake_simplex_tree.h b/src/Toplex_map/example/Fake_simplex_tree.h index c3d87e47..6a7e7bdc 100644 --- a/src/Toplex_map/example/Fake_simplex_tree.h +++ b/src/Toplex_map/example/Fake_simplex_tree.h @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -13,9 +12,9 @@ namespace Gudhi { struct Visitor { - Lazy_Toplex_map* tm; + Toplex_map* tm; - Visitor(Lazy_Toplex_map* tm) + Visitor(Toplex_map* tm) :tm(tm) {} @@ -99,7 +98,7 @@ protected: template void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(nan(""), new Lazy_Toplex_map()); + toplex_maps.emplace(nan(""), new Toplex_map()); using vertex_iterator = typename boost::graph_traits::vertex_iterator; vertex_iterator vi, vi_end; for (std::tie(vi, vi_end) = boost::vertices(skel_graph); vi != vi_end; ++vi) { -- cgit v1.2.3 From db4d235b9f7995351f3d4559a132dfe15f30b655 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 15 May 2018 15:39:51 +0000 Subject: better unit test git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3444 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0dd6c254d59c71e4bafe7413e87ce0d27c87a4ab --- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 4 ++-- src/Toplex_map/test/CMakeLists.txt | 1 + src/Toplex_map/test/toplex_map_unit_test.cpp | 11 +++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 50785b5a..396961fe 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -64,8 +64,8 @@ private: std::size_t size_lbound = 0; std::size_t size = 0; - const double alpha = 2; //time - const double betta = 4; //memory + const double alpha = 4; //time + const double betta = 8; //memory }; template diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt index 5ed55e97..8bf5cf14 100644 --- a/src/Toplex_map/test/CMakeLists.txt +++ b/src/Toplex_map/test/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 2.6) project(Toplex_map_tests) +add_executable(chrono chrono.cpp) add_executable ( ToplexMapUT toplex_map_unit_test.cpp ) target_link_libraries(ToplexMapUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index 95ee7a02..c12ad094 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -28,10 +28,17 @@ BOOST_AUTO_TEST_CASE(toplexmap) { K.insert_simplex(sigma6); K.insert_simplex(sigma7); BOOST_CHECK(K.membership(sigma4)); - BOOST_CHECK(!K.maximality(sigma5)); + BOOST_CHECK(!K.maximality(sigma3)); BOOST_CHECK(!K.membership(sigma5)); - K.contraction(4,5); + K.insert_simplex(sigma5); + std::vector sigma9 = {1, 2, 3}; + std::vector sigma10 = {2, 7}; + auto r = K.contraction(4,5); + sigma9.emplace_back(r); + sigma10.emplace_back(r); BOOST_CHECK(!K.membership(sigma6)); + BOOST_CHECK(K.membership(sigma9)); + BOOST_CHECK(K.membership(sigma10)); } -- cgit v1.2.3 From 68443280388d3a83adc3f927b3252b2debafb11c Mon Sep 17 00:00:00 2001 From: fgodi Date: Wed, 23 May 2018 12:49:36 +0000 Subject: strange git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3454 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9860c0af5c014faeb5d16b81e1fafa8a4eb27786 --- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 396961fe..31f3da4b 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -175,7 +175,7 @@ inline void Lazy_Toplex_map::erase_max(const Input_vertex_range &vertex_range){ Simplex sigma(vertex_range.begin(),vertex_range.end()); empty_toplex = false; Simplex_ptr sptr = std::make_shared(sigma); - bool erased; + bool erased=false; for(const Vertex& v : sigma){ erased = t0.at(v).erase(sptr) > 0; if(t0.at(v).size()==0) @@ -206,17 +206,17 @@ std::size_t Lazy_Toplex_map::get_gamma0_lbound(const Vertex v) const{ void Lazy_Toplex_map::clean(const Vertex v){ Toplex_map toplices; std::unordered_map> dsorted_simplices; - int max_dim = 0; + std::size_t max_dim = 0; for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ if(sptr->size() > max_dim){ - for(int d = max_dim+1; d<=sptr->size(); d++) + for(std::size_t d = max_dim+1; d<=sptr->size(); d++) dsorted_simplices.emplace(d, std::vector()); max_dim = sptr->size(); } dsorted_simplices[sptr->size()].emplace_back(*sptr); erase_max(*sptr); } - for(int d = max_dim; d>=1; d--) + for(std::size_t d = max_dim; d>=1; d--) for(const Simplex &s : dsorted_simplices.at(d)) if(!toplices.membership(s)) toplices.insert_independent_simplex(s); -- cgit v1.2.3 From 0522bc89cf47440088c284c640d9800504f7548e Mon Sep 17 00:00:00 2001 From: fgodi Date: Wed, 23 May 2018 12:49:44 +0000 Subject: strange git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3455 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4e66029b1f96b6843de7c5249b5e5206a964e619 --- src/Toplex_map/benchmark/chrono.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp index e65dcba2..a745f099 100644 --- a/src/Toplex_map/benchmark/chrono.cpp +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -3,12 +3,14 @@ #include #include +#include #include using namespace Gudhi; -typedef Toplex_map::Vertex Vertex; typedef Toplex_map::Simplex Simplex; +typedef Toplex_map::Vertex Vertex; +typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; class ST_wrapper { @@ -65,7 +67,7 @@ int nb_contraction = 300; int nb_insert_simplex2 = 3000; int nb_membership2 = 400000; -Simplex random_simplex(int n, int d){ +Simplex random_simplex(int n, std::size_t d){ std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution dis(1, n); -- cgit v1.2.3 From caed57893851dddad58f63d68ea41be724582cc1 Mon Sep 17 00:00:00 2001 From: fgodi Date: Wed, 23 May 2018 17:12:50 +0000 Subject: bug marc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3456 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 71d185c40486ba495bd113ec5abf683d6e3b1cd9 --- src/Toplex_map/include/gudhi/Toplex_map.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index ccea34d5..b6bb5381 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -220,7 +220,8 @@ template void Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ for(const Toplex_map::Vertex& v : vertex_range){ if(!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); - t0.at(v).emplace(get_key(vertex_range)); + auto k = get_key(vertex_range); + t0.at(v).emplace(k); } } -- cgit v1.2.3 From 0ccb8a63c7aa857e99802a6bce2ff3aa8c4b3d65 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 30 May 2018 05:40:59 +0000 Subject: Add Toplex_map image path in Doxyfile Fix Toplex_map test CMakeLists.txt issue git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3490 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 988ba1cd8d198444f70ab648bfd34e10cc82f6eb --- src/Doxyfile | 3 ++- src/Toplex_map/test/CMakeLists.txt | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Doxyfile b/src/Doxyfile index 0ef81e5c..bc6dc279 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -851,7 +851,8 @@ IMAGE_PATH = doc/Skeleton_blocker/ \ doc/Subsampling/ \ doc/Spatial_searching/ \ doc/Tangential_complex/ \ - doc/Bottleneck_distance/ + doc/Bottleneck_distance/ \ + doc/Toplex_map/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt index 8bf5cf14..5ed55e97 100644 --- a/src/Toplex_map/test/CMakeLists.txt +++ b/src/Toplex_map/test/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 2.6) project(Toplex_map_tests) -add_executable(chrono chrono.cpp) add_executable ( ToplexMapUT toplex_map_unit_test.cpp ) target_link_libraries(ToplexMapUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -- cgit v1.2.3 From 516e2942d8529e03311539ad0b001b33e45721f4 Mon Sep 17 00:00:00 2001 From: fgodi Date: Tue, 19 Jun 2018 14:39:12 +0000 Subject: unitary collapses function git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3623 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 26c1fe89a979d9e1953e7916b15faa34e41da97b --- src/Toplex_map/include/gudhi/Toplex_map.h | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index b6bb5381..7a2e5b09 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -2,6 +2,7 @@ #define TOPLEX_MAP_H #include +#include #include #include #include @@ -69,7 +70,7 @@ public: * The edge has to verify the link condition if you want to preserve topology. * Returns the remaining vertex. * \ingroup toplex_map */ - Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y, bool force=false); + Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); /** Adds the given simplex to the complex. * The simplex must not have neither maximal face nor coface in the complex. @@ -89,6 +90,8 @@ public: * \ingroup toplex_map */ std::size_t num_simplices() const; + std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); + protected: /** \internal Gives an index in order to look for a simplex quickly. * \ingroup toplex_map */ @@ -196,18 +199,17 @@ Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range return cofaces; } -Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y, bool force){ +Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y){ if(!t0.count(x)) return y; if(!t0.count(y)) return x; int k, d; - if(force || (t0.at(x).size() > t0.at(y).size())) + if(t0.at(x).size() > t0.at(y).size()) k=x, d=y; else k=y, d=x; for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ //Copy constructor needed because the set is modified Simplex sigma(*sptr); - Simplex s; s.insert(2); erase_maximal(sptr); sigma.erase(d); sigma.insert(k); @@ -216,12 +218,27 @@ Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Top return k; } +std::set Toplex_map::unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d){ + std::set r; + for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ + //Copy constructor needed because the set is modified + Simplex sigma(*sptr); + erase_maximal(sptr); + sigma.erase(d); + for(const Toplex_map::Vertex v : sigma) + r.insert(v); + sigma.insert(k); + insert_simplex(sigma); + } + return r; +} + template void Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ + auto key = get_key(vertex_range); for(const Toplex_map::Vertex& v : vertex_range){ if(!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); - auto k = get_key(vertex_range); - t0.at(v).emplace(k); + t0.at(v).emplace(key); } } -- cgit v1.2.3 From 6673dbcb6474d8521cf79dd6b7a1f342b17cee17 Mon Sep 17 00:00:00 2001 From: fgodi Date: Sun, 8 Jul 2018 08:23:13 +0000 Subject: ordered simplices git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3685 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 56442cd98146404e1b9eab10d32bb3d18aa2baee --- src/Toplex_map/include/gudhi/Toplex_map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 7a2e5b09..73d2c63d 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -25,7 +25,7 @@ public: /** Simplex is the type of simplices. * \ingroup toplex_map */ - typedef std::unordered_set Simplex; + typedef std::set Simplex; /** The type of the pointers to maximal simplices. * \ingroup toplex_map */ -- cgit v1.2.3 From a6ba309f1995700369e6b7b2c38f10ce0f9fd010 Mon Sep 17 00:00:00 2001 From: fgodi Date: Sun, 8 Jul 2018 08:36:05 +0000 Subject: doc lazy git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3686 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9d94007cdd821651df934054481a3eaedfcc8e50 --- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 32 +++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 31f3da4b..25281998 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -7,6 +7,9 @@ namespace Gudhi { +/** A Lazy_Toplex_map represents the simplicial complex. + * A "toplex" is a maximal simplex but not all simplices in a LTM are toplices. + * \ingroup toplex_map */ class Lazy_Toplex_map { public: @@ -27,20 +30,43 @@ public: * \ingroup toplex_map */ typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + /** Adds the given simplex to the complex. + * The simplex must not have maximal coface in the complex. + * \ingroup toplex_map */ template - void insert_max_simplex(const Input_vertex_range &vertex_range); + void insert_independent_simplex(const Input_vertex_range &vertex_range); + + /** \brief Adds the given simplex to the complex. + * Nothing happens if the simplex has a coface in the complex. + * \ingroup toplex_map */ template bool insert_simplex(const Input_vertex_range &vertex_range); + + /** \brief Removes the given simplex and its cofaces from the complex. + * Its faces are kept inside. + * \ingroup toplex_map */ template void remove_simplex(const Input_vertex_range &vertex_range); + /** Does a simplex belong to the complex ? + * \ingroup toplex_map */ template bool membership(const Input_vertex_range &vertex_range); + + + /** Do all the facets of a simplex belong to the complex ? + * \ingroup toplex_map */ template bool all_facets_inside(const Input_vertex_range &vertex_range); + /** Contracts one edge in the complex. + * The edge has to verify the link condition if you want to preserve topology. + * Returns the remaining vertex. + * \ingroup toplex_map */ Vertex contraction(const Vertex x, const Vertex y); + /** \brief Number of simplices stored. + * \ingroup toplex_map */ std::size_t num_simplices() const; std::unordered_map gamma0_lbounds; @@ -69,7 +95,7 @@ private: }; template -void Lazy_Toplex_map::insert_max_simplex(const Input_vertex_range &vertex_range){ +void Lazy_Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ for(const Vertex& v : vertex_range) if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); else gamma0_lbounds[v]++; @@ -116,7 +142,7 @@ void Lazy_Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ if(included(vertex_range, *sptr)){ erase_max(*sptr); for(const Simplex& f : facets(vertex_range)) - insert_max_simplex(f); + insert_independent_simplex(f); } } } -- cgit v1.2.3 From 004ff4cfc01d1c8128a2b39092dbfbc25149069d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 12 Oct 2018 12:42:11 +0000 Subject: Rename num_simplices num_maximal_simplices Make unitary tests working git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3947 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: eddea297f7cf6a0fd172ceaa3fbb28b6e3cb2e63 --- src/Toplex_map/benchmark/CMakeLists.txt | 1 - src/Toplex_map/example/CMakeLists.txt | 5 +- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 5 +- src/Toplex_map/include/gudhi/Toplex_map.h | 4 +- src/Toplex_map/test/CMakeLists.txt | 14 +--- src/Toplex_map/test/toplex_map_unit_test.cpp | 109 +++++++++++++++---------- 6 files changed, 77 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/CMakeLists.txt b/src/Toplex_map/benchmark/CMakeLists.txt index 2c67892c..c2f216bc 100644 --- a/src/Toplex_map/benchmark/CMakeLists.txt +++ b/src/Toplex_map/benchmark/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Toplex_map_benchmark) add_executable(toplex_map_chrono chrono.cpp) diff --git a/src/Toplex_map/example/CMakeLists.txt b/src/Toplex_map/example/CMakeLists.txt index 051d7bcd..58185fd5 100644 --- a/src/Toplex_map/example/CMakeLists.txt +++ b/src/Toplex_map/example/CMakeLists.txt @@ -1,5 +1,4 @@ -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) +#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/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 25281998..ea10d390 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -3,7 +3,6 @@ #include #include -#include namespace Gudhi { @@ -67,7 +66,7 @@ public: /** \brief Number of simplices stored. * \ingroup toplex_map */ - std::size_t num_simplices() const; + std::size_t num_maximal_simplices() const; std::unordered_map gamma0_lbounds; @@ -254,7 +253,7 @@ void Lazy_Toplex_map::clean(const Vertex v){ insert_simplex(*sptr); } -std::size_t Lazy_Toplex_map::num_simplices() const{ +std::size_t Lazy_Toplex_map::num_maximal_simplices() const{ return size; } diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 73d2c63d..5a6c7dbf 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -88,7 +88,7 @@ public: /** \brief Number of maximal simplices. * \ingroup toplex_map */ - std::size_t num_simplices() const; + std::size_t num_maximal_simplices() const; std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); @@ -251,7 +251,7 @@ void Toplex_map::remove_vertex(const Toplex_map::Vertex x){ } } -std::size_t Toplex_map::num_simplices() const{ +std::size_t Toplex_map::num_maximal_simplices() const{ return maximal_cofaces(Simplex()).size(); } diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt index 5ed55e97..237cfdad 100644 --- a/src/Toplex_map/test/CMakeLists.txt +++ b/src/Toplex_map/test/CMakeLists.txt @@ -1,14 +1,8 @@ -cmake_minimum_required(VERSION 2.6) project(Toplex_map_tests) -add_executable ( ToplexMapUT toplex_map_unit_test.cpp ) -target_link_libraries(ToplexMapUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +include(GUDHI_test_coverage) +add_executable( Toplex_map_unit_test toplex_map_unit_test.cpp ) +target_link_libraries(Toplex_map_unit_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) -# Unitary tests -add_test(NAME ToplexMapUT - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/ToplexMapUT - ${CMAKE_SOURCE_DIR}/src/Toplex_map/test/test.txt - # XML format for Jenkins xUnit plugin - --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/ToplexMapUT.xml --log_level=test_suite --report_level=no) - +gudhi_add_coverage_test(Toplex_map_unit_test) diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index c12ad094..2c584c5d 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -1,54 +1,79 @@ #include -#include +#include +#include #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "toplex map" #include +#include + +using list_of_tested_variants = boost::mpl::list; + +BOOST_AUTO_TEST_CASE_TEMPLATE(common_toplex_map_functionnalities, Toplex_map, list_of_tested_variants) { + using Vertex = typename Toplex_map::Vertex; + + std::vector sigma1 = {1, 2, 3, 4}; + std::vector sigma2 = {5, 2, 3, 6}; + std::vector sigma3 = {5}; + std::vector sigma4 = {5, 2, 3}; + std::vector sigma5 = {5, 2, 7}; + std::vector sigma6 = {4, 5, 3}; + std::vector sigma7 = {4, 5, 9}; + std::vector sigma8 = {1, 2, 3, 6}; + + Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma6); + K.insert_simplex(sigma7); + + std::cout << K.num_maximal_simplices(); + + BOOST_CHECK(K.membership(sigma4)); + //BOOST_CHECK(!K.maximality(sigma3)); + BOOST_CHECK(!K.membership(sigma5)); + K.insert_simplex(sigma5); + + std::cout << K.num_maximal_simplices(); + + BOOST_CHECK(K.membership(sigma5)); + std::vector sigma9 = {1, 2, 3}; + std::vector sigma10 = {2, 7}; + auto r = K.contraction(4,5); + + std::cout << K.num_maximal_simplices(); + + sigma9.emplace_back(r); + sigma10.emplace_back(r); + BOOST_CHECK(!K.membership(sigma6)); + BOOST_CHECK(K.membership(sigma9)); + BOOST_CHECK(K.membership(sigma10)); + K.remove_simplex(sigma10); + BOOST_CHECK(!K.membership(sigma10)); -using namespace Gudhi; - -typedef Toplex_map::Vertex Vertex; - -std::vector sigma1 = {1, 2, 3, 4}; -std::vector sigma2 = {5, 2, 3, 6}; -std::vector sigma3 = {5}; -std::vector sigma4 = {5, 2, 3}; -std::vector sigma5 = {5, 2, 7}; -std::vector sigma6 = {4, 5, 3}; -std::vector sigma7 = {4, 5, 9}; -std::vector sigma8 = {1, 2, 3, 6}; - - -BOOST_AUTO_TEST_CASE(toplexmap) { - Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma6); - K.insert_simplex(sigma7); - BOOST_CHECK(K.membership(sigma4)); - BOOST_CHECK(!K.maximality(sigma3)); - BOOST_CHECK(!K.membership(sigma5)); - K.insert_simplex(sigma5); - std::vector sigma9 = {1, 2, 3}; - std::vector sigma10 = {2, 7}; - auto r = K.contraction(4,5); - sigma9.emplace_back(r); - sigma10.emplace_back(r); - BOOST_CHECK(!K.membership(sigma6)); - BOOST_CHECK(K.membership(sigma9)); - BOOST_CHECK(K.membership(sigma10)); } +BOOST_AUTO_TEST_CASE(toplex_map_maximality) { + using Vertex = Gudhi::Toplex_map::Vertex; + + std::vector sigma1 = {1, 2, 3, 4}; + std::vector sigma2 = {5, 2, 3, 6}; + std::vector sigma3 = {5}; + std::vector sigma4 = {4, 5, 3}; + std::vector sigma5 = {4, 5, 9}; -BOOST_AUTO_TEST_CASE(ftoplexmap) { - Filtered_toplex_map K; - K.insert_simplex_and_subfaces(sigma1, 2.); - K.insert_simplex_and_subfaces(sigma2, 2.); - K.insert_simplex_and_subfaces(sigma6, 1.); - K.insert_simplex_and_subfaces(sigma7, 1.); - BOOST_CHECK(K.filtration(sigma4)==2.); - BOOST_CHECK(K.filtration(sigma3)==1.); + Gudhi::Toplex_map K; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma4); + K.insert_simplex(sigma5); + BOOST_CHECK(K.maximality(sigma1)); + BOOST_CHECK(K.maximality(sigma2)); + BOOST_CHECK(!K.maximality(sigma3)); + BOOST_CHECK(K.maximality(sigma4)); + BOOST_CHECK(K.maximality(sigma5)); } -- cgit v1.2.3 From 4b619ec130bfa6cff47fbde47a732d890327f465 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 12 Oct 2018 12:54:03 +0000 Subject: Bad comment for lazy num_maximal_simplices git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3948 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f0926058af8b0cfc77c9346feda6f6c4db2c9828 --- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 4 ++-- src/Toplex_map/test/toplex_map_unit_test.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index ea10d390..0cae967e 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -64,8 +64,8 @@ public: * \ingroup toplex_map */ Vertex contraction(const Vertex x, const Vertex y); - /** \brief Number of simplices stored. - * \ingroup toplex_map */ + /** \brief Number of maximal simplices. + * \ingroup toplex_map */ std::size_t num_maximal_simplices() const; std::unordered_map gamma0_lbounds; diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index 2c584c5d..c1540eb5 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -55,6 +55,30 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(common_toplex_map_functionnalities, Toplex_map, li } +BOOST_AUTO_TEST_CASE(toplex_map_num_maximal_simplices) { + using Vertex = Gudhi::Toplex_map::Vertex; + + Gudhi::Toplex_map K; + K.insert_simplex({1, 2, 3, 4}); + K.insert_simplex({5, 2, 3, 6}); + K.insert_simplex({4, 5, 3}); + K.insert_simplex({4, 5, 9}); + + std::cout << K.num_maximal_simplices(); + BOOST_CHECK(K.num_maximal_simplices() == 4); + + K.insert_simplex({5, 2, 7}); + + std::cout << K.num_maximal_simplices(); + BOOST_CHECK(K.num_maximal_simplices() == 5); + + auto r = K.contraction(4,5); + + std::cout << K.num_maximal_simplices(); + BOOST_CHECK(K.num_maximal_simplices() == 4); + +} + BOOST_AUTO_TEST_CASE(toplex_map_maximality) { using Vertex = Gudhi::Toplex_map::Vertex; -- cgit v1.2.3 From 05b163f41a8b2ee0b10b862b0c7497d3f6e9b4b3 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 12 Oct 2018 13:09:43 +0000 Subject: Remove all documentation from user manual git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3949 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ef6f0dd7622590ae3d550162174120c2e0406cb7 --- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 27 ++++-------- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 33 +++++--------- src/Toplex_map/include/gudhi/Toplex_map.h | 50 ++++++++-------------- 3 files changed, 37 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h index ed65e36f..9a35b8b7 100644 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h @@ -8,44 +8,35 @@ namespace Gudhi { /** A Filtered_toplex_map represents the simplicial complex with a filtration. - * A "toplex" is a critical simplex. - * \ingroup toplex_map */ + * A "toplex" is a critical simplex. */ class Filtered_toplex_map { public: - /** Vertex is the type of vertices. - * \ingroup toplex_map */ + /** Vertex is the type of vertices. */ typedef Toplex_map::Vertex Vertex; - /** Simplex is the type of simplices. - * \ingroup toplex_map */ + /** Simplex is the type of simplices. */ typedef Toplex_map::Simplex Simplex; - /** The type of the pointers to maximal simplices. - * \ingroup toplex_map */ + /** The type of the pointers to maximal simplices. */ typedef Toplex_map::Simplex_ptr Simplex_ptr; - /** The type of the sets of Simplex_ptr. - * \ingroup toplex_map */ + /** The type of the sets of Simplex_ptr. */ typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; - /** The type of the filtration values. - * \ingroup toplex_map */ + /** The type of the filtration values. */ typedef double Filtration_value; /** Add a simplex and its subfaces with the given filtration value - * in the Filtered_toplex_map. - * \ingroup toplex_map */ + * in the Filtered_toplex_map. */ template std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = std::numeric_limits::quiet_NaN()); - /** Gives the filtration of the input simplex. - * \ingroup toplex_map */ + /** Gives the filtration of the input simplex. */ template Filtration_value filtration(const Input_vertex_range &vertex_range) const; - /** Is the input simplex member of the complex ? - * \ingroup toplex_map */ + /** Is the input simplex member of the complex ? */ template bool membership(const Input_vertex_range &vertex_range) const; diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 0cae967e..9aa163f9 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -13,59 +13,48 @@ class Lazy_Toplex_map { public: - /** Vertex is the type of vertices. - * \ingroup toplex_map */ + /** Vertex is the type of vertices. */ typedef Toplex_map::Vertex Vertex; - /** Simplex is the type of simplices. - * \ingroup toplex_map */ + /** Simplex is the type of simplices. */ typedef Toplex_map::Simplex Simplex; - /** The type of the pointers to maximal simplices. - * \ingroup toplex_map */ + /** The type of the pointers to maximal simplices. */ typedef Toplex_map::Simplex_ptr Simplex_ptr; - /** The type of the sets of Simplex_ptr. - * \ingroup toplex_map */ + /** The type of the sets of Simplex_ptr. */ typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; /** Adds the given simplex to the complex. - * The simplex must not have maximal coface in the complex. - * \ingroup toplex_map */ + * The simplex must not have maximal coface in the complex. */ template void insert_independent_simplex(const Input_vertex_range &vertex_range); /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. - * \ingroup toplex_map */ + * Nothing happens if the simplex has a coface in the complex. */ template bool insert_simplex(const Input_vertex_range &vertex_range); /** \brief Removes the given simplex and its cofaces from the complex. - * Its faces are kept inside. - * \ingroup toplex_map */ + * Its faces are kept inside. */ template void remove_simplex(const Input_vertex_range &vertex_range); - /** Does a simplex belong to the complex ? - * \ingroup toplex_map */ + /** Does a simplex belong to the complex ? */ template bool membership(const Input_vertex_range &vertex_range); - /** Do all the facets of a simplex belong to the complex ? - * \ingroup toplex_map */ + /** Do all the facets of a simplex belong to the complex ? */ template bool all_facets_inside(const Input_vertex_range &vertex_range); /** Contracts one edge in the complex. * The edge has to verify the link condition if you want to preserve topology. - * Returns the remaining vertex. - * \ingroup toplex_map */ + * Returns the remaining vertex. */ Vertex contraction(const Vertex x, const Vertex y); - /** \brief Number of maximal simplices. - * \ingroup toplex_map */ + /** \brief Number of maximal simplices. */ std::size_t num_maximal_simplices() const; std::unordered_map gamma0_lbounds; diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 5a6c7dbf..271d0970 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -14,92 +14,76 @@ namespace Gudhi { /** A Toplex_map represents the simplicial complex. * A "toplex" is a maximal simplex. - * \ingroup toplex_map */ + * \ingroup toplex_map */ class Toplex_map { public: - /** Vertex is the type of vertices. - * \ingroup toplex_map */ + /** Vertex is the type of vertices. */ typedef std::size_t Vertex; - /** Simplex is the type of simplices. - * \ingroup toplex_map */ + /** Simplex is the type of simplices. */ typedef std::set Simplex; - /** The type of the pointers to maximal simplices. - * \ingroup toplex_map */ + /** The type of the pointers to maximal simplices. */ typedef std::shared_ptr Simplex_ptr; struct Sptr_hash{ std::size_t operator()(const Toplex_map::Simplex_ptr& s) const; }; struct Sptr_equal{ std::size_t operator()(const Toplex_map::Simplex_ptr& a, const Toplex_map::Simplex_ptr& b) const; }; - /** The type of the sets of Toplex_map::Simplex_ptr. - * \ingroup toplex_map */ + /** The type of the sets of Toplex_map::Simplex_ptr. */ typedef std::unordered_set Simplex_ptr_set; /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. - * \ingroup toplex_map */ + * Nothing happens if the simplex has a coface in the complex. */ template void insert_simplex(const Input_vertex_range &vertex_range); /** \brief Removes the given simplex and its cofaces from the complex. - * Its faces are kept inside. - * \ingroup toplex_map */ + * Its faces are kept inside. */ template void remove_simplex(const Input_vertex_range &vertex_range); - /** Does a simplex belong to the complex ? - * \ingroup toplex_map */ + /** Does a simplex belong to the complex ? */ template bool membership(const Input_vertex_range &vertex_range) const; - /** Does a simplex is a toplex ? - * \ingroup toplex_map */ + /** Does a simplex is a toplex ? */ template bool maximality(const Input_vertex_range &vertex_range) const; /** Gives a set of pointers to the maximal cofaces of a simplex. * Gives all the toplices if given the empty simplex. - * Gives not more than max_number maximal cofaces if max_number is strictly positive. - * \ingroup toplex_map */ + * Gives not more than max_number maximal cofaces if max_number is strictly positive. */ template Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; /** Contracts one edge in the complex. * The edge has to verify the link condition if you want to preserve topology. - * Returns the remaining vertex. - * \ingroup toplex_map */ + * Returns the remaining vertex. */ Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); /** Adds the given simplex to the complex. - * The simplex must not have neither maximal face nor coface in the complex. - * \ingroup toplex_map */ + * The simplex must not have neither maximal face nor coface in the complex. */ template void insert_independent_simplex(const Input_vertex_range &vertex_range); - /** \internal Removes a toplex without adding facets after. - * \ingroup toplex_map */ + /** \internal Removes a toplex without adding facets after. */ void erase_maximal(const Toplex_map::Simplex_ptr& sptr); - /** Removes a vertex from any simplex containing it. - * \ingroup toplex_map */ + /** Removes a vertex from any simplex containing it. */ void remove_vertex(const Toplex_map::Vertex x); - /** \brief Number of maximal simplices. - * \ingroup toplex_map */ + /** \brief Number of maximal simplices. */ std::size_t num_maximal_simplices() const; std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); protected: - /** \internal Gives an index in order to look for a simplex quickly. - * \ingroup toplex_map */ + /** \internal Gives an index in order to look for a simplex quickly. */ template Toplex_map::Vertex best_index(const Input_vertex_range &vertex_range) const; - /** \internal The map from vertices to toplices - * \ingroup toplex_map */ + /** \internal The map from vertices to toplices */ std::unordered_map t0; }; -- cgit v1.2.3 From 0b903a02242c935e7621006818e9f9dc442f0e79 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 12 Oct 2018 14:06:01 +0000 Subject: Add some unitary tests num_maximum_simplices results are a bit strange git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3950 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 86c7a4607f9d774c89c79dcc6d95f1ce2f5951d5 --- src/Toplex_map/benchmark/chrono.cpp | 56 +++++++++---------- src/Toplex_map/include/gudhi/Toplex_map.h | 4 +- src/Toplex_map/test/toplex_map_unit_test.cpp | 81 ++++++++++++++++++++++++---- 3 files changed, 96 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp index a745f099..db87e217 100644 --- a/src/Toplex_map/benchmark/chrono.cpp +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -15,48 +15,40 @@ typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; class ST_wrapper { public: - void insert_simplex(const Simplex& tau); - bool membership(const Simplex& tau); - Vertex contraction(const Vertex x, const Vertex y); - std::size_t num_simplices(); - -private: - Simplex_tree<> simplexTree; - void erase_max(const Simplex& sigma); -}; - -void ST_wrapper::insert_simplex(const Simplex& tau){ + void insert_simplex(const Simplex& tau) { simplexTree.insert_simplex_and_subfaces(tau); -} + } -bool ST_wrapper::membership(const Simplex& tau) { + bool membership(const Simplex& tau) { return simplexTree.find(tau) != simplexTree.null_simplex(); -} - -void ST_wrapper::erase_max(const Simplex& sigma){ - if(membership(sigma)) - simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); -} + } -Vertex ST_wrapper::contraction(const Vertex x, const Vertex y){ + Vertex contraction(const Vertex x, const Vertex y) { Simplex sx; sx.insert(x); auto hx = simplexTree.find(sx); if(hx != simplexTree.null_simplex()) - for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ - auto sr = simplexTree.simplex_vertex_range(h); - Simplex sigma(sr.begin(),sr.end()); - erase_max(sigma); - sigma.erase(x); - sigma.insert(y); - insert_simplex(sigma); - } + for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ + auto sr = simplexTree.simplex_vertex_range(h); + Simplex sigma(sr.begin(),sr.end()); + erase_max(sigma); + sigma.erase(x); + sigma.insert(y); + insert_simplex(sigma); + } return y; -} + } -std::size_t ST_wrapper::num_simplices(){ + std::size_t num_maximal_simplices() { return simplexTree.num_simplices(); -} + } +private: + Simplex_tree<> simplexTree; + void erase_max(const Simplex& sigma) { + if(membership(sigma)) + simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); + } +}; int n = 300; @@ -120,7 +112,7 @@ void chrono(int n, int d){ end = std::chrono::system_clock::now(); auto c2 = std::chrono::duration_cast(end-start).count(); - std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_simplices() << std::endl; + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; } int main(){ diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 271d0970..4c6c4b02 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -8,8 +8,6 @@ #include #include -#define vertex_upper_bound std::numeric_limits::max() - namespace Gudhi { /** A Toplex_map represents the simplicial complex. @@ -85,6 +83,8 @@ protected: /** \internal The map from vertices to toplices */ std::unordered_map t0; + + const Toplex_map::Vertex vertex_upper_bound = std::numeric_limits::max(); }; // Pointers are also used as key in the hash sets. diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index c1540eb5..9ee5dff2 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -29,21 +29,21 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(common_toplex_map_functionnalities, Toplex_map, li K.insert_simplex(sigma6); K.insert_simplex(sigma7); - std::cout << K.num_maximal_simplices(); + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; BOOST_CHECK(K.membership(sigma4)); //BOOST_CHECK(!K.maximality(sigma3)); BOOST_CHECK(!K.membership(sigma5)); K.insert_simplex(sigma5); - std::cout << K.num_maximal_simplices(); + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; BOOST_CHECK(K.membership(sigma5)); std::vector sigma9 = {1, 2, 3}; std::vector sigma10 = {2, 7}; auto r = K.contraction(4,5); - std::cout << K.num_maximal_simplices(); + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; sigma9.emplace_back(r); sigma10.emplace_back(r); @@ -59,24 +59,83 @@ BOOST_AUTO_TEST_CASE(toplex_map_num_maximal_simplices) { using Vertex = Gudhi::Toplex_map::Vertex; Gudhi::Toplex_map K; - K.insert_simplex({1, 2, 3, 4}); - K.insert_simplex({5, 2, 3, 6}); - K.insert_simplex({4, 5, 3}); - K.insert_simplex({4, 5, 9}); + std::vector sigma1 = {1, 2, 3, 4}; + std::vector sigma2 = {5, 2, 3, 6}; + std::vector sigma3 = {4, 5, 3}; + std::vector sigma4 = {4, 5, 9}; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma4); - std::cout << K.num_maximal_simplices(); + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; BOOST_CHECK(K.num_maximal_simplices() == 4); - K.insert_simplex({5, 2, 7}); + std::vector sigma5 = {5, 2, 7}; + K.insert_simplex(sigma5); - std::cout << K.num_maximal_simplices(); + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; BOOST_CHECK(K.num_maximal_simplices() == 5); auto r = K.contraction(4,5); + std::cout << "r=" << r << std::endl; + BOOST_CHECK(r == 5); - std::cout << K.num_maximal_simplices(); + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; BOOST_CHECK(K.num_maximal_simplices() == 4); + std::vector sigma6 = {2, 7}; + K.remove_simplex(sigma6); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 4); + + K.remove_simplex(sigma2); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 6); +} + +BOOST_AUTO_TEST_CASE(lazy_toplex_map_num_maximal_simplices) { + using Vertex = Gudhi::Lazy_Toplex_map::Vertex; + + Gudhi::Lazy_Toplex_map K; + std::vector sigma1 = {1, 2, 3, 4}; + std::vector sigma2 = {5, 2, 3, 6}; + std::vector sigma3 = {4, 5, 3}; + std::vector sigma4 = {4, 5, 9}; + K.insert_simplex(sigma1); + K.insert_simplex(sigma2); + K.insert_simplex(sigma3); + K.insert_simplex(sigma4); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 4); + + std::vector sigma5 = {5, 2, 7}; + K.insert_simplex(sigma5); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 5); + + auto r = K.contraction(4,5); + std::cout << "r=" << r << std::endl; + BOOST_CHECK(r == 5); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 5); + + std::vector sigma6 = {2, 7}; + K.remove_simplex(sigma6); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 6); + + K.remove_simplex(sigma2); + + std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; + BOOST_CHECK(K.num_maximal_simplices() == 9); + } BOOST_AUTO_TEST_CASE(toplex_map_maximality) { -- cgit v1.2.3 From c3bdde667d7249dc3325cf76c2813272df4adf8f Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 15 Oct 2018 18:56:59 +0000 Subject: Add num_vertices method git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3951 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f91b42722e47c05da799ac40038f9f12eb70f974 --- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 4 ++++ src/Toplex_map/include/gudhi/Toplex_map.h | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 9aa163f9..434fea47 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -57,6 +57,10 @@ public: /** \brief Number of maximal simplices. */ std::size_t num_maximal_simplices() const; + /** \brief Number of vertices. */ + std::size_t num_vertices() const{ + return t0.size(); + } std::unordered_map gamma0_lbounds; private: diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 4c6c4b02..565415e1 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -74,7 +74,12 @@ public: /** \brief Number of maximal simplices. */ std::size_t num_maximal_simplices() const; - std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); + /** \brief Number of vertices. */ + std::size_t num_vertices() const{ + return t0.size(); + } + + std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); protected: /** \internal Gives an index in order to look for a simplex quickly. */ -- cgit v1.2.3 From 5854b60c83f2ea05de429179ad68f1f3f572e2d8 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 15 Oct 2018 18:57:35 +0000 Subject: Remove Simplex tree edge contraction that seg fault git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3952 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c2ac4648bed0cf72d1a1bfa0697708f04e258ec5 --- src/Toplex_map/benchmark/chrono.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp index db87e217..de6d701f 100644 --- a/src/Toplex_map/benchmark/chrono.cpp +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -16,6 +16,11 @@ class ST_wrapper { public: void insert_simplex(const Simplex& tau) { + /*std::cout << "insert_simplex - " << simplexTree.num_simplices() << " - "; + for (auto v : tau) + std::cout << v << ", "; + std::cout << std::endl; + */ simplexTree.insert_simplex_and_subfaces(tau); } @@ -24,17 +29,7 @@ public: } Vertex contraction(const Vertex x, const Vertex y) { - Simplex sx; sx.insert(x); - auto hx = simplexTree.find(sx); - if(hx != simplexTree.null_simplex()) - for(auto h : simplexTree.cofaces_simplex_range(hx,0)){ - auto sr = simplexTree.simplex_vertex_range(h); - Simplex sigma(sr.begin(),sr.end()); - erase_max(sigma); - sigma.erase(x); - sigma.insert(y); - insert_simplex(sigma); - } + // TODO (VR): edge contraction is not yet available for Simplex_tree return y; } @@ -64,7 +59,7 @@ Simplex random_simplex(int n, std::size_t d){ std::mt19937 gen(rd()); std::uniform_int_distribution dis(1, n); Simplex s; - while(s.size()!=d) + while(s.size() < d) s.insert(dis(gen)); return s; } @@ -95,7 +90,7 @@ void chrono(int n, int d){ K.membership(s); start = std::chrono::system_clock::now(); - for(int i = 0; i<=nb_contraction; i++) + for(int i = 1; i<=nb_contraction; i++) K.contraction(n-2*i,n-2*i-1); end = std::chrono::system_clock::now(); auto c3 = std::chrono::duration_cast(end-start).count(); -- cgit v1.2.3 From da1d57f361de13f48d606eda427e63c700574f74 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 15 Oct 2018 20:39:12 +0000 Subject: Toplex_map indentation simple toplex map example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3953 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 253f001adf27dbe8318ae12996f32b07e4fab139 --- src/Toplex_map/example/CMakeLists.txt | 1 + src/Toplex_map/example/simple_toplex_map.cpp | 160 +++++++++++++++++++++++++++ src/Toplex_map/include/gudhi/Toplex_map.h | 143 +++++++++++++----------- 3 files changed, 238 insertions(+), 66 deletions(-) create mode 100644 src/Toplex_map/example/simple_toplex_map.cpp (limited to 'src') diff --git a/src/Toplex_map/example/CMakeLists.txt b/src/Toplex_map/example/CMakeLists.txt index 58185fd5..346d35d0 100644 --- a/src/Toplex_map/example/CMakeLists.txt +++ b/src/Toplex_map/example/CMakeLists.txt @@ -1,4 +1,5 @@ project(Toplex_map_examples) +add_executable(simple_toplex_map simple_toplex_map.cpp) #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/simple_toplex_map.cpp b/src/Toplex_map/example/simple_toplex_map.cpp new file mode 100644 index 00000000..0d80f94e --- /dev/null +++ b/src/Toplex_map/example/simple_toplex_map.cpp @@ -0,0 +1,160 @@ +/* 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 . + */ + +#include +#include + +#include +#include // for pair +#include + +int main(int argc, char * const argv[]) { + using Simplex = Gudhi::Toplex_map::Simplex; + Simplex sigma1 = {1, 2, 3}; + Simplex sigma2 = {2, 3, 4, 5}; + + Gudhi::Toplex_map tm; + tm.insert_simplex(sigma1); + tm.insert_simplex(sigma2); + + /* Simplex is: */ + /* 2 4 */ + /* o---o */ + /* /X\5/ */ + /* o---o */ + /* 1 3 */ + + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + + // Browse maximal cofaces + Simplex sigma3 = {2, 3}; + std::cout << "Maximal cofaces of {2, 3} are :" << std::endl; + for (auto simplex_ptr : tm.maximal_cofaces(sigma3, 2)) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + } + + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + } + + Simplex sigma4 = {1, 3}; + assert(tm.membership(sigma4)); + + Gudhi::Toplex_map::Vertex v = tm.contraction(1, 3); + std::cout << "After contraction(1, 3) - " << v << std::endl; + /* Simplex is: */ + /* 2 4 */ + /* o---o */ + /* \5/ */ + /* o */ + /* 3 */ + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + } + + Simplex sigma5 = {3, 4}; + assert(tm.membership(sigma5)); + + v = tm.contraction(3, 4); + std::cout << "After contraction(3, 4) - " << v << std::endl; + /* Simplex is: */ + /* 2 4 */ + /* o---o */ + /* \X/ */ + /* o */ + /* 5 */ + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + } + + tm.insert_simplex(sigma1); + tm.insert_simplex(sigma2); + /* Simplex is: */ + /* 2 4 */ + /* o---o */ + /* /X\5/ */ + /* o---o */ + /* 1 3 */ + tm.remove_simplex(sigma1); + + std::cout << "After remove_simplex(1, 2, 3)" << std::endl; + /* Simplex is: */ + /* 2 4 */ + /* o---o */ + /* / \5/ */ + /* o---o */ + /* 1 3 */ + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + } + + tm.remove_vertex(1); + + std::cout << "After remove_vertex(1)" << std::endl; + /* Simplex is: */ + /* 2 4 */ + /* o---o */ + /* \5/ */ + /* o */ + /* 3 */ + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + } + + return 0; +} diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 565415e1..7cde8ea1 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -17,79 +17,94 @@ class Toplex_map { public: - /** Vertex is the type of vertices. */ - typedef std::size_t Vertex; - - /** Simplex is the type of simplices. */ - typedef std::set Simplex; - - /** The type of the pointers to maximal simplices. */ - typedef std::shared_ptr Simplex_ptr; - - struct Sptr_hash{ std::size_t operator()(const Toplex_map::Simplex_ptr& s) const; }; - struct Sptr_equal{ std::size_t operator()(const Toplex_map::Simplex_ptr& a, const Toplex_map::Simplex_ptr& b) const; }; - /** The type of the sets of Toplex_map::Simplex_ptr. */ - typedef std::unordered_set Simplex_ptr_set; - - /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. */ - template - void insert_simplex(const Input_vertex_range &vertex_range); - - /** \brief Removes the given simplex and its cofaces from the complex. - * Its faces are kept inside. */ - template - void remove_simplex(const Input_vertex_range &vertex_range); - - /** Does a simplex belong to the complex ? */ - template - bool membership(const Input_vertex_range &vertex_range) const; - - /** Does a simplex is a toplex ? */ - template - bool maximality(const Input_vertex_range &vertex_range) const; - - /** Gives a set of pointers to the maximal cofaces of a simplex. - * Gives all the toplices if given the empty simplex. - * Gives not more than max_number maximal cofaces if max_number is strictly positive. */ - template - Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; - - /** Contracts one edge in the complex. - * The edge has to verify the link condition if you want to preserve topology. - * Returns the remaining vertex. */ - Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); - - /** Adds the given simplex to the complex. - * The simplex must not have neither maximal face nor coface in the complex. */ - template - void insert_independent_simplex(const Input_vertex_range &vertex_range); + /** Vertex is the type of vertices. */ + using Vertex = std::size_t; + + /** Simplex is the type of simplices. */ + using Simplex = std::set; + + /** The type of the pointers to maximal simplices. */ + using Simplex_ptr = std::shared_ptr; + + struct Sptr_hash { + std::size_t operator()(const Toplex_map::Simplex_ptr& s) const; + }; + + struct Sptr_equal{ + std::size_t operator()(const Toplex_map::Simplex_ptr& a, const Toplex_map::Simplex_ptr& b) const; + }; + + /** The type of the sets of Toplex_map::Simplex_ptr. */ + using Simplex_ptr_set = std::unordered_set; + + /** \brief Adds the given simplex to the complex. + * Nothing happens if the simplex has a coface in the complex. */ + template + void insert_simplex(const Input_vertex_range &vertex_range); + + /** \brief Removes the given simplex and its cofaces from the complex. + * Its faces are kept inside. */ + template + void remove_simplex(const Input_vertex_range &vertex_range); + + /** Does a simplex belong to the complex ? */ + template + bool membership(const Input_vertex_range &vertex_range) const; + + /** Does a simplex is a toplex ? */ + template + bool maximality(const Input_vertex_range &vertex_range) const; + + /** Gives a set of pointers to the maximal cofaces of a simplex. + * Gives all the toplices if given the empty simplex. + * Gives not more than max_number maximal cofaces if max_number is strictly positive. */ + template + Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; + + /** Gives a set of pointers to the maximal simplices. + * Gives not more than max_number maximal cofaces if max_number is strictly positive. */ + Toplex_map::Simplex_ptr_set maximal_simplices(const std::size_t max_number = 0) const { + return maximal_cofaces(Simplex(), max_number); + } - /** \internal Removes a toplex without adding facets after. */ - void erase_maximal(const Toplex_map::Simplex_ptr& sptr); + /** Contracts one edge in the complex. + * The edge has to verify the link condition if you want to preserve topology. + * Returns the remaining vertex. */ + Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); - /** Removes a vertex from any simplex containing it. */ - void remove_vertex(const Toplex_map::Vertex x); + /** Removes a vertex from any simplex containing it. */ + void remove_vertex(const Toplex_map::Vertex x); - /** \brief Number of maximal simplices. */ - std::size_t num_maximal_simplices() const; + /** \brief Number of maximal simplices. */ + std::size_t num_maximal_simplices() const { + return maximal_simplices().size(); + } /** \brief Number of vertices. */ - std::size_t num_vertices() const{ + std::size_t num_vertices() const { return t0.size(); } std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); + /** Adds the given simplex to the complex. + * The simplex must not have neither maximal face nor coface in the complex. */ + template + void insert_independent_simplex(const Input_vertex_range &vertex_range); + protected: - /** \internal Gives an index in order to look for a simplex quickly. */ - template - Toplex_map::Vertex best_index(const Input_vertex_range &vertex_range) const; - - /** \internal The map from vertices to toplices */ - std::unordered_map t0; - - const Toplex_map::Vertex vertex_upper_bound = std::numeric_limits::max(); + /** \internal Gives an index in order to look for a simplex quickly. */ + template + Toplex_map::Vertex best_index(const Input_vertex_range &vertex_range) const; + + /** \internal The map from vertices to toplices */ + std::unordered_map t0; + + const Toplex_map::Vertex vertex_upper_bound = std::numeric_limits::max(); + + /** \internal Removes a toplex without adding facets after. */ + void erase_maximal(const Toplex_map::Simplex_ptr& sptr); + }; // Pointers are also used as key in the hash sets. @@ -240,10 +255,6 @@ void Toplex_map::remove_vertex(const Toplex_map::Vertex x){ } } -std::size_t Toplex_map::num_maximal_simplices() const{ - return maximal_cofaces(Simplex()).size(); -} - inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr){ Simplex sigma(*sptr); if (sptr->size()==0) -- cgit v1.2.3 From b4ac7c5daefa6a22a513a20119c4fdd8ec926f5e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 16 Oct 2018 08:25:18 +0000 Subject: Resize map.png Add simple_toplex_map in test git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3954 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8899f42427e297b4527147a051adab1f9e8850dd --- src/Toplex_map/doc/map.png | Bin 278692 -> 71815 bytes src/Toplex_map/example/CMakeLists.txt | 5 ++--- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/doc/map.png b/src/Toplex_map/doc/map.png index d1987043..0f9cde2b 100644 Binary files a/src/Toplex_map/doc/map.png and b/src/Toplex_map/doc/map.png differ diff --git a/src/Toplex_map/example/CMakeLists.txt b/src/Toplex_map/example/CMakeLists.txt index 346d35d0..1d54fe87 100644 --- a/src/Toplex_map/example/CMakeLists.txt +++ b/src/Toplex_map/example/CMakeLists.txt @@ -1,5 +1,4 @@ project(Toplex_map_examples) -add_executable(simple_toplex_map simple_toplex_map.cpp) -#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) +add_executable(Toplex_map_example_simple_toplex_map simple_toplex_map.cpp) +add_test(NAME Toplex_map_example_simple_toplex_map COMMAND $) -- cgit v1.2.3 From c882b0478d4b0899005bf6c0e9528a1fc8785cf9 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 16 Oct 2018 08:35:12 +0000 Subject: Toplex definition Remove witness complex graph to compare Toplex_map vs Simplex_tree git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3955 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5a1fc1be157b74963faa98b7844b8b47e54a82b6 --- src/Toplex_map/doc/Intro_Toplex_map.h | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h index e3f18b32..93534e0e 100644 --- a/src/Toplex_map/doc/Intro_Toplex_map.h +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -2,7 +2,7 @@ * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * - * Author: François Godi + * Author: François Godi, Vincent Rouvreau * * Copyright (C) 2017 INRIA * @@ -32,27 +32,24 @@ namespace Gudhi { * @{ * * \section toplexmapdefinition Definition - * - * Let's consider a simplicial complex, denote by \f$d\f$ its dimension - * and by \f$k\f$ its number of maximal simplices. - * Furthermore, denote by \f$\gamma_0\f$ the maximal number of toplices, i.e. maximal simplices, - * that contain a same vertex. * - * The goal of the Toplex Map is both to represent the complex in optimal - * O(kd) space and to provide fast standard operations such as : insertion, removal - * and membership of a simplex, contraction of an edge, collapses. The time needed - * for these operation is linear or quadratic in \f$\gamma_0\f$ and \f$d\f$. + * A Toplex_map is a data structure to represent and store a simplicial complex. A "toplex" is the contraction of + * "top-simplex", also known as a maximal simplex. We will call "toplices" a set of "toplex". * - * Toplex map is composed firstly of a raw storage of toplices and secondly of a - * map which associate any vertex to a set of pointers toward all toplices - * containing this vertex. + * Let's consider a simplicial complex, denote by \f$d\f$ its dimension and by \f$k\f$ its number of maximal simplices. + * Furthermore, denote by \f$\gamma_0\f$ the maximal number of toplices, i.e. maximal simplices, that contain a same + * vertex. * - * \image html map.png + * The goal of the Toplex Map is both to represent the complex in optimal O(kd) space and to provide fast standard + * operations such as : insertion, removal, contraction of an edge, collapses and membership of a simplex. The time + * needed for these operation is linear or quadratic in \f$\gamma_0\f$ and \f$d\f$. * - * The performances are a lot better than in simplex tree as soon you use maximal simplices and not simplices, - * here the construction of a strong witness complex of a point set with growing parameter : + * Toplex map is composed firstly of a raw storage of toplices and secondly of a map which associate any vertex to a + * set of pointers toward all toplices containing this vertex. + * + * \image html map.png * - * \image html graph.png + * The performances are a lot better than the `Simplex_tree` as soon you use maximal simplices and not simplices. * */ /** @} */ // end defgroup toplex_map -- cgit v1.2.3 From c71dce7fe646cd4ca4da5f385cb0d97535e4d941 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 16 Oct 2018 13:57:50 +0000 Subject: Add lazy_toplex_map_unit_test Class documentation rewrite Fix conventions in code git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3956 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 65f79ee3c0f22157b2cedfc498e5d9c97dd055f6 --- src/Toplex_map/benchmark/chrono.cpp | 5 +- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 123 +++++------ src/Toplex_map/include/gudhi/Toplex_map.h | 13 +- src/Toplex_map/test/CMakeLists.txt | 5 +- src/Toplex_map/test/lazy_toplex_map_unit_test.cpp | 78 +++++++ src/Toplex_map/test/toplex_map_unit_test.cpp | 237 +++++++++------------- 6 files changed, 253 insertions(+), 208 deletions(-) create mode 100644 src/Toplex_map/test/lazy_toplex_map_unit_test.cpp (limited to 'src') diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp index de6d701f..e6172c61 100644 --- a/src/Toplex_map/benchmark/chrono.cpp +++ b/src/Toplex_map/benchmark/chrono.cpp @@ -107,7 +107,10 @@ void chrono(int n, int d){ end = std::chrono::system_clock::now(); auto c2 = std::chrono::duration_cast(end-start).count(); - std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; + if (c3 > 0) + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; + else + std::cout << c1 << "\t \t" << c2 << "\t \tN/A\t \t" << K.num_maximal_simplices() << std::endl; } int main(){ diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h index 434fea47..5461c0a3 100644 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h @@ -6,84 +6,90 @@ namespace Gudhi { -/** A Lazy_Toplex_map represents the simplicial complex. - * A "toplex" is a maximal simplex but not all simplices in a LTM are toplices. - * \ingroup toplex_map */ +/** + * \brief Lazy toplex map data structure for representing unfiltered simplicial complexes. + * + * \details A Toplex_map is an unordered map from vertices to maximal simplices (aka. toplices). + * The lazy version is not always up to date as it requires clean operation in order to be. + * + * \ingroup toplex_map */ class Lazy_Toplex_map { public: + /** Vertex is the type of vertices. */ + using Vertex = Toplex_map::Vertex; - /** Vertex is the type of vertices. */ - typedef Toplex_map::Vertex Vertex; + /** Simplex is the type of simplices. */ + using Simplex = Toplex_map::Simplex; - /** Simplex is the type of simplices. */ - typedef Toplex_map::Simplex Simplex; + /** The type of the pointers to maximal simplices. */ + using Simplex_ptr = Toplex_map::Simplex_ptr; - /** The type of the pointers to maximal simplices. */ - typedef Toplex_map::Simplex_ptr Simplex_ptr; + /** The type of the sets of Simplex_ptr. */ + using Simplex_ptr_set = Toplex_map::Simplex_ptr_set; - /** The type of the sets of Simplex_ptr. */ - typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; + /** Adds the given simplex to the complex. + * The simplex must not have maximal coface in the complex. */ + template + void insert_independent_simplex(const Input_vertex_range &vertex_range); - /** Adds the given simplex to the complex. - * The simplex must not have maximal coface in the complex. */ - template - void insert_independent_simplex(const Input_vertex_range &vertex_range); + /** \brief Adds the given simplex to the complex. + * Nothing happens if the simplex has a coface in the complex. */ + template + bool insert_simplex(const Input_vertex_range &vertex_range); - /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. */ - template - bool insert_simplex(const Input_vertex_range &vertex_range); + /** \brief Removes the given simplex and its cofaces from the complex. + * Its faces are kept inside. */ + template + void remove_simplex(const Input_vertex_range &vertex_range); - /** \brief Removes the given simplex and its cofaces from the complex. - * Its faces are kept inside. */ - template - void remove_simplex(const Input_vertex_range &vertex_range); + /** Does a simplex belong to the complex ? */ + template + bool membership(const Input_vertex_range &vertex_range); - /** Does a simplex belong to the complex ? */ - template - bool membership(const Input_vertex_range &vertex_range); + /** Do all the facets of a simplex belong to the complex ? */ + template + bool all_facets_inside(const Input_vertex_range &vertex_range); - /** Do all the facets of a simplex belong to the complex ? */ - template - bool all_facets_inside(const Input_vertex_range &vertex_range); + /** Contracts one edge in the complex. + * The edge has to verify the link condition if you want to preserve topology. + * Returns the remaining vertex. */ + Vertex contraction(const Vertex x, const Vertex y); - /** Contracts one edge in the complex. - * The edge has to verify the link condition if you want to preserve topology. - * Returns the remaining vertex. */ - Vertex contraction(const Vertex x, const Vertex y); - - /** \brief Number of maximal simplices. */ - std::size_t num_maximal_simplices() const; + /** \brief Number of maximal simplices. */ + std::size_t num_maximal_simplices() const { + return size; + } /** \brief Number of vertices. */ std::size_t num_vertices() const{ return t0.size(); } - std::unordered_map gamma0_lbounds; private: - template - void erase_max(const Input_vertex_range &vertex_range); - template - Vertex best_index(const Input_vertex_range &vertex_range); - void clean(const Vertex v); + template + void erase_max(const Input_vertex_range &vertex_range); + template + Vertex best_index(const Input_vertex_range &vertex_range); + void clean(const Vertex v); + + std::unordered_map gamma0_lbounds; - std::unordered_map t0; - bool empty_toplex; // Is the empty simplex a toplex ? + std::unordered_map t0; + bool empty_toplex; // Is the empty simplex a toplex ? - typedef boost::heap::fibonacci_heap> PriorityQueue; - PriorityQueue cleaning_priority; - std::unordered_map cp_handles; + typedef boost::heap::fibonacci_heap> PriorityQueue; + PriorityQueue cleaning_priority; + std::unordered_map cp_handles; - std::size_t get_gamma0_lbound(const Vertex v) const; + std::size_t get_gamma0_lbound(const Vertex v) const; - std::size_t size_lbound = 0; - std::size_t size = 0; + std::size_t size_lbound = 0; + std::size_t size = 0; - const double alpha = 4; //time - const double betta = 8; //memory + const double ALPHA = 4; //time + const double BETTA = 8; //memory }; template @@ -112,7 +118,7 @@ bool Lazy_Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ } if(inserted) size++; - if(size > (size_lbound+1) * betta) + if(size > (size_lbound+1) * BETTA) clean(cleaning_priority.top().second); return inserted; } @@ -167,7 +173,7 @@ bool Lazy_Toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ } /* Returns the remaining vertex */ -Toplex_map::Vertex Lazy_Toplex_map::contraction(const Vertex x, const Vertex y){ +Lazy_Toplex_map::Vertex Lazy_Toplex_map::contraction(const Vertex x, const Vertex y){ if(!t0.count(x)) return y; if(!t0.count(y)) return x; Vertex k, d; @@ -204,14 +210,14 @@ inline void Lazy_Toplex_map::erase_max(const Input_vertex_range &vertex_range){ } template -Toplex_map::Vertex Lazy_Toplex_map::best_index(const Input_vertex_range &vertex_range){ +Lazy_Toplex_map::Vertex Lazy_Toplex_map::best_index(const Input_vertex_range &vertex_range) { Simplex tau(vertex_range.begin(),vertex_range.end()); std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; for(const Vertex& v : tau) if(!t0.count(v)) return v; else if(t0.at(v).size() < min) min = t0.at(v).size(), arg_min = v; - if(min > alpha * get_gamma0_lbound(arg_min)) + if(min > ALPHA * get_gamma0_lbound(arg_min)) clean(arg_min); return arg_min; } @@ -220,7 +226,6 @@ std::size_t Lazy_Toplex_map::get_gamma0_lbound(const Vertex v) const{ return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; } - void Lazy_Toplex_map::clean(const Vertex v){ Toplex_map toplices; std::unordered_map> dsorted_simplices; @@ -246,10 +251,6 @@ void Lazy_Toplex_map::clean(const Vertex v){ insert_simplex(*sptr); } -std::size_t Lazy_Toplex_map::num_maximal_simplices() const{ - return size; -} - } //namespace Gudhi #endif /* LAZY_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 7cde8ea1..b7a5db41 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -10,8 +10,11 @@ namespace Gudhi { -/** A Toplex_map represents the simplicial complex. - * A "toplex" is a maximal simplex. +/** + * \brief Toplex map data structure for representing unfiltered simplicial complexes. + * + * \details A Toplex_map is an unordered map from vertices to maximal simplices (aka. toplices). + * * \ingroup toplex_map */ class Toplex_map { @@ -100,7 +103,7 @@ protected: /** \internal The map from vertices to toplices */ std::unordered_map t0; - const Toplex_map::Vertex vertex_upper_bound = std::numeric_limits::max(); + const Toplex_map::Vertex VERTEX_UPPER_BOUND = std::numeric_limits::max(); /** \internal Removes a toplex without adding facets after. */ void erase_maximal(const Toplex_map::Simplex_ptr& sptr); @@ -258,7 +261,7 @@ void Toplex_map::remove_vertex(const Toplex_map::Vertex x){ inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr){ Simplex sigma(*sptr); if (sptr->size()==0) - sigma.insert(vertex_upper_bound); + sigma.insert(VERTEX_UPPER_BOUND); for(const Toplex_map::Vertex& v : sigma){ t0.at(v).erase(sptr); if(t0.at(v).size()==0) t0.erase(v); @@ -268,7 +271,7 @@ inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr){ template Toplex_map::Vertex Toplex_map::best_index(const Input_vertex_range &vertex_range) const{ std::size_t min = std::numeric_limits::max(); - Vertex arg_min = vertex_upper_bound; + Vertex arg_min = VERTEX_UPPER_BOUND; for(const Toplex_map::Vertex& v : vertex_range) if(!t0.count(v)) return v; else if(t0.at(v).size() < min) diff --git a/src/Toplex_map/test/CMakeLists.txt b/src/Toplex_map/test/CMakeLists.txt index 237cfdad..59517db5 100644 --- a/src/Toplex_map/test/CMakeLists.txt +++ b/src/Toplex_map/test/CMakeLists.txt @@ -4,5 +4,8 @@ include(GUDHI_test_coverage) add_executable( Toplex_map_unit_test toplex_map_unit_test.cpp ) target_link_libraries(Toplex_map_unit_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) - gudhi_add_coverage_test(Toplex_map_unit_test) + +add_executable( Lazy_toplex_map_unit_test lazy_toplex_map_unit_test.cpp ) +target_link_libraries(Lazy_toplex_map_unit_test ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +gudhi_add_coverage_test(Lazy_toplex_map_unit_test) diff --git a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp new file mode 100644 index 00000000..77d464ae --- /dev/null +++ b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp @@ -0,0 +1,78 @@ +#include +#include +#include + + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "lazy toplex map" +#include + +BOOST_AUTO_TEST_CASE(toplex_map) { + using Vertex = Gudhi::Lazy_Toplex_map::Vertex; + + Gudhi::Lazy_Toplex_map tm; + std::cout << "insert_simplex {1, 2, 3, 4}" << std::endl; + std::vector sigma1 = {1, 2, 3, 4}; + tm.insert_simplex(sigma1); + std::cout << "insert_simplex {5, 2, 3, 6}" << std::endl; + std::vector sigma2 = {5, 2, 3, 6}; + tm.insert_simplex(sigma2); + std::cout << "insert_simplex {5}" << std::endl; + std::vector sigma3 = {5}; + tm.insert_simplex(sigma3); + std::cout << "insert_simplex {4, 5, 3}" << std::endl; + std::vector sigma6 = {4, 5, 3}; + tm.insert_simplex(sigma6); + std::cout << "insert_simplex {4, 5, 9}" << std::endl; + std::vector sigma7 = {4, 5, 9}; + tm.insert_simplex(sigma7); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 5); + + std::vector sigma4 = {5, 2, 3}; + std::vector sigma5 = {5, 2, 7}; + BOOST_CHECK(tm.membership(sigma4)); + BOOST_CHECK(!tm.membership(sigma5)); + std::cout << "insert_simplex {5, 2, 7}" << std::endl; + tm.insert_simplex(sigma5); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 6); + + BOOST_CHECK(tm.membership(sigma5)); + + std::cout << "contraction(4,5)" << std::endl; + auto r = tm.contraction(4,5); + std::cout << "r=" << r << std::endl; + BOOST_CHECK(r == 5); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 6); + + std::vector sigma8 = {1, 2, 3}; + std::vector sigma9 = {2, 7}; + + sigma8.emplace_back(r); + sigma9.emplace_back(r); + BOOST_CHECK(!tm.membership(sigma6)); + BOOST_CHECK(tm.membership(sigma8)); + BOOST_CHECK(tm.membership(sigma9)); + + std::cout << "remove_simplex({2, 7, r = 5})" << std::endl; + tm.remove_simplex(sigma9); + BOOST_CHECK(!tm.membership(sigma9)); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 8); + + // {2, 7, 5} is removed, but verify its edges are still there + std::vector edge = {2, 7}; + BOOST_CHECK(tm.membership(edge)); + edge = {2, 5}; + BOOST_CHECK(tm.membership(edge)); + edge = {7, 5}; + BOOST_CHECK(tm.membership(edge)); + +} + diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index 9ee5dff2..59c104ce 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -1,162 +1,119 @@ #include #include -#include +#include #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "toplex map" #include -#include -using list_of_tested_variants = boost::mpl::list; - -BOOST_AUTO_TEST_CASE_TEMPLATE(common_toplex_map_functionnalities, Toplex_map, list_of_tested_variants) { - using Vertex = typename Toplex_map::Vertex; +BOOST_AUTO_TEST_CASE(toplex_map) { + using Vertex = Gudhi::Toplex_map::Vertex; + Gudhi::Toplex_map tm; + std::cout << "insert_simplex {1, 2, 3, 4}" << std::endl; std::vector sigma1 = {1, 2, 3, 4}; + tm.insert_simplex(sigma1); + std::cout << "insert_simplex {5, 2, 3, 6}" << std::endl; std::vector sigma2 = {5, 2, 3, 6}; + tm.insert_simplex(sigma2); + std::cout << "insert_simplex {5}" << std::endl; std::vector sigma3 = {5}; - std::vector sigma4 = {5, 2, 3}; - std::vector sigma5 = {5, 2, 7}; + tm.insert_simplex(sigma3); + std::cout << "insert_simplex {4, 5, 3}" << std::endl; std::vector sigma6 = {4, 5, 3}; + tm.insert_simplex(sigma6); + std::cout << "insert_simplex {4, 5, 9}" << std::endl; std::vector sigma7 = {4, 5, 9}; - std::vector sigma8 = {1, 2, 3, 6}; - - Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma6); - K.insert_simplex(sigma7); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - - BOOST_CHECK(K.membership(sigma4)); - //BOOST_CHECK(!K.maximality(sigma3)); - BOOST_CHECK(!K.membership(sigma5)); - K.insert_simplex(sigma5); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - - BOOST_CHECK(K.membership(sigma5)); - std::vector sigma9 = {1, 2, 3}; - std::vector sigma10 = {2, 7}; - auto r = K.contraction(4,5); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - - sigma9.emplace_back(r); - sigma10.emplace_back(r); - BOOST_CHECK(!K.membership(sigma6)); - BOOST_CHECK(K.membership(sigma9)); - BOOST_CHECK(K.membership(sigma10)); - K.remove_simplex(sigma10); - BOOST_CHECK(!K.membership(sigma10)); - -} - -BOOST_AUTO_TEST_CASE(toplex_map_num_maximal_simplices) { - using Vertex = Gudhi::Toplex_map::Vertex; - - Gudhi::Toplex_map K; - std::vector sigma1 = {1, 2, 3, 4}; - std::vector sigma2 = {5, 2, 3, 6}; - std::vector sigma3 = {4, 5, 3}; - std::vector sigma4 = {4, 5, 9}; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma4); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 4); - - std::vector sigma5 = {5, 2, 7}; - K.insert_simplex(sigma5); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 5); - - auto r = K.contraction(4,5); - std::cout << "r=" << r << std::endl; - BOOST_CHECK(r == 5); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 4); - - std::vector sigma6 = {2, 7}; - K.remove_simplex(sigma6); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 4); - - K.remove_simplex(sigma2); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 6); -} - -BOOST_AUTO_TEST_CASE(lazy_toplex_map_num_maximal_simplices) { - using Vertex = Gudhi::Lazy_Toplex_map::Vertex; - - Gudhi::Lazy_Toplex_map K; - std::vector sigma1 = {1, 2, 3, 4}; - std::vector sigma2 = {5, 2, 3, 6}; - std::vector sigma3 = {4, 5, 3}; - std::vector sigma4 = {4, 5, 9}; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma4); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 4); + tm.insert_simplex(sigma7); + + std::cout << "num_maximal_simplices" << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 4); + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + BOOST_CHECK(tm.maximality(*simplex_ptr)); + } + + BOOST_CHECK(tm.maximality(sigma1)); + BOOST_CHECK(tm.maximality(sigma2)); + BOOST_CHECK(!tm.maximality(sigma3)); + BOOST_CHECK(tm.maximality(sigma6)); + BOOST_CHECK(tm.maximality(sigma7)); + std::vector sigma4 = {5, 2, 3}; std::vector sigma5 = {5, 2, 7}; - K.insert_simplex(sigma5); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 5); - - auto r = K.contraction(4,5); + BOOST_CHECK(tm.membership(sigma4)); + BOOST_CHECK(!tm.membership(sigma5)); + std::cout << "insert_simplex {5, 2, 7}" << std::endl; + tm.insert_simplex(sigma5); + + std::cout << "num_maximal_simplices" << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 5); + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + BOOST_CHECK(tm.maximality(*simplex_ptr)); + } + + BOOST_CHECK(tm.membership(sigma5)); + + std::cout << "contraction(4,5)" << std::endl; + auto r = tm.contraction(4,5); std::cout << "r=" << r << std::endl; BOOST_CHECK(r == 5); - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 5); - - std::vector sigma6 = {2, 7}; - K.remove_simplex(sigma6); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 6); - - K.remove_simplex(sigma2); - - std::cout << "num_maximal_simplices" << K.num_maximal_simplices() << std::endl; - BOOST_CHECK(K.num_maximal_simplices() == 9); - -} - -BOOST_AUTO_TEST_CASE(toplex_map_maximality) { - using Vertex = Gudhi::Toplex_map::Vertex; + std::cout << "num_maximal_simplices" << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 4); + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + BOOST_CHECK(tm.maximality(*simplex_ptr)); + } + + std::vector sigma8 = {1, 2, 3}; + std::vector sigma9 = {2, 7}; + + sigma8.emplace_back(r); + sigma9.emplace_back(r); + BOOST_CHECK(!tm.membership(sigma6)); + BOOST_CHECK(tm.membership(sigma8)); + BOOST_CHECK(tm.membership(sigma9)); + + std::cout << "remove_simplex({2, 7, r = 5})" << std::endl; + tm.remove_simplex(sigma9); + BOOST_CHECK(!tm.membership(sigma9)); + + std::cout << "num_maximal_simplices" << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 5); + // Browse maximal simplices + std::cout << "Maximal simplices are :" << std::endl; + for (auto simplex_ptr : tm.maximal_simplices()) { + for (auto v : *simplex_ptr) { + std::cout << v << ", "; + } + std::cout << std::endl; + BOOST_CHECK(tm.maximality(*simplex_ptr)); + } + // {2, 7, 5} is removed, but verify its edges are still there + std::vector edge = {2, 7}; + BOOST_CHECK(tm.membership(edge)); + edge = {2, 5}; + BOOST_CHECK(tm.membership(edge)); + edge = {7, 5}; + BOOST_CHECK(tm.membership(edge)); - std::vector sigma1 = {1, 2, 3, 4}; - std::vector sigma2 = {5, 2, 3, 6}; - std::vector sigma3 = {5}; - std::vector sigma4 = {4, 5, 3}; - std::vector sigma5 = {4, 5, 9}; - - Gudhi::Toplex_map K; - K.insert_simplex(sigma1); - K.insert_simplex(sigma2); - K.insert_simplex(sigma3); - K.insert_simplex(sigma4); - K.insert_simplex(sigma5); - BOOST_CHECK(K.maximality(sigma1)); - BOOST_CHECK(K.maximality(sigma2)); - BOOST_CHECK(!K.maximality(sigma3)); - BOOST_CHECK(K.maximality(sigma4)); - BOOST_CHECK(K.maximality(sigma5)); } -- cgit v1.2.3 From 418180d74ea25cfc70a272ab7e883d93ecb31e93 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 16 Oct 2018 14:06:53 +0000 Subject: Rename Lazy_Toplex_map accordingly to code conventions git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3957 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7e73d088dbc458f42219e6f7a50baf98d8db65ed --- src/Toplex_map/benchmark/CMakeLists.txt | 2 +- src/Toplex_map/benchmark/benchmark_tm.cpp | 129 +++++++++++ src/Toplex_map/benchmark/chrono.cpp | 129 ----------- src/Toplex_map/example/simple_toplex_map.cpp | 4 +- src/Toplex_map/include/gudhi/Lazy_Toplex_map.h | 256 ---------------------- src/Toplex_map/include/gudhi/Lazy_toplex_map.h | 256 ++++++++++++++++++++++ src/Toplex_map/test/lazy_toplex_map_unit_test.cpp | 6 +- 7 files changed, 391 insertions(+), 391 deletions(-) create mode 100644 src/Toplex_map/benchmark/benchmark_tm.cpp delete mode 100644 src/Toplex_map/benchmark/chrono.cpp delete mode 100644 src/Toplex_map/include/gudhi/Lazy_Toplex_map.h create mode 100644 src/Toplex_map/include/gudhi/Lazy_toplex_map.h (limited to 'src') diff --git a/src/Toplex_map/benchmark/CMakeLists.txt b/src/Toplex_map/benchmark/CMakeLists.txt index c2f216bc..2d58a156 100644 --- a/src/Toplex_map/benchmark/CMakeLists.txt +++ b/src/Toplex_map/benchmark/CMakeLists.txt @@ -1,3 +1,3 @@ project(Toplex_map_benchmark) -add_executable(toplex_map_chrono chrono.cpp) +add_executable(Toplex_map_benchmark benchmark_tm.cpp) diff --git a/src/Toplex_map/benchmark/benchmark_tm.cpp b/src/Toplex_map/benchmark/benchmark_tm.cpp new file mode 100644 index 00000000..5f13288c --- /dev/null +++ b/src/Toplex_map/benchmark/benchmark_tm.cpp @@ -0,0 +1,129 @@ +#include +#include +#include + +#include +#include +#include + +using namespace Gudhi; + +typedef Toplex_map::Simplex Simplex; +typedef Toplex_map::Vertex Vertex; +typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +class ST_wrapper { + +public: + void insert_simplex(const Simplex& tau) { + /*std::cout << "insert_simplex - " << simplexTree.num_simplices() << " - "; + for (auto v : tau) + std::cout << v << ", "; + std::cout << std::endl; + */ + simplexTree.insert_simplex_and_subfaces(tau); + } + + bool membership(const Simplex& tau) { + return simplexTree.find(tau) != simplexTree.null_simplex(); + } + + Vertex contraction(const Vertex x, const Vertex y) { + // TODO (VR): edge contraction is not yet available for Simplex_tree + return y; + } + + std::size_t num_maximal_simplices() { + return simplexTree.num_simplices(); + } + +private: + Simplex_tree<> simplexTree; + void erase_max(const Simplex& sigma) { + if(membership(sigma)) + simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); + } +}; + + +int n = 300; + +int nb_insert_simplex1 = 3000; +int nb_membership1 = 4000; +int nb_contraction = 300; +int nb_insert_simplex2 = 3000; +int nb_membership2 = 400000; + +Simplex random_simplex(int n, std::size_t d){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(1, n); + Simplex s; + while(s.size() < d) + s.insert(dis(gen)); + return s; +} + +std::vector r_vector_simplices(int n, int max_d, int m){ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(1, max_d); + std::vector v; + for(int i=0; i +void chrono(int n, int d){ + complex_type K; + std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); + std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); + std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); + std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); + std::chrono::time_point start, end; + + for(const Simplex& s : simplices_insert_simplex1) + K.insert_simplex(s); + + for(const Simplex& s : simplices_membership1) + K.membership(s); + + start = std::chrono::system_clock::now(); + for(int i = 1; i<=nb_contraction; i++) + K.contraction(n-2*i,n-2*i-1); + end = std::chrono::system_clock::now(); + auto c3 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_insert_simplex2) + K.insert_simplex(s); + end = std::chrono::system_clock::now(); + auto c1 = std::chrono::duration_cast(end-start).count(); + + start = std::chrono::system_clock::now(); + for(const Simplex& s : simplices_membership2) + K.membership(s); + end = std::chrono::system_clock::now(); + auto c2 = std::chrono::duration_cast(end-start).count(); + + if (c3 > 0) + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; + else + std::cout << c1 << "\t \t" << c2 << "\t \tN/A\t \t" << K.num_maximal_simplices() << std::endl; +} + +int main(){ + for(int d=5;d<=40;d+=5){ + std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; + std::cout << "T Map \t \t"; + chrono(n,d); + std::cout << "Lazy \t \t"; + chrono(n,d); + if(d<=15){ + std::cout << "ST \t \t"; + chrono(n,d); + } + std::cout << std::endl; + } +} diff --git a/src/Toplex_map/benchmark/chrono.cpp b/src/Toplex_map/benchmark/chrono.cpp deleted file mode 100644 index e6172c61..00000000 --- a/src/Toplex_map/benchmark/chrono.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -using namespace Gudhi; - -typedef Toplex_map::Simplex Simplex; -typedef Toplex_map::Vertex Vertex; -typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - -class ST_wrapper { - -public: - void insert_simplex(const Simplex& tau) { - /*std::cout << "insert_simplex - " << simplexTree.num_simplices() << " - "; - for (auto v : tau) - std::cout << v << ", "; - std::cout << std::endl; - */ - simplexTree.insert_simplex_and_subfaces(tau); - } - - bool membership(const Simplex& tau) { - return simplexTree.find(tau) != simplexTree.null_simplex(); - } - - Vertex contraction(const Vertex x, const Vertex y) { - // TODO (VR): edge contraction is not yet available for Simplex_tree - return y; - } - - std::size_t num_maximal_simplices() { - return simplexTree.num_simplices(); - } - -private: - Simplex_tree<> simplexTree; - void erase_max(const Simplex& sigma) { - if(membership(sigma)) - simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); - } -}; - - -int n = 300; - -int nb_insert_simplex1 = 3000; -int nb_membership1 = 4000; -int nb_contraction = 300; -int nb_insert_simplex2 = 3000; -int nb_membership2 = 400000; - -Simplex random_simplex(int n, std::size_t d){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(1, n); - Simplex s; - while(s.size() < d) - s.insert(dis(gen)); - return s; -} - -std::vector r_vector_simplices(int n, int max_d, int m){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(1, max_d); - std::vector v; - for(int i=0; i -void chrono(int n, int d){ - complex_type K; - std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); - std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); - std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); - std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); - std::chrono::time_point start, end; - - for(const Simplex& s : simplices_insert_simplex1) - K.insert_simplex(s); - - for(const Simplex& s : simplices_membership1) - K.membership(s); - - start = std::chrono::system_clock::now(); - for(int i = 1; i<=nb_contraction; i++) - K.contraction(n-2*i,n-2*i-1); - end = std::chrono::system_clock::now(); - auto c3 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_insert_simplex2) - K.insert_simplex(s); - end = std::chrono::system_clock::now(); - auto c1 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_membership2) - K.membership(s); - end = std::chrono::system_clock::now(); - auto c2 = std::chrono::duration_cast(end-start).count(); - - if (c3 > 0) - std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; - else - std::cout << c1 << "\t \t" << c2 << "\t \tN/A\t \t" << K.num_maximal_simplices() << std::endl; -} - -int main(){ - for(int d=5;d<=40;d+=5){ - std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; - std::cout << "T Map \t \t"; - chrono(n,d); - std::cout << "Lazy \t \t"; - chrono(n,d); - if(d<=15){ - std::cout << "ST \t \t"; - chrono(n,d); - } - std::cout << std::endl; - } -} diff --git a/src/Toplex_map/example/simple_toplex_map.cpp b/src/Toplex_map/example/simple_toplex_map.cpp index 0d80f94e..912d79a0 100644 --- a/src/Toplex_map/example/simple_toplex_map.cpp +++ b/src/Toplex_map/example/simple_toplex_map.cpp @@ -4,7 +4,7 @@ * * Author(s): Vincent Rouvreau * - * Copyright (C) 2017 + * Copyright (C) 2018 * * 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 @@ -20,12 +20,12 @@ * along with this program. If not, see . */ -#include #include #include #include // for pair #include +#include int main(int argc, char * const argv[]) { using Simplex = Gudhi::Toplex_map::Simplex; diff --git a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h deleted file mode 100644 index 5461c0a3..00000000 --- a/src/Toplex_map/include/gudhi/Lazy_Toplex_map.h +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef LAZY_TOPLEX_MAP_H -#define LAZY_TOPLEX_MAP_H - -#include -#include - -namespace Gudhi { - -/** - * \brief Lazy toplex map data structure for representing unfiltered simplicial complexes. - * - * \details A Toplex_map is an unordered map from vertices to maximal simplices (aka. toplices). - * The lazy version is not always up to date as it requires clean operation in order to be. - * - * \ingroup toplex_map */ -class Lazy_Toplex_map { - -public: - /** Vertex is the type of vertices. */ - using Vertex = Toplex_map::Vertex; - - /** Simplex is the type of simplices. */ - using Simplex = Toplex_map::Simplex; - - /** The type of the pointers to maximal simplices. */ - using Simplex_ptr = Toplex_map::Simplex_ptr; - - /** The type of the sets of Simplex_ptr. */ - using Simplex_ptr_set = Toplex_map::Simplex_ptr_set; - - /** Adds the given simplex to the complex. - * The simplex must not have maximal coface in the complex. */ - template - void insert_independent_simplex(const Input_vertex_range &vertex_range); - - /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. */ - template - bool insert_simplex(const Input_vertex_range &vertex_range); - - /** \brief Removes the given simplex and its cofaces from the complex. - * Its faces are kept inside. */ - template - void remove_simplex(const Input_vertex_range &vertex_range); - - /** Does a simplex belong to the complex ? */ - template - bool membership(const Input_vertex_range &vertex_range); - - - /** Do all the facets of a simplex belong to the complex ? */ - template - bool all_facets_inside(const Input_vertex_range &vertex_range); - - /** Contracts one edge in the complex. - * The edge has to verify the link condition if you want to preserve topology. - * Returns the remaining vertex. */ - Vertex contraction(const Vertex x, const Vertex y); - - /** \brief Number of maximal simplices. */ - std::size_t num_maximal_simplices() const { - return size; - } - - /** \brief Number of vertices. */ - std::size_t num_vertices() const{ - return t0.size(); - } - -private: - template - void erase_max(const Input_vertex_range &vertex_range); - template - Vertex best_index(const Input_vertex_range &vertex_range); - void clean(const Vertex v); - - std::unordered_map gamma0_lbounds; - - std::unordered_map t0; - bool empty_toplex; // Is the empty simplex a toplex ? - - typedef boost::heap::fibonacci_heap> PriorityQueue; - PriorityQueue cleaning_priority; - std::unordered_map cp_handles; - - std::size_t get_gamma0_lbound(const Vertex v) const; - - std::size_t size_lbound = 0; - std::size_t size = 0; - - const double ALPHA = 4; //time - const double BETTA = 8; //memory -}; - -template -void Lazy_Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ - for(const Vertex& v : vertex_range) - if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); - else gamma0_lbounds[v]++; - size_lbound++; - insert_simplex(vertex_range); -} - -template -bool Lazy_Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - empty_toplex = (sigma.size()==0); //vérifier la gestion de empty face - Simplex_ptr sptr = std::make_shared(sigma); - bool inserted = false; - for(const Vertex& v : sigma){ - if(!t0.count(v)){ - t0.emplace(v, Simplex_ptr_set()); - auto v_handle = cleaning_priority.push(std::make_pair(0, v)); - cp_handles.emplace(v, v_handle); - } - inserted = t0.at(v).emplace(sptr).second; - cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v),v)); - } - if(inserted) - size++; - if(size > (size_lbound+1) * BETTA) - clean(cleaning_priority.top().second); - return inserted; -} - -template -void Lazy_Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ - if(vertex_range.begin()==vertex_range.end()){ - t0.clear(); - gamma0_lbounds.clear(); - cleaning_priority.clear(); - size_lbound = 0; - size = 0; - empty_toplex = false; - } - else { - const Vertex& v = best_index(vertex_range); - //Copy constructor needed because the set is modified - if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) - if(included(vertex_range, *sptr)){ - erase_max(*sptr); - for(const Simplex& f : facets(vertex_range)) - insert_independent_simplex(f); - } - } -} - -template -bool Lazy_Toplex_map::membership(const Input_vertex_range &vertex_range){ - if(t0.size()==0 && !empty_toplex) return false; //empty complex - if(vertex_range.begin()==vertex_range.end()) return true; //empty query simplex - Vertex v = best_index(vertex_range); - if(!t0.count(v)) return false; - for(const Simplex_ptr& sptr : t0.at(v)) - if(included(vertex_range, *sptr)) return true; - return false; -} - -template -bool Lazy_Toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - Vertex v = best_index(sigma); - if(!t0.count(v)) return false; - Simplex f = sigma; f.erase(v); - if(!membership(f)) return false; - std::unordered_set facets_inside; - for(const Simplex_ptr& sptr : t0.at(v)) - for(const Vertex& w : sigma){ - f = sigma; f.erase(w); - if(included(f, *sptr)) facets_inside.insert(w); - } - return facets_inside.size() == sigma.size() - 1; -} - -/* Returns the remaining vertex */ -Lazy_Toplex_map::Vertex Lazy_Toplex_map::contraction(const Vertex x, const Vertex y){ - if(!t0.count(x)) return y; - if(!t0.count(y)) return x; - Vertex k, d; - if(t0.at(x).size() > t0.at(y).size()) - k=x, d=y; - else - k=y, d=x; - //Copy constructor needed because the set is modified - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ - Simplex sigma(*sptr); - erase_max(sigma); - sigma.erase(d); - sigma.insert(k); - insert_simplex(sigma); - } - t0.erase(d); - return k; -} - -/* No facets insert_simplexed */ -template -inline void Lazy_Toplex_map::erase_max(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - empty_toplex = false; - Simplex_ptr sptr = std::make_shared(sigma); - bool erased=false; - for(const Vertex& v : sigma){ - erased = t0.at(v).erase(sptr) > 0; - if(t0.at(v).size()==0) - t0.erase(v); - } - if (erased) - size--; -} - -template -Lazy_Toplex_map::Vertex Lazy_Toplex_map::best_index(const Input_vertex_range &vertex_range) { - Simplex tau(vertex_range.begin(),vertex_range.end()); - std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; - for(const Vertex& v : tau) - if(!t0.count(v)) return v; - else if(t0.at(v).size() < min) - min = t0.at(v).size(), arg_min = v; - if(min > ALPHA * get_gamma0_lbound(arg_min)) - clean(arg_min); - return arg_min; -} - -std::size_t Lazy_Toplex_map::get_gamma0_lbound(const Vertex v) const{ - return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; -} - -void Lazy_Toplex_map::clean(const Vertex v){ - Toplex_map toplices; - std::unordered_map> dsorted_simplices; - std::size_t max_dim = 0; - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ - if(sptr->size() > max_dim){ - for(std::size_t d = max_dim+1; d<=sptr->size(); d++) - dsorted_simplices.emplace(d, std::vector()); - max_dim = sptr->size(); - } - dsorted_simplices[sptr->size()].emplace_back(*sptr); - erase_max(*sptr); - } - for(std::size_t d = max_dim; d>=1; d--) - for(const Simplex &s : dsorted_simplices.at(d)) - if(!toplices.membership(s)) - toplices.insert_independent_simplex(s); - Simplex sv; sv.insert(v); - auto clean_cofaces = toplices.maximal_cofaces(sv); - size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); - gamma0_lbounds[v] = clean_cofaces.size(); - for(const Simplex_ptr& sptr : clean_cofaces) - insert_simplex(*sptr); -} - -} //namespace Gudhi - -#endif /* LAZY_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h new file mode 100644 index 00000000..8cc5610a --- /dev/null +++ b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h @@ -0,0 +1,256 @@ +#ifndef LAZY_TOPLEX_MAP_H +#define LAZY_TOPLEX_MAP_H + +#include +#include + +namespace Gudhi { + +/** + * \brief Lazy toplex map data structure for representing unfiltered simplicial complexes. + * + * \details A Toplex_map is an unordered map from vertices to maximal simplices (aka. toplices). + * The lazy version is not always up to date as it requires clean operation in order to be. + * + * \ingroup toplex_map */ +class Lazy_toplex_map { + +public: + /** Vertex is the type of vertices. */ + using Vertex = Toplex_map::Vertex; + + /** Simplex is the type of simplices. */ + using Simplex = Toplex_map::Simplex; + + /** The type of the pointers to maximal simplices. */ + using Simplex_ptr = Toplex_map::Simplex_ptr; + + /** The type of the sets of Simplex_ptr. */ + using Simplex_ptr_set = Toplex_map::Simplex_ptr_set; + + /** Adds the given simplex to the complex. + * The simplex must not have maximal coface in the complex. */ + template + void insert_independent_simplex(const Input_vertex_range &vertex_range); + + /** \brief Adds the given simplex to the complex. + * Nothing happens if the simplex has a coface in the complex. */ + template + bool insert_simplex(const Input_vertex_range &vertex_range); + + /** \brief Removes the given simplex and its cofaces from the complex. + * Its faces are kept inside. */ + template + void remove_simplex(const Input_vertex_range &vertex_range); + + /** Does a simplex belong to the complex ? */ + template + bool membership(const Input_vertex_range &vertex_range); + + + /** Do all the facets of a simplex belong to the complex ? */ + template + bool all_facets_inside(const Input_vertex_range &vertex_range); + + /** Contracts one edge in the complex. + * The edge has to verify the link condition if you want to preserve topology. + * Returns the remaining vertex. */ + Vertex contraction(const Vertex x, const Vertex y); + + /** \brief Number of maximal simplices. */ + std::size_t num_maximal_simplices() const { + return size; + } + + /** \brief Number of vertices. */ + std::size_t num_vertices() const{ + return t0.size(); + } + +private: + template + void erase_max(const Input_vertex_range &vertex_range); + template + Vertex best_index(const Input_vertex_range &vertex_range); + void clean(const Vertex v); + + std::unordered_map gamma0_lbounds; + + std::unordered_map t0; + bool empty_toplex; // Is the empty simplex a toplex ? + + typedef boost::heap::fibonacci_heap> PriorityQueue; + PriorityQueue cleaning_priority; + std::unordered_map cp_handles; + + std::size_t get_gamma0_lbound(const Vertex v) const; + + std::size_t size_lbound = 0; + std::size_t size = 0; + + const double ALPHA = 4; //time + const double BETTA = 8; //memory +}; + +template +void Lazy_toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ + for(const Vertex& v : vertex_range) + if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); + else gamma0_lbounds[v]++; + size_lbound++; + insert_simplex(vertex_range); +} + +template +bool Lazy_toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + empty_toplex = (sigma.size()==0); //vérifier la gestion de empty face + Simplex_ptr sptr = std::make_shared(sigma); + bool inserted = false; + for(const Vertex& v : sigma){ + if(!t0.count(v)){ + t0.emplace(v, Simplex_ptr_set()); + auto v_handle = cleaning_priority.push(std::make_pair(0, v)); + cp_handles.emplace(v, v_handle); + } + inserted = t0.at(v).emplace(sptr).second; + cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v),v)); + } + if(inserted) + size++; + if(size > (size_lbound+1) * BETTA) + clean(cleaning_priority.top().second); + return inserted; +} + +template +void Lazy_toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ + if(vertex_range.begin()==vertex_range.end()){ + t0.clear(); + gamma0_lbounds.clear(); + cleaning_priority.clear(); + size_lbound = 0; + size = 0; + empty_toplex = false; + } + else { + const Vertex& v = best_index(vertex_range); + //Copy constructor needed because the set is modified + if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) + if(included(vertex_range, *sptr)){ + erase_max(*sptr); + for(const Simplex& f : facets(vertex_range)) + insert_independent_simplex(f); + } + } +} + +template +bool Lazy_toplex_map::membership(const Input_vertex_range &vertex_range){ + if(t0.size()==0 && !empty_toplex) return false; //empty complex + if(vertex_range.begin()==vertex_range.end()) return true; //empty query simplex + Vertex v = best_index(vertex_range); + if(!t0.count(v)) return false; + for(const Simplex_ptr& sptr : t0.at(v)) + if(included(vertex_range, *sptr)) return true; + return false; +} + +template +bool Lazy_toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + Vertex v = best_index(sigma); + if(!t0.count(v)) return false; + Simplex f = sigma; f.erase(v); + if(!membership(f)) return false; + std::unordered_set facets_inside; + for(const Simplex_ptr& sptr : t0.at(v)) + for(const Vertex& w : sigma){ + f = sigma; f.erase(w); + if(included(f, *sptr)) facets_inside.insert(w); + } + return facets_inside.size() == sigma.size() - 1; +} + +/* Returns the remaining vertex */ +Lazy_toplex_map::Vertex Lazy_toplex_map::contraction(const Vertex x, const Vertex y){ + if(!t0.count(x)) return y; + if(!t0.count(y)) return x; + Vertex k, d; + if(t0.at(x).size() > t0.at(y).size()) + k=x, d=y; + else + k=y, d=x; + //Copy constructor needed because the set is modified + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ + Simplex sigma(*sptr); + erase_max(sigma); + sigma.erase(d); + sigma.insert(k); + insert_simplex(sigma); + } + t0.erase(d); + return k; +} + +/* No facets insert_simplexed */ +template +inline void Lazy_toplex_map::erase_max(const Input_vertex_range &vertex_range){ + Simplex sigma(vertex_range.begin(),vertex_range.end()); + empty_toplex = false; + Simplex_ptr sptr = std::make_shared(sigma); + bool erased=false; + for(const Vertex& v : sigma){ + erased = t0.at(v).erase(sptr) > 0; + if(t0.at(v).size()==0) + t0.erase(v); + } + if (erased) + size--; +} + +template +Lazy_toplex_map::Vertex Lazy_toplex_map::best_index(const Input_vertex_range &vertex_range) { + Simplex tau(vertex_range.begin(),vertex_range.end()); + std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; + for(const Vertex& v : tau) + if(!t0.count(v)) return v; + else if(t0.at(v).size() < min) + min = t0.at(v).size(), arg_min = v; + if(min > ALPHA * get_gamma0_lbound(arg_min)) + clean(arg_min); + return arg_min; +} + +std::size_t Lazy_toplex_map::get_gamma0_lbound(const Vertex v) const{ + return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; +} + +void Lazy_toplex_map::clean(const Vertex v){ + Toplex_map toplices; + std::unordered_map> dsorted_simplices; + std::size_t max_dim = 0; + for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ + if(sptr->size() > max_dim){ + for(std::size_t d = max_dim+1; d<=sptr->size(); d++) + dsorted_simplices.emplace(d, std::vector()); + max_dim = sptr->size(); + } + dsorted_simplices[sptr->size()].emplace_back(*sptr); + erase_max(*sptr); + } + for(std::size_t d = max_dim; d>=1; d--) + for(const Simplex &s : dsorted_simplices.at(d)) + if(!toplices.membership(s)) + toplices.insert_independent_simplex(s); + Simplex sv; sv.insert(v); + auto clean_cofaces = toplices.maximal_cofaces(sv); + size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); + gamma0_lbounds[v] = clean_cofaces.size(); + for(const Simplex_ptr& sptr : clean_cofaces) + insert_simplex(*sptr); +} + +} //namespace Gudhi + +#endif /* LAZY_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp index 77d464ae..5d71c295 100644 --- a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #define BOOST_TEST_DYN_LINK @@ -8,9 +8,9 @@ #include BOOST_AUTO_TEST_CASE(toplex_map) { - using Vertex = Gudhi::Lazy_Toplex_map::Vertex; + using Vertex = Gudhi::Lazy_toplex_map::Vertex; - Gudhi::Lazy_Toplex_map tm; + Gudhi::Lazy_toplex_map tm; std::cout << "insert_simplex {1, 2, 3, 4}" << std::endl; std::vector sigma1 = {1, 2, 3, 4}; tm.insert_simplex(sigma1); -- cgit v1.2.3 From 3cf8477c5b259cd83ee869cb2b0913c31566aeda Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 16 Oct 2018 14:09:33 +0000 Subject: Remove Filtered_toplex_map and its derivative git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3958 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2833261794ce5bda7a0e120cde6a7851553bd00c --- src/Toplex_map/example/Fake_simplex_tree.h | 188 ------------------ src/Toplex_map/example/Simple_toplex_map.cpp | 218 --------------------- .../example/Toplex_map_from_cliques_of_graph.cpp | 93 --------- src/Toplex_map/include/gudhi/Filtered_toplex_map.h | 75 ------- 4 files changed, 574 deletions(-) delete mode 100644 src/Toplex_map/example/Fake_simplex_tree.h delete mode 100644 src/Toplex_map/example/Simple_toplex_map.cpp delete mode 100644 src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp delete mode 100644 src/Toplex_map/include/gudhi/Filtered_toplex_map.h (limited to 'src') diff --git a/src/Toplex_map/example/Fake_simplex_tree.h b/src/Toplex_map/example/Fake_simplex_tree.h deleted file mode 100644 index 6a7e7bdc..00000000 --- a/src/Toplex_map/example/Fake_simplex_tree.h +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef FAKE_SIMPLEX_TREE_H -#define FAKE_SIMPLEX_TREE_H - -#include - -#include -#include - -#include -#include - -namespace Gudhi { - -struct Visitor { - Toplex_map* tm; - - Visitor(Toplex_map* tm) - :tm(tm) - {} - - template - 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 - 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 max_simplices() const; - - /** Returns all the simplices, of max dimension d if a parameter d is given. - * \ingroup toplex_map */ - std::vector filtration_simplex_range(int d=std::numeric_limits::max()) const; - - /** Returns all the simplices of max dimension d - * \ingroup toplex_map */ - std::vector 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 - bool all_facets_inside(const Input_vertex_range &vertex_range) const; - -}; - -template -void Fake_simplex_tree::insert_graph(const OneSkeletonGraph& skel_graph){ - toplex_maps.emplace(nan(""), new Toplex_map()); - using vertex_iterator = typename boost::graph_traits::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 -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 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 Fake_simplex_tree::max_simplices() const{ - std::vector 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 Fake_simplex_tree::filtration_simplex_range(int d) const{ - std::vector m = max_simplices(); - std::vector 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 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 deleted file mode 100644 index d383e84b..00000000 --- a/src/Toplex_map/example/Simple_toplex_map.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* 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 . - */ - -#include -#include "Fake_simplex_tree.h" - -#include -#include // for pair -#include - -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 deleted file mode 100644 index c43f1b69..00000000 --- a/src/Toplex_map/example/Toplex_map_from_cliques_of_graph.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* 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 . - */ - -#include -#include "Fake_simplex_tree.h" - -#include -#include -#include -#include // 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(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(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(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; -} diff --git a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h b/src/Toplex_map/include/gudhi/Filtered_toplex_map.h deleted file mode 100644 index 9a35b8b7..00000000 --- a/src/Toplex_map/include/gudhi/Filtered_toplex_map.h +++ /dev/null @@ -1,75 +0,0 @@ - #ifndef FILTERED_TOPLEX_MAP_H -#define FILTERED_TOPLEX_MAP_H - -#include -#include -#include - -namespace Gudhi { - -/** A Filtered_toplex_map represents the simplicial complex with a filtration. - * A "toplex" is a critical simplex. */ -class Filtered_toplex_map { - -public: - /** Vertex is the type of vertices. */ - typedef Toplex_map::Vertex Vertex; - - /** Simplex is the type of simplices. */ - typedef Toplex_map::Simplex Simplex; - - /** The type of the pointers to maximal simplices. */ - typedef Toplex_map::Simplex_ptr Simplex_ptr; - - /** The type of the sets of Simplex_ptr. */ - typedef Toplex_map::Simplex_ptr_set Simplex_ptr_set; - - /** The type of the filtration values. */ - typedef double Filtration_value; - - /** Add a simplex and its subfaces with the given filtration value - * in the Filtered_toplex_map. */ - template - std::pair insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f = std::numeric_limits::quiet_NaN()); - - /** Gives the filtration of the input simplex. */ - template - Filtration_value filtration(const Input_vertex_range &vertex_range) const; - - /** Is the input simplex member of the complex ? */ - template - bool membership(const Input_vertex_range &vertex_range) const; - -protected: - std::map toplex_maps; -}; - -template -std::pair Filtered_toplex_map::insert_simplex_and_subfaces(const Input_vertex_range &vertex_range, Filtration_value f){ - Simplex s(vertex_range.begin(),vertex_range.end()); - if(membership(s)) return make_pair(s,false); - if(!toplex_maps.count(f)) toplex_maps.emplace(f,new Toplex_map()); - toplex_maps.at(f)->insert_simplex(vertex_range); - return make_pair(s,true); -} - - -template -Filtered_toplex_map::Filtration_value Filtered_toplex_map::filtration(const Input_vertex_range &vertex_range) const{ - for(auto kv : toplex_maps) - if(kv.second->membership(vertex_range)) - return kv.first; //min only because a map is ordered - return std::numeric_limits::quiet_NaN() ; -} - -template -bool Filtered_toplex_map::membership(const Input_vertex_range &vertex_range) const{ - for(auto kv : toplex_maps) - if(kv.second->membership(vertex_range)) - return true; - return false; -} - -} //namespace Gudhi - -#endif /* FILTERED_TOPLEX_MAP_H */ -- cgit v1.2.3 From dda6af124625a4fbcd2524d623ef904b394af001 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 16 Oct 2018 14:33:27 +0000 Subject: Add copyrights Fix cpplint git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3959 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 02c873347468e28d50f0c8ac385be988c07c96df --- src/Toplex_map/benchmark/benchmark_tm.cpp | 170 +++++----- src/Toplex_map/doc/Intro_Toplex_map.h | 6 +- src/Toplex_map/example/simple_toplex_map.cpp | 17 +- src/Toplex_map/include/gudhi/Lazy_toplex_map.h | 299 +++++++++--------- src/Toplex_map/include/gudhi/Toplex_map.h | 369 +++++++++++----------- src/Toplex_map/test/lazy_toplex_map_unit_test.cpp | 27 +- src/Toplex_map/test/toplex_map_unit_test.cpp | 27 +- 7 files changed, 497 insertions(+), 418 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/benchmark/benchmark_tm.cpp b/src/Toplex_map/benchmark/benchmark_tm.cpp index 5f13288c..eedb442b 100644 --- a/src/Toplex_map/benchmark/benchmark_tm.cpp +++ b/src/Toplex_map/benchmark/benchmark_tm.cpp @@ -1,3 +1,25 @@ +/* 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: François Godi, Vincent Rouvreau + * + * Copyright (C) 2018 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 . + */ + #include #include #include @@ -10,11 +32,10 @@ using namespace Gudhi; typedef Toplex_map::Simplex Simplex; typedef Toplex_map::Vertex Vertex; -typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; +typedef std::pair::Simplex_handle, bool> typePairSimplexBool; class ST_wrapper { - -public: + public: void insert_simplex(const Simplex& tau) { /*std::cout << "insert_simplex - " << simplexTree.num_simplices() << " - "; for (auto v : tau) @@ -24,28 +45,22 @@ public: simplexTree.insert_simplex_and_subfaces(tau); } - bool membership(const Simplex& tau) { - return simplexTree.find(tau) != simplexTree.null_simplex(); - } + bool membership(const Simplex& tau) { return simplexTree.find(tau) != simplexTree.null_simplex(); } Vertex contraction(const Vertex x, const Vertex y) { // TODO (VR): edge contraction is not yet available for Simplex_tree return y; } - std::size_t num_maximal_simplices() { - return simplexTree.num_simplices(); - } + std::size_t num_maximal_simplices() { return simplexTree.num_simplices(); } -private: - Simplex_tree<> simplexTree; - void erase_max(const Simplex& sigma) { - if(membership(sigma)) - simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); - } + private: + Simplex_tree<> simplexTree; + void erase_max(const Simplex& sigma) { + if (membership(sigma)) simplexTree.remove_maximal_simplex(simplexTree.find(sigma)); + } }; - int n = 300; int nb_insert_simplex1 = 3000; @@ -54,76 +69,69 @@ int nb_contraction = 300; int nb_insert_simplex2 = 3000; int nb_membership2 = 400000; -Simplex random_simplex(int n, std::size_t d){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(1, n); - Simplex s; - while(s.size() < d) - s.insert(dis(gen)); - return s; +Simplex random_simplex(int n, std::size_t d) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(1, n); + Simplex s; + while (s.size() < d) s.insert(dis(gen)); + return s; } -std::vector r_vector_simplices(int n, int max_d, int m){ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(1, max_d); - std::vector v; - for(int i=0; i r_vector_simplices(int n, int max_d, int m) { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(1, max_d); + std::vector v; + for (int i = 0; i < m; i++) v.push_back(random_simplex(n, dis(gen))); + return v; } -template -void chrono(int n, int d){ - complex_type K; - std::vector simplices_insert_simplex1 = r_vector_simplices(n,d,nb_insert_simplex1); - std::vector simplices_membership1 = r_vector_simplices(n,d,nb_membership1); - std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2*nb_contraction,d,nb_insert_simplex2); - std::vector simplices_membership2 = r_vector_simplices(n - 2*nb_contraction,d,nb_membership2); - std::chrono::time_point start, end; - - for(const Simplex& s : simplices_insert_simplex1) - K.insert_simplex(s); - - for(const Simplex& s : simplices_membership1) - K.membership(s); - - start = std::chrono::system_clock::now(); - for(int i = 1; i<=nb_contraction; i++) - K.contraction(n-2*i,n-2*i-1); - end = std::chrono::system_clock::now(); - auto c3 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_insert_simplex2) - K.insert_simplex(s); - end = std::chrono::system_clock::now(); - auto c1 = std::chrono::duration_cast(end-start).count(); - - start = std::chrono::system_clock::now(); - for(const Simplex& s : simplices_membership2) - K.membership(s); - end = std::chrono::system_clock::now(); - auto c2 = std::chrono::duration_cast(end-start).count(); - - if (c3 > 0) - std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; - else - std::cout << c1 << "\t \t" << c2 << "\t \tN/A\t \t" << K.num_maximal_simplices() << std::endl; +template +void chrono(int n, int d) { + complex_type K; + std::vector simplices_insert_simplex1 = r_vector_simplices(n, d, nb_insert_simplex1); + std::vector simplices_membership1 = r_vector_simplices(n, d, nb_membership1); + std::vector simplices_insert_simplex2 = r_vector_simplices(n - 2 * nb_contraction, d, nb_insert_simplex2); + std::vector simplices_membership2 = r_vector_simplices(n - 2 * nb_contraction, d, nb_membership2); + std::chrono::time_point start, end; + + for (const Simplex& s : simplices_insert_simplex1) K.insert_simplex(s); + + for (const Simplex& s : simplices_membership1) K.membership(s); + + start = std::chrono::system_clock::now(); + for (int i = 1; i <= nb_contraction; i++) K.contraction(n - 2 * i, n - 2 * i - 1); + end = std::chrono::system_clock::now(); + auto c3 = std::chrono::duration_cast(end - start).count(); + + start = std::chrono::system_clock::now(); + for (const Simplex& s : simplices_insert_simplex2) K.insert_simplex(s); + end = std::chrono::system_clock::now(); + auto c1 = std::chrono::duration_cast(end - start).count(); + + start = std::chrono::system_clock::now(); + for (const Simplex& s : simplices_membership2) K.membership(s); + end = std::chrono::system_clock::now(); + auto c2 = std::chrono::duration_cast(end - start).count(); + + if (c3 > 0) + std::cout << c1 << "\t \t" << c2 << "\t \t" << c3 << "\t \t" << K.num_maximal_simplices() << std::endl; + else + std::cout << c1 << "\t \t" << c2 << "\t \tN/A\t \t" << K.num_maximal_simplices() << std::endl; } -int main(){ - for(int d=5;d<=40;d+=5){ - std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; - std::cout << "T Map \t \t"; - chrono(n,d); - std::cout << "Lazy \t \t"; - chrono(n,d); - if(d<=15){ - std::cout << "ST \t \t"; - chrono(n,d); - } - std::cout << std::endl; +int main() { + for (int d = 5; d <= 40; d += 5) { + std::cout << "d=" << d << " \t Insertions \t Membership \t Contractions \t Size" << std::endl; + std::cout << "T Map \t \t"; + chrono(n, d); + std::cout << "Lazy \t \t"; + chrono(n, d); + if (d <= 15) { + std::cout << "ST \t \t"; + chrono(n, d); } + std::cout << std::endl; + } } diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h index 93534e0e..649c27f9 100644 --- a/src/Toplex_map/doc/Intro_Toplex_map.h +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef DOC_TOPLEX_MAP_H_ -#define DOC_TOPLEX_MAP_H_ +#ifndef DOC_TOPLEX_MAP_INTRO_TOPLEX_MAP_H_ +#define DOC_TOPLEX_MAP_INTRO_TOPLEX_MAP_H_ // needs namespace for Doxygen to link on classes namespace Gudhi { @@ -56,4 +56,4 @@ namespace Gudhi { } // namespace Gudhi -#endif // DOC_TOPLEX_MAP_H_ +#endif // DOC_TOPLEX_MAP_INTRO_TOPLEX_MAP_H_ diff --git a/src/Toplex_map/example/simple_toplex_map.cpp b/src/Toplex_map/example/simple_toplex_map.cpp index 912d79a0..e1c12ed6 100644 --- a/src/Toplex_map/example/simple_toplex_map.cpp +++ b/src/Toplex_map/example/simple_toplex_map.cpp @@ -27,7 +27,7 @@ #include #include -int main(int argc, char * const argv[]) { +int main(int argc, char* const argv[]) { using Simplex = Gudhi::Toplex_map::Simplex; Simplex sigma1 = {1, 2, 3}; Simplex sigma2 = {2, 3, 4, 5}; @@ -43,7 +43,8 @@ int main(int argc, char * const argv[]) { /* o---o */ /* 1 3 */ - std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() + << std::endl; // Browse maximal cofaces Simplex sigma3 = {2, 3}; @@ -75,7 +76,8 @@ int main(int argc, char * const argv[]) { /* \5/ */ /* o */ /* 3 */ - std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() + << std::endl; // Browse maximal simplices std::cout << "Maximal simplices are :" << std::endl; @@ -97,7 +99,8 @@ int main(int argc, char * const argv[]) { /* \X/ */ /* o */ /* 5 */ - std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() + << std::endl; // Browse maximal simplices std::cout << "Maximal simplices are :" << std::endl; @@ -125,7 +128,8 @@ int main(int argc, char * const argv[]) { /* / \5/ */ /* o---o */ /* 1 3 */ - std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() + << std::endl; // Browse maximal simplices std::cout << "Maximal simplices are :" << std::endl; @@ -145,7 +149,8 @@ int main(int argc, char * const argv[]) { /* \5/ */ /* o */ /* 3 */ - std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() << std::endl; + std::cout << "num max simplices = " << tm.num_maximal_simplices() << " - num vertices = " << tm.num_vertices() + << std::endl; // Browse maximal simplices std::cout << "Maximal simplices are :" << std::endl; diff --git a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h index 8cc5610a..63c933d9 100644 --- a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h @@ -1,3 +1,25 @@ +/* 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: François Godi, Vincent Rouvreau + * + * Copyright (C) 2018 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 . + */ + #ifndef LAZY_TOPLEX_MAP_H #define LAZY_TOPLEX_MAP_H @@ -14,8 +36,7 @@ namespace Gudhi { * * \ingroup toplex_map */ class Lazy_toplex_map { - -public: + public: /** Vertex is the type of vertices. */ using Vertex = Toplex_map::Vertex; @@ -47,7 +68,6 @@ public: template bool membership(const Input_vertex_range &vertex_range); - /** Do all the facets of a simplex belong to the complex ? */ template bool all_facets_inside(const Input_vertex_range &vertex_range); @@ -58,16 +78,12 @@ public: Vertex contraction(const Vertex x, const Vertex y); /** \brief Number of maximal simplices. */ - std::size_t num_maximal_simplices() const { - return size; - } + std::size_t num_maximal_simplices() const { return size; } /** \brief Number of vertices. */ - std::size_t num_vertices() const{ - return t0.size(); - } + std::size_t num_vertices() const { return t0.size(); } -private: + private: template void erase_max(const Input_vertex_range &vertex_range); template @@ -77,9 +93,9 @@ private: std::unordered_map gamma0_lbounds; std::unordered_map t0; - bool empty_toplex; // Is the empty simplex a toplex ? + bool empty_toplex; // Is the empty simplex a toplex ? - typedef boost::heap::fibonacci_heap> PriorityQueue; + typedef boost::heap::fibonacci_heap> PriorityQueue; PriorityQueue cleaning_priority; std::unordered_map cp_handles; @@ -88,169 +104,168 @@ private: std::size_t size_lbound = 0; std::size_t size = 0; - const double ALPHA = 4; //time - const double BETTA = 8; //memory + const double ALPHA = 4; // time + const double BETTA = 8; // memory }; template -void Lazy_toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ - for(const Vertex& v : vertex_range) - if(!gamma0_lbounds.count(v)) gamma0_lbounds.emplace(v,1); - else gamma0_lbounds[v]++; - size_lbound++; - insert_simplex(vertex_range); +void Lazy_toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range) { + for (const Vertex &v : vertex_range) + if (!gamma0_lbounds.count(v)) + gamma0_lbounds.emplace(v, 1); + else + gamma0_lbounds[v]++; + size_lbound++; + insert_simplex(vertex_range); } template -bool Lazy_toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - empty_toplex = (sigma.size()==0); //vérifier la gestion de empty face - Simplex_ptr sptr = std::make_shared(sigma); - bool inserted = false; - for(const Vertex& v : sigma){ - if(!t0.count(v)){ - t0.emplace(v, Simplex_ptr_set()); - auto v_handle = cleaning_priority.push(std::make_pair(0, v)); - cp_handles.emplace(v, v_handle); - } - inserted = t0.at(v).emplace(sptr).second; - cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v),v)); +bool Lazy_toplex_map::insert_simplex(const Input_vertex_range &vertex_range) { + Simplex sigma(vertex_range.begin(), vertex_range.end()); + // Check empty face management + empty_toplex = (sigma.size() == 0); + Simplex_ptr sptr = std::make_shared(sigma); + bool inserted = false; + for (const Vertex &v : sigma) { + if (!t0.count(v)) { + t0.emplace(v, Simplex_ptr_set()); + auto v_handle = cleaning_priority.push(std::make_pair(0, v)); + cp_handles.emplace(v, v_handle); } - if(inserted) - size++; - if(size > (size_lbound+1) * BETTA) - clean(cleaning_priority.top().second); - return inserted; + inserted = t0.at(v).emplace(sptr).second; + cleaning_priority.update(cp_handles.at(v), std::make_pair(t0.at(v).size() - get_gamma0_lbound(v), v)); + } + if (inserted) size++; + if (size > (size_lbound + 1) * BETTA) clean(cleaning_priority.top().second); + return inserted; } template -void Lazy_toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ - if(vertex_range.begin()==vertex_range.end()){ - t0.clear(); - gamma0_lbounds.clear(); - cleaning_priority.clear(); - size_lbound = 0; - size = 0; - empty_toplex = false; - } - else { - const Vertex& v = best_index(vertex_range); - //Copy constructor needed because the set is modified - if(t0.count(v)) for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) - if(included(vertex_range, *sptr)){ - erase_max(*sptr); - for(const Simplex& f : facets(vertex_range)) - insert_independent_simplex(f); - } - } +void Lazy_toplex_map::remove_simplex(const Input_vertex_range &vertex_range) { + if (vertex_range.begin() == vertex_range.end()) { + t0.clear(); + gamma0_lbounds.clear(); + cleaning_priority.clear(); + size_lbound = 0; + size = 0; + empty_toplex = false; + } else { + const Vertex &v = best_index(vertex_range); + // Copy constructor needed because the set is modified + if (t0.count(v)) + for (const Simplex_ptr &sptr : Simplex_ptr_set(t0.at(v))) + if (included(vertex_range, *sptr)) { + erase_max(*sptr); + for (const Simplex &f : facets(vertex_range)) insert_independent_simplex(f); + } + } } template -bool Lazy_toplex_map::membership(const Input_vertex_range &vertex_range){ - if(t0.size()==0 && !empty_toplex) return false; //empty complex - if(vertex_range.begin()==vertex_range.end()) return true; //empty query simplex - Vertex v = best_index(vertex_range); - if(!t0.count(v)) return false; - for(const Simplex_ptr& sptr : t0.at(v)) - if(included(vertex_range, *sptr)) return true; - return false; +bool Lazy_toplex_map::membership(const Input_vertex_range &vertex_range) { + if (t0.size() == 0 && !empty_toplex) return false; // empty complex + if (vertex_range.begin() == vertex_range.end()) return true; // empty query simplex + Vertex v = best_index(vertex_range); + if (!t0.count(v)) return false; + for (const Simplex_ptr &sptr : t0.at(v)) + if (included(vertex_range, *sptr)) return true; + return false; } template -bool Lazy_toplex_map::all_facets_inside(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - Vertex v = best_index(sigma); - if(!t0.count(v)) return false; - Simplex f = sigma; f.erase(v); - if(!membership(f)) return false; - std::unordered_set facets_inside; - for(const Simplex_ptr& sptr : t0.at(v)) - for(const Vertex& w : sigma){ - f = sigma; f.erase(w); - if(included(f, *sptr)) facets_inside.insert(w); - } - return facets_inside.size() == sigma.size() - 1; +bool Lazy_toplex_map::all_facets_inside(const Input_vertex_range &vertex_range) { + Simplex sigma(vertex_range.begin(), vertex_range.end()); + Vertex v = best_index(sigma); + if (!t0.count(v)) return false; + Simplex f = sigma; + f.erase(v); + if (!membership(f)) return false; + std::unordered_set facets_inside; + for (const Simplex_ptr &sptr : t0.at(v)) + for (const Vertex &w : sigma) { + f = sigma; + f.erase(w); + if (included(f, *sptr)) facets_inside.insert(w); + } + return facets_inside.size() == sigma.size() - 1; } /* Returns the remaining vertex */ -Lazy_toplex_map::Vertex Lazy_toplex_map::contraction(const Vertex x, const Vertex y){ - if(!t0.count(x)) return y; - if(!t0.count(y)) return x; - Vertex k, d; - if(t0.at(x).size() > t0.at(y).size()) - k=x, d=y; - else - k=y, d=x; - //Copy constructor needed because the set is modified - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ - Simplex sigma(*sptr); - erase_max(sigma); - sigma.erase(d); - sigma.insert(k); - insert_simplex(sigma); - } - t0.erase(d); - return k; +Lazy_toplex_map::Vertex Lazy_toplex_map::contraction(const Vertex x, const Vertex y) { + if (!t0.count(x)) return y; + if (!t0.count(y)) return x; + Vertex k, d; + if (t0.at(x).size() > t0.at(y).size()) + k = x, d = y; + else + k = y, d = x; + // Copy constructor needed because the set is modified + for (const Simplex_ptr &sptr : Simplex_ptr_set(t0.at(d))) { + Simplex sigma(*sptr); + erase_max(sigma); + sigma.erase(d); + sigma.insert(k); + insert_simplex(sigma); + } + t0.erase(d); + return k; } /* No facets insert_simplexed */ template -inline void Lazy_toplex_map::erase_max(const Input_vertex_range &vertex_range){ - Simplex sigma(vertex_range.begin(),vertex_range.end()); - empty_toplex = false; - Simplex_ptr sptr = std::make_shared(sigma); - bool erased=false; - for(const Vertex& v : sigma){ - erased = t0.at(v).erase(sptr) > 0; - if(t0.at(v).size()==0) - t0.erase(v); - } - if (erased) - size--; +inline void Lazy_toplex_map::erase_max(const Input_vertex_range &vertex_range) { + Simplex sigma(vertex_range.begin(), vertex_range.end()); + empty_toplex = false; + Simplex_ptr sptr = std::make_shared(sigma); + bool erased = false; + for (const Vertex &v : sigma) { + erased = t0.at(v).erase(sptr) > 0; + if (t0.at(v).size() == 0) t0.erase(v); + } + if (erased) size--; } template Lazy_toplex_map::Vertex Lazy_toplex_map::best_index(const Input_vertex_range &vertex_range) { - Simplex tau(vertex_range.begin(),vertex_range.end()); - std::size_t min = std::numeric_limits::max(); Vertex arg_min = -1; - for(const Vertex& v : tau) - if(!t0.count(v)) return v; - else if(t0.at(v).size() < min) - min = t0.at(v).size(), arg_min = v; - if(min > ALPHA * get_gamma0_lbound(arg_min)) - clean(arg_min); - return arg_min; + Simplex tau(vertex_range.begin(), vertex_range.end()); + std::size_t min = std::numeric_limits::max(); + Vertex arg_min = -1; + for (const Vertex &v : tau) + if (!t0.count(v)) + return v; + else if (t0.at(v).size() < min) + min = t0.at(v).size(), arg_min = v; + if (min > ALPHA * get_gamma0_lbound(arg_min)) clean(arg_min); + return arg_min; } -std::size_t Lazy_toplex_map::get_gamma0_lbound(const Vertex v) const{ - return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; +std::size_t Lazy_toplex_map::get_gamma0_lbound(const Vertex v) const { + return gamma0_lbounds.count(v) ? gamma0_lbounds.at(v) : 0; } -void Lazy_toplex_map::clean(const Vertex v){ - Toplex_map toplices; - std::unordered_map> dsorted_simplices; - std::size_t max_dim = 0; - for(const Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))){ - if(sptr->size() > max_dim){ - for(std::size_t d = max_dim+1; d<=sptr->size(); d++) - dsorted_simplices.emplace(d, std::vector()); - max_dim = sptr->size(); - } - dsorted_simplices[sptr->size()].emplace_back(*sptr); - erase_max(*sptr); +void Lazy_toplex_map::clean(const Vertex v) { + Toplex_map toplices; + std::unordered_map> dsorted_simplices; + std::size_t max_dim = 0; + for (const Simplex_ptr &sptr : Simplex_ptr_set(t0.at(v))) { + if (sptr->size() > max_dim) { + for (std::size_t d = max_dim + 1; d <= sptr->size(); d++) dsorted_simplices.emplace(d, std::vector()); + max_dim = sptr->size(); } - for(std::size_t d = max_dim; d>=1; d--) - for(const Simplex &s : dsorted_simplices.at(d)) - if(!toplices.membership(s)) - toplices.insert_independent_simplex(s); - Simplex sv; sv.insert(v); - auto clean_cofaces = toplices.maximal_cofaces(sv); - size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); - gamma0_lbounds[v] = clean_cofaces.size(); - for(const Simplex_ptr& sptr : clean_cofaces) - insert_simplex(*sptr); + dsorted_simplices[sptr->size()].emplace_back(*sptr); + erase_max(*sptr); + } + for (std::size_t d = max_dim; d >= 1; d--) + for (const Simplex &s : dsorted_simplices.at(d)) + if (!toplices.membership(s)) toplices.insert_independent_simplex(s); + Simplex sv; + sv.insert(v); + auto clean_cofaces = toplices.maximal_cofaces(sv); + size_lbound = size_lbound - get_gamma0_lbound(v) + clean_cofaces.size(); + gamma0_lbounds[v] = clean_cofaces.size(); + for (const Simplex_ptr &sptr : clean_cofaces) insert_simplex(*sptr); } -} //namespace Gudhi +} // namespace Gudhi #endif /* LAZY_TOPLEX_MAP_H */ diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index b7a5db41..3da505f8 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -1,3 +1,25 @@ +/* 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: François Godi, Vincent Rouvreau + * + * Copyright (C) 2018 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 . + */ + #ifndef TOPLEX_MAP_H #define TOPLEX_MAP_H @@ -17,9 +39,7 @@ namespace Gudhi { * * \ingroup toplex_map */ class Toplex_map { - -public: - + public: /** Vertex is the type of vertices. */ using Vertex = std::size_t; @@ -33,7 +53,7 @@ public: std::size_t operator()(const Toplex_map::Simplex_ptr& s) const; }; - struct Sptr_equal{ + struct Sptr_equal { std::size_t operator()(const Toplex_map::Simplex_ptr& a, const Toplex_map::Simplex_ptr& b) const; }; @@ -43,26 +63,27 @@ public: /** \brief Adds the given simplex to the complex. * Nothing happens if the simplex has a coface in the complex. */ template - void insert_simplex(const Input_vertex_range &vertex_range); + void insert_simplex(const Input_vertex_range& vertex_range); /** \brief Removes the given simplex and its cofaces from the complex. * Its faces are kept inside. */ template - void remove_simplex(const Input_vertex_range &vertex_range); + void remove_simplex(const Input_vertex_range& vertex_range); /** Does a simplex belong to the complex ? */ template - bool membership(const Input_vertex_range &vertex_range) const; + bool membership(const Input_vertex_range& vertex_range) const; /** Does a simplex is a toplex ? */ template - bool maximality(const Input_vertex_range &vertex_range) const; + bool maximality(const Input_vertex_range& vertex_range) const; /** Gives a set of pointers to the maximal cofaces of a simplex. * Gives all the toplices if given the empty simplex. * Gives not more than max_number maximal cofaces if max_number is strictly positive. */ template - Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number = 0) const; + Toplex_map::Simplex_ptr_set maximal_cofaces(const Input_vertex_range& vertex_range, + const std::size_t max_number = 0) const; /** Gives a set of pointers to the maximal simplices. * Gives not more than max_number maximal cofaces if max_number is strictly positive. */ @@ -79,26 +100,22 @@ public: void remove_vertex(const Toplex_map::Vertex x); /** \brief Number of maximal simplices. */ - std::size_t num_maximal_simplices() const { - return maximal_simplices().size(); - } + std::size_t num_maximal_simplices() const { return maximal_simplices().size(); } /** \brief Number of vertices. */ - std::size_t num_vertices() const { - return t0.size(); - } + std::size_t num_vertices() const { return t0.size(); } std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); /** Adds the given simplex to the complex. * The simplex must not have neither maximal face nor coface in the complex. */ template - void insert_independent_simplex(const Input_vertex_range &vertex_range); + void insert_independent_simplex(const Input_vertex_range& vertex_range); -protected: + protected: /** \internal Gives an index in order to look for a simplex quickly. */ template - Toplex_map::Vertex best_index(const Input_vertex_range &vertex_range) const; + Toplex_map::Vertex best_index(const Input_vertex_range& vertex_range) const; /** \internal The map from vertices to toplices */ std::unordered_map t0; @@ -107,219 +124,215 @@ protected: /** \internal Removes a toplex without adding facets after. */ void erase_maximal(const Toplex_map::Simplex_ptr& sptr); - }; // Pointers are also used as key in the hash sets. template -Toplex_map::Simplex_ptr get_key(const Input_vertex_range &vertex_range); +Toplex_map::Simplex_ptr get_key(const Input_vertex_range& vertex_range); // Is the first simplex a face of the second ? template -bool included(const Input_vertex_range1 &vertex_range1, const Input_vertex_range2 &vertex_range2); +bool included(const Input_vertex_range1& vertex_range1, const Input_vertex_range2& vertex_range2); // All the facets of the given simplex. template -std::vector facets(const Input_vertex_range &vertex_range); +std::vector facets(const Input_vertex_range& vertex_range); template -void Toplex_map::insert_simplex(const Input_vertex_range &vertex_range){ - if(membership(vertex_range)) return; - bool replace_facets = true; - for(const Toplex_map::Simplex& facet : facets(vertex_range)) - if(!maximality(facet)) - { - replace_facets=false; - break; - } - if(replace_facets) - for(const Toplex_map::Simplex& facet : facets(vertex_range)) - erase_maximal(get_key(facet)); - else - for(const Toplex_map::Vertex& v : vertex_range) - if(t0.count(v)) for(const Toplex_map::Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v))) - //Copy constructor needed because the set is modified - if(included(*fptr,vertex_range)) erase_maximal(fptr); - // We erase all the maximal faces of the simplex - insert_independent_simplex(vertex_range); +void Toplex_map::insert_simplex(const Input_vertex_range& vertex_range) { + if (membership(vertex_range)) return; + bool replace_facets = true; + for (const Toplex_map::Simplex& facet : facets(vertex_range)) + if (!maximality(facet)) { + replace_facets = false; + break; + } + if (replace_facets) + for (const Toplex_map::Simplex& facet : facets(vertex_range)) erase_maximal(get_key(facet)); + else + for (const Toplex_map::Vertex& v : vertex_range) + if (t0.count(v)) + for (const Toplex_map::Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v))) + // Copy constructor needed because the set is modified + if (included(*fptr, vertex_range)) erase_maximal(fptr); + // We erase all the maximal faces of the simplex + insert_independent_simplex(vertex_range); } template -void Toplex_map::remove_simplex(const Input_vertex_range &vertex_range){ - if(vertex_range.begin()==vertex_range.end()) - t0.clear(); - // Removal of the empty simplex means cleaning everything - else { - const Toplex_map::Vertex& v = best_index(vertex_range); - if(t0.count(v)) for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) - //Copy constructor needed because the set is modified - if(included(vertex_range, *sptr)){ - erase_maximal(sptr); - for(const Toplex_map::Simplex& f : facets(vertex_range)) - if(!membership(f)) insert_independent_simplex(f); - // We add the facets which are new maximal simplices - } - } +void Toplex_map::remove_simplex(const Input_vertex_range& vertex_range) { + if (vertex_range.begin() == vertex_range.end()) t0.clear(); + // Removal of the empty simplex means cleaning everything + else { + const Toplex_map::Vertex& v = best_index(vertex_range); + if (t0.count(v)) + for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) + // Copy constructor needed because the set is modified + if (included(vertex_range, *sptr)) { + erase_maximal(sptr); + for (const Toplex_map::Simplex& f : facets(vertex_range)) + if (!membership(f)) insert_independent_simplex(f); + // We add the facets which are new maximal simplices + } + } } template -bool Toplex_map::membership(const Input_vertex_range &vertex_range) const{ - if(t0.size()==0) return false; - const Toplex_map::Vertex& v = best_index(vertex_range); - if(!t0.count(v)) return false; - if(maximality(vertex_range)) return true; - for(const Toplex_map::Simplex_ptr& sptr : t0.at(v)) - if(included(vertex_range, *sptr)) - return true; - return false; +bool Toplex_map::membership(const Input_vertex_range& vertex_range) const { + if (t0.size() == 0) return false; + const Toplex_map::Vertex& v = best_index(vertex_range); + if (!t0.count(v)) return false; + if (maximality(vertex_range)) return true; + for (const Toplex_map::Simplex_ptr& sptr : t0.at(v)) + if (included(vertex_range, *sptr)) return true; + return false; } template -bool Toplex_map::maximality(const Input_vertex_range &vertex_range) const{ - const Toplex_map::Vertex& v = best_index(vertex_range); - if(!t0.count(v)) return false; - return t0.at(v).count(get_key(vertex_range)); +bool Toplex_map::maximality(const Input_vertex_range& vertex_range) const { + const Toplex_map::Vertex& v = best_index(vertex_range); + if (!t0.count(v)) return false; + return t0.at(v).count(get_key(vertex_range)); } template -Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range &vertex_range, const std::size_t max_number) const{ - Simplex_ptr_set cofaces; - if(maximality(vertex_range)) - cofaces.emplace(get_key(vertex_range)); - else if(vertex_range.begin()==vertex_range.end()) - for(const auto& kv : t0) - for(const Toplex_map::Simplex_ptr& sptr : kv.second){ - //kv.second is a Simplex_ptr_set - cofaces.emplace(sptr); - if(cofaces.size()==max_number) - return cofaces; - } - else { - const Toplex_map::Vertex& v = best_index(vertex_range); - if(t0.count(v)) for(const Toplex_map::Simplex_ptr& sptr : t0.at(v)) - if(included(vertex_range, *sptr)){ - cofaces.emplace(sptr); - if(cofaces.size()==max_number) - return cofaces; - } - } - return cofaces; +Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range& vertex_range, + const std::size_t max_number) const { + Simplex_ptr_set cofaces; + if (maximality(vertex_range)) + cofaces.emplace(get_key(vertex_range)); + else if (vertex_range.begin() == vertex_range.end()) + for (const auto& kv : t0) + for (const Toplex_map::Simplex_ptr& sptr : kv.second) { + // kv.second is a Simplex_ptr_set + cofaces.emplace(sptr); + if (cofaces.size() == max_number) return cofaces; + } + else { + const Toplex_map::Vertex& v = best_index(vertex_range); + if (t0.count(v)) + for (const Toplex_map::Simplex_ptr& sptr : t0.at(v)) + if (included(vertex_range, *sptr)) { + cofaces.emplace(sptr); + if (cofaces.size() == max_number) return cofaces; + } + } + return cofaces; } -Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y){ - if(!t0.count(x)) return y; - if(!t0.count(y)) return x; - int k, d; - if(t0.at(x).size() > t0.at(y).size()) - k=x, d=y; - else - k=y, d=x; - for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ - //Copy constructor needed because the set is modified - Simplex sigma(*sptr); - erase_maximal(sptr); - sigma.erase(d); - sigma.insert(k); - insert_simplex(sigma); - } - return k; +Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y) { + if (!t0.count(x)) return y; + if (!t0.count(y)) return x; + int k, d; + if (t0.at(x).size() > t0.at(y).size()) + k = x, d = y; + else + k = y, d = x; + for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))) { + // Copy constructor needed because the set is modified + Simplex sigma(*sptr); + erase_maximal(sptr); + sigma.erase(d); + sigma.insert(k); + insert_simplex(sigma); + } + return k; } -std::set Toplex_map::unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d){ - std::set r; - for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))){ - //Copy constructor needed because the set is modified - Simplex sigma(*sptr); - erase_maximal(sptr); - sigma.erase(d); - for(const Toplex_map::Vertex v : sigma) - r.insert(v); - sigma.insert(k); - insert_simplex(sigma); - } - return r; +std::set Toplex_map::unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d) { + std::set r; + for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))) { + // Copy constructor needed because the set is modified + Simplex sigma(*sptr); + erase_maximal(sptr); + sigma.erase(d); + for (const Toplex_map::Vertex v : sigma) r.insert(v); + sigma.insert(k); + insert_simplex(sigma); + } + return r; } template -void Toplex_map::insert_independent_simplex(const Input_vertex_range &vertex_range){ - auto key = get_key(vertex_range); - for(const Toplex_map::Vertex& v : vertex_range){ - if(!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); - t0.at(v).emplace(key); - } +void Toplex_map::insert_independent_simplex(const Input_vertex_range& vertex_range) { + auto key = get_key(vertex_range); + for (const Toplex_map::Vertex& v : vertex_range) { + if (!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); + t0.at(v).emplace(key); + } } -void Toplex_map::remove_vertex(const Toplex_map::Vertex x){ - for(const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(x))){ - Simplex sigma(*sptr); - erase_maximal(sptr); - sigma.erase(x); - insert_simplex(sigma); - } +void Toplex_map::remove_vertex(const Toplex_map::Vertex x) { + for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(x))) { + Simplex sigma(*sptr); + erase_maximal(sptr); + sigma.erase(x); + insert_simplex(sigma); + } } -inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr){ - Simplex sigma(*sptr); - if (sptr->size()==0) - sigma.insert(VERTEX_UPPER_BOUND); - for(const Toplex_map::Vertex& v : sigma){ - t0.at(v).erase(sptr); - if(t0.at(v).size()==0) t0.erase(v); - } +inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr) { + Simplex sigma(*sptr); + if (sptr->size() == 0) sigma.insert(VERTEX_UPPER_BOUND); + for (const Toplex_map::Vertex& v : sigma) { + t0.at(v).erase(sptr); + if (t0.at(v).size() == 0) t0.erase(v); + } } template -Toplex_map::Vertex Toplex_map::best_index(const Input_vertex_range &vertex_range) const{ - std::size_t min = std::numeric_limits::max(); - Vertex arg_min = VERTEX_UPPER_BOUND; - for(const Toplex_map::Vertex& v : vertex_range) - if(!t0.count(v)) return v; - else if(t0.at(v).size() < min) - min = t0.at(v).size(), arg_min = v; - return arg_min; +Toplex_map::Vertex Toplex_map::best_index(const Input_vertex_range& vertex_range) const { + std::size_t min = std::numeric_limits::max(); + Vertex arg_min = VERTEX_UPPER_BOUND; + for (const Toplex_map::Vertex& v : vertex_range) + if (!t0.count(v)) + return v; + else if (t0.at(v).size() < min) + min = t0.at(v).size(), arg_min = v; + return arg_min; } -std::size_t Toplex_map::Sptr_equal::operator()(const Toplex_map::Simplex_ptr& s1, const Toplex_map::Simplex_ptr& s2) const { - if (s1->size() != s2->size()) return false; - return included(*s1,*s2); - // inclusion tests equality for same size simplices +std::size_t Toplex_map::Sptr_equal::operator()(const Toplex_map::Simplex_ptr& s1, + const Toplex_map::Simplex_ptr& s2) const { + if (s1->size() != s2->size()) return false; + return included(*s1, *s2); + // inclusion tests equality for same size simplices } std::size_t Toplex_map::Sptr_hash::operator()(const Toplex_map::Simplex_ptr& s) const { - std::hash h_f; - //double hash works better than int hash - size_t h = 0; - for(const Toplex_map::Vertex& v : *s) - h += h_f(static_cast(v)); - return h; + std::hash h_f; + // double hash works better than int hash + size_t h = 0; + for (const Toplex_map::Vertex& v : *s) h += h_f(static_cast(v)); + return h; } template -Toplex_map::Simplex_ptr get_key(const Input_vertex_range &vertex_range){ - Toplex_map::Simplex s(vertex_range.begin(), vertex_range.end()); - return std::make_shared(s); +Toplex_map::Simplex_ptr get_key(const Input_vertex_range& vertex_range) { + Toplex_map::Simplex s(vertex_range.begin(), vertex_range.end()); + return std::make_shared(s); } template -bool included(const Input_vertex_range1 &vertex_range1, const Input_vertex_range2 &vertex_range2){ - Toplex_map::Simplex s2(vertex_range2.begin(), vertex_range2.end()); - for(const Toplex_map::Vertex& v : vertex_range1) - if(!s2.count(v)) return false; - return true; +bool included(const Input_vertex_range1& vertex_range1, const Input_vertex_range2& vertex_range2) { + Toplex_map::Simplex s2(vertex_range2.begin(), vertex_range2.end()); + for (const Toplex_map::Vertex& v : vertex_range1) + if (!s2.count(v)) return false; + return true; } template -std::vector facets(const Input_vertex_range &vertex_range){ - std::vector facets; - Toplex_map::Simplex f(vertex_range.begin(), vertex_range.end()); - for(const Toplex_map::Vertex& v : vertex_range){ - f.erase(v); - facets.emplace_back(f); - f.insert(v); - } - return facets; +std::vector facets(const Input_vertex_range& vertex_range) { + std::vector facets; + Toplex_map::Simplex f(vertex_range.begin(), vertex_range.end()); + for (const Toplex_map::Vertex& v : vertex_range) { + f.erase(v); + facets.emplace_back(f); + f.insert(v); + } + return facets; } -} //namespace Gudhi +} // namespace Gudhi #endif /* TOPLEX_MAP_H */ diff --git a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp index 5d71c295..eb1aa0b5 100644 --- a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp @@ -1,8 +1,29 @@ +/* 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: François Godi, Vincent Rouvreau + * + * Copyright (C) 2018 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 . + */ + #include #include #include - #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "lazy toplex map" #include @@ -43,7 +64,7 @@ BOOST_AUTO_TEST_CASE(toplex_map) { BOOST_CHECK(tm.membership(sigma5)); std::cout << "contraction(4,5)" << std::endl; - auto r = tm.contraction(4,5); + auto r = tm.contraction(4, 5); std::cout << "r=" << r << std::endl; BOOST_CHECK(r == 5); @@ -73,6 +94,4 @@ BOOST_AUTO_TEST_CASE(toplex_map) { BOOST_CHECK(tm.membership(edge)); edge = {7, 5}; BOOST_CHECK(tm.membership(edge)); - } - diff --git a/src/Toplex_map/test/toplex_map_unit_test.cpp b/src/Toplex_map/test/toplex_map_unit_test.cpp index 59c104ce..2bd27936 100644 --- a/src/Toplex_map/test/toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/toplex_map_unit_test.cpp @@ -1,8 +1,29 @@ +/* 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: François Godi, Vincent Rouvreau + * + * Copyright (C) 2018 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 . + */ + #include #include #include - #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "toplex map" #include @@ -67,7 +88,7 @@ BOOST_AUTO_TEST_CASE(toplex_map) { BOOST_CHECK(tm.membership(sigma5)); std::cout << "contraction(4,5)" << std::endl; - auto r = tm.contraction(4,5); + auto r = tm.contraction(4, 5); std::cout << "r=" << r << std::endl; BOOST_CHECK(r == 5); @@ -114,6 +135,4 @@ BOOST_AUTO_TEST_CASE(toplex_map) { BOOST_CHECK(tm.membership(edge)); edge = {7, 5}; BOOST_CHECK(tm.membership(edge)); - } - -- cgit v1.2.3 From 11b1de2771b060fb286bf428ac081c07ff73e8ec Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 08:20:00 +0000 Subject: Doc review : Gamma_0 instead of gamma_0 to be like in the paper toplices is the plural form of toplex (not a set of toplex) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3984 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4cfeebffcbf9006fd98bbf32a8dbd9eb683c9bf5 --- src/Toplex_map/doc/Intro_Toplex_map.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h index 649c27f9..0cfbae03 100644 --- a/src/Toplex_map/doc/Intro_Toplex_map.h +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -34,15 +34,15 @@ namespace Gudhi { * \section toplexmapdefinition Definition * * A Toplex_map is a data structure to represent and store a simplicial complex. A "toplex" is the contraction of - * "top-simplex", also known as a maximal simplex. We will call "toplices" a set of "toplex". + * "top-simplex", also known as a maximal simplex. The plural form of "toplex" will be called "toplices". * * Let's consider a simplicial complex, denote by \f$d\f$ its dimension and by \f$k\f$ its number of maximal simplices. - * Furthermore, denote by \f$\gamma_0\f$ the maximal number of toplices, i.e. maximal simplices, that contain a same + * Furthermore, denote by \f$\Gamma_0\f$ the maximal number of toplices, i.e. maximal simplices, that contain a same * vertex. * * The goal of the Toplex Map is both to represent the complex in optimal O(kd) space and to provide fast standard * operations such as : insertion, removal, contraction of an edge, collapses and membership of a simplex. The time - * needed for these operation is linear or quadratic in \f$\gamma_0\f$ and \f$d\f$. + * needed for these operation is linear or quadratic in \f$\Gamma_0\f$ and \f$d\f$. * * Toplex map is composed firstly of a raw storage of toplices and secondly of a map which associate any vertex to a * set of pointers toward all toplices containing this vertex. -- cgit v1.2.3 From d444c2da6e5081018784a50fab00cb81b772a3e0 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 09:02:08 +0000 Subject: Doc review : Simplicial complex terms instead of toplex map ones. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3985 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b8debf06602f03185929ac7b33e2b49ea69deaad --- src/Toplex_map/include/gudhi/Toplex_map.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 3da505f8..a46961c6 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -61,7 +61,7 @@ class Toplex_map { using Simplex_ptr_set = std::unordered_set; /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. */ + * Nothing happens if the simplex has a coface in the complex (i.e. it is a face of one of the toplices). */ template void insert_simplex(const Input_vertex_range& vertex_range); @@ -108,7 +108,7 @@ class Toplex_map { std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); /** Adds the given simplex to the complex. - * The simplex must not have neither maximal face nor coface in the complex. */ + * The simplex must not be in the complex already, and it must not contain one of the current toplices. */ template void insert_independent_simplex(const Input_vertex_range& vertex_range); -- cgit v1.2.3 From 0f73517f412056bfd7ac5a3089845815c149d47e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 09:10:00 +0000 Subject: Doc review : Simplicial complex terms instead of toplex map ones. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3986 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5f8c05b80f6cb4db8f64aaaf33869495a3e7be7b --- src/Toplex_map/include/gudhi/Lazy_toplex_map.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h index 63c933d9..bc09c57d 100644 --- a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h @@ -50,12 +50,12 @@ class Lazy_toplex_map { using Simplex_ptr_set = Toplex_map::Simplex_ptr_set; /** Adds the given simplex to the complex. - * The simplex must not have maximal coface in the complex. */ + * The simplex must not be in the complex already, and it must not contain one of the current toplices. */ template void insert_independent_simplex(const Input_vertex_range &vertex_range); /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex. */ + * Nothing happens if the simplex has a coface in the complex (i.e. it is a face of one of the toplices). */ template bool insert_simplex(const Input_vertex_range &vertex_range); -- cgit v1.2.3 From 93879e423d5f3ae94318696335b19e1f10ce2a7d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 09:32:32 +0000 Subject: Code review : No need to use Toplex_map::Vertex inside Toplex_map class git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3987 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1e419e7d7efbfdc47a250c32209613f48ab46745 --- src/Toplex_map/include/gudhi/Toplex_map.h | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index a46961c6..ebdbdc0b 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -44,7 +44,7 @@ class Toplex_map { using Vertex = std::size_t; /** Simplex is the type of simplices. */ - using Simplex = std::set; + using Simplex = std::set; /** The type of the pointers to maximal simplices. */ using Simplex_ptr = std::shared_ptr; @@ -94,10 +94,10 @@ class Toplex_map { /** Contracts one edge in the complex. * The edge has to verify the link condition if you want to preserve topology. * Returns the remaining vertex. */ - Toplex_map::Vertex contraction(const Toplex_map::Vertex x, const Toplex_map::Vertex y); + Vertex contraction(const Vertex x, const Vertex y); /** Removes a vertex from any simplex containing it. */ - void remove_vertex(const Toplex_map::Vertex x); + void remove_vertex(const Vertex x); /** \brief Number of maximal simplices. */ std::size_t num_maximal_simplices() const { return maximal_simplices().size(); } @@ -105,7 +105,7 @@ class Toplex_map { /** \brief Number of vertices. */ std::size_t num_vertices() const { return t0.size(); } - std::set unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d); + std::set unitary_collapse(const Vertex k, const Vertex d); /** Adds the given simplex to the complex. * The simplex must not be in the complex already, and it must not contain one of the current toplices. */ @@ -115,12 +115,12 @@ class Toplex_map { protected: /** \internal Gives an index in order to look for a simplex quickly. */ template - Toplex_map::Vertex best_index(const Input_vertex_range& vertex_range) const; + Vertex best_index(const Input_vertex_range& vertex_range) const; /** \internal The map from vertices to toplices */ - std::unordered_map t0; + std::unordered_map t0; - const Toplex_map::Vertex VERTEX_UPPER_BOUND = std::numeric_limits::max(); + const Vertex VERTEX_UPPER_BOUND = std::numeric_limits::max(); /** \internal Removes a toplex without adding facets after. */ void erase_maximal(const Toplex_map::Simplex_ptr& sptr); @@ -150,7 +150,7 @@ void Toplex_map::insert_simplex(const Input_vertex_range& vertex_range) { if (replace_facets) for (const Toplex_map::Simplex& facet : facets(vertex_range)) erase_maximal(get_key(facet)); else - for (const Toplex_map::Vertex& v : vertex_range) + for (const Vertex& v : vertex_range) if (t0.count(v)) for (const Toplex_map::Simplex_ptr& fptr : Simplex_ptr_set(t0.at(v))) // Copy constructor needed because the set is modified @@ -164,7 +164,7 @@ void Toplex_map::remove_simplex(const Input_vertex_range& vertex_range) { if (vertex_range.begin() == vertex_range.end()) t0.clear(); // Removal of the empty simplex means cleaning everything else { - const Toplex_map::Vertex& v = best_index(vertex_range); + const Vertex& v = best_index(vertex_range); if (t0.count(v)) for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(v))) // Copy constructor needed because the set is modified @@ -180,7 +180,7 @@ void Toplex_map::remove_simplex(const Input_vertex_range& vertex_range) { template bool Toplex_map::membership(const Input_vertex_range& vertex_range) const { if (t0.size() == 0) return false; - const Toplex_map::Vertex& v = best_index(vertex_range); + const Vertex& v = best_index(vertex_range); if (!t0.count(v)) return false; if (maximality(vertex_range)) return true; for (const Toplex_map::Simplex_ptr& sptr : t0.at(v)) @@ -190,7 +190,7 @@ bool Toplex_map::membership(const Input_vertex_range& vertex_range) const { template bool Toplex_map::maximality(const Input_vertex_range& vertex_range) const { - const Toplex_map::Vertex& v = best_index(vertex_range); + const Vertex& v = best_index(vertex_range); if (!t0.count(v)) return false; return t0.at(v).count(get_key(vertex_range)); } @@ -209,7 +209,7 @@ Toplex_map::Simplex_ptr_set Toplex_map::maximal_cofaces(const Input_vertex_range if (cofaces.size() == max_number) return cofaces; } else { - const Toplex_map::Vertex& v = best_index(vertex_range); + const Vertex& v = best_index(vertex_range); if (t0.count(v)) for (const Toplex_map::Simplex_ptr& sptr : t0.at(v)) if (included(vertex_range, *sptr)) { @@ -240,13 +240,13 @@ Toplex_map::Vertex Toplex_map::contraction(const Toplex_map::Vertex x, const Top } std::set Toplex_map::unitary_collapse(const Toplex_map::Vertex k, const Toplex_map::Vertex d) { - std::set r; + Toplex_map::Simplex r; for (const Toplex_map::Simplex_ptr& sptr : Simplex_ptr_set(t0.at(d))) { // Copy constructor needed because the set is modified Simplex sigma(*sptr); erase_maximal(sptr); sigma.erase(d); - for (const Toplex_map::Vertex v : sigma) r.insert(v); + for (const Vertex v : sigma) r.insert(v); sigma.insert(k); insert_simplex(sigma); } @@ -256,7 +256,7 @@ std::set Toplex_map::unitary_collapse(const Toplex_map::Vert template void Toplex_map::insert_independent_simplex(const Input_vertex_range& vertex_range) { auto key = get_key(vertex_range); - for (const Toplex_map::Vertex& v : vertex_range) { + for (const Vertex& v : vertex_range) { if (!t0.count(v)) t0.emplace(v, Simplex_ptr_set()); t0.at(v).emplace(key); } @@ -274,7 +274,7 @@ void Toplex_map::remove_vertex(const Toplex_map::Vertex x) { inline void Toplex_map::erase_maximal(const Toplex_map::Simplex_ptr& sptr) { Simplex sigma(*sptr); if (sptr->size() == 0) sigma.insert(VERTEX_UPPER_BOUND); - for (const Toplex_map::Vertex& v : sigma) { + for (const Vertex& v : sigma) { t0.at(v).erase(sptr); if (t0.at(v).size() == 0) t0.erase(v); } @@ -284,7 +284,7 @@ template Toplex_map::Vertex Toplex_map::best_index(const Input_vertex_range& vertex_range) const { std::size_t min = std::numeric_limits::max(); Vertex arg_min = VERTEX_UPPER_BOUND; - for (const Toplex_map::Vertex& v : vertex_range) + for (const Vertex& v : vertex_range) if (!t0.count(v)) return v; else if (t0.at(v).size() < min) @@ -303,7 +303,7 @@ std::size_t Toplex_map::Sptr_hash::operator()(const Toplex_map::Simplex_ptr& s) std::hash h_f; // double hash works better than int hash size_t h = 0; - for (const Toplex_map::Vertex& v : *s) h += h_f(static_cast(v)); + for (const Vertex& v : *s) h += h_f(static_cast(v)); return h; } -- cgit v1.2.3 From 5ef02f9f29f4a4fdb63bf7c0f58f535f15c3e254 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 09:37:33 +0000 Subject: Doc review : Rephrase remove_vertex doc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3988 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9930dc524fb4d646135a53e07cc8b8934528442d --- src/Toplex_map/include/gudhi/Toplex_map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index ebdbdc0b..03f348e4 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -96,7 +96,7 @@ class Toplex_map { * Returns the remaining vertex. */ Vertex contraction(const Vertex x, const Vertex y); - /** Removes a vertex from any simplex containing it. */ + /** Remove the vertex and all its cofaces from the complex. */ void remove_vertex(const Vertex x); /** \brief Number of maximal simplices. */ -- cgit v1.2.3 From 2530c5352fec28cc6c27af6b8f645a8b85d86676 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 11:07:35 +0000 Subject: Add some tests for empty toplex management git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3989 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 37ae2287e7905210bc2e699eacbc656ba873e40d --- src/Toplex_map/test/lazy_toplex_map_unit_test.cpp | 73 +++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'src') diff --git a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp index eb1aa0b5..a050cc92 100644 --- a/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp +++ b/src/Toplex_map/test/lazy_toplex_map_unit_test.cpp @@ -95,3 +95,76 @@ BOOST_AUTO_TEST_CASE(toplex_map) { edge = {7, 5}; BOOST_CHECK(tm.membership(edge)); } + +BOOST_AUTO_TEST_CASE(toplex_map_empty_toplex) { + using Vertex = Gudhi::Lazy_toplex_map::Vertex; + + Gudhi::Lazy_toplex_map tm; + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 0); + std::cout << "num_vertices = " << tm.num_vertices() << std::endl; + BOOST_CHECK(tm.num_vertices() == 0); + + std::cout << "Check an empty simplex is a member." << std::endl; + std::vector empty_sigma = {}; + BOOST_CHECK(tm.membership(empty_sigma)); + + std::cout << "Check the edge 2,7 is not a member." << std::endl; + std::vector edge = {2, 7}; + BOOST_CHECK(!tm.membership(edge)); + + std::cout << "Insert an empty simplex." << std::endl; + tm.insert_simplex(empty_sigma); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 0); + std::cout << "num_vertices = " << tm.num_vertices() << std::endl; + BOOST_CHECK(tm.num_vertices() == 0); + + std::cout << "Check an empty simplex is a member." << std::endl; + BOOST_CHECK(tm.membership(empty_sigma)); + std::cout << "Check the edge 2,7 is not a member." << std::endl; + BOOST_CHECK(!tm.membership(edge)); + + std::cout << "Insert edge 2,7." << std::endl; + tm.insert_simplex(edge); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 1); + std::cout << "num_vertices = " << tm.num_vertices() << std::endl; + BOOST_CHECK(tm.num_vertices() == 2); + + std::cout << "Check an empty simplex is a member." << std::endl; + BOOST_CHECK(tm.membership(empty_sigma)); + std::cout << "Check the edge 2,7 is a member." << std::endl; + BOOST_CHECK(tm.membership(edge)); + + std::cout << "contraction(2,7)" << std::endl; + auto r = tm.contraction(2, 7); + std::cout << "r=" << r << std::endl; + BOOST_CHECK(r == 7); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 1); + std::cout << "num_vertices = " << tm.num_vertices() << std::endl; + BOOST_CHECK(tm.num_vertices() == 1); + + std::cout << "Check an empty simplex is a member." << std::endl; + BOOST_CHECK(tm.membership(empty_sigma)); + std::cout << "Check the edge 2,7 is not a member." << std::endl; + BOOST_CHECK(!tm.membership(edge)); + + std::cout << "Remove the vertex 7." << std::endl; + std::vector vertex = {7}; + tm.remove_simplex(vertex); + + std::cout << "num_maximal_simplices = " << tm.num_maximal_simplices() << std::endl; + BOOST_CHECK(tm.num_maximal_simplices() == 0); + std::cout << "num_vertices = " << tm.num_vertices() << std::endl; + BOOST_CHECK(tm.num_vertices() == 0); + + std::cout << "Check an empty simplex is a member." << std::endl; + BOOST_CHECK(tm.membership(empty_sigma)); + std::cout << "Check the edge 2,7 is not a member." << std::endl; + BOOST_CHECK(!tm.membership(edge)); +} -- cgit v1.2.3 From 8ca964ddf732e5e2926ccc5feb1d27d827ba3d40 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Nov 2018 15:11:22 +0000 Subject: Doc review : Bad copy/paste git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@3993 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 20fe516698230f532c38535ec21b89dc12b7a9d9 --- src/Toplex_map/include/gudhi/Lazy_toplex_map.h | 2 +- src/Toplex_map/include/gudhi/Toplex_map.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h index bc09c57d..b0b3706e 100644 --- a/src/Toplex_map/include/gudhi/Lazy_toplex_map.h +++ b/src/Toplex_map/include/gudhi/Lazy_toplex_map.h @@ -55,7 +55,7 @@ class Lazy_toplex_map { void insert_independent_simplex(const Input_vertex_range &vertex_range); /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex (i.e. it is a face of one of the toplices). */ + * Nothing happens if the simplex is already in the complex (i.e. it is a face of one of the toplices). */ template bool insert_simplex(const Input_vertex_range &vertex_range); diff --git a/src/Toplex_map/include/gudhi/Toplex_map.h b/src/Toplex_map/include/gudhi/Toplex_map.h index 03f348e4..4dc2331f 100644 --- a/src/Toplex_map/include/gudhi/Toplex_map.h +++ b/src/Toplex_map/include/gudhi/Toplex_map.h @@ -61,7 +61,7 @@ class Toplex_map { using Simplex_ptr_set = std::unordered_set; /** \brief Adds the given simplex to the complex. - * Nothing happens if the simplex has a coface in the complex (i.e. it is a face of one of the toplices). */ + * Nothing happens if the simplex is already in the complex (i.e. it is a face of one of the toplices). */ template void insert_simplex(const Input_vertex_range& vertex_range); -- cgit v1.2.3 From 6f9bbc57d9abb1bd395b7c4d58184ee53656fc72 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 18 Feb 2019 17:15:41 +0000 Subject: Add biblio and doc references git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/toplex_map@4111 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 42a6e48271d333d604cb5cb0c9c9f1e56b8f1965 --- biblio/bibliography.bib | 34 ++++++++++++++++++++++++++++++++++ src/Toplex_map/doc/Intro_Toplex_map.h | 6 ++++-- 2 files changed, 38 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index 16f43d6f..47c6b35b 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -1103,3 +1103,37 @@ language={English} pages = {778--796}, year = {2013} } + +@InProceedings{boissonnat_et_al:LIPIcs:2015:5098, + author = {Jean-Daniel Boissonnat and Karthik C. S. and S{\'e}bastien Tavenas}, + title = {{Building Efficient and Compact Data Structures for Simplicial Complexes}}, + booktitle = {31st International Symposium on Computational Geometry (SoCG 2015)}, + pages = {642--656}, + series = {Leibniz International Proceedings in Informatics (LIPIcs)}, + ISBN = {978-3-939897-83-5}, + ISSN = {1868-8969}, + year = {2015}, + volume = {34}, + editor = {Lars Arge and J{\'a}nos Pach}, + publisher = {Schloss Dagstuhl--Leibniz-Zentrum fuer Informatik}, + address = {Dagstuhl, Germany}, + URL = {http://drops.dagstuhl.de/opus/volltexte/2015/5098}, + URN = {urn:nbn:de:0030-drops-50981}, + doi = {10.4230/LIPIcs.SOCG.2015.642}, + annote = {Keywords: Simplicial complex, Compact data structures, Automaton, NP-hard} +} + +@article{DBLP:journals/corr/BoissonnatS16, + author = {Jean{-}Daniel Boissonnat and + {Karthik {C. S.}}}, + title = {An Efficient Representation for Filtrations of Simplicial Complexes}, + journal = {CoRR}, + volume = {abs/1607.08449}, + year = {2016}, + url = {http://arxiv.org/abs/1607.08449}, + archivePrefix = {arXiv}, + eprint = {1607.08449}, + timestamp = {Mon, 13 Aug 2018 16:46:26 +0200}, + biburl = {https://dblp.org/rec/bib/journals/corr/BoissonnatS16}, + bibsource = {dblp computer science bibliography, https://dblp.org} +} \ No newline at end of file diff --git a/src/Toplex_map/doc/Intro_Toplex_map.h b/src/Toplex_map/doc/Intro_Toplex_map.h index 0cfbae03..a925dc2b 100644 --- a/src/Toplex_map/doc/Intro_Toplex_map.h +++ b/src/Toplex_map/doc/Intro_Toplex_map.h @@ -45,11 +45,13 @@ namespace Gudhi { * needed for these operation is linear or quadratic in \f$\Gamma_0\f$ and \f$d\f$. * * Toplex map is composed firstly of a raw storage of toplices and secondly of a map which associate any vertex to a - * set of pointers toward all toplices containing this vertex. + * set of pointers toward all toplices containing this vertex. The data structure is described in + * \cite boissonnat_et_al:LIPIcs:2015:5098 (aka. Simplex Array List or SAL). * * \image html map.png * - * The performances are a lot better than the `Simplex_tree` as soon you use maximal simplices and not simplices. + * The performances are a lot better than the `Simplex_tree` as soon you use maximal simplices and not simplices + * (cf. \cite DBLP:journals/corr/BoissonnatS16 ). * */ /** @} */ // end defgroup toplex_map -- cgit v1.2.3