From 15059e2c538cc289d6e67d81d829b8f1ad30c46b Mon Sep 17 00:00:00 2001 From: salinasd Date: Wed, 11 Feb 2015 12:13:22 +0000 Subject: skbl improve efficiency code constructor git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@467 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c1feee162465b6ef0e00811c028d94177e4fa6fc --- .../include/gudhi/Skeleton_blocker_complex.h | 136 +++++++++------------ 1 file changed, 57 insertions(+), 79 deletions(-) (limited to 'src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h') diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h index 81fc28cb..893c65c6 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h @@ -173,23 +173,8 @@ public: } private: - typedef Trie> STrie; - - template - /** - * return a vector of simplex trie for every vertex - */ - std::vector compute_cofaces(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) { - std::vector cofaces(num_vertices(), 0); - for (auto i = 0u; i < num_vertices(); ++i) - cofaces[i] = new STrie(Vertex_handle(i)); - for (auto s_it = simplex_begin; s_it != simplex_end; ++s_it) { - if (s_it->dimension() >= 1) - cofaces[s_it->first_vertex()]->add_simplex(*s_it); - } - return cofaces; - } - + // typedef Trie> STrie; + typedef Trie STrie; public: /** @@ -201,6 +186,16 @@ public: : num_vertices_(0), num_blockers_(0), visitor(visitor_) { + add_vertex_and_edges(simplex_begin,simplex_end); + + if (!is_flag_complex) + // need to compute blockers + add_blockers(simplex_begin,simplex_end); + } + +private: + template + void add_vertex_and_edges(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end){ std::vector> edges; // first pass to add vertices and edges int num_vertex = -1; @@ -212,71 +207,53 @@ public: for (const auto& e : edges) add_edge(e.first, e.second); + } - if (!is_flag_complex) { - // need to compute blockers - std::vector cofaces(compute_cofaces(simplex_begin, simplex_end)); - std::vector max_faces; - - for (auto i = 0u; i < num_vertices(); ++i) { - auto max_faces_i = cofaces[i]->maximal_faces(); - max_faces.insert(max_faces.end(), max_faces_i.begin(), max_faces_i.end()); - } - - // all time here - - // for every maximal face s, it picks its first vertex v and check for all nv \in N(v) - // if s union nv is in the complex, if not it is a blocker. - for (auto max_face : max_faces) { - if (max_face.dimension() > 0) { - auto first_v = max_face.first_vertex(); - for (auto nv : vertex_range(first_v)) { - if (!max_face.contains(nv) && max_face.first_vertex() < nv) { - // check that all edges in vertices(max_face)\cup nv are here - // since max_face is a simplex, we only need to check that edges - // (x nv) where x \in max_face are present - bool all_edges_here = true; - for (auto x : max_face) - if (!contains_edge(x, nv)) { - all_edges_here = false; - break; - } - if (all_edges_here) { // eg this->contains(max_face) - max_face.add_vertex(nv); - if (!cofaces[first_v]->contains(max_face)) { - // if there exists a blocker included in max_face, we remove it - // as it is not a minimum missing face - // the other alternative would be to check to all properfaces - // are in the complex before adding a blocker but that - // would be more expensive if there are few blockers - std::vector blockers_to_remove; - bool is_blocker = true; - for (auto b : blocker_range(first_v)) - if (b->contains(max_face)){ - blockers_to_remove.push_back(b); - } - else - if (max_face.contains(*b)) { - is_blocker = false; - break; - } - for (auto b : blockers_to_remove) - this->delete_blocker(b); - - if(is_blocker) - add_blocker(max_face); - } - max_face.remove_vertex(nv); - } + template + void add_blockers(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end){ + Tries tries(num_vertices(),simplex_begin,simplex_end); + tries.init_next_dimension(); + auto simplices(tries.next_dimension_simplices()); + + while(!simplices.empty()){ + simplices = tries.next_dimension_simplices(); + for(auto& sigma : simplices){ + //common_positive_neighbors is the set of vertices u such that + //for all s in sigma, us is an edge and u>s + Simplex_handle common_positive_neighbors(tries.positive_neighbors(sigma.last_vertex())); + for(auto sigma_it = sigma.rbegin(); sigma_it != sigma.rend(); ++sigma_it/**/) + if(sigma_it != sigma.rbegin()) + common_positive_neighbors.intersection(tries.positive_neighbors(*sigma_it)); + + for(auto x : common_positive_neighbors){ + //first test that all edges sx are here for all s in sigma + bool all_edges_here = true; + for(auto s : sigma) + if(!contains_edge(x,s)){ + all_edges_here = false; + break; } - } + if(!all_edges_here) continue; + + // all edges of sigma \cup x are here + //we have a blocker if all proper faces of sigma \cup x + // are in the complex and if sigma \cup x is not in the complex + //the first is equivalent at checking if blocks(sigma \cup x) is true + //as all blockers of lower dimension have already been computed + sigma.add_vertex(x); + if(!tries.contains(sigma)&&!blocks(sigma)) + add_blocker(sigma); + sigma.remove_vertex(x); } + } - for (auto i = 0u; i < num_vertices(); ++i) - delete(cofaces[i]); } } + +public: + + // We cannot use the default copy constructor since we need // to make a copy of each of the blockers @@ -824,11 +801,12 @@ private: * is a face of sigma. */ bool blocks(const Simplex_handle & sigma) const { - for (auto blocker : const_blocker_range()) { - if (sigma.contains(*blocker)) - return true; - } + for(auto s : sigma) + for (auto blocker : const_blocker_range(s)) + if (sigma.contains(*blocker)) + return true; return false; + } //@} -- cgit v1.2.3