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/include/gudhi/Lazy_toplex_map.h | 299 +++++++++++++------------ 1 file changed, 157 insertions(+), 142 deletions(-) (limited to 'src/Toplex_map/include/gudhi/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 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 */ -- cgit v1.2.3